bug 11814: Allow template to have details info in key/value pairs.

This commit is contained in:
Kelven Yang 2011-11-14 18:04:30 -08:00
parent 0b05badaaa
commit 277c60e4f6
15 changed files with 311 additions and 25 deletions

View File

@ -18,7 +18,9 @@
package com.cloud.api.commands; package com.cloud.api.commands;
import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.Map;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
@ -91,7 +93,10 @@ import com.cloud.user.UserContext;
private String url; private String url;
@Parameter(name=ApiConstants.TEMPLATE_TAG, type=CommandType.STRING, description="the tag for this template.") @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 /////////////////////// // ///////////////// Accessors ///////////////////////
@ -151,7 +156,18 @@ import com.cloud.user.UserContext;
public String getTemplateTag() { public String getTemplateTag() {
return templateTag; 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/////////////////// // ///////////// API Implementation///////////////////
// /////////////////////////////////////////////////// // ///////////////////////////////////////////////////

View File

@ -18,7 +18,9 @@
package com.cloud.api.commands; package com.cloud.api.commands;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.Map;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
@ -28,6 +30,7 @@ import com.cloud.api.IdentityMapper;
import com.cloud.api.Implementation; import com.cloud.api.Implementation;
import com.cloud.api.Parameter; import com.cloud.api.Parameter;
import com.cloud.api.ServerApiException; import com.cloud.api.ServerApiException;
import com.cloud.api.BaseCmd.CommandType;
import com.cloud.api.response.ListResponse; import com.cloud.api.response.ListResponse;
import com.cloud.api.response.TemplateResponse; import com.cloud.api.response.TemplateResponse;
import com.cloud.async.AsyncJob; import com.cloud.async.AsyncJob;
@ -102,6 +105,9 @@ public class RegisterTemplateCmd extends BaseCmd {
@IdentityMapper(entityTableName="projects") @IdentityMapper(entityTableName="projects")
@Parameter(name=ApiConstants.PROJECT_ID, type=CommandType.LONG, description="Register template for the project") @Parameter(name=ApiConstants.PROJECT_ID, type=CommandType.LONG, description="Register template for the project")
private Long projectId; private Long projectId;
@Parameter(name=ApiConstants.DETAILS, type=CommandType.MAP, description="Template details in key/value pairs.")
protected Map details;
///////////////////////////////////////////////////// /////////////////////////////////////////////////////
/////////////////// Accessors /////////////////////// /////////////////// Accessors ///////////////////////
@ -173,7 +179,18 @@ public class RegisterTemplateCmd extends BaseCmd {
public String getTemplateTag() { public String getTemplateTag() {
return templateTag; 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/////////////////// /////////////// API Implementation///////////////////
///////////////////////////////////////////////////// /////////////////////////////////////////////////////

View File

@ -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 <http://www.gnu.org/licenses/>.
*
*/
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;
}
}

View File

@ -19,6 +19,7 @@
package com.cloud.storage; package com.cloud.storage;
import java.util.Date; import java.util.Date;
import java.util.Map;
import java.util.UUID; import java.util.UUID;
import javax.persistence.Column; import javax.persistence.Column;
@ -122,9 +123,10 @@ public class VMTemplateVO implements VirtualMachineTemplate, Identity {
@Column(name="uuid") @Column(name="uuid")
private String uuid; private String uuid;
@Column(name="sort_key") @Column(name="sort_key")
int sortKey; int sortKey;
Map details;
@Override @Override
public String getUniqueName() { public String getUniqueName() {
@ -142,13 +144,13 @@ public class VMTemplateVO implements VirtualMachineTemplate, Identity {
/** /**
* Proper constructor for a new vm template. * 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) { 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); 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(); 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) { 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); this(id, name, format, isPublic, featured, isExtractable, type, url, requiresHvm, bits, accountId, cksum, displayText, enablePassword, guestOSId, bootable, hyperType, details);
this.templateTag = templateTag; this.templateTag = templateTag;
this.uuid = UUID.randomUUID().toString(); this.uuid = UUID.randomUUID().toString();
} }
@ -176,14 +178,15 @@ public class VMTemplateVO implements VirtualMachineTemplate, Identity {
} }
// Has an extra attribute - isExtractable // 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(id, uniqueName, name, format, isPublic, featured, type, url, created, requiresHvm, bits, accountId, cksum, displayText, enablePassword, guestOSId, bootable, hyperType);
this.extractable = isExtractable; this.extractable = isExtractable;
this.uuid = UUID.randomUUID().toString(); 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) { 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); 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.templateTag = templateTag;
this.uuid = UUID.randomUUID().toString(); this.uuid = UUID.randomUUID().toString();
} }
@ -404,6 +407,14 @@ public class VMTemplateVO implements VirtualMachineTemplate, Identity {
public void setUuid(String uuid) { public void setUuid(String uuid) {
this.uuid = uuid; this.uuid = uuid;
} }
public Map getDetails() {
return this.details;
}
public void setDetails(Map details) {
this.details = details;
}
@Override @Override
public boolean equals(Object that) { public boolean equals(Object that) {

View File

@ -185,7 +185,7 @@ public class BareMetalVmManagerImpl extends UserVmManagerImpl implements BareMet
try { try {
TemplateProfile tmplProfile; TemplateProfile tmplProfile;
tmplProfile = adapter.prepare(false, userId, cmd.getTemplateName(), cmd.getDisplayText(), cmd.getBits(), false, false, cmd.getUrl(), cmd.isPublic(), cmd.isFeatured(), false, 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())) { if (!_pxeMgr.prepareCreateTemplate(_pxeMgr.getPxeServerType(pxe), pxe.getId(), vm, cmd.getUrl())) {
throw new Exception("Prepare PXE boot file for host " + hostId + " failed"); throw new Exception("Prepare PXE boot file for host " + hostId + " failed");

View File

@ -148,6 +148,7 @@ import com.cloud.storage.dao.StoragePoolWorkDaoImpl;
import com.cloud.storage.dao.SwiftDaoImpl; import com.cloud.storage.dao.SwiftDaoImpl;
import com.cloud.storage.dao.UploadDaoImpl; import com.cloud.storage.dao.UploadDaoImpl;
import com.cloud.storage.dao.VMTemplateDaoImpl; import com.cloud.storage.dao.VMTemplateDaoImpl;
import com.cloud.storage.dao.VMTemplateDetailsDaoImpl;
import com.cloud.storage.dao.VMTemplateHostDaoImpl; import com.cloud.storage.dao.VMTemplateHostDaoImpl;
import com.cloud.storage.dao.VMTemplatePoolDaoImpl; import com.cloud.storage.dao.VMTemplatePoolDaoImpl;
import com.cloud.storage.dao.VMTemplateSwiftDaoImpl; import com.cloud.storage.dao.VMTemplateSwiftDaoImpl;
@ -195,6 +196,7 @@ public class DefaultComponentLibrary extends ComponentLibraryBase implements Com
protected void populateDaos() { protected void populateDaos() {
addDao("StackMaidDao", StackMaidDaoImpl.class); addDao("StackMaidDao", StackMaidDaoImpl.class);
addDao("VMTemplateZoneDao", VMTemplateZoneDaoImpl.class); addDao("VMTemplateZoneDao", VMTemplateZoneDaoImpl.class);
addDao("VMTemplateDetailsDao", VMTemplateDetailsDaoImpl.class);
addDao("DomainRouterDao", DomainRouterDaoImpl.class); addDao("DomainRouterDao", DomainRouterDaoImpl.class);
addDao("HostDao", HostDaoImpl.class); addDao("HostDao", HostDaoImpl.class);
addDao("VMInstanceDao", VMInstanceDaoImpl.class); addDao("VMInstanceDao", VMInstanceDaoImpl.class);

View File

@ -68,6 +68,9 @@ public class VMTemplateDaoImpl extends GenericDaoBase<VMTemplateVO, Long> implem
@Inject @Inject
VMTemplateZoneDao _templateZoneDao; VMTemplateZoneDao _templateZoneDao;
@Inject
VMTemplateDetailsDao _templateDetailsDao;
@Inject @Inject
ConfigurationDao _configDao; ConfigurationDao _configDao;
@Inject @Inject
@ -681,6 +684,9 @@ public class VMTemplateDaoImpl extends GenericDaoBase<VMTemplateVO, Long> implem
VMTemplateVO tmplt2 = findById(tmplt.getId()); VMTemplateVO tmplt2 = findById(tmplt.getId());
if (tmplt2 == null){ if (tmplt2 == null){
persist(tmplt); persist(tmplt);
if(tmplt.getDetails() != null) {
_templateDetailsDao.persist(tmplt.getId(), tmplt.getDetails());
}
} }
VMTemplateZoneVO tmpltZoneVO = _templateZoneDao.findByZoneTemplate(zoneId, tmplt.getId()); VMTemplateZoneVO tmpltZoneVO = _templateZoneDao.findByZoneTemplate(zoneId, tmplt.getId());
if ( tmpltZoneVO == null ) { if ( tmpltZoneVO == null ) {

View File

@ -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 <http://www.gnu.org/licenses/>.
*
*/
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<VMTemplateDetailVO, Long> {
Map<String, String> findDetails(long templateId);
void persist(long templateId, Map<String, String> details);
VMTemplateDetailVO findDetail(long templateId, String name);
void deleteDetails(long vmId);
}

View File

@ -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<VMTemplateDetailVO, Long> implements VMTemplateDetailsDao {
protected final SearchBuilder<VMTemplateDetailVO> TemplateSearch;
protected final SearchBuilder<VMTemplateDetailVO> 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<VMTemplateDetailVO> sc = TemplateSearch.create();
sc.setParameters("templateId", templateId);
List<VMTemplateDetailVO> results = search(sc, null);
for (VMTemplateDetailVO result : results) {
remove(result.getId());
}
}
@Override
public VMTemplateDetailVO findDetail(long templateId, String name) {
SearchCriteria<VMTemplateDetailVO> sc = DetailSearch.create();
sc.setParameters("templateId", templateId);
sc.setParameters("name", name);
return findOneBy(sc);
}
@Override
public Map<String, String> findDetails(long templateId) {
SearchCriteria<VMTemplateDetailVO> sc = TemplateSearch.create();
sc.setParameters("templateId", templateId);
List<VMTemplateDetailVO> results = search(sc, null);
Map<String, String> details = new HashMap<String, String>(results.size());
for (VMTemplateDetailVO result : results) {
details.put(result.getName(), result.getValue());
}
return details;
}
@Override
public void persist(long templateId, Map<String, String> details) {
Transaction txn = Transaction.currentTxn();
txn.start();
SearchCriteria<VMTemplateDetailVO> sc = TemplateSearch.create();
sc.setParameters("templateId", templateId);
expunge(sc);
for (Map.Entry<String, String> detail : details.entrySet()) {
VMTemplateDetailVO vo = new VMTemplateDetailVO(templateId, detail.getKey(), detail.getValue());
persist(vo);
}
txn.commit();
}
}

View File

@ -1,5 +1,7 @@
package com.cloud.template; package com.cloud.template;
import java.util.Map;
import com.cloud.api.commands.DeleteIsoCmd; import com.cloud.api.commands.DeleteIsoCmd;
import com.cloud.api.commands.DeleteTemplateCmd; import com.cloud.api.commands.DeleteTemplateCmd;
import com.cloud.api.commands.RegisterIsoCmd; 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, public TemplateProfile prepare(boolean isIso, Long userId, String name, String displayText, Integer bits,
Boolean passwordEnabled, Boolean requiresHVM, String url, Boolean isPublic, Boolean featured, Boolean passwordEnabled, Boolean requiresHVM, String url, Boolean isPublic, Boolean featured,
Boolean isExtractable, String format, Long guestOSId, Long zoneId, HypervisorType hypervisorType, 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, public TemplateProfile prepare(boolean isIso, Long userId, String name, String displayText, Integer bits,
Boolean passwordEnabled, Boolean requiresHVM, String url, Boolean isPublic, Boolean featured, Boolean passwordEnabled, Boolean requiresHVM, String url, Boolean isPublic, Boolean featured,
Boolean isExtractable, String format, Long guestOSId, Long zoneId, HypervisorType hypervisorType, 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;
} }

View File

@ -90,14 +90,14 @@ public abstract class TemplateAdapterBase implements TemplateAdapter {
public TemplateProfile prepare(boolean isIso, Long userId, String name, String displayText, Integer bits, public TemplateProfile prepare(boolean isIso, Long userId, String name, String displayText, Integer bits,
Boolean passwordEnabled, Boolean requiresHVM, String url, Boolean isPublic, Boolean featured, Boolean passwordEnabled, Boolean requiresHVM, String url, Boolean isPublic, Boolean featured,
Boolean isExtractable, String format, Long guestOSId, Long zoneId, HypervisorType hypervisorType, 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, 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, public TemplateProfile prepare(boolean isIso, Long userId, String name, String displayText, Integer bits,
Boolean passwordEnabled, Boolean requiresHVM, String url, Boolean isPublic, Boolean featured, Boolean passwordEnabled, Boolean requiresHVM, String url, Boolean isPublic, Boolean featured,
Boolean isExtractable, String format, Long guestOSId, Long zoneId, HypervisorType hypervisorType, 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; //Long accountId = null;
// parameters verification // parameters verification
@ -200,7 +200,7 @@ public abstract class TemplateAdapterBase implements TemplateAdapter {
Long id = _tmpltDao.getNextInSequence(Long.class, "id"); Long id = _tmpltDao.getNextInSequence(Long.class, "id");
UserContext.current().setEventDetails("Id: " +id+ " name: " + name); UserContext.current().setEventDetails("Id: " +id+ " name: " + name);
return new TemplateProfile(id, userId, name, displayText, bits, passwordEnabled, requiresHVM, url, isPublic, 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 @Override
@ -213,7 +213,7 @@ public abstract class TemplateAdapterBase implements TemplateAdapter {
return prepare(false, UserContext.current().getCallerUserId(), cmd.getTemplateName(), cmd.getDisplayText(), return prepare(false, UserContext.current().getCallerUserId(), cmd.getTemplateName(), cmd.getDisplayText(),
cmd.getBits(), cmd.isPasswordEnabled(), cmd.getRequiresHvm(), cmd.getUrl(), cmd.isPublic(), cmd.isFeatured(), 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.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 { 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, 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(), 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) { 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(), VMTemplateVO template = new VMTemplateVO(profile.getTemplateId(), profile.getName(), profile.getFormat(), profile.getIsPublic(),
profile.getFeatured(), profile.getIsExtractable(), TemplateType.USER, profile.getUrl(), profile.getRequiresHVM(), profile.getFeatured(), profile.getIsExtractable(), TemplateType.USER, profile.getUrl(), profile.getRequiresHVM(),
profile.getBits(), profile.getAccountId(), profile.getCheckSum(), profile.getDisplayText(), 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) { if (zoneId == null || zoneId == -1) {
List<DataCenterVO> dcs = _dcDao.listAllIncludingRemoved(); List<DataCenterVO> dcs = _dcDao.listAllIncludingRemoved();

View File

@ -1,5 +1,7 @@
package com.cloud.template; package com.cloud.template;
import java.util.Map;
import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.Storage.ImageFormat;
import com.cloud.storage.VMTemplateVO; import com.cloud.storage.VMTemplateVO;
@ -27,10 +29,11 @@ public class TemplateProfile {
Long templateId; Long templateId;
VMTemplateVO template; VMTemplateVO template;
String templateTag; String templateTag;
Map details;
public TemplateProfile(Long templateId, Long userId, String name, String displayText, Integer bits, Boolean passwordEnabled, Boolean requiresHvm, 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, 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.templateId = templateId;
this.userId = userId; this.userId = userId;
this.name = name; this.name = name;
@ -51,6 +54,7 @@ public class TemplateProfile {
this.accountId = accountId; this.accountId = accountId;
this.chksum = chksum; this.chksum = chksum;
this.bootable = bootable; this.bootable = bootable;
this.details = details;
} }
public TemplateProfile(Long userId, VMTemplateVO template, Long zoneId) { 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, 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, 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, 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; this.templateTag = templateTag;
} }
@ -215,4 +219,11 @@ public class TemplateProfile {
this.templateTag = templateTag; this.templateTag = templateTag;
} }
public Map getDetails() {
return this.details;
}
public void setDetails(Map details) {
this.details = details;
}
} }

View File

@ -178,6 +178,7 @@ import com.cloud.storage.dao.GuestOSDao;
import com.cloud.storage.dao.SnapshotDao; import com.cloud.storage.dao.SnapshotDao;
import com.cloud.storage.dao.StoragePoolDao; import com.cloud.storage.dao.StoragePoolDao;
import com.cloud.storage.dao.VMTemplateDao; import com.cloud.storage.dao.VMTemplateDao;
import com.cloud.storage.dao.VMTemplateDetailsDao;
import com.cloud.storage.dao.VMTemplateHostDao; import com.cloud.storage.dao.VMTemplateHostDao;
import com.cloud.storage.dao.VMTemplateZoneDao; import com.cloud.storage.dao.VMTemplateZoneDao;
import com.cloud.storage.dao.VolumeDao; import com.cloud.storage.dao.VolumeDao;
@ -247,6 +248,8 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
@Inject @Inject
protected VMTemplateDao _templateDao = null; protected VMTemplateDao _templateDao = null;
@Inject @Inject
protected VMTemplateDetailsDao _templateDetailsDao = null;
@Inject
protected VMTemplateHostDao _templateHostDao = null; protected VMTemplateHostDao _templateHostDao = null;
@Inject @Inject
protected VMTemplateZoneDao _templateZoneDao = null; 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, 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(sourceTemplateId != null){
if(s_logger.isDebugEnabled()){ if(s_logger.isDebugEnabled()){
s_logger.debug("This template is getting created from other template, setting source template Id to: "+sourceTemplateId); 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); VMTemplateVO template = _templateDao.persist(privateTemplate);
// Increment the number of templates // Increment the number of templates
if (template != null) { if (template != null) {
if(cmd.getDetails() != null) {
_templateDetailsDao.persist(template.getId(), cmd.getDetails());
}
_resourceLimitMgr.incrementResourceCount(accountId, ResourceType.template); _resourceLimitMgr.incrementResourceCount(accountId, ResourceType.template);
} }

View File

@ -906,6 +906,15 @@ CREATE TABLE `cloud`.`vm_template` (
CONSTRAINT `uc_vm_template__uuid` UNIQUE (`uuid`) CONSTRAINT `uc_vm_template__uuid` UNIQUE (`uuid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8; ) 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` ( CREATE TABLE `cloud`.`vm_instance` (
`id` bigint unsigned UNIQUE NOT NULL, `id` bigint unsigned UNIQUE NOT NULL,
`name` varchar(255) NOT NULL, `name` varchar(255) NOT NULL,

View File

@ -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 COLUMN `uuid` varchar(40);
ALTER TABLE `cloud`.`nics` ADD CONSTRAINT `uc_nics__uuid` UNIQUE (`uuid`); 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;