Finish refactoring createTemplate to new API framework. The executor and result object from old framework still need to be deleted, but this commit moves all the business logic to the manager with validation in the createPrivateTemplateRecord and creating a snapshot if necessary in createPrivateTemplate. Additionally, added a find method on the template dao to check if the template name is in use for the account (this is part of the validation).

This commit is contained in:
Kris McQueen 2010-08-23 16:17:48 -07:00
parent 97f3068687
commit defae59126
6 changed files with 283 additions and 172 deletions

View File

@ -18,10 +18,9 @@
package com.cloud.storage.dao;
import java.util.List;
import java.util.List;
import com.cloud.domain.DomainVO;
import com.cloud.storage.VMTemplateHostVO;
import com.cloud.storage.VMTemplateVO;
import com.cloud.user.Account;
import com.cloud.utils.db.GenericDao;
@ -45,7 +44,16 @@ public interface VMTemplateDao extends GenericDao<VMTemplateVO, Long> {
//finds by the column "unique_name"
public VMTemplateVO findByName(String templateName);
//finds by the column "name"
public VMTemplateVO findByTemplateName(String templateName);
public VMTemplateVO findByTemplateName(String templateName);
/**
* Find a template by name for a specific account.
* @param templateName the name to search for
* @param accountId the account to use for filtering the search results
* @return the template with the given name for the given account if it exists, null otherwise
*/
public VMTemplateVO findByTemplateNameAccountId(String templateName, Long accountId);
//public void update(VMTemplateVO template);
public VMTemplateVO findRoutingTemplate();
public VMTemplateVO findConsoleProxyTemplate();

View File

@ -55,16 +55,16 @@ public class VMTemplateDaoImpl extends GenericDaoBase<VMTemplateVO, Long> implem
private final String SELECT_ALL = "SELECT t.id, t.unique_name, t.name, t.public, t.featured, t.type, t.hvm, t.bits, t.url, t.format, t.created, t.account_id, " +
"t.checksum, t.display_text, t.enable_password, t.guest_os_id, t.bootable, t.prepopulate, t.cross_zones FROM vm_template t";
protected static final String SELECT_ALL_IN_ZONE =
private static final String SELECT_ALL_IN_ZONE =
"SELECT t.id, t.unique_name, t.name, t.public, t.featured, t.type, t.hvm, t.bits, t.url, t.format, t.created, t.removed, t.account_id, " +
"t.checksum, t.display_text, t.enable_password, t.guest_os_id, t.bootable, t.prepopulate, t.cross_zones FROM vm_template t, template_zone_ref tz where t.removed is null and tz.removed is null and t.id = tz.template_id and tz.zone_id=? ";
protected SearchBuilder<VMTemplateVO> TemplateNameSearch;
protected SearchBuilder<VMTemplateVO> UniqueNameSearch;
protected SearchBuilder<VMTemplateVO> AccountIdSearch;
protected SearchBuilder<VMTemplateVO> NameSearch;
private SearchBuilder<VMTemplateVO> UniqueNameSearch;
private SearchBuilder<VMTemplateVO> AccountIdSearch;
private SearchBuilder<VMTemplateVO> NameSearch;
private SearchBuilder<VMTemplateVO> PublicSearch;
private SearchBuilder<VMTemplateVO> NameAccountIdSearch;
protected SearchBuilder<VMTemplateVO> PublicSearch;
private String routerTmpltName;
private String consoleProxyTmpltName;
@ -90,7 +90,15 @@ public class VMTemplateDaoImpl extends GenericDaoBase<VMTemplateVO, Long> implem
sc.setParameters("name", templateName);
return findOneBy(sc);
}
@Override
public VMTemplateVO findByTemplateNameAccountId(String templateName, Long accountId) {
SearchCriteria<VMTemplateVO> sc = NameAccountIdSearch.create();
sc.setParameters("name", templateName);
sc.setParameters("accountId", accountId);
return findOneBy(sc);
}
@Override
public VMTemplateVO findRoutingTemplate() {
SearchCriteria<VMTemplateVO> sc = UniqueNameSearch.create();
@ -152,14 +160,16 @@ public class VMTemplateDaoImpl extends GenericDaoBase<VMTemplateVO, Long> implem
consoleProxyTmpltName = "routing";
if(s_logger.isDebugEnabled())
s_logger.debug("Use console proxy template : " + consoleProxyTmpltName);
TemplateNameSearch = createSearchBuilder();
TemplateNameSearch.and("name", TemplateNameSearch.entity().getName(), SearchCriteria.Op.EQ);
UniqueNameSearch = createSearchBuilder();
UniqueNameSearch.and("uniqueName", UniqueNameSearch.entity().getUniqueName(), SearchCriteria.Op.EQ);
NameSearch = createSearchBuilder();
NameSearch.and("name", NameSearch.entity().getName(), SearchCriteria.Op.EQ);
NameAccountIdSearch = createSearchBuilder();
NameAccountIdSearch.and("name", NameAccountIdSearch.entity().getName(), SearchCriteria.Op.EQ);
NameAccountIdSearch.and("accountId", NameAccountIdSearch.entity().getAccountId(), SearchCriteria.Op.EQ);
AccountIdSearch = createSearchBuilder();
AccountIdSearch.and("accountId", AccountIdSearch.entity().getAccountId(), SearchCriteria.Op.EQ);
AccountIdSearch.and("publicTemplate", AccountIdSearch.entity().isPublicTemplate(), SearchCriteria.Op.EQ);

View File

@ -18,47 +18,20 @@
package com.cloud.api.commands;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.apache.log4j.Logger;
import com.cloud.api.BaseCmd;
import com.cloud.api.BaseCmd.Manager;
import com.cloud.api.BaseAsyncCreateCmd;
import com.cloud.api.BaseCmd.Manager;
import com.cloud.api.Implementation;
import com.cloud.api.Parameter;
import com.cloud.api.ServerApiException;
import com.cloud.async.executor.CreatePrivateTemplateResultObject;
import com.cloud.api.response.TemplateResponse;
import com.cloud.serializer.SerializerHelper;
import com.cloud.server.Criteria;
import com.cloud.storage.Snapshot;
import com.cloud.storage.VMTemplateVO;
import com.cloud.storage.VolumeVO;
import com.cloud.user.Account;
import com.cloud.utils.Pair;
@Implementation(method="createPrivateTemplate", createMethod="createPrivateTemplateRecord", manager=Manager.UserVmManager)
public class CreateTemplateCmd extends BaseAsyncCreateCmd {
public static final Logger s_logger = Logger.getLogger(CreateTemplateCmd.class.getName());
private static final String s_name = "createtemplateresponse";
private static final List<Pair<Enum, Boolean>> s_properties = new ArrayList<Pair<Enum, Boolean>>();
static {
s_properties.add(new Pair<Enum, Boolean>(BaseCmd.Properties.BITS, Boolean.FALSE));
s_properties.add(new Pair<Enum, Boolean>(BaseCmd.Properties.DISPLAY_TEXT, Boolean.TRUE));
s_properties.add(new Pair<Enum, Boolean>(BaseCmd.Properties.IS_FEATURED, Boolean.FALSE));
s_properties.add(new Pair<Enum, Boolean>(BaseCmd.Properties.IS_PUBLIC, Boolean.FALSE));
s_properties.add(new Pair<Enum, Boolean>(BaseCmd.Properties.NAME, Boolean.TRUE));
s_properties.add(new Pair<Enum, Boolean>(BaseCmd.Properties.OS_TYPE_ID, Boolean.TRUE));
s_properties.add(new Pair<Enum, Boolean>(BaseCmd.Properties.PASSWORD_ENABLED, Boolean.FALSE));
s_properties.add(new Pair<Enum, Boolean>(BaseCmd.Properties.REQUIRES_HVM, Boolean.FALSE));
s_properties.add(new Pair<Enum, Boolean>(BaseCmd.Properties.SNAPSHOT_ID, Boolean.FALSE));
s_properties.add(new Pair<Enum, Boolean>(BaseCmd.Properties.VOLUME_ID, Boolean.FALSE));
s_properties.add(new Pair<Enum, Boolean>(BaseCmd.Properties.ACCOUNT_OBJ, Boolean.FALSE));
s_properties.add(new Pair<Enum, Boolean>(BaseCmd.Properties.USER_ID, Boolean.FALSE));
}
/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
@ -154,108 +127,40 @@ public class CreateTemplateCmd extends BaseAsyncCreateCmd {
}
@Override
public String getResponse() {
public String getResponse() {
VMTemplateVO template = (VMTemplateVO)getResponseObject();
TemplateResponse response = new TemplateResponse();
response.setId(template.getId());
response.setName(template.getName());
response.setDisplayText(template.getDisplayText());
response.setPublic(template.isPublicTemplate());
response.setPasswordEnabled(template.getEnablePassword());
response.setCrossZones(template.isCrossZones());
// TODO: implement
// VMTemplateHostVO templateHostRef = managerServer.findTemplateHostRef(template.getId(), volume.getDataCenterId());
// response.setCreated(templateHostRef.getCreated());
// response.setReady(templateHostRef != null && templateHostRef.getDownloadState() == Status.DOWNLOADED);
// if (os != null) {
// resultObject.setOsTypeId(os.getId());
// resultObject.setOsTypeName(os.getDisplayName());
// } else {
// resultObject.setOsTypeId(-1L);
// resultObject.setOsTypeName("");
// }
// Account owner = managerServer.findAccountById(template.getAccountId());
// if (owner != null) {
// resultObject.setAccount(owner.getAccountName());
// resultObject.setDomainId(owner.getDomainId());
// resultObject.setDomainName(managerServer.findDomainIdById(owner.getDomainId()).getName());
// }
// DataCenterVO zone = managerServer.findDataCenterById(dataCenterId);
// if (zone != null) {
// resultObject.setZoneId(zone.getId());
// resultObject.setZoneName(zone.getName());
// }
return SerializerHelper.toSerializedString(response);
}
@Override
public List<Pair<String, Object>> execute(Map<String, Object> params) {
String description = (String)params.get(BaseCmd.Properties.DISPLAY_TEXT.getName());
String name = (String)params.get(BaseCmd.Properties.NAME.getName());
Long volumeId = (Long)params.get(BaseCmd.Properties.VOLUME_ID.getName());
Long guestOSId = (Long) params.get(BaseCmd.Properties.OS_TYPE_ID.getName());
Account account = (Account)params.get(BaseCmd.Properties.ACCOUNT_OBJ.getName());
Long userId = (Long)params.get(BaseCmd.Properties.USER_ID.getName());
Boolean requiresHvm = (Boolean)params.get(BaseCmd.Properties.REQUIRES_HVM.getName());
Integer bits = (Integer)params.get(BaseCmd.Properties.BITS.getName());
Boolean passwordEnabled = (Boolean)params.get(BaseCmd.Properties.PASSWORD_ENABLED.getName());
Boolean isPublic = (Boolean)params.get(BaseCmd.Properties.IS_PUBLIC.getName());
Boolean featured = (Boolean)params.get(BaseCmd.Properties.IS_FEATURED.getName());
Long snapshotId = (Long)params.get(BaseCmd.Properties.SNAPSHOT_ID.getName());
if (volumeId == null && snapshotId == null) {
throw new ServerApiException(BaseCmd.PARAM_ERROR, "Specify at least one of the two parameters volumeId or snapshotId");
}
VolumeVO volume = null;
// Verify input parameters
if (snapshotId != null) {
Snapshot snapshot = getManagementServer().findSnapshotById(snapshotId);
if (snapshot == null) {
throw new ServerApiException(BaseCmd.PARAM_ERROR, "No snapshot exists with the given id: " + snapshotId);
}
if (volumeId != null) {
throw new ServerApiException(BaseCmd.PARAM_ERROR, "Specify only one of the two parameters volumeId or snapshotId");
}
// Set the volumeId to that of the snapshot. All further input parameter checks will be done w.r.t the volume.
volumeId = snapshot.getVolumeId();
volume = getManagementServer().findAnyVolumeById(volumeId);
} else {
volume = getManagementServer().findAnyVolumeById(volumeId);
}
if (volume == null) {
throw new ServerApiException(BaseCmd.PARAM_ERROR, "unable to find a volume with id " + volumeId);
}
boolean isAdmin = ((account == null) || isAdmin(account.getType()));
if (!isAdmin) {
if (account.getId().longValue() != volume.getAccountId()) {
throw new ServerApiException(BaseCmd.ACCOUNT_ERROR, "unable to find a volume with id " + volumeId + " for this account");
}
} else if ((account != null) && !getManagementServer().isChildDomain(account.getDomainId(), volume.getDomainId())) {
throw new ServerApiException(BaseCmd.ACCOUNT_ERROR, "Unable to create a template from volume with id " + volumeId + ", permission denied.");
}
if (isPublic == null) {
isPublic = Boolean.FALSE;
}
boolean allowPublicUserTemplates = Boolean.parseBoolean(getManagementServer().getConfigurationValue("allow.public.user.templates"));
if (!isAdmin && !allowPublicUserTemplates && isPublic) {
throw new ServerApiException(BaseCmd.PARAM_ERROR, "Only private templates can be created.");
}
if (!isAdmin || featured == null) {
featured = Boolean.FALSE;
}
Criteria c = new Criteria();
c.addCriteria(Criteria.NAME, name);
c.addCriteria(Criteria.CREATED_BY, Long.valueOf(volume.getAccountId()));
List<VMTemplateVO> templates = getManagementServer().searchForTemplates(c);
// If command is executed via 8096 port, set userId to the id of System account (1)
if (userId == null) {
userId = Long.valueOf(1);
}
try {
long jobId = getManagementServer().createPrivateTemplateAsync(userId, volumeId, name, description, guestOSId, requiresHvm, bits, passwordEnabled, isPublic, featured, snapshotId);
if (jobId == 0) {
s_logger.warn("Unable to schedule async-job for CreateTemplate command");
} else {
if (s_logger.isDebugEnabled())
s_logger.debug("CreateTemplate command has been accepted, job id: " + jobId);
}
long templateId = waitInstanceCreation(jobId);
List<Pair<String, Object>> returnValues = new ArrayList<Pair<String, Object>>();
returnValues.add(new Pair<String, Object>(BaseCmd.Properties.JOB_ID.getName(), Long.valueOf(jobId)));
returnValues.add(new Pair<String, Object>(BaseCmd.Properties.TEMPLATE_ID.getName(), Long.valueOf(templateId)));
return returnValues;
} catch (Exception ex) {
throw new ServerApiException(BaseCmd.CREATE_PRIVATE_TEMPLATE_ERROR, "Unhandled exception while creating template name: " + name + " for volume " + volumeId + ", reason, " + ex.getMessage());
}
}
protected long getInstanceIdFromJobSuccessResult(String result) {
CreatePrivateTemplateResultObject resultObject = (CreatePrivateTemplateResultObject)SerializerHelper.fromSerializedString(result);
if (resultObject != null) {
return resultObject.getId();
}
return 0;
}
}

View File

@ -0,0 +1,184 @@
package com.cloud.api.response;
import java.util.Date;
import com.cloud.api.ResponseObject;
import com.cloud.serializer.Param;
public class TemplateResponse implements ResponseObject {
@Param(name="id")
private long id;
@Param(name="name")
private String name;
@Param(name="displaytext")
private String displayText;
@Param(name="ispublic", propName="public")
private boolean isPublic;
@Param(name="created")
private Date created;
@Param(name="isready", propName="ready")
private boolean isReady;
@Param(name="passwordenabled")
private boolean passwordEnabled;
@Param(name="crossZones")
private boolean crossZones;
@Param(name="ostypeid")
private Long osTypeId;
@Param(name="ostypename")
private String osTypeName;
@Param(name="accountid")
private Long accountId;
@Param(name="account")
private String account;
@Param(name="zoneid")
private Long zoneId;
@Param(name="zonename")
private String zoneName;
@Param(name="domain")
private String domainName;
@Param(name="domainid")
private long domainId;
public Long getZoneId() {
return zoneId;
}
public void setZoneId(Long zoneId) {
this.zoneId = zoneId;
}
public String getZoneName() {
return zoneName;
}
public void setZoneName(String zoneName) {
this.zoneName = zoneName;
}
public Long getAccountId() {
return accountId;
}
public void setAccountId(Long accountId) {
this.accountId = accountId;
}
public String getAccount() {
return account;
}
public void setAccount(String account) {
this.account = account;
}
public Long getOsTypeId() {
return osTypeId;
}
public void setOsTypeId(Long osTypeId) {
this.osTypeId = osTypeId;
}
public String getOsTypeName() {
return osTypeName;
}
public void setOsTypeName(String osTypeName) {
this.osTypeName = osTypeName;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDisplayText() {
return displayText;
}
public void setDisplayText(String displayText) {
this.displayText = displayText;
}
public boolean isPublic() {
return isPublic;
}
public void setPublic(boolean isPublic) {
this.isPublic = isPublic;
}
public Date getCreated() {
return created;
}
public void setCreated(Date created) {
this.created = created;
}
public boolean isReady() {
return isReady;
}
public void setReady(boolean isReady) {
this.isReady = isReady;
}
public boolean isPasswordEnabled() {
return passwordEnabled;
}
public void setPasswordEnabled(boolean passwordEnabled) {
this.passwordEnabled = passwordEnabled;
}
public boolean isCrossZones() {
return crossZones;
}
public void setCrossZones(boolean crossZones) {
this.crossZones = crossZones;
}
public long getDomainId() {
return domainId;
}
public String getDomainName(){
return domainName;
}
public void setDomainName(String domainName) {
this.domainName = domainName;
}
public void setDomainId(long domainId) {
this.domainId = domainId;
}
}

View File

@ -220,7 +220,7 @@ public interface UserVmManager extends Manager, VirtualMachineManager<UserVmVO>
* @param description the user give description (aka display text) for the template
* @return a template if successfully created, null otherwise
*/
VMTemplateVO createPrivateTemplate(CreateTemplateCmd cmd);
VMTemplateVO createPrivateTemplate(CreateTemplateCmd cmd) throws InternalErrorException;
/**
* @param userId The Id of the user who invoked this operation.

View File

@ -37,8 +37,6 @@ import java.util.concurrent.TimeUnit;
import javax.ejb.Local;
import javax.naming.ConfigurationException;
import net.sf.ehcache.config.Configuration;
import org.apache.log4j.Logger;
import com.cloud.agent.api.Answer;
@ -85,7 +83,6 @@ import com.cloud.async.executor.OperationResponse;
import com.cloud.async.executor.RebootVMExecutor;
import com.cloud.async.executor.StartVMExecutor;
import com.cloud.async.executor.StopVMExecutor;
import com.cloud.async.executor.UpgradeVMParam;
import com.cloud.async.executor.VMExecutorHelper;
import com.cloud.async.executor.VMOperationListener;
import com.cloud.async.executor.VMOperationParam;
@ -141,8 +138,6 @@ import com.cloud.network.security.NetworkGroupVO;
import com.cloud.offering.ServiceOffering;
import com.cloud.offering.ServiceOffering.GuestIpType;
import com.cloud.offerings.NetworkOfferingVO;
import com.cloud.serializer.GsonHelper;
import com.cloud.server.ManagementServer;
import com.cloud.service.ServiceOfferingVO;
import com.cloud.service.dao.ServiceOfferingDao;
import com.cloud.storage.DiskOfferingVO;
@ -200,7 +195,6 @@ import com.cloud.vm.VirtualMachine.Event;
import com.cloud.vm.VirtualMachine.Type;
import com.cloud.vm.dao.DomainRouterDao;
import com.cloud.vm.dao.UserVmDao;
import com.google.gson.Gson;
@Local(value={UserVmManager.class})
public class UserVmManagerImpl implements UserVmManager {
@ -737,9 +731,7 @@ public class UserVmManagerImpl implements UserVmManager {
VMTemplateVO template = _templateDao.findById(vm.getTemplateId());
ServiceOffering offering = _offeringDao.findById(vm.getServiceOfferingId());
long diskOfferingId = -1;
// If an ISO path is passed in, boot from that ISO
// Else, check if the VM already has an ISO attached to it. If so, start the VM with that ISO inserted, but don't boot from it.
boolean bootFromISO = false;
@ -1199,8 +1191,7 @@ public class UserVmManagerImpl implements UserVmManager {
/*
* TODO: cleanup eventually - Refactored API call
*/
public boolean upgradeVirtualMachine(UpgradeVMCmd cmd) throws ServerApiException, InvalidParameterValueException
{
public boolean upgradeVirtualMachine(UpgradeVMCmd cmd) throws ServerApiException, InvalidParameterValueException {
Long virtualMachineId = cmd.getId();
Long serviceOfferingId = cmd.getServiceOfferingId();
Account account = (Account)UserContext.current().getAccountObject();
@ -1264,8 +1255,9 @@ public class UserVmManagerImpl implements UserVmManager {
"current service offering. Current service offering tags: " + currentTags + "; " +
"new service offering tags: " + newTags);
}
long eventId = EventUtils.saveScheduledEvent(userId, vmInstance.getAccountId(), EventTypes.EVENT_VM_UPGRADE, "upgrading Vm with Id: "+vmInstance.getId());
// FIXME: save this eventId somewhere as part of the async process?
/*long eventId = */EventUtils.saveScheduledEvent(userId, vmInstance.getAccountId(), EventTypes.EVENT_VM_UPGRADE, "upgrading Vm with Id: "+vmInstance.getId());
vmInstance.setServiceOfferingId(serviceOfferingId);
vmInstance.setHaEnabled(_serviceOfferingDao.findById(serviceOfferingId).getOfferHA());
@ -2630,10 +2622,10 @@ public class UserVmManagerImpl implements UserVmManager {
if (!isAdmin) {
if (account.getId().longValue() != volume.getAccountId()) {
throw new ServerApiException(BaseCmd.ACCOUNT_ERROR, "unable to find a volume with id " + volumeId + " for this account");
throw new PermissionDeniedException("Unable to create a template from volume with id " + volumeId + ", permission denied.");
}
} else if ((account != null) && !_domainDao.isChildDomain(account.getDomainId(), volume.getDomainId())) {
throw new ServerApiException(BaseCmd.ACCOUNT_ERROR, "Unable to create a template from volume with id " + volumeId + ", permission denied.");
throw new PermissionDeniedException("Unable to create a template from volume with id " + volumeId + ", permission denied.");
}
String name = cmd.getTemplateName();
@ -2646,6 +2638,11 @@ public class UserVmManagerImpl implements UserVmManager {
}
String uniqueName = Long.valueOf((userId == null)?1:userId).toString() + Long.valueOf(volumeId).toString() + UUID.nameUUIDFromBytes(name.getBytes()).toString();
VMTemplateVO existingTemplate = _templateDao.findByTemplateNameAccountId(name, volume.getAccountId());
if (existingTemplate != null) {
throw new InvalidParameterValueException("Failed to create private template " + name + ", a template with that name already exists.");
}
// do some parameter defaulting
Integer bits = cmd.getBits();
Boolean requiresHvm = cmd.getRequiresHvm();
@ -2714,22 +2711,33 @@ public class UserVmManagerImpl implements UserVmManager {
// FIXME: scheduled events should get saved when the command is actually scheduled, not when it starts executing, need another callback
// for when the command is scheduled? Could this fit into the setup / execute / response lifecycle? Right after setup you would
// know your job is being scheduled, so you could save this kind of event in setup after verifying params.
long eventId = EventUtils.saveScheduledEvent(userId, volume.getAccountId(), EventTypes.EVENT_TEMPLATE_CREATE, "creating template" +name);
/*long eventId = */EventUtils.saveScheduledEvent(userId, volume.getAccountId(), EventTypes.EVENT_TEMPLATE_CREATE, "creating template" +name);
return _templateDao.persist(privateTemplate);
}
@Override @DB
public VMTemplateVO createPrivateTemplate(CreateTemplateCmd command) {
public VMTemplateVO createPrivateTemplate(CreateTemplateCmd command) throws InternalErrorException {
Long userId = UserContext.current().getUserId();
if (userId == null) {
userId = User.UID_SYSTEM;
}
Long volumeId = command.getVolumeId();
Long snapshotId = command.getSnapshotId();
SnapshotVO snapshot = null;
// Verify input parameters
if (snapshotId != null) {
Snapshot snapshot = _snapshotDao.findById(snapshotId);
snapshot = _snapshotDao.findById(snapshotId);
// Set the volumeId to that of the snapshot. All further input parameter checks will be done w.r.t the volume.
volumeId = snapshot.getVolumeId();
} else {
// We are create private template from volume. Create a snapshot, copy the vhd chain of the disk to secondary storage.
// For template snapshot, we use a separate snapshot method.
snapshot = createTemplateSnapshot(userId, volumeId);
snapshotId = snapshot.getId();
}
// The volume below could be destroyed or removed.
@ -2749,13 +2757,13 @@ public class UserVmManagerImpl implements UserVmManager {
VMTemplateVO privateTemplate = null;
long templateId = command.getId();
if (snapshotId != null) {
volumeId = snapshot.getVolumeId();
volume = _volsDao.findById(volumeId);
StringBuilder userFolder = new StringBuilder();
Formatter userFolderFormat = new Formatter(userFolder);
userFolderFormat.format("u%06d", snapshot.getAccountId());
String uniqueName = getRandomPrivateTemplateName();
String name = command.getTemplateName();
long zoneId = volume.getDataCenterId();
HostVO secondaryStorageHost = _storageMgr.getSecondaryStorageHost(zoneId);
@ -2860,14 +2868,10 @@ public class UserVmManagerImpl implements UserVmManager {
// Increment the number of templates
_accountMgr.incrementResourceCount(volume.getAccountId(), ResourceType.template);
} else {
// Remove the template record
_templateDao.remove(templateId);
}
}
return privateTemplate;
}