diff --git a/api/src/com/cloud/api/commands/CreateTemplateCmd.java b/api/src/com/cloud/api/commands/CreateTemplateCmd.java
index 6559dbdf344..397f868346a 100755
--- a/api/src/com/cloud/api/commands/CreateTemplateCmd.java
+++ b/api/src/com/cloud/api/commands/CreateTemplateCmd.java
@@ -18,7 +18,9 @@
package com.cloud.api.commands;
+import java.util.Collection;
import java.util.List;
+import java.util.Map;
import org.apache.log4j.Logger;
@@ -91,7 +93,10 @@ import com.cloud.user.UserContext;
private String url;
@Parameter(name=ApiConstants.TEMPLATE_TAG, type=CommandType.STRING, description="the tag for this template.")
- private String templateTag;
+ private String templateTag;
+
+ @Parameter(name=ApiConstants.DETAILS, type=CommandType.MAP, description="Template details in key/value pairs.")
+ protected Map details;
// ///////////////////////////////////////////////////
// ///////////////// Accessors ///////////////////////
@@ -151,7 +156,18 @@ import com.cloud.user.UserContext;
public String getTemplateTag() {
return templateTag;
- }
+ }
+
+ public Map getDetails() {
+ if (details == null || details.isEmpty()) {
+ return null;
+ }
+
+ Collection paramsCollection = details.values();
+ Map params = (Map) (paramsCollection.toArray())[0];
+ return params;
+ }
+
// ///////////////////////////////////////////////////
// ///////////// API Implementation///////////////////
// ///////////////////////////////////////////////////
diff --git a/api/src/com/cloud/api/commands/RegisterTemplateCmd.java b/api/src/com/cloud/api/commands/RegisterTemplateCmd.java
index df9f10196ec..c4059711ce7 100755
--- a/api/src/com/cloud/api/commands/RegisterTemplateCmd.java
+++ b/api/src/com/cloud/api/commands/RegisterTemplateCmd.java
@@ -18,7 +18,9 @@
package com.cloud.api.commands;
import java.net.URISyntaxException;
+import java.util.Collection;
import java.util.List;
+import java.util.Map;
import org.apache.log4j.Logger;
@@ -28,6 +30,7 @@ import com.cloud.api.IdentityMapper;
import com.cloud.api.Implementation;
import com.cloud.api.Parameter;
import com.cloud.api.ServerApiException;
+import com.cloud.api.BaseCmd.CommandType;
import com.cloud.api.response.ListResponse;
import com.cloud.api.response.TemplateResponse;
import com.cloud.async.AsyncJob;
@@ -102,6 +105,9 @@ public class RegisterTemplateCmd extends BaseCmd {
@IdentityMapper(entityTableName="projects")
@Parameter(name=ApiConstants.PROJECT_ID, type=CommandType.LONG, description="Register template for the project")
private Long projectId;
+
+ @Parameter(name=ApiConstants.DETAILS, type=CommandType.MAP, description="Template details in key/value pairs.")
+ protected Map details;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
@@ -173,7 +179,18 @@ public class RegisterTemplateCmd extends BaseCmd {
public String getTemplateTag() {
return templateTag;
- }
+ }
+
+ public Map getDetails() {
+ if (details == null || details.isEmpty()) {
+ return null;
+ }
+
+ Collection paramsCollection = details.values();
+ Map params = (Map) (paramsCollection.toArray())[0];
+ return params;
+ }
+
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
diff --git a/core/src/com/cloud/storage/VMTemplateDetailVO.java b/core/src/com/cloud/storage/VMTemplateDetailVO.java
new file mode 100644
index 00000000000..89f4b821812
--- /dev/null
+++ b/core/src/com/cloud/storage/VMTemplateDetailVO.java
@@ -0,0 +1,83 @@
+/**
+ * Copyright (C) 2010 Cloud.com, Inc. All rights reserved.
+ *
+ * This software is licensed under the GNU General Public License v3 or later.
+ *
+ * It is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+package com.cloud.storage;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+@Entity
+@Table(name="vm_template_details")
+public class VMTemplateDetailVO {
+ @Id
+ @GeneratedValue(strategy=GenerationType.IDENTITY)
+ @Column(name="id")
+ private long id;
+
+ @Column(name="template_id")
+ private long templateId;
+
+ @Column(name="name")
+ private String name;
+
+ @Column(name="value", length=1024)
+ private String value;
+
+ public VMTemplateDetailVO() {}
+
+ public VMTemplateDetailVO(long templateId, String name, String value) {
+ this.templateId = templateId;
+ this.name = name;
+ this.value = value;
+ }
+
+ public long getId() {
+ return id;
+ }
+
+ public long getTemplateId() {
+ return templateId;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ public void setTemplateId(long templateId) {
+ this.templateId = templateId;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public void setValue(String value) {
+ this.value = value;
+ }
+}
diff --git a/core/src/com/cloud/storage/VMTemplateVO.java b/core/src/com/cloud/storage/VMTemplateVO.java
index cf757da11fc..98866bddf32 100755
--- a/core/src/com/cloud/storage/VMTemplateVO.java
+++ b/core/src/com/cloud/storage/VMTemplateVO.java
@@ -19,6 +19,7 @@
package com.cloud.storage;
import java.util.Date;
+import java.util.Map;
import java.util.UUID;
import javax.persistence.Column;
@@ -122,9 +123,10 @@ public class VMTemplateVO implements VirtualMachineTemplate, Identity {
@Column(name="uuid")
private String uuid;
-
@Column(name="sort_key")
int sortKey;
+
+ Map details;
@Override
public String getUniqueName() {
@@ -142,13 +144,13 @@ public class VMTemplateVO implements VirtualMachineTemplate, Identity {
/**
* Proper constructor for a new vm template.
*/
- public VMTemplateVO(long id, String name, ImageFormat format, boolean isPublic, boolean featured, boolean isExtractable, TemplateType type, String url, boolean requiresHvm, int bits, long accountId, String cksum, String displayText, boolean enablePassword, long guestOSId, boolean bootable, HypervisorType hyperType) {
- this(id, generateUniqueName(id, accountId, name), name, format, isPublic, featured, isExtractable, type, url, null, requiresHvm, bits, accountId, cksum, displayText, enablePassword, guestOSId, bootable, hyperType);
+ public VMTemplateVO(long id, String name, ImageFormat format, boolean isPublic, boolean featured, boolean isExtractable, TemplateType type, String url, boolean requiresHvm, int bits, long accountId, String cksum, String displayText, boolean enablePassword, long guestOSId, boolean bootable, HypervisorType hyperType, Map details) {
+ this(id, generateUniqueName(id, accountId, name), name, format, isPublic, featured, isExtractable, type, url, null, requiresHvm, bits, accountId, cksum, displayText, enablePassword, guestOSId, bootable, hyperType, details);
this.uuid = UUID.randomUUID().toString();
}
- public VMTemplateVO(long id, String name, ImageFormat format, boolean isPublic, boolean featured, boolean isExtractable, TemplateType type, String url, boolean requiresHvm, int bits, long accountId, String cksum, String displayText, boolean enablePassword, long guestOSId, boolean bootable, HypervisorType hyperType, String templateTag) {
- this(id, name, format, isPublic, featured, isExtractable, type, url, requiresHvm, bits, accountId, cksum, displayText, enablePassword, guestOSId, bootable, hyperType);
+ public VMTemplateVO(long id, String name, ImageFormat format, boolean isPublic, boolean featured, boolean isExtractable, TemplateType type, String url, boolean requiresHvm, int bits, long accountId, String cksum, String displayText, boolean enablePassword, long guestOSId, boolean bootable, HypervisorType hyperType, String templateTag, Map details) {
+ this(id, name, format, isPublic, featured, isExtractable, type, url, requiresHvm, bits, accountId, cksum, displayText, enablePassword, guestOSId, bootable, hyperType, details);
this.templateTag = templateTag;
this.uuid = UUID.randomUUID().toString();
}
@@ -176,14 +178,15 @@ public class VMTemplateVO implements VirtualMachineTemplate, Identity {
}
// Has an extra attribute - isExtractable
- public VMTemplateVO(Long id, String uniqueName, String name, ImageFormat format, boolean isPublic, boolean featured, boolean isExtractable, TemplateType type, String url, Date created, boolean requiresHvm, int bits, long accountId, String cksum, String displayText, boolean enablePassword, long guestOSId, boolean bootable, HypervisorType hyperType) {
+ public VMTemplateVO(Long id, String uniqueName, String name, ImageFormat format, boolean isPublic, boolean featured, boolean isExtractable, TemplateType type, String url, Date created, boolean requiresHvm, int bits, long accountId, String cksum, String displayText, boolean enablePassword, long guestOSId, boolean bootable, HypervisorType hyperType, Map details) {
this(id, uniqueName, name, format, isPublic, featured, type, url, created, requiresHvm, bits, accountId, cksum, displayText, enablePassword, guestOSId, bootable, hyperType);
this.extractable = isExtractable;
this.uuid = UUID.randomUUID().toString();
+ this.details = details;
}
- public VMTemplateVO(Long id, String uniqueName, String name, ImageFormat format, boolean isPublic, boolean featured, boolean isExtractable, TemplateType type, String url, Date created, boolean requiresHvm, int bits, long accountId, String cksum, String displayText, boolean enablePassword, long guestOSId, boolean bootable, HypervisorType hyperType, String templateTag) {
- this(id, uniqueName, name, format, isPublic, featured, isExtractable, type, url, created, requiresHvm, bits, accountId, cksum, displayText, enablePassword, guestOSId, bootable, hyperType);
+ public VMTemplateVO(Long id, String uniqueName, String name, ImageFormat format, boolean isPublic, boolean featured, boolean isExtractable, TemplateType type, String url, Date created, boolean requiresHvm, int bits, long accountId, String cksum, String displayText, boolean enablePassword, long guestOSId, boolean bootable, HypervisorType hyperType, String templateTag, Map details) {
+ this(id, uniqueName, name, format, isPublic, featured, isExtractable, type, url, created, requiresHvm, bits, accountId, cksum, displayText, enablePassword, guestOSId, bootable, hyperType, details);
this.templateTag = templateTag;
this.uuid = UUID.randomUUID().toString();
}
@@ -404,6 +407,14 @@ public class VMTemplateVO implements VirtualMachineTemplate, Identity {
public void setUuid(String uuid) {
this.uuid = uuid;
}
+
+ public Map getDetails() {
+ return this.details;
+ }
+
+ public void setDetails(Map details) {
+ this.details = details;
+ }
@Override
public boolean equals(Object that) {
diff --git a/server/src/com/cloud/baremetal/BareMetalVmManagerImpl.java b/server/src/com/cloud/baremetal/BareMetalVmManagerImpl.java
index 634910021dd..895424cf1a3 100755
--- a/server/src/com/cloud/baremetal/BareMetalVmManagerImpl.java
+++ b/server/src/com/cloud/baremetal/BareMetalVmManagerImpl.java
@@ -185,7 +185,7 @@ public class BareMetalVmManagerImpl extends UserVmManagerImpl implements BareMet
try {
TemplateProfile tmplProfile;
tmplProfile = adapter.prepare(false, userId, cmd.getTemplateName(), cmd.getDisplayText(), cmd.getBits(), false, false, cmd.getUrl(), cmd.isPublic(), cmd.isFeatured(), false,
- "BareMetal", cmd.getOsTypeId(), pxe.getDataCenterId(), HypervisorType.BareMetal, account.getAccountName(), account.getDomainId(), "0", true);
+ "BareMetal", cmd.getOsTypeId(), pxe.getDataCenterId(), HypervisorType.BareMetal, account.getAccountName(), account.getDomainId(), "0", true, cmd.getDetails());
if (!_pxeMgr.prepareCreateTemplate(_pxeMgr.getPxeServerType(pxe), pxe.getId(), vm, cmd.getUrl())) {
throw new Exception("Prepare PXE boot file for host " + hostId + " failed");
diff --git a/server/src/com/cloud/configuration/DefaultComponentLibrary.java b/server/src/com/cloud/configuration/DefaultComponentLibrary.java
index a3bb83d72ba..7dc10cacf1b 100755
--- a/server/src/com/cloud/configuration/DefaultComponentLibrary.java
+++ b/server/src/com/cloud/configuration/DefaultComponentLibrary.java
@@ -148,6 +148,7 @@ import com.cloud.storage.dao.StoragePoolWorkDaoImpl;
import com.cloud.storage.dao.SwiftDaoImpl;
import com.cloud.storage.dao.UploadDaoImpl;
import com.cloud.storage.dao.VMTemplateDaoImpl;
+import com.cloud.storage.dao.VMTemplateDetailsDaoImpl;
import com.cloud.storage.dao.VMTemplateHostDaoImpl;
import com.cloud.storage.dao.VMTemplatePoolDaoImpl;
import com.cloud.storage.dao.VMTemplateSwiftDaoImpl;
@@ -195,6 +196,7 @@ public class DefaultComponentLibrary extends ComponentLibraryBase implements Com
protected void populateDaos() {
addDao("StackMaidDao", StackMaidDaoImpl.class);
addDao("VMTemplateZoneDao", VMTemplateZoneDaoImpl.class);
+ addDao("VMTemplateDetailsDao", VMTemplateDetailsDaoImpl.class);
addDao("DomainRouterDao", DomainRouterDaoImpl.class);
addDao("HostDao", HostDaoImpl.class);
addDao("VMInstanceDao", VMInstanceDaoImpl.class);
diff --git a/server/src/com/cloud/storage/dao/VMTemplateDaoImpl.java b/server/src/com/cloud/storage/dao/VMTemplateDaoImpl.java
index ffabe1c6fd4..4ae11d9ccb0 100755
--- a/server/src/com/cloud/storage/dao/VMTemplateDaoImpl.java
+++ b/server/src/com/cloud/storage/dao/VMTemplateDaoImpl.java
@@ -68,6 +68,9 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem
@Inject
VMTemplateZoneDao _templateZoneDao;
+ @Inject
+ VMTemplateDetailsDao _templateDetailsDao;
+
@Inject
ConfigurationDao _configDao;
@Inject
@@ -681,6 +684,9 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem
VMTemplateVO tmplt2 = findById(tmplt.getId());
if (tmplt2 == null){
persist(tmplt);
+ if(tmplt.getDetails() != null) {
+ _templateDetailsDao.persist(tmplt.getId(), tmplt.getDetails());
+ }
}
VMTemplateZoneVO tmpltZoneVO = _templateZoneDao.findByZoneTemplate(zoneId, tmplt.getId());
if ( tmpltZoneVO == null ) {
diff --git a/server/src/com/cloud/storage/dao/VMTemplateDetailsDao.java b/server/src/com/cloud/storage/dao/VMTemplateDetailsDao.java
new file mode 100644
index 00000000000..9b742f90fa2
--- /dev/null
+++ b/server/src/com/cloud/storage/dao/VMTemplateDetailsDao.java
@@ -0,0 +1,33 @@
+/**
+ * Copyright (C) 2010 Cloud.com, Inc. All rights reserved.
+ *
+ * This software is licensed under the GNU General Public License v3 or later.
+ *
+ * It is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+package com.cloud.storage.dao;
+
+import java.util.Map;
+
+import com.cloud.storage.VMTemplateDetailVO;
+import com.cloud.utils.db.GenericDao;
+
+public interface VMTemplateDetailsDao extends GenericDao {
+ Map findDetails(long templateId);
+
+ void persist(long templateId, Map details);
+
+ VMTemplateDetailVO findDetail(long templateId, String name);
+
+ void deleteDetails(long vmId);
+}
diff --git a/server/src/com/cloud/storage/dao/VMTemplateDetailsDaoImpl.java b/server/src/com/cloud/storage/dao/VMTemplateDetailsDaoImpl.java
new file mode 100644
index 00000000000..9550f4a15bb
--- /dev/null
+++ b/server/src/com/cloud/storage/dao/VMTemplateDetailsDaoImpl.java
@@ -0,0 +1,80 @@
+package com.cloud.storage.dao;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.ejb.Local;
+
+import com.cloud.storage.VMTemplateDetailVO;
+import com.cloud.utils.db.GenericDaoBase;
+import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.db.SearchCriteria;
+import com.cloud.utils.db.Transaction;
+
+@Local(value=VMTemplateDetailsDao.class)
+public class VMTemplateDetailsDaoImpl extends GenericDaoBase implements VMTemplateDetailsDao {
+
+ protected final SearchBuilder TemplateSearch;
+ protected final SearchBuilder DetailSearch;
+
+ protected VMTemplateDetailsDaoImpl() {
+ TemplateSearch = createSearchBuilder();
+ TemplateSearch.and("templateId", TemplateSearch.entity().getTemplateId(), SearchCriteria.Op.EQ);
+ TemplateSearch.done();
+
+ DetailSearch = createSearchBuilder();
+ DetailSearch.and("templateId", DetailSearch.entity().getTemplateId(), SearchCriteria.Op.EQ);
+ DetailSearch.and("name", DetailSearch.entity().getName(), SearchCriteria.Op.EQ);
+ DetailSearch.done();
+ }
+
+ @Override
+ public void deleteDetails(long templateId) {
+ SearchCriteria sc = TemplateSearch.create();
+ sc.setParameters("templateId", templateId);
+
+ List results = search(sc, null);
+ for (VMTemplateDetailVO result : results) {
+ remove(result.getId());
+ }
+ }
+
+ @Override
+ public VMTemplateDetailVO findDetail(long templateId, String name) {
+ SearchCriteria sc = DetailSearch.create();
+ sc.setParameters("templateId", templateId);
+ sc.setParameters("name", name);
+
+ return findOneBy(sc);
+ }
+
+ @Override
+ public Map findDetails(long templateId) {
+ SearchCriteria sc = TemplateSearch.create();
+ sc.setParameters("templateId", templateId);
+
+ List results = search(sc, null);
+ Map details = new HashMap(results.size());
+ for (VMTemplateDetailVO result : results) {
+ details.put(result.getName(), result.getValue());
+ }
+
+ return details;
+ }
+
+ @Override
+ public void persist(long templateId, Map details) {
+ Transaction txn = Transaction.currentTxn();
+ txn.start();
+ SearchCriteria sc = TemplateSearch.create();
+ sc.setParameters("templateId", templateId);
+ expunge(sc);
+
+ for (Map.Entry detail : details.entrySet()) {
+ VMTemplateDetailVO vo = new VMTemplateDetailVO(templateId, detail.getKey(), detail.getValue());
+ persist(vo);
+ }
+ txn.commit();
+ }
+}
diff --git a/server/src/com/cloud/template/TemplateAdapter.java b/server/src/com/cloud/template/TemplateAdapter.java
index c27f7d3fc44..5c9027ee402 100644
--- a/server/src/com/cloud/template/TemplateAdapter.java
+++ b/server/src/com/cloud/template/TemplateAdapter.java
@@ -1,5 +1,7 @@
package com.cloud.template;
+import java.util.Map;
+
import com.cloud.api.commands.DeleteIsoCmd;
import com.cloud.api.commands.DeleteTemplateCmd;
import com.cloud.api.commands.RegisterIsoCmd;
@@ -41,10 +43,10 @@ public interface TemplateAdapter extends Adapter {
public TemplateProfile prepare(boolean isIso, Long userId, String name, String displayText, Integer bits,
Boolean passwordEnabled, Boolean requiresHVM, String url, Boolean isPublic, Boolean featured,
Boolean isExtractable, String format, Long guestOSId, Long zoneId, HypervisorType hypervisorType,
- String accountName, Long domainId, String chksum, Boolean bootable) throws ResourceAllocationException;
+ String accountName, Long domainId, String chksum, Boolean bootable, Map details) throws ResourceAllocationException;
public TemplateProfile prepare(boolean isIso, Long userId, String name, String displayText, Integer bits,
Boolean passwordEnabled, Boolean requiresHVM, String url, Boolean isPublic, Boolean featured,
Boolean isExtractable, String format, Long guestOSId, Long zoneId, HypervisorType hypervisorType,
- String chksum, Boolean bootable, String templateTag, Account templateOwner) throws ResourceAllocationException;
+ String chksum, Boolean bootable, String templateTag, Account templateOwner, Map details) throws ResourceAllocationException;
}
diff --git a/server/src/com/cloud/template/TemplateAdapterBase.java b/server/src/com/cloud/template/TemplateAdapterBase.java
index b8695cd2254..f6f0c441d8a 100755
--- a/server/src/com/cloud/template/TemplateAdapterBase.java
+++ b/server/src/com/cloud/template/TemplateAdapterBase.java
@@ -90,14 +90,14 @@ public abstract class TemplateAdapterBase implements TemplateAdapter {
public TemplateProfile prepare(boolean isIso, Long userId, String name, String displayText, Integer bits,
Boolean passwordEnabled, Boolean requiresHVM, String url, Boolean isPublic, Boolean featured,
Boolean isExtractable, String format, Long guestOSId, Long zoneId, HypervisorType hypervisorType,
- String accountName, Long domainId, String chksum, Boolean bootable) throws ResourceAllocationException {
+ String accountName, Long domainId, String chksum, Boolean bootable, Map details) throws ResourceAllocationException {
return prepare(isIso, userId, name, displayText, bits, passwordEnabled, requiresHVM, url, isPublic, featured, isExtractable, format, guestOSId, zoneId, hypervisorType,
- chksum, bootable, null, null);
+ chksum, bootable, null, null, details);
}
public TemplateProfile prepare(boolean isIso, Long userId, String name, String displayText, Integer bits,
Boolean passwordEnabled, Boolean requiresHVM, String url, Boolean isPublic, Boolean featured,
Boolean isExtractable, String format, Long guestOSId, Long zoneId, HypervisorType hypervisorType,
- String chksum, Boolean bootable, String templateTag, Account templateOwner) throws ResourceAllocationException {
+ String chksum, Boolean bootable, String templateTag, Account templateOwner, Map details) throws ResourceAllocationException {
//Long accountId = null;
// parameters verification
@@ -200,7 +200,7 @@ public abstract class TemplateAdapterBase implements TemplateAdapter {
Long id = _tmpltDao.getNextInSequence(Long.class, "id");
UserContext.current().setEventDetails("Id: " +id+ " name: " + name);
return new TemplateProfile(id, userId, name, displayText, bits, passwordEnabled, requiresHVM, url, isPublic,
- featured, isExtractable, imgfmt, guestOSId, zoneId, hypervisorType, templateOwner.getAccountName(), templateOwner.getDomainId(), templateOwner.getAccountId(), chksum, bootable, templateTag);
+ featured, isExtractable, imgfmt, guestOSId, zoneId, hypervisorType, templateOwner.getAccountName(), templateOwner.getDomainId(), templateOwner.getAccountId(), chksum, bootable, templateTag, details);
}
@Override
@@ -213,7 +213,7 @@ public abstract class TemplateAdapterBase implements TemplateAdapter {
return prepare(false, UserContext.current().getCallerUserId(), cmd.getTemplateName(), cmd.getDisplayText(),
cmd.getBits(), cmd.isPasswordEnabled(), cmd.getRequiresHvm(), cmd.getUrl(), cmd.isPublic(), cmd.isFeatured(),
cmd.isExtractable(), cmd.getFormat(), cmd.getOsTypeId(), cmd.getZoneId(), HypervisorType.getType(cmd.getHypervisor()),
- cmd.getChecksum(), true, cmd.getTemplateTag(), owner);
+ cmd.getChecksum(), true, cmd.getTemplateTag(), owner, cmd.getDetails());
}
public TemplateProfile prepare(RegisterIsoCmd cmd) throws ResourceAllocationException {
@@ -224,7 +224,7 @@ public abstract class TemplateAdapterBase implements TemplateAdapter {
return prepare(true, UserContext.current().getCallerUserId(), cmd.getIsoName(), cmd.getDisplayText(), 64, false,
true, cmd.getUrl(), cmd.isPublic(), cmd.isFeatured(), cmd.isExtractable(), ImageFormat.ISO.toString(), cmd.getOsTypeId(),
- cmd.getZoneId(), HypervisorType.None, cmd.getChecksum(), cmd.isBootable(), null, owner);
+ cmd.getZoneId(), HypervisorType.None, cmd.getChecksum(), cmd.isBootable(), null, owner, null);
}
protected VMTemplateVO persistTemplate(TemplateProfile profile) {
@@ -232,7 +232,8 @@ public abstract class TemplateAdapterBase implements TemplateAdapter {
VMTemplateVO template = new VMTemplateVO(profile.getTemplateId(), profile.getName(), profile.getFormat(), profile.getIsPublic(),
profile.getFeatured(), profile.getIsExtractable(), TemplateType.USER, profile.getUrl(), profile.getRequiresHVM(),
profile.getBits(), profile.getAccountId(), profile.getCheckSum(), profile.getDisplayText(),
- profile.getPasswordEnabled(), profile.getGuestOsId(), profile.getBootable(), profile.getHypervisorType(), profile.getTemplateTag());
+ profile.getPasswordEnabled(), profile.getGuestOsId(), profile.getBootable(), profile.getHypervisorType(), profile.getTemplateTag(),
+ profile.getDetails());
if (zoneId == null || zoneId == -1) {
List dcs = _dcDao.listAllIncludingRemoved();
diff --git a/server/src/com/cloud/template/TemplateProfile.java b/server/src/com/cloud/template/TemplateProfile.java
index f5e7ee39285..6e9bb223d9c 100644
--- a/server/src/com/cloud/template/TemplateProfile.java
+++ b/server/src/com/cloud/template/TemplateProfile.java
@@ -1,5 +1,7 @@
package com.cloud.template;
+import java.util.Map;
+
import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.storage.Storage.ImageFormat;
import com.cloud.storage.VMTemplateVO;
@@ -27,10 +29,11 @@ public class TemplateProfile {
Long templateId;
VMTemplateVO template;
String templateTag;
+ Map details;
public TemplateProfile(Long templateId, Long userId, String name, String displayText, Integer bits, Boolean passwordEnabled, Boolean requiresHvm,
String url, Boolean isPublic, Boolean featured, Boolean isExtractable, ImageFormat format, Long guestOsId, Long zoneId,
- HypervisorType hypervisorType, String accountName, Long domainId, Long accountId, String chksum, Boolean bootable) {
+ HypervisorType hypervisorType, String accountName, Long domainId, Long accountId, String chksum, Boolean bootable, Map details) {
this.templateId = templateId;
this.userId = userId;
this.name = name;
@@ -51,6 +54,7 @@ public class TemplateProfile {
this.accountId = accountId;
this.chksum = chksum;
this.bootable = bootable;
+ this.details = details;
}
public TemplateProfile(Long userId, VMTemplateVO template, Long zoneId) {
@@ -61,9 +65,9 @@ public class TemplateProfile {
public TemplateProfile(Long templateId, Long userId, String name, String displayText, Integer bits, Boolean passwordEnabled, Boolean requiresHvm,
String url, Boolean isPublic, Boolean featured, Boolean isExtractable, ImageFormat format, Long guestOsId, Long zoneId,
- HypervisorType hypervisorType, String accountName, Long domainId, Long accountId, String chksum, Boolean bootable, String templateTag) {
+ HypervisorType hypervisorType, String accountName, Long domainId, Long accountId, String chksum, Boolean bootable, String templateTag, Map details) {
this(templateId, userId, name, displayText, bits, passwordEnabled, requiresHvm, url, isPublic, featured, isExtractable, format, guestOsId, zoneId,
- hypervisorType, accountName, domainId, accountId, chksum, bootable);
+ hypervisorType, accountName, domainId, accountId, chksum, bootable, details);
this.templateTag = templateTag;
}
@@ -215,4 +219,11 @@ public class TemplateProfile {
this.templateTag = templateTag;
}
+ public Map getDetails() {
+ return this.details;
+ }
+
+ public void setDetails(Map details) {
+ this.details = details;
+ }
}
diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java
index a7f36d8079e..2bfc0448548 100755
--- a/server/src/com/cloud/vm/UserVmManagerImpl.java
+++ b/server/src/com/cloud/vm/UserVmManagerImpl.java
@@ -178,6 +178,7 @@ import com.cloud.storage.dao.GuestOSDao;
import com.cloud.storage.dao.SnapshotDao;
import com.cloud.storage.dao.StoragePoolDao;
import com.cloud.storage.dao.VMTemplateDao;
+import com.cloud.storage.dao.VMTemplateDetailsDao;
import com.cloud.storage.dao.VMTemplateHostDao;
import com.cloud.storage.dao.VMTemplateZoneDao;
import com.cloud.storage.dao.VolumeDao;
@@ -247,6 +248,8 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
@Inject
protected VMTemplateDao _templateDao = null;
@Inject
+ protected VMTemplateDetailsDao _templateDetailsDao = null;
+ @Inject
protected VMTemplateHostDao _templateHostDao = null;
@Inject
protected VMTemplateZoneDao _templateZoneDao = null;
@@ -1424,7 +1427,7 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
}
}
privateTemplate = new VMTemplateVO(nextTemplateId, uniqueName, name, ImageFormat.RAW, isPublic, featured, isExtractable, TemplateType.USER, null, null, requiresHvmValue, bitsValue, accountId,
- null, description, passwordEnabledValue, guestOS.getId(), true, hyperType, templateTag);
+ null, description, passwordEnabledValue, guestOS.getId(), true, hyperType, templateTag, cmd.getDetails());
if(sourceTemplateId != null){
if(s_logger.isDebugEnabled()){
s_logger.debug("This template is getting created from other template, setting source template Id to: "+sourceTemplateId);
@@ -1435,6 +1438,10 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
VMTemplateVO template = _templateDao.persist(privateTemplate);
// Increment the number of templates
if (template != null) {
+ if(cmd.getDetails() != null) {
+ _templateDetailsDao.persist(template.getId(), cmd.getDetails());
+ }
+
_resourceLimitMgr.incrementResourceCount(accountId, ResourceType.template);
}
diff --git a/setup/db/create-schema.sql b/setup/db/create-schema.sql
index 56b7d967621..b56528ab281 100755
--- a/setup/db/create-schema.sql
+++ b/setup/db/create-schema.sql
@@ -906,6 +906,15 @@ CREATE TABLE `cloud`.`vm_template` (
CONSTRAINT `uc_vm_template__uuid` UNIQUE (`uuid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+CREATE TABLE `cloud`.`vm_template_details` (
+ `id` bigint unsigned NOT NULL auto_increment,
+ `template_id` bigint unsigned NOT NULL COMMENT 'template id',
+ `name` varchar(255) NOT NULL,
+ `value` varchar(1024) NOT NULL,
+ PRIMARY KEY (`id`),
+ CONSTRAINT `fk_vm_template_details__template_id` FOREIGN KEY `fk_vm_template_details__template_id`(`template_id`) REFERENCES `vm_template`(`id`) ON DELETE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
CREATE TABLE `cloud`.`vm_instance` (
`id` bigint unsigned UNIQUE NOT NULL,
`name` varchar(255) NOT NULL,
diff --git a/setup/db/db/schema-2213to30.sql b/setup/db/db/schema-2213to30.sql
index 7cb06e94fca..69a2c79782d 100755
--- a/setup/db/db/schema-2213to30.sql
+++ b/setup/db/db/schema-2213to30.sql
@@ -217,3 +217,11 @@ ALTER TABLE `cloud`.`guest_os_category` ADD CONSTRAINT `uc_guest_os_category__uu
ALTER TABLE `cloud`.`nics` ADD COLUMN `uuid` varchar(40);
ALTER TABLE `cloud`.`nics` ADD CONSTRAINT `uc_nics__uuid` UNIQUE (`uuid`);
+CREATE TABLE `cloud`.`vm_template_details` (
+ `id` bigint unsigned NOT NULL auto_increment,
+ `template_id` bigint unsigned NOT NULL COMMENT 'template id',
+ `name` varchar(255) NOT NULL,
+ `value` varchar(1024) NOT NULL,
+ PRIMARY KEY (`id`),
+ CONSTRAINT `fk_vm_template_details__template_id` FOREIGN KEY `fk_vm_template_details__template_id`(`template_id`) REFERENCES `vm_template`(`id`) ON DELETE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;