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/06 03:43:28 UTC

[35/50] [abbrv] squash changes into one giant patch

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/7ff41648/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/7ff41648/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 54447a2..672f02b 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/7ff41648/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;
 
 }