You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by ed...@apache.org on 2013/02/21 20:23:50 UTC
[3/28] squash changes into one giant patch
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/a22403ed/server/src/com/cloud/template/TemplateManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/template/TemplateManagerImpl.java b/server/src/com/cloud/template/TemplateManagerImpl.java
index f9cf277..736f712 100755
--- a/server/src/com/cloud/template/TemplateManagerImpl.java
+++ b/server/src/com/cloud/template/TemplateManagerImpl.java
@@ -26,6 +26,9 @@ import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
+import java.util.Random;
+import java.util.UUID;
+import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
@@ -35,22 +38,50 @@ import javax.ejb.Local;
import javax.inject.Inject;
import javax.naming.ConfigurationException;
+import org.apache.cloudstack.acl.SecurityChecker.AccessType;
import org.apache.cloudstack.api.BaseListTemplateOrIsoPermissionsCmd;
import org.apache.cloudstack.api.BaseUpdateTemplateOrIsoPermissionsCmd;
-import org.apache.cloudstack.api.command.user.iso.*;
-import org.apache.cloudstack.api.command.user.template.*;
+import org.apache.cloudstack.api.command.user.iso.DeleteIsoCmd;
+import org.apache.cloudstack.api.command.user.iso.ExtractIsoCmd;
+import org.apache.cloudstack.api.command.user.iso.ListIsoPermissionsCmd;
+import org.apache.cloudstack.api.command.user.iso.RegisterIsoCmd;
+import org.apache.cloudstack.api.command.user.iso.UpdateIsoPermissionsCmd;
+import org.apache.cloudstack.api.command.user.template.CopyTemplateCmd;
+import org.apache.cloudstack.api.command.user.template.CreateTemplateCmd;
+import org.apache.cloudstack.api.command.user.template.DeleteTemplateCmd;
+import org.apache.cloudstack.api.command.user.template.ExtractTemplateCmd;
+import org.apache.cloudstack.api.command.user.template.ListTemplatePermissionsCmd;
+import org.apache.cloudstack.api.command.user.template.RegisterTemplateCmd;
+import org.apache.cloudstack.api.command.user.template.UpdateTemplatePermissionsCmd;
+import org.apache.cloudstack.engine.subsystem.api.storage.CommandResult;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreRole;
+import org.apache.cloudstack.engine.subsystem.api.storage.ImageDataFactory;
+import org.apache.cloudstack.engine.subsystem.api.storage.ImageService;
+import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotDataFactory;
+import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo;
+import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo;
+import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
+import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
+import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope;
+import org.apache.cloudstack.framework.async.AsyncCallFuture;
+import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
-import org.apache.cloudstack.acl.SecurityChecker.AccessType;
import com.cloud.agent.AgentManager;
import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.AttachIsoCommand;
+import com.cloud.agent.api.ComputeChecksumCommand;
import com.cloud.agent.api.downloadTemplateFromSwiftToSecondaryStorageCommand;
+import com.cloud.agent.api.uploadTemplateToSwiftFromSecondaryStorageCommand;
import com.cloud.agent.api.storage.DestroyCommand;
import com.cloud.agent.api.storage.PrimaryStorageDownloadAnswer;
import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand;
import com.cloud.agent.api.to.SwiftTO;
-import com.cloud.agent.api.uploadTemplateToSwiftFromSecondaryStorageCommand;
+
+import com.cloud.api.ApiDBUtils;
import com.cloud.async.AsyncJobManager;
import com.cloud.async.AsyncJobVO;
import com.cloud.configuration.Config;
@@ -64,12 +95,14 @@ import com.cloud.domain.dao.DomainDao;
import com.cloud.event.ActionEvent;
import com.cloud.event.EventTypes;
import com.cloud.event.UsageEventUtils;
+import com.cloud.event.UsageEventVO;
import com.cloud.event.dao.EventDao;
import com.cloud.event.dao.UsageEventDao;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.PermissionDeniedException;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.exception.StorageUnavailableException;
+import com.cloud.host.Host;
import com.cloud.host.HostVO;
import com.cloud.host.dao.HostDao;
import com.cloud.hypervisor.Hypervisor;
@@ -77,34 +110,72 @@ import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.hypervisor.HypervisorGuruManager;
import com.cloud.projects.Project;
import com.cloud.projects.ProjectManager;
-import com.cloud.storage.*;
+
+import com.cloud.resource.ResourceManager;
+import com.cloud.storage.GuestOSVO;
+import com.cloud.storage.LaunchPermissionVO;
+import com.cloud.storage.Snapshot;
+import com.cloud.storage.SnapshotVO;
+import com.cloud.storage.Storage;
+
import com.cloud.storage.Storage.ImageFormat;
import com.cloud.storage.Storage.TemplateType;
import com.cloud.storage.StorageManager;
import com.cloud.storage.StoragePool;
import com.cloud.storage.StoragePoolHostVO;
import com.cloud.storage.StoragePoolStatus;
-import com.cloud.storage.StoragePoolVO;
import com.cloud.storage.TemplateProfile;
import com.cloud.storage.Upload;
import com.cloud.storage.Upload.Type;
+
+import com.cloud.storage.UploadVO;
+import com.cloud.storage.VMTemplateHostVO;
+import com.cloud.storage.VMTemplateS3VO;
+import com.cloud.storage.VMTemplateStoragePoolVO;
+import com.cloud.storage.VMTemplateStorageResourceAssoc;
import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
-import com.cloud.storage.dao.*;
+import com.cloud.storage.VMTemplateSwiftVO;
+import com.cloud.storage.VMTemplateVO;
+import com.cloud.storage.VMTemplateZoneVO;
+import com.cloud.storage.Volume;
+import com.cloud.storage.VolumeManager;
+import com.cloud.storage.VolumeVO;
+import com.cloud.storage.dao.GuestOSDao;
+import com.cloud.storage.dao.LaunchPermissionDao;
+import com.cloud.storage.dao.SnapshotDao;
+import com.cloud.storage.dao.StoragePoolDao;
+import com.cloud.storage.dao.StoragePoolHostDao;
+import com.cloud.storage.dao.UploadDao;
+import com.cloud.storage.dao.VMTemplateDao;
+import com.cloud.storage.dao.VMTemplateDetailsDao;
+import com.cloud.storage.dao.VMTemplateHostDao;
+import com.cloud.storage.dao.VMTemplatePoolDao;
+import com.cloud.storage.dao.VMTemplateS3Dao;
+import com.cloud.storage.dao.VMTemplateSwiftDao;
+import com.cloud.storage.dao.VMTemplateZoneDao;
+import com.cloud.storage.dao.VolumeDao;
import com.cloud.storage.download.DownloadMonitor;
import com.cloud.storage.s3.S3Manager;
import com.cloud.storage.secondary.SecondaryStorageVmManager;
import com.cloud.storage.swift.SwiftManager;
import com.cloud.storage.upload.UploadMonitor;
import com.cloud.template.TemplateAdapter.TemplateAdapterType;
-import com.cloud.user.*;
+
+import com.cloud.user.Account;
+import com.cloud.user.AccountManager;
+import com.cloud.user.AccountService;
+import com.cloud.user.AccountVO;
+import com.cloud.user.ResourceLimitService;
+import com.cloud.user.User;
+import com.cloud.user.UserContext;
import com.cloud.user.dao.AccountDao;
import com.cloud.user.dao.UserAccountDao;
import com.cloud.user.dao.UserDao;
import com.cloud.uservm.UserVm;
import com.cloud.utils.NumbersUtil;
+import com.cloud.utils.Pair;
import com.cloud.utils.component.AdapterBase;
import com.cloud.utils.component.ManagerBase;
-
import com.cloud.utils.concurrency.NamedThreadFactory;
import com.cloud.utils.db.*;
import com.cloud.utils.exception.CloudRuntimeException;
@@ -123,6 +194,8 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
@Inject VMTemplateHostDao _tmpltHostDao;
@Inject VMTemplatePoolDao _tmpltPoolDao;
@Inject VMTemplateZoneDao _tmpltZoneDao;
+ @Inject
+ protected VMTemplateDetailsDao _templateDetailsDao;
@Inject VMInstanceDao _vmInstanceDao;
@Inject StoragePoolDao _poolDao;
@Inject StoragePoolHostDao _poolHostDao;
@@ -153,6 +226,8 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
ClusterDao _clusterDao;
@Inject DomainDao _domainDao;
@Inject UploadDao _uploadDao;
+ @Inject
+ protected GuestOSDao _guestOSDao;
long _routerTemplateId = -1;
@Inject StorageManager _storageMgr;
@Inject AsyncJobManager _asyncMgr;
@@ -164,6 +239,20 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
@Inject SecondaryStorageVmManager _ssvmMgr;
@Inject LaunchPermissionDao _launchPermissionDao;
@Inject ProjectManager _projectMgr;
+ @Inject
+ VolumeDataFactory volFactory;
+ @Inject
+ ImageDataFactory tmplFactory;
+ @Inject
+ SnapshotDataFactory snapshotFactory;
+ @Inject
+ ImageService imageSvr;
+ @Inject
+ DataStoreManager dataStoreMgr;
+ @Inject
+ protected ResourceManager _resourceMgr;
+ @Inject VolumeManager volumeMgr;
+ @Inject VMTemplateHostDao templateHostDao;
int _primaryStorageDownloadWait;
@@ -217,7 +306,8 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
if(!_accountService.isRootAdmin(account.getType())){
throw new PermissionDeniedException("Parameter templatetag can only be specified by a Root Admin, permission denied");
}
- }
+ }
+
TemplateAdapter adapter = getAdapter(HypervisorType.getType(cmd.getHypervisor()));
TemplateProfile profile = adapter.prepare(cmd);
VMTemplateVO template = adapter.create(profile);
@@ -228,6 +318,22 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
throw new CloudRuntimeException("Failed to create a template");
}
}
+
+ @Override
+ public DataStore getImageStore(String storeUuid, long zoneId) {
+ DataStore imageStore = null;
+ if (storeUuid != null) {
+ imageStore = this.dataStoreMgr.getDataStore(storeUuid, DataStoreRole.Image);
+ } else {
+ List<DataStore> stores = this.dataStoreMgr.getImageStores(new ZoneScope(zoneId));
+ if (stores.size() > 1) {
+ throw new CloudRuntimeException("multiple image stores, don't know which one to use");
+ }
+ imageStore = stores.get(0);
+ }
+
+ return imageStore;
+ }
@Override
@ActionEvent(eventType = EventTypes.EVENT_ISO_EXTRACT, eventDescription = "extracting ISO", async = true)
@@ -330,7 +436,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
_accountMgr.checkAccess(caller, AccessType.ModifyEntry, true, template);
- List<HostVO> sservers = _storageMgr.getSecondaryStorageHosts(zoneId);
+ List<HostVO> sservers = getSecondaryStorageHosts(zoneId);
VMTemplateHostVO tmpltHostRef = null;
if (sservers != null) {
@@ -425,7 +531,8 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
private void reallyRun() {
s_logger.info("Start to preload template " + template.getId() + " into primary storage " + pool.getId());
- prepareTemplateForCreate(template, pool);
+ StoragePool pol = (StoragePool)dataStoreMgr.getPrimaryDataStore(pool.getId());
+ prepareTemplateForCreate(template, pol);
s_logger.info("End of preloading template " + template.getId() + " into primary storage " + pool.getId());
}
});
@@ -539,8 +646,8 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
}
@Override @DB
- public VMTemplateStoragePoolVO prepareTemplateForCreate(VMTemplateVO template, StoragePool pool) {
- template = _tmpltDao.findById(template.getId(), true);
+ public VMTemplateStoragePoolVO prepareTemplateForCreate(VMTemplateVO templ, StoragePool pool) {
+ VMTemplateVO template = _tmpltDao.findById(templ.getId(), true);
long poolId = pool.getId();
long templateId = template.getId();
@@ -564,7 +671,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
}
}
- templateHostRef = _storageMgr.findVmTemplateHost(templateId, pool);
+ templateHostRef = findVmTemplateHost(templateId, pool);
if (templateHostRef == null || templateHostRef.getDownloadState() != Status.DOWNLOADED) {
String result = downloadTemplateFromSwiftToSecondaryStorage(dcId, templateId);
@@ -578,7 +685,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
s_logger.error("Unable to find a secondary storage host who has completely downloaded the template.");
return null;
}
- templateHostRef = _storageMgr.findVmTemplateHost(templateId, pool);
+ templateHostRef = findVmTemplateHost(templateId, pool);
if (templateHostRef == null || templateHostRef.getDownloadState() != Status.DOWNLOADED) {
s_logger.error("Unable to find a secondary storage host who has completely downloaded the template.");
return null;
@@ -671,6 +778,61 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
return null;
}
+
+
+
+ @Override
+ public VMTemplateHostVO findVmTemplateHost(long templateId,
+ StoragePool pool) {
+ long dcId = pool.getDataCenterId();
+ Long podId = pool.getPodId();
+
+ List<HostVO> secHosts = _ssvmMgr
+ .listSecondaryStorageHostsInOneZone(dcId);
+
+
+ if (secHosts.size() == 1) {
+ VMTemplateHostVO templateHostVO = this._tmpltHostDao
+ .findByHostTemplate(secHosts.get(0).getId(), templateId);
+ return templateHostVO;
+ }
+ if (podId != null) {
+ List<VMTemplateHostVO> templHosts = this._tmpltHostDao
+ .listByTemplateStatus(templateId, dcId, podId,
+ VMTemplateStorageResourceAssoc.Status.DOWNLOADED);
+ if (templHosts != null && !templHosts.isEmpty()) {
+ Collections.shuffle(templHosts);
+ return templHosts.get(0);
+ }
+ }
+ List<VMTemplateHostVO> templHosts = this._tmpltHostDao
+ .listByTemplateStatus(templateId, dcId,
+ VMTemplateStorageResourceAssoc.Status.DOWNLOADED);
+ if (templHosts != null && !templHosts.isEmpty()) {
+ Collections.shuffle(templHosts);
+ return templHosts.get(0);
+ }
+ return null;
+ }
+
+ @Override
+ public String getChecksum(Long hostId, String templatePath) {
+ HostVO ssHost = _hostDao.findById(hostId);
+ Host.Type type = ssHost.getType();
+ if (type != Host.Type.SecondaryStorage
+ && type != Host.Type.LocalSecondaryStorage) {
+ return null;
+ }
+ String secUrl = ssHost.getStorageUrl();
+ Answer answer;
+ answer = _agentMgr.sendToSecStorage(ssHost, new ComputeChecksumCommand(
+ secUrl, templatePath));
+ if (answer != null && answer.getResult()) {
+ return answer.getDetails();
+ }
+ return null;
+ }
+
@Override
@DB
public VMTemplateHostVO prepareISOForCreate(VMTemplateVO template, StoragePool pool) {
@@ -684,7 +846,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
long templateStoragePoolRefId;
String origUrl = null;
- templateHostRef = _storageMgr.findVmTemplateHost(templateId, pool);
+ templateHostRef = findVmTemplateHost(templateId, pool);
if (templateHostRef == null || templateHostRef.getDownloadState() != Status.DOWNLOADED) {
String result = downloadTemplateFromSwiftToSecondaryStorage(dcId, templateId);
@@ -698,7 +860,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
s_logger.error("Unable to find a secondary storage host who has completely downloaded the template.");
return null;
}
- templateHostRef = _storageMgr.findVmTemplateHost(templateId, pool);
+ templateHostRef = findVmTemplateHost(templateId, pool);
if (templateHostRef == null || templateHostRef.getDownloadState() != Status.DOWNLOADED) {
s_logger.error("Unable to find a secondary storage host who has completely downloaded the template.");
return null;
@@ -839,13 +1001,13 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
throw new InvalidParameterValueException("Unable to find template with id");
}
- HostVO dstSecHost = _storageMgr.getSecondaryStorageHost(destZoneId, templateId);
+ HostVO dstSecHost = getSecondaryStorageHost(destZoneId, templateId);
if ( dstSecHost != null ) {
s_logger.debug("There is template " + templateId + " in secondary storage " + dstSecHost.getId() + " in zone " + destZoneId + " , don't need to copy");
return template;
}
- HostVO srcSecHost = _storageMgr.getSecondaryStorageHost(sourceZoneId, templateId);
+ HostVO srcSecHost = getSecondaryStorageHost(sourceZoneId, templateId);
if ( srcSecHost == null ) {
throw new InvalidParameterValueException("There is no template " + templateId + " in zone " + sourceZoneId );
}
@@ -900,7 +1062,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
@Override
public void evictTemplateFromStoragePool(VMTemplateStoragePoolVO templatePoolVO) {
- StoragePoolVO pool = _poolDao.findById(templatePoolVO.getPoolId());
+ StoragePool pool = (StoragePool)this.dataStoreMgr.getPrimaryDataStore(templatePoolVO.getPoolId());
VMTemplateVO template = _tmpltDao.findByIdIncludingRemoved(templatePoolVO.getTemplateId());
@@ -1176,12 +1338,57 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
throw new CloudRuntimeException("Failed to attach iso");
}
}
+
+ private boolean attachISOToVM(long vmId, long isoId, boolean attach) {
+ UserVmVO vm = this._userVmDao.findById(vmId);
+
+ if (vm == null) {
+ return false;
+ } else if (vm.getState() != State.Running) {
+ return true;
+ }
+ String isoPath;
+ VMTemplateVO tmplt = this._tmpltDao.findById(isoId);
+ if (tmplt == null) {
+ s_logger.warn("ISO: " + isoId + " does not exist");
+ return false;
+ }
+ // Get the path of the ISO
+ Pair<String, String> isoPathPair = null;
+ if (tmplt.getTemplateType() == TemplateType.PERHOST) {
+ isoPath = tmplt.getName();
+ } else {
+ isoPathPair = getAbsoluteIsoPath(isoId,
+ vm.getDataCenterId());
+ if (isoPathPair == null) {
+ s_logger.warn("Couldn't get absolute iso path");
+ return false;
+ } else {
+ isoPath = isoPathPair.first();
+ }
+ }
+
+ String vmName = vm.getInstanceName();
+
+ HostVO host = _hostDao.findById(vm.getHostId());
+ if (host == null) {
+ s_logger.warn("Host: " + vm.getHostId() + " does not exist");
+ return false;
+ }
+ AttachIsoCommand cmd = new AttachIsoCommand(vmName, isoPath, attach);
+ if (isoPathPair != null) {
+ cmd.setStoreUrl(isoPathPair.second());
+ }
+ Answer a = _agentMgr.easySend(vm.getHostId(), cmd);
+
+ return (a != null && a.getResult());
+ }
private boolean attachISOToVM(long vmId, long userId, long isoId, boolean attach) {
UserVmVO vm = _userVmDao.findById(vmId);
VMTemplateVO iso = _tmpltDao.findById(isoId);
- boolean success = _vmMgr.attachISOToVM(vmId, isoId, attach);
+ boolean success = attachISOToVM(vmId, isoId, attach);
if ( success && attach) {
vm.setIsoId(iso.getId());
_userVmDao.update(vmId, vm);
@@ -1475,4 +1682,456 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
return true;
}
+
+ private String getRandomPrivateTemplateName() {
+ return UUID.randomUUID().toString();
+ }
+
+
+
+
+
+ @Override
+ @DB
+ @ActionEvent(eventType = EventTypes.EVENT_TEMPLATE_CREATE, eventDescription = "creating template", async = true)
+ public VirtualMachineTemplate createPrivateTemplate(CreateTemplateCmd command)
+ throws CloudRuntimeException {
+ Long userId = UserContext.current().getCallerUserId();
+ if (userId == null) {
+ userId = User.UID_SYSTEM;
+ }
+ long templateId = command.getEntityId();
+ Long volumeId = command.getVolumeId();
+ Long snapshotId = command.getSnapshotId();
+ VMTemplateVO privateTemplate = null;
+ Long accountId = null;
+ SnapshotVO snapshot = null;
+
+ try {
+ TemplateInfo tmplInfo = this.tmplFactory.getTemplate(templateId);
+ snapshot = _snapshotDao.findById(snapshotId);
+ ZoneScope scope = new ZoneScope(snapshot.getDataCenterId());
+ List<DataStore> store = this.dataStoreMgr.getImageStores(scope);
+ if (store.size() > 1) {
+ throw new CloudRuntimeException("muliple image data store, don't know which one to use");
+ }
+ AsyncCallFuture<CommandResult> future = null;
+ if (snapshotId != null) {
+ SnapshotInfo snapInfo = this.snapshotFactory.getSnapshot(snapshotId);
+ future = this.imageSvr.createTemplateFromSnapshotAsync(snapInfo, tmplInfo, store.get(0));
+ } else if (volumeId != null) {
+ VolumeInfo volInfo = this.volFactory.getVolume(volumeId);
+ future = this.imageSvr.createTemplateFromVolumeAsync(volInfo, tmplInfo, store.get(0));
+ } else {
+ throw new CloudRuntimeException(
+ "Creating private Template need to specify snapshotId or volumeId");
+ }
+
+ CommandResult result = null;
+ try {
+ result = future.get();
+ if (result.isFailed()) {
+ privateTemplate = null;
+ s_logger.debug("Failed to create template" + result.getResult());
+ throw new CloudRuntimeException("Failed to create template" + result.getResult());
+ }
+
+ privateTemplate = this._tmpltDao.findById(templateId);
+ UsageEventVO usageEvent = new UsageEventVO(
+ EventTypes.EVENT_TEMPLATE_CREATE,
+ privateTemplate.getAccountId(),
+ snapshot.getDataCenterId(),
+ privateTemplate.getId(), privateTemplate.getName(),
+ null, privateTemplate.getSourceTemplateId(),
+ privateTemplate.getSize());
+ _usageEventDao.persist(usageEvent);
+ } catch (InterruptedException e) {
+ s_logger.debug("Failed to create template", e);
+ throw new CloudRuntimeException("Failed to create template", e);
+ } catch (ExecutionException e) {
+ s_logger.debug("Failed to create template", e);
+ throw new CloudRuntimeException("Failed to create template", e);
+ }
+
+ } finally {
+ /*if (snapshot != null && snapshot.getSwiftId() != null
+ && secondaryStorageURL != null && zoneId != null
+ && accountId != null && volumeId != null) {
+ _snapshotMgr.deleteSnapshotsForVolume(secondaryStorageURL,
+ zoneId, accountId, volumeId);
+ }*/
+ if (privateTemplate == null) {
+ Transaction txn = Transaction.currentTxn();
+ txn.start();
+ // Remove the template record
+ this._tmpltDao.expunge(templateId);
+
+ // decrement resource count
+ if (accountId != null) {
+ _resourceLimitMgr.decrementResourceCount(accountId,
+ ResourceType.template);
+ }
+ txn.commit();
+ }
+ }
+
+ if (privateTemplate != null) {
+ return privateTemplate;
+ } else {
+ throw new CloudRuntimeException("Failed to create a template");
+ }
+ }
+
+ private static boolean isAdmin(short accountType) {
+ return ((accountType == Account.ACCOUNT_TYPE_ADMIN)
+ || (accountType == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN)
+ || (accountType == Account.ACCOUNT_TYPE_DOMAIN_ADMIN) || (accountType == Account.ACCOUNT_TYPE_READ_ONLY_ADMIN));
+ }
+ @Override
+ @ActionEvent(eventType = EventTypes.EVENT_TEMPLATE_CREATE, eventDescription = "creating template", create = true)
+ public VMTemplateVO createPrivateTemplateRecord(CreateTemplateCmd cmd,
+ Account templateOwner) throws ResourceAllocationException {
+ Long userId = UserContext.current().getCallerUserId();
+
+ Account caller = UserContext.current().getCaller();
+ boolean isAdmin = (isAdmin(caller.getType()));
+
+ _accountMgr.checkAccess(caller, null, true, templateOwner);
+
+ String name = cmd.getTemplateName();
+ if ((name == null) || (name.length() > 32)) {
+ throw new InvalidParameterValueException(
+ "Template name cannot be null and should be less than 32 characters");
+ }
+
+ if (cmd.getTemplateTag() != null) {
+ if (!_accountService.isRootAdmin(caller.getType())) {
+ throw new PermissionDeniedException(
+ "Parameter templatetag can only be specified by a Root Admin, permission denied");
+ }
+ }
+
+ // do some parameter defaulting
+ Integer bits = cmd.getBits();
+ Boolean requiresHvm = cmd.getRequiresHvm();
+ Boolean passwordEnabled = cmd.isPasswordEnabled();
+ Boolean isPublic = cmd.isPublic();
+ Boolean featured = cmd.isFeatured();
+ int bitsValue = ((bits == null) ? 64 : bits.intValue());
+ boolean requiresHvmValue = ((requiresHvm == null) ? true : requiresHvm
+ .booleanValue());
+ boolean passwordEnabledValue = ((passwordEnabled == null) ? false
+ : passwordEnabled.booleanValue());
+ if (isPublic == null) {
+ isPublic = Boolean.FALSE;
+ }
+ boolean allowPublicUserTemplates = Boolean.parseBoolean(_configDao
+ .getValue("allow.public.user.templates"));
+ if (!isAdmin && !allowPublicUserTemplates && isPublic) {
+ throw new PermissionDeniedException("Failed to create template "
+ + name + ", only private templates can be created.");
+ }
+
+ Long volumeId = cmd.getVolumeId();
+ Long snapshotId = cmd.getSnapshotId();
+ if ((volumeId == null) && (snapshotId == null)) {
+ throw new InvalidParameterValueException(
+ "Failed to create private template record, neither volume ID nor snapshot ID were specified.");
+ }
+ if ((volumeId != null) && (snapshotId != null)) {
+ throw new InvalidParameterValueException(
+ "Failed to create private template record, please specify only one of volume ID ("
+ + volumeId
+ + ") and snapshot ID ("
+ + snapshotId
+ + ")");
+ }
+
+ HypervisorType hyperType;
+ VolumeVO volume = null;
+ VMTemplateVO privateTemplate = null;
+ if (volumeId != null) { // create template from volume
+ volume = this._volumeDao.findById(volumeId);
+ if (volume == null) {
+ throw new InvalidParameterValueException(
+ "Failed to create private template record, unable to find volume "
+ + volumeId);
+ }
+ // check permissions
+ _accountMgr.checkAccess(caller, null, true, volume);
+
+ // If private template is created from Volume, check that the volume
+ // will not be active when the private template is
+ // created
+ if (!this.volumeMgr.volumeInactive(volume)) {
+ String msg = "Unable to create private template for volume: "
+ + volume.getName()
+ + "; volume is attached to a non-stopped VM, please stop the VM first";
+ if (s_logger.isInfoEnabled()) {
+ s_logger.info(msg);
+ }
+ throw new CloudRuntimeException(msg);
+ }
+ hyperType = this._volumeDao.getHypervisorType(volumeId);
+ } else { // create template from snapshot
+ SnapshotVO snapshot = _snapshotDao.findById(snapshotId);
+ if (snapshot == null) {
+ throw new InvalidParameterValueException(
+ "Failed to create private template record, unable to find snapshot "
+ + snapshotId);
+ }
+
+ volume = this._volumeDao.findById(snapshot.getVolumeId());
+ VolumeVO snapshotVolume = this._volumeDao
+ .findByIdIncludingRemoved(snapshot.getVolumeId());
+
+ // check permissions
+ _accountMgr.checkAccess(caller, null, true, snapshot);
+
+ if (snapshot.getState() != Snapshot.State.BackedUp) {
+ throw new InvalidParameterValueException("Snapshot id="
+ + snapshotId + " is not in " + Snapshot.State.BackedUp
+ + " state yet and can't be used for template creation");
+ }
+
+ /*
+ * // bug #11428. Operation not supported if vmware and snapshots
+ * parent volume = ROOT if(snapshot.getHypervisorType() ==
+ * HypervisorType.VMware && snapshotVolume.getVolumeType() ==
+ * Type.DATADISK){ throw new UnsupportedServiceException(
+ * "operation not supported, snapshot with id " + snapshotId +
+ * " is created from Data Disk"); }
+ */
+
+ hyperType = snapshot.getHypervisorType();
+ }
+
+ _resourceLimitMgr.checkResourceLimit(templateOwner,
+ ResourceType.template);
+
+ if (!isAdmin || featured == null) {
+ featured = Boolean.FALSE;
+ }
+ Long guestOSId = cmd.getOsTypeId();
+ GuestOSVO guestOS = this._guestOSDao.findById(guestOSId);
+ if (guestOS == null) {
+ throw new InvalidParameterValueException("GuestOS with ID: "
+ + guestOSId + " does not exist.");
+ }
+
+ String uniqueName = Long.valueOf((userId == null) ? 1 : userId)
+ .toString()
+ + UUID.nameUUIDFromBytes(name.getBytes()).toString();
+ Long nextTemplateId = this._tmpltDao.getNextInSequence(Long.class, "id");
+ String description = cmd.getDisplayText();
+ boolean isExtractable = false;
+ Long sourceTemplateId = null;
+ if (volume != null) {
+ VMTemplateVO template = ApiDBUtils.findTemplateById(volume
+ .getTemplateId());
+ isExtractable = template != null
+ && template.isExtractable()
+ && template.getTemplateType() != Storage.TemplateType.SYSTEM;
+ if (template != null) {
+ sourceTemplateId = template.getId();
+ } else if (volume.getVolumeType() == Volume.Type.ROOT) { // vm created out
+ // of blank
+ // template
+ UserVm userVm = ApiDBUtils.findUserVmById(volume
+ .getInstanceId());
+ sourceTemplateId = userVm.getIsoId();
+ }
+ }
+ String templateTag = cmd.getTemplateTag();
+ if (templateTag != null) {
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Adding template tag: " + templateTag);
+ }
+ }
+ privateTemplate = new VMTemplateVO(nextTemplateId, uniqueName, name,
+ ImageFormat.RAW, isPublic, featured, isExtractable,
+ TemplateType.USER, null, null, requiresHvmValue, bitsValue,
+ templateOwner.getId(), 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);
+ }
+ }
+ privateTemplate.setSourceTemplateId(sourceTemplateId);
+
+ VMTemplateVO template = this._tmpltDao.persist(privateTemplate);
+ // Increment the number of templates
+ if (template != null) {
+ if (cmd.getDetails() != null) {
+ this._templateDetailsDao.persist(template.getId(), cmd.getDetails());
+ }
+
+ _resourceLimitMgr.incrementResourceCount(templateOwner.getId(),
+ ResourceType.template);
+ }
+
+ if (template != null) {
+ return template;
+ } else {
+ throw new CloudRuntimeException("Failed to create a template");
+ }
+
+ }
+
+ @Override
+ public Pair<String, String> getAbsoluteIsoPath(long templateId,
+ long dataCenterId) {
+ String isoPath = null;
+
+ List<HostVO> storageHosts = _resourceMgr.listAllHostsInOneZoneByType(
+ Host.Type.SecondaryStorage, dataCenterId);
+ if (storageHosts != null) {
+ for (HostVO storageHost : storageHosts) {
+ List<VMTemplateHostVO> templateHostVOs = this._tmpltHostDao
+ .listByTemplateHostStatus(
+ templateId,
+ storageHost.getId(),
+ VMTemplateStorageResourceAssoc.Status.DOWNLOADED);
+ if (templateHostVOs != null && !templateHostVOs.isEmpty()) {
+ VMTemplateHostVO tmpHostVO = templateHostVOs.get(0);
+ isoPath = storageHost.getStorageUrl() + "/"
+ + tmpHostVO.getInstallPath();
+ return new Pair<String, String>(isoPath,
+ storageHost.getStorageUrl());
+ }
+ }
+ }
+ s_logger.warn("Unable to find secondary storage in zone id="
+ + dataCenterId);
+ return null;
+ }
+
+ @Override
+ public String getSecondaryStorageURL(long zoneId) {
+ // Determine the secondary storage URL
+ HostVO secondaryStorageHost = getSecondaryStorageHost(zoneId);
+
+ if (secondaryStorageHost == null) {
+ return null;
+ }
+
+ return secondaryStorageHost.getStorageUrl();
+ }
+
+ @Override
+ public HostVO getSecondaryStorageHost(long zoneId, long tmpltId) {
+ List<HostVO> hosts = _ssvmMgr
+ .listSecondaryStorageHostsInOneZone(zoneId);
+ if (hosts == null || hosts.size() == 0) {
+ return null;
+ }
+ for (HostVO host : hosts) {
+ VMTemplateHostVO tmpltHost = this._tmpltHostDao.findByHostTemplate(
+ host.getId(), tmpltId);
+ if (tmpltHost != null
+ && !tmpltHost.getDestroyed()
+ && tmpltHost.getDownloadState() == VMTemplateStorageResourceAssoc.Status.DOWNLOADED) {
+ return host;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public VMTemplateHostVO getTemplateHostRef(long zoneId, long tmpltId,
+ boolean readyOnly) {
+ List<HostVO> hosts = _ssvmMgr
+ .listSecondaryStorageHostsInOneZone(zoneId);
+ if (hosts == null || hosts.size() == 0) {
+ return null;
+ }
+ VMTemplateHostVO inProgress = null;
+ VMTemplateHostVO other = null;
+ for (HostVO host : hosts) {
+ VMTemplateHostVO tmpltHost = this._tmpltHostDao.findByHostTemplate(
+ host.getId(), tmpltId);
+ if (tmpltHost != null && !tmpltHost.getDestroyed()) {
+ if (tmpltHost.getDownloadState() == VMTemplateStorageResourceAssoc.Status.DOWNLOADED) {
+ return tmpltHost;
+ } else if (tmpltHost.getDownloadState() == VMTemplateStorageResourceAssoc.Status.DOWNLOAD_IN_PROGRESS) {
+ inProgress = tmpltHost;
+ } else {
+ other = tmpltHost;
+ }
+ }
+ }
+ if (inProgress != null) {
+ return inProgress;
+ }
+ return other;
+ }
+
+ @Override
+ public HostVO getSecondaryStorageHost(long zoneId) {
+ List<HostVO> hosts = _ssvmMgr
+ .listSecondaryStorageHostsInOneZone(zoneId);
+ if (hosts == null || hosts.size() == 0) {
+ hosts = _ssvmMgr.listLocalSecondaryStorageHostsInOneZone(zoneId);
+ if (hosts.isEmpty()) {
+ return null;
+ }
+ }
+
+ int size = hosts.size();
+ Random rn = new Random();
+ int index = rn.nextInt(size);
+ return hosts.get(index);
+ }
+
+ @Override
+ public List<HostVO> getSecondaryStorageHosts(long zoneId) {
+ List<HostVO> hosts = _ssvmMgr
+ .listSecondaryStorageHostsInOneZone(zoneId);
+ if (hosts == null || hosts.size() == 0) {
+ hosts = _ssvmMgr.listLocalSecondaryStorageHostsInOneZone(zoneId);
+ if (hosts.isEmpty()) {
+ return new ArrayList<HostVO>();
+ }
+ }
+ return hosts;
+ }
+
+ @Override
+ public Long getTemplateSize(long templateId, long zoneId) {
+ SearchCriteria<VMTemplateHostVO> sc = HostTemplateStatesSearch.create();
+ sc.setParameters("id", templateId);
+ sc.setParameters(
+ "state",
+ com.cloud.storage.VMTemplateStorageResourceAssoc.Status.DOWNLOADED);
+ sc.setJoinParameters("host", "dcId", zoneId);
+ List<VMTemplateSwiftVO> tsvs = _tmpltSwiftDao
+ .listByTemplateId(templateId);
+ Long size = null;
+ if (tsvs != null && tsvs.size() > 0) {
+ size = tsvs.get(0).getSize();
+ }
+
+ if (size == null && _s3Mgr.isS3Enabled()) {
+ VMTemplateS3VO vmTemplateS3VO = _vmS3TemplateDao
+ .findOneByTemplateId(templateId);
+ if (vmTemplateS3VO != null) {
+ size = vmTemplateS3VO.getSize();
+ }
+ }
+
+ if (size == null) {
+ List<VMTemplateHostVO> sss = this.templateHostDao.search(sc, null);
+ if (sss == null || sss.size() == 0) {
+ throw new CloudRuntimeException("Template "
+ + templateId
+ + " has not been completely downloaded to zone "
+ + zoneId);
+ }
+ size = sss.get(0).getSize();
+ }
+ return size;
+ }
+
}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/a22403ed/server/src/com/cloud/user/AccountManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/user/AccountManagerImpl.java b/server/src/com/cloud/user/AccountManagerImpl.java
index a3f9505..f9a61e8 100755
--- a/server/src/com/cloud/user/AccountManagerImpl.java
+++ b/server/src/com/cloud/user/AccountManagerImpl.java
@@ -104,6 +104,7 @@ import com.cloud.server.auth.UserAuthenticator;
import com.cloud.storage.StorageManager;
import com.cloud.storage.VMTemplateVO;
import com.cloud.storage.Volume;
+import com.cloud.storage.VolumeManager;
import com.cloud.storage.VolumeVO;
import com.cloud.storage.dao.SnapshotDao;
import com.cloud.storage.dao.VMTemplateDao;
@@ -118,7 +119,6 @@ import com.cloud.user.dao.UserDao;
import com.cloud.utils.NumbersUtil;
import com.cloud.utils.Pair;
import com.cloud.utils.Ternary;
-
import com.cloud.utils.component.Manager;
import com.cloud.utils.component.ManagerBase;
import com.cloud.utils.concurrency.NamedThreadFactory;
@@ -226,6 +226,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
Site2SiteVpnManager _vpnMgr;
@Inject
private AutoScaleManager _autoscaleMgr;
+ @Inject VolumeManager volumeMgr;
@Inject
private List<UserAuthenticator> _userAuthenticators;
@@ -576,7 +577,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
for (VolumeVO volume : volumes) {
if (!volume.getState().equals(Volume.State.Destroy)) {
try {
- _storageMgr.deleteVolume(volume.getId(), caller);
+ this.volumeMgr.deleteVolume(volume.getId(), caller);
} catch (Exception ex) {
s_logger.warn("Failed to cleanup volumes as a part of account id=" + accountId + " cleanup due to Exception: ", ex);
accountCleanupNeeded = true;
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/a22403ed/server/src/com/cloud/vm/UserVmManager.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/vm/UserVmManager.java b/server/src/com/cloud/vm/UserVmManager.java
index 3e4a2db..cc1fffd 100755
--- a/server/src/com/cloud/vm/UserVmManager.java
+++ b/server/src/com/cloud/vm/UserVmManager.java
@@ -49,16 +49,7 @@ public interface UserVmManager extends VirtualMachineGuru<UserVmVO>, UserVmServi
* @return VirtualMachine
*/
UserVmVO getVirtualMachine(long vmId);
-
- /**
- * Attaches an ISO to the virtual CDROM device of the specified VM. Will eject any existing virtual CDROM if isoPath is null.
- * @param vmId
- * @param isoId
- * @param attach whether to attach or detach the given iso
- * @return
- */
- boolean attachISOToVM(long vmId, long isoId, boolean attach);
-
+
/**
* Stops the virtual machine
* @param userId the id of the user performing the action
@@ -101,8 +92,6 @@ public interface UserVmManager extends VirtualMachineGuru<UserVmVO>, UserVmServi
*/
Pair<List<UserVmJoinVO>, Integer> searchForUserVMs(Criteria c, Account caller, Long domainId, boolean isRecursive, List<Long> permittedAccounts, boolean listAll, ListProjectResourcesCriteria listProjectResourcesCriteria, Map<String, String> tags);
- String getChecksum(Long hostId, String templatePath);
-
Pair<UserVmVO, Map<VirtualMachineProfile.Param, Object>> startVirtualMachine(long vmId, Long hostId, Map<VirtualMachineProfile.Param, Object> additionalParams) throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException;
}