You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by pr...@apache.org on 2013/01/08 21:04:58 UTC

[2/3] OrchestrationService: some changes for DeployVM

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/a4f4c986/server/src/com/cloud/vm/UserVmManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java
index 650a11b..e0454c3 100755
--- a/server/src/com/cloud/vm/UserVmManagerImpl.java
+++ b/server/src/com/cloud/vm/UserVmManagerImpl.java
@@ -32,6 +32,8 @@ import javax.ejb.Local;
 import javax.inject.Inject;
 import javax.naming.ConfigurationException;
 
+import org.apache.cloudstack.engine.cloud.entity.api.VirtualMachineEntity;
+import org.apache.cloudstack.engine.service.api.OrchestrationService;
 import org.apache.commons.codec.binary.Base64;
 import org.apache.log4j.Logger;
 import org.springframework.stereotype.Component;
@@ -161,6 +163,7 @@ import com.cloud.server.ResourceTag.TaggedResourceType;
 import com.cloud.service.ServiceOfferingVO;
 import com.cloud.service.dao.ServiceOfferingDao;
 import com.cloud.storage.DiskOfferingVO;
+import com.cloud.storage.GuestOSCategoryVO;
 import com.cloud.storage.GuestOSVO;
 import com.cloud.storage.Snapshot;
 import com.cloud.storage.SnapshotVO;
@@ -181,6 +184,7 @@ import com.cloud.storage.Volume.Type;
 import com.cloud.storage.VolumeHostVO;
 import com.cloud.storage.VolumeVO;
 import com.cloud.storage.dao.DiskOfferingDao;
+import com.cloud.storage.dao.GuestOSCategoryDao;
 import com.cloud.storage.dao.GuestOSDao;
 import com.cloud.storage.dao.SnapshotDao;
 import com.cloud.storage.dao.StoragePoolDao;
@@ -238,3584 +242,4437 @@ import com.cloud.vm.dao.VMInstanceDao;
 @Component
 @Local(value = { UserVmManager.class, UserVmService.class })
 public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager {
-    private static final Logger s_logger = Logger.getLogger(UserVmManagerImpl.class);
-
-    private static final int ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_COOPERATION = 3; // 3 seconds
-
-    @Inject
-    protected HostDao _hostDao = null;
-    @Inject
-    protected ServiceOfferingDao _offeringDao = null;
-    @Inject
-    protected DiskOfferingDao _diskOfferingDao = null;
-    @Inject
-    protected VMTemplateDao _templateDao = null;
-    @Inject
-    protected VMTemplateDetailsDao _templateDetailsDao = null;
-    @Inject
-    protected VMTemplateHostDao _templateHostDao = null;
-    @Inject
-    protected VMTemplateZoneDao _templateZoneDao = null;
-    @Inject
-    protected DomainDao _domainDao = null;
-    @Inject
-    protected UserVmDao _vmDao = null;
-    @Inject
-    protected VolumeDao _volsDao = null;
-    @Inject
-    protected DataCenterDao _dcDao = null;
-    @Inject
-    protected FirewallRulesDao _rulesDao = null;
-    @Inject
-    protected LoadBalancerVMMapDao _loadBalancerVMMapDao = null;
-    @Inject
-    protected PortForwardingRulesDao _portForwardingDao;
-    @Inject
-    protected IPAddressDao _ipAddressDao = null;
-    @Inject
-    protected HostPodDao _podDao = null;
-    @Inject
-    protected NetworkManager _networkMgr = null;
-    @Inject
-    protected StorageManager _storageMgr = null;
-    @Inject
-    protected SnapshotManager _snapshotMgr = null;
-    @Inject
-    protected AgentManager _agentMgr = null;
-    @Inject
-    protected ConfigurationManager _configMgr = null;
-    @Inject
-    protected AccountDao _accountDao = null;
-    @Inject
-    protected UserDao _userDao = null;
-    @Inject
-    protected SnapshotDao _snapshotDao = null;
-    @Inject
-    protected GuestOSDao _guestOSDao = null;
-    @Inject
-    protected HighAvailabilityManager _haMgr = null;
-    @Inject
-    protected AlertManager _alertMgr = null;
-    @Inject
-    protected AccountManager _accountMgr;
-    @Inject
-    protected AccountService _accountService;
-    @Inject
-    protected AsyncJobManager _asyncMgr;
-    @Inject
-    protected ClusterDao _clusterDao;
-    @Inject
-    protected StoragePoolDao _storagePoolDao;
-    @Inject
-    protected SecurityGroupManager _securityGroupMgr;
-    @Inject
-    protected ServiceOfferingDao _serviceOfferingDao;
-    @Inject
-    protected NetworkOfferingDao _networkOfferingDao;
-    @Inject
-    protected InstanceGroupDao _vmGroupDao;
-    @Inject
-    protected InstanceGroupVMMapDao _groupVMMapDao;
-    @Inject
-    protected VirtualMachineManager _itMgr;
-    @Inject
-    protected NetworkDao _networkDao;
-    @Inject
-    protected NicDao _nicDao;
-    @Inject
-    protected VpcDao _vpcDao;
-    @Inject
-    protected RulesManager _rulesMgr;
-    @Inject
-    protected LoadBalancingRulesManager _lbMgr;
-    @Inject
-    protected UsageEventDao _usageEventDao;
-    @Inject
-    protected SSHKeyPairDao _sshKeyPairDao;
-    @Inject
-    protected UserVmDetailsDao _vmDetailsDao;
-    @Inject
-    protected HypervisorCapabilitiesDao _hypervisorCapabilitiesDao;
-    @Inject
-    protected SecurityGroupDao _securityGroupDao;
-    @Inject 
-    protected CapacityManager _capacityMgr;;
-    @Inject 
-    protected VMInstanceDao _vmInstanceDao;
-    @Inject
-    protected ResourceLimitService _resourceLimitMgr;
-    @Inject
-    protected FirewallManager _firewallMgr;
-    @Inject
-    protected ProjectManager _projectMgr;
-    @Inject
-    protected ResourceManager _resourceMgr;
-    @Inject 
-    protected NetworkServiceMapDao _ntwkSrvcDao;
-    @Inject
-    SecurityGroupVMMapDao _securityGroupVMMapDao;
-    @Inject
-    protected ItWorkDao _workDao;
-    @Inject
-    protected VolumeHostDao _volumeHostDao;
-    @Inject
-    ResourceTagDao _resourceTagDao;
-    @Inject
-    PhysicalNetworkDao _physicalNetworkDao;
-    @Inject
-    VpcManager _vpcMgr;
-
-    protected ScheduledExecutorService _executor = null;
-    protected int _expungeInterval;
-    protected int _expungeDelay;
-
-    protected String _name;
-    protected String _instance;
-    protected String _zone;
-
-    private ConfigurationDao _configDao;
-    private int _createprivatetemplatefromvolumewait;
-    private int _createprivatetemplatefromsnapshotwait;
-    @Override
-    public UserVmVO getVirtualMachine(long vmId) {
-        return _vmDao.findById(vmId);
-    }
-
-    @Override
-    public List<? extends UserVm> getVirtualMachines(long hostId) {
-        return _vmDao.listByHostId(hostId);
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_VM_RESETPASSWORD, eventDescription = "resetting Vm password", async = true)
-    public UserVm resetVMPassword(ResetVMPasswordCmd cmd, String password) throws ResourceUnavailableException, InsufficientCapacityException {
-        Account caller = UserContext.current().getCaller();
-        Long vmId = cmd.getId();
-        UserVmVO userVm = _vmDao.findById(cmd.getId());
-        _vmDao.loadDetails(userVm);
-
-        // Do parameters input validation
-        if (userVm == null) {
-            throw new InvalidParameterValueException("unable to find a virtual machine with id " + cmd.getId());
-        }
-
-        VMTemplateVO template = _templateDao.findByIdIncludingRemoved(userVm.getTemplateId());
-        if (template == null || !template.getEnablePassword()) {
-            throw new InvalidParameterValueException("Fail to reset password for the virtual machine, the template is not password enabled");
-        }
-
-        if (userVm.getState() == State.Error || userVm.getState() == State.Expunging) {
-            s_logger.error("vm is not in the right state: " + vmId);
-            throw new InvalidParameterValueException("Vm with id " + vmId + " is not in the right state");
-        }
-
-        _accountMgr.checkAccess(caller, null, true, userVm);
-
-        boolean result = resetVMPasswordInternal(cmd, password);
-
-        if (result) {
-            userVm.setPassword(password);
-            //update the password in vm_details table too 
-            // Check if an SSH key pair was selected for the instance and if so use it to encrypt & save the vm password
-            String sshPublicKey = userVm.getDetail("SSH.PublicKey");
-            if (sshPublicKey != null && !sshPublicKey.equals("") && password != null && !password.equals("saved_password")) {
-                String encryptedPasswd = RSAHelper.encryptWithSSHPublicKey(sshPublicKey, password);
-                if (encryptedPasswd == null) {
-                    throw new CloudRuntimeException("Error encrypting password");
-                }
-
-                userVm.setDetail("Encrypted.Password", encryptedPasswd);
-                _vmDao.saveDetails(userVm);
-            }
-        } else {
-            throw new CloudRuntimeException("Failed to reset password for the virtual machine ");
-        }
-
-        return userVm;
-    }
-
-    private boolean resetVMPasswordInternal(ResetVMPasswordCmd cmd, String password) throws ResourceUnavailableException, InsufficientCapacityException {
-        Long vmId = cmd.getId();
-        Long userId = UserContext.current().getCallerUserId();
-        VMInstanceVO vmInstance = _vmDao.findById(vmId);
-
-        if (password == null || password.equals("")) {
-            return false;
-        }
-
-        VMTemplateVO template = _templateDao.findByIdIncludingRemoved(vmInstance.getTemplateId());
-        if (template.getEnablePassword()) {
-            Nic defaultNic = _networkMgr.getDefaultNic(vmId);
-            if (defaultNic == null) {
-                s_logger.error("Unable to reset password for vm " + vmInstance + " as the instance doesn't have default nic");
-                return false;
-            }
-
-            Network defaultNetwork = _networkDao.findById(defaultNic.getNetworkId());
-            NicProfile defaultNicProfile = new NicProfile(defaultNic, defaultNetwork, null, null, null, _networkMgr.isSecurityGroupSupportedInNetwork(defaultNetwork), _networkMgr.getNetworkTag(template.getHypervisorType(), defaultNetwork));
-            VirtualMachineProfile<VMInstanceVO> vmProfile = new VirtualMachineProfileImpl<VMInstanceVO>(vmInstance);
-            vmProfile.setParameter(VirtualMachineProfile.Param.VmPassword, password);
-
-            UserDataServiceProvider element = _networkMgr.getPasswordResetProvider(defaultNetwork);
-            if (element == null) {
-                throw new CloudRuntimeException("Can't find network element for " + Service.UserData.getName() + 
-                        " provider needed for password reset");
-            }
-
-            boolean result = element.savePassword(defaultNetwork, defaultNicProfile, vmProfile);
-
-            // Need to reboot the virtual machine so that the password gets redownloaded from the DomR, and reset on the VM
-            if (!result) {
-                s_logger.debug("Failed to reset password for the virutal machine; no need to reboot the vm");
-                return false;
-            } else {
-                if (vmInstance.getState() == State.Stopped) {
-                    s_logger.debug("Vm " + vmInstance + " is stopped, not rebooting it as a part of password reset");
-                    return true;
-                }
-
-                if (rebootVirtualMachine(userId, vmId) == null) { 
-                    s_logger.warn("Failed to reboot the vm " + vmInstance);
-                    return false;
-                } else {
-                    s_logger.debug("Vm " + vmInstance + " is rebooted successfully as a part of password reset");
-                    return true;
-                }
-            }
-        } else {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Reset password called for a vm that is not using a password enabled template");
-            }
-            return false;
-        }
-    }
-
-    @Override
-    public boolean stopVirtualMachine(long userId, long vmId) {
-        boolean status = false;
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Stopping vm=" + vmId);
-        }
-        UserVmVO vm = _vmDao.findById(vmId);
-        if (vm == null || vm.getRemoved() != null) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("VM is either removed or deleted.");
-            }
-            return true;
-        }
-
-        User user = _userDao.findById(userId);
-        Account account = _accountDao.findById(user.getAccountId());
-
-        try {
-            status = _itMgr.stop(vm, user, account);
-        } catch (ResourceUnavailableException e) {
-            s_logger.debug("Unable to stop due to ", e);
-            status = false;
-        }
-
-        if (status) {
-            return status;
-        } else {
-            return status;
-        }
-    }
-
-    private int getMaxDataVolumesSupported(UserVmVO vm) {
-        Long hostId = vm.getHostId();
-        if (hostId == null) {
-            hostId = vm.getLastHostId();
-        }
-        HostVO host = _hostDao.findById(hostId);
-        Integer maxDataVolumesSupported = null;
-        if (host != null) {
-            _hostDao.loadDetails(host);
-            maxDataVolumesSupported = _hypervisorCapabilitiesDao.getMaxDataVolumesLimit(host.getHypervisorType(), host.getDetail("product_version"));
-        }
-        if (maxDataVolumesSupported == null) {
-            maxDataVolumesSupported = 6;  // 6 data disks by default if nothing is specified in 'hypervisor_capabilities' table
-        }
-
-        return maxDataVolumesSupported.intValue();
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_VOLUME_ATTACH, eventDescription = "attaching volume", async = true)
-    public Volume attachVolumeToVM(AttachVolumeCmd command) {
-        Long vmId = command.getVirtualMachineId();
-        Long volumeId = command.getId();
-        Long deviceId = command.getDeviceId();
-        Account caller = UserContext.current().getCaller();
-
-        // Check that the volume ID is valid
-        VolumeVO volume = _volsDao.findById(volumeId);
-        // Check that the volume is a data volume
-        if (volume == null || volume.getVolumeType() != Volume.Type.DATADISK) {
-            throw new InvalidParameterValueException("Please specify a valid data volume.");
-        }
-
-        // Check that the volume is not currently attached to any VM
-        if (volume.getInstanceId() != null) {
-            throw new InvalidParameterValueException("Please specify a volume that is not attached to any VM.");
-        }
-
-        // Check that the volume is not destroyed
-        if (volume.getState() == Volume.State.Destroy) {
-            throw new InvalidParameterValueException("Please specify a volume that is not destroyed.");
-        }
-
-        // Check that the virtual machine ID is valid and it's a user vm
-        UserVmVO vm = _vmDao.findById(vmId);
-        if (vm == null || vm.getType() != VirtualMachine.Type.User) {
-            throw new InvalidParameterValueException("Please specify a valid User VM.");
-        }
-
-        // Check that the VM is in the correct state
-        if (vm.getState() != State.Running && vm.getState() != State.Stopped) {
-            throw new InvalidParameterValueException("Please specify a VM that is either running or stopped.");
-        }
-
-        // Check that the device ID is valid
-        if (deviceId != null) {
-            if (deviceId.longValue() == 0) {
-                throw new InvalidParameterValueException("deviceId can't be 0, which is used by Root device");
-            }
-        }
-
-        // Check that the number of data volumes attached to VM is less than that supported by hypervisor
-        List<VolumeVO> existingDataVolumes = _volsDao.findByInstanceAndType(vmId, Volume.Type.DATADISK);
-        int maxDataVolumesSupported = getMaxDataVolumesSupported(vm);
-        if (existingDataVolumes.size() >= maxDataVolumesSupported) {
-            throw new InvalidParameterValueException("The specified VM already has the maximum number of data disks (" + maxDataVolumesSupported + "). Please specify another VM.");
-        }
-
-        // Check that the VM and the volume are in the same zone
-        if (vm.getDataCenterIdToDeployIn() != volume.getDataCenterId()) {
-            throw new InvalidParameterValueException("Please specify a VM that is in the same zone as the volume.");
-        }
-
-        // If local storage is disabled then attaching a volume with local disk offering not allowed
-        DataCenterVO dataCenter = _dcDao.findById(volume.getDataCenterId());
-        if (!dataCenter.isLocalStorageEnabled()) {
-            DiskOfferingVO diskOffering = _diskOfferingDao.findById(volume.getDiskOfferingId());
-            if (diskOffering.getUseLocalStorage()) {
-                throw new InvalidParameterValueException("Zone is not configured to use local storage but volume's disk offering " + diskOffering.getName() + " uses it");
-            }
-        }
-
-        //permission check
-        _accountMgr.checkAccess(caller, null, true, volume, vm);
-
-        //Check if volume is stored on secondary Storage.
-        boolean isVolumeOnSec = false;
-        VolumeHostVO  volHostVO = _volumeHostDao.findByVolumeId(volume.getId());
-        if (volHostVO != null){
-            isVolumeOnSec = true;
-            if( !(volHostVO.getDownloadState() == Status.DOWNLOADED) ){
-                throw new InvalidParameterValueException("Volume is not uploaded yet. Please try this operation once the volume is uploaded");
-            }
-        }
-
-        if ( !(Volume.State.Allocated.equals(volume.getState()) || Volume.State.Ready.equals(volume.getState()) || Volume.State.UploadOp.equals(volume.getState())) ) {
-            throw new InvalidParameterValueException("Volume state must be in Allocated, Ready or in Uploaded state");
-        }
-
-        VolumeVO rootVolumeOfVm = null;
-        List<VolumeVO> rootVolumesOfVm = _volsDao.findByInstanceAndType(vmId, Volume.Type.ROOT);
-        if (rootVolumesOfVm.size() != 1) {
-            throw new CloudRuntimeException("The VM " + vm.getHostName() + " has more than one ROOT volume and is in an invalid state.");
-        } else {
-            rootVolumeOfVm = rootVolumesOfVm.get(0);
-        }
-
-        HypervisorType rootDiskHyperType = vm.getHypervisorType();
-
-        HypervisorType dataDiskHyperType = _volsDao.getHypervisorType(volume.getId());
-        if (dataDiskHyperType != HypervisorType.None && rootDiskHyperType != dataDiskHyperType) {
-            throw new InvalidParameterValueException("Can't attach a volume created by: " + dataDiskHyperType + " to a " + rootDiskHyperType + " vm");
-        }
-
-        //allocate deviceId
-        List<VolumeVO> vols = _volsDao.findByInstance(vmId);
-        if (deviceId != null) {
-            if (deviceId.longValue() > 15 || deviceId.longValue() == 0 || deviceId.longValue() == 3) {
-                throw new RuntimeException("deviceId should be 1,2,4-15");
-            }
-            for (VolumeVO vol : vols) {
-                if (vol.getDeviceId().equals(deviceId)) {
-                    throw new RuntimeException("deviceId " + deviceId + " is used by VM " + vm.getHostName());
-                }
-            }
-        } else {
-            // allocate deviceId here
-            List<String> devIds = new ArrayList<String>();
-            for (int i = 1; i < 15; i++) {
-                devIds.add(String.valueOf(i));
-            }
-            devIds.remove("3");
-            for (VolumeVO vol : vols) {
-                devIds.remove(vol.getDeviceId().toString().trim());
-            }
-            deviceId = Long.parseLong(devIds.iterator().next());
-        }
-
-        boolean createVolumeOnBackend = true;
-        if (rootVolumeOfVm.getState() == Volume.State.Allocated) {
-            createVolumeOnBackend = false;
-            if(isVolumeOnSec){
-                throw new CloudRuntimeException("Cant attach uploaded volume to the vm which is not created. Please start it and then retry");
-            }
-        }
-
-        //create volume on the backend only when vm's root volume is allocated
-        if (createVolumeOnBackend) {
-            if (volume.getState().equals(Volume.State.Allocated) || isVolumeOnSec) {
-                /* Need to create the volume */
-                VMTemplateVO rootDiskTmplt = _templateDao.findById(vm.getTemplateId());
-                DataCenterVO dcVO = _dcDao.findById(vm.getDataCenterIdToDeployIn());
-                HostPodVO pod = _podDao.findById(vm.getPodIdToDeployIn());
-                StoragePoolVO rootDiskPool = _storagePoolDao.findById(rootVolumeOfVm.getPoolId());
-                ServiceOfferingVO svo = _serviceOfferingDao.findById(vm.getServiceOfferingId());
-                DiskOfferingVO diskVO = _diskOfferingDao.findById(volume.getDiskOfferingId());
-                Long clusterId = (rootDiskPool == null ? null : rootDiskPool.getClusterId());
-
-                if (!isVolumeOnSec){
-                    volume = _storageMgr.createVolume(volume, vm, rootDiskTmplt, dcVO, pod, clusterId, svo, diskVO, new ArrayList<StoragePoolVO>(), volume.getSize(), rootDiskHyperType);
-                }else {
-                    try {
-                        // Format of data disk should be the same as root disk
-                        if( ! volHostVO.getFormat().getFileExtension().equals(_storageMgr.getSupportedImageFormatForCluster(rootDiskPool.getClusterId())) ){
-                            throw new InvalidParameterValueException("Failed to attach volume to VM since volumes format " +volHostVO.getFormat().getFileExtension() + " is not compatible with the vm hypervisor type" );
-                        }
-
-                        // Check that there is some shared storage.
-                        StoragePoolVO vmRootVolumePool = _storagePoolDao.findById(rootVolumeOfVm.getPoolId());                                           
-                        List<StoragePoolVO> sharedVMPools = _storagePoolDao.findPoolsByTags(vmRootVolumePool.getDataCenterId(), vmRootVolumePool.getPodId(), vmRootVolumePool.getClusterId(), null, true);
-                        if (sharedVMPools.size() == 0) {
-                            throw new CloudRuntimeException("Cannot attach volume since there are no shared storage pools in the VM's cluster to copy the uploaded volume to.");
-                        }
-
-                        volume = _storageMgr.copyVolumeFromSecToPrimary(volume, vm, rootDiskTmplt, dcVO, pod, rootDiskPool.getClusterId(), svo, diskVO, new ArrayList<StoragePoolVO>(), volume.getSize(), rootDiskHyperType);
-                    } catch (NoTransitionException e) {
-                        throw new CloudRuntimeException("Unable to transition the volume ",e);
-                    }
-                }
-
-                if (volume == null) {
-                    throw new CloudRuntimeException("Failed to create volume when attaching it to VM: " + vm.getHostName());
-                }
-            }
-
-            StoragePoolVO vmRootVolumePool = _storagePoolDao.findById(rootVolumeOfVm.getPoolId());
-            DiskOfferingVO volumeDiskOffering = _diskOfferingDao.findById(volume.getDiskOfferingId());
-            String[] volumeTags = volumeDiskOffering.getTagsArray();
-
-            boolean isVolumeOnSharedPool = !volumeDiskOffering.getUseLocalStorage();
-            StoragePoolVO sourcePool = _storagePoolDao.findById(volume.getPoolId());
-            List<StoragePoolVO> matchingVMPools = _storagePoolDao.findPoolsByTags(vmRootVolumePool.getDataCenterId(), vmRootVolumePool.getPodId(), vmRootVolumePool.getClusterId(), volumeTags, isVolumeOnSharedPool);
-            boolean moveVolumeNeeded = true;
-            if (matchingVMPools.size() == 0) {
-                String poolType;
-                if (vmRootVolumePool.getClusterId() != null) {
-                    poolType = "cluster";
-                } else if (vmRootVolumePool.getPodId() != null) {
-                    poolType = "pod";
-                } else {
-                    poolType = "zone";
-                }
-                throw new CloudRuntimeException("There are no storage pools in the VM's " + poolType + " with all of the volume's tags (" + volumeDiskOffering.getTags() + ").");
-            } else {
-                long sourcePoolId = sourcePool.getId();
-                Long sourcePoolDcId = sourcePool.getDataCenterId();
-                Long sourcePoolPodId = sourcePool.getPodId();
-                Long sourcePoolClusterId = sourcePool.getClusterId();
-                for (StoragePoolVO vmPool : matchingVMPools) {
-                    long vmPoolId = vmPool.getId();
-                    Long vmPoolDcId = vmPool.getDataCenterId();
-                    Long vmPoolPodId = vmPool.getPodId();
-                    Long vmPoolClusterId = vmPool.getClusterId();
-
-                    // Moving a volume is not required if storage pools belongs to same cluster in case of shared volume or
-                    // identical storage pool in case of local
-                    if (sourcePoolDcId == vmPoolDcId && sourcePoolPodId == vmPoolPodId && sourcePoolClusterId == vmPoolClusterId
-                            && (isVolumeOnSharedPool || sourcePoolId == vmPoolId)) {
-                        moveVolumeNeeded = false;
-                        break;
-                    }
-                }
-            }
-
-            if (moveVolumeNeeded) {
-                if (isVolumeOnSharedPool) {
-                    // Move the volume to a storage pool in the VM's zone, pod, or cluster
-                    try {
-                        volume = _storageMgr.moveVolume(volume, vmRootVolumePool.getDataCenterId(), vmRootVolumePool.getPodId(), vmRootVolumePool.getClusterId(), dataDiskHyperType);
-                    } catch (ConcurrentOperationException e) {
-                        throw new CloudRuntimeException(e.toString());
-                    }
-                } else {
-                    throw new CloudRuntimeException("Failed to attach local data volume " + volume.getName() + " to VM " + vm.getDisplayName() + " as migration of local data volume is not allowed");
-                }
-            }
-        }
-
-        AsyncJobExecutor asyncExecutor = BaseAsyncJobExecutor.getCurrentExecutor();
-        if (asyncExecutor != null) {
-            AsyncJobVO job = asyncExecutor.getJob();
-
-            if (s_logger.isInfoEnabled()) {
-                s_logger.info("Trying to attaching volume " + volumeId + " to vm instance:" + vm.getId() + ", update async job-" + job.getId() + " progress status");
-            }
-
-            _asyncMgr.updateAsyncJobAttachment(job.getId(), "volume", volumeId);
-            _asyncMgr.updateAsyncJobStatus(job.getId(), BaseCmd.PROGRESS_INSTANCE_CREATED, volumeId);
-        }
-
-        String errorMsg = "Failed to attach volume: " + volume.getName() + " to VM: " + vm.getHostName();
-        boolean sendCommand = (vm.getState() == State.Running);
-        AttachVolumeAnswer answer = null;
-        Long hostId = vm.getHostId();
-        if (hostId == null) {
-            hostId = vm.getLastHostId();
-            HostVO host = _hostDao.findById(hostId);
-            if (host != null && host.getHypervisorType() == HypervisorType.VMware) {
-                sendCommand = true;
-            }
-        }
-
-        if (sendCommand) {
-            StoragePoolVO volumePool = _storagePoolDao.findById(volume.getPoolId());
-            AttachVolumeCommand cmd = new AttachVolumeCommand(true, vm.getInstanceName(), volume.getPoolType(), volume.getFolder(), volume.getPath(), volume.getName(), deviceId, volume.getChainInfo());
-            cmd.setPoolUuid(volumePool.getUuid());
-
-            try {
-                answer = (AttachVolumeAnswer) _agentMgr.send(hostId, cmd);
-            } catch (Exception e) {
-                throw new CloudRuntimeException(errorMsg + " due to: " + e.getMessage());
-            }
-        }
-
-        if (!sendCommand || (answer != null && answer.getResult())) {
-            // Mark the volume as attached
-            if (sendCommand) {
-                _volsDao.attachVolume(volume.getId(), vmId, answer.getDeviceId());
-            } else {
-                _volsDao.attachVolume(volume.getId(), vmId, deviceId);
-            }
-            return _volsDao.findById(volumeId);
-        } else {
-            if (answer != null) {
-                String details = answer.getDetails();
-                if (details != null && !details.isEmpty()) {
-                    errorMsg += "; " + details;
-                }
-            }
-            throw new CloudRuntimeException(errorMsg);
-        }
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_VOLUME_DETACH, eventDescription = "detaching volume", async = true)
-    public Volume detachVolumeFromVM(DetachVolumeCmd cmmd) {
-        Account caller = UserContext.current().getCaller();
-        if ((cmmd.getId() == null && cmmd.getDeviceId() == null && cmmd.getVirtualMachineId() == null) || (cmmd.getId() != null && (cmmd.getDeviceId() != null || cmmd.getVirtualMachineId() != null))
-                || (cmmd.getId() == null && (cmmd.getDeviceId() == null || cmmd.getVirtualMachineId() == null))) {
-            throw new InvalidParameterValueException("Please provide either a volume id, or a tuple(device id, instance id)");
-        }
-
-        Long volumeId = cmmd.getId();
-        VolumeVO volume = null;
-
-        if (volumeId != null) {
-            volume = _volsDao.findById(volumeId);
-        } else {
-            volume = _volsDao.findByInstanceAndDeviceId(cmmd.getVirtualMachineId(), cmmd.getDeviceId()).get(0);
-        }
-
-        Long vmId = null;
-
-        if (cmmd.getVirtualMachineId() == null) {
-            vmId = volume.getInstanceId();
-        } else {
-            vmId = cmmd.getVirtualMachineId();
-        }
-
-        // Check that the volume ID is valid
-        if (volume == null) {
-            throw new InvalidParameterValueException("Unable to find volume with ID: " + volumeId);
-        }
-
-        // Permissions check
-        _accountMgr.checkAccess(caller, null, true, volume);
-
-        // Check that the volume is a data volume
-        if (volume.getVolumeType() != Volume.Type.DATADISK) {
-            throw new InvalidParameterValueException("Please specify a data volume.");
-        }
-
-        // Check that the volume is currently attached to a VM
-        if (vmId == null) {
-            throw new InvalidParameterValueException("The specified volume is not attached to a VM.");
-        }
-
-        // Check that the VM is in the correct state
-        UserVmVO vm = _vmDao.findById(vmId);
-        if (vm.getState() != State.Running && vm.getState() != State.Stopped && vm.getState() != State.Destroyed) {
-            throw new InvalidParameterValueException("Please specify a VM that is either running or stopped.");
-        }
-
-        AsyncJobExecutor asyncExecutor = BaseAsyncJobExecutor.getCurrentExecutor();
-        if (asyncExecutor != null) {
-            AsyncJobVO job = asyncExecutor.getJob();
-
-            if (s_logger.isInfoEnabled()) {
-                s_logger.info("Trying to attaching volume " + volumeId + "to vm instance:" + vm.getId() + ", update async job-" + job.getId() + " progress status");
-            }
-
-            _asyncMgr.updateAsyncJobAttachment(job.getId(), "volume", volumeId);
-            _asyncMgr.updateAsyncJobStatus(job.getId(), BaseCmd.PROGRESS_INSTANCE_CREATED, volumeId);
-        }
-
-        String errorMsg = "Failed to detach volume: " + volume.getName() + " from VM: " + vm.getHostName();
-        boolean sendCommand = (vm.getState() == State.Running);
-        Answer answer = null;
-
-        if (sendCommand) {
-            AttachVolumeCommand cmd = new AttachVolumeCommand(false, vm.getInstanceName(), volume.getPoolType(), volume.getFolder(), volume.getPath(), volume.getName(),
-                    cmmd.getDeviceId() != null ? cmmd.getDeviceId() : volume.getDeviceId(), volume.getChainInfo());
-
-            StoragePoolVO volumePool = _storagePoolDao.findById(volume.getPoolId());
-            cmd.setPoolUuid(volumePool.getUuid());
-
-            try {
-                answer = _agentMgr.send(vm.getHostId(), cmd);
-            } catch (Exception e) {
-                throw new CloudRuntimeException(errorMsg + " due to: " + e.getMessage());
-            }
-        }
-
-        if (!sendCommand || (answer != null && answer.getResult())) {
-            // Mark the volume as detached
-            _volsDao.detachVolume(volume.getId());
-            if (answer != null && answer instanceof AttachVolumeAnswer) {
-                volume.setChainInfo(((AttachVolumeAnswer) answer).getChainInfo());
-                _volsDao.update(volume.getId(), volume);
-            }
-
-            return _volsDao.findById(volumeId);
-        } else {
-
-            if (answer != null) {
-                String details = answer.getDetails();
-                if (details != null && !details.isEmpty()) {
-                    errorMsg += "; " + details;
-                }
-            }
-
-            throw new CloudRuntimeException(errorMsg);
-        }
-    }
-
-    @Override
-    public boolean attachISOToVM(long vmId, long isoId, boolean attach) {
-        UserVmVO vm = _vmDao.findById(vmId);
-
-        if (vm == null) {
-            return false;
-        } else if (vm.getState() != State.Running) {
-            return true;
-        }
-        String isoPath;
-        VMTemplateVO tmplt = _templateDao.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 = _storageMgr.getAbsoluteIsoPath(isoId, vm.getDataCenterIdToDeployIn());
-            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 UserVm rebootVirtualMachine(long userId, long vmId) throws InsufficientCapacityException, ResourceUnavailableException {
-        UserVmVO vm = _vmDao.findById(vmId);
-        User caller = _accountMgr.getActiveUser(userId);
-        Account owner = _accountMgr.getAccount(vm.getAccountId());
-
-        if (vm == null || vm.getState() == State.Destroyed || vm.getState() == State.Expunging || vm.getRemoved() != null) {
-            s_logger.warn("Vm id=" + vmId + " doesn't exist");
-            return null;
-        }
-
-        if (vm.getState() == State.Running && vm.getHostId() != null) {
-            return _itMgr.reboot(vm, null, caller, owner);
-        } else {
-            s_logger.error("Vm id=" + vmId + " is not in Running state, failed to reboot");
-            return null;
-        }
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_VM_UPGRADE, eventDescription = "upgrading Vm")
-    /*
-     * TODO: cleanup eventually - Refactored API call
-     */
-    public UserVm upgradeVirtualMachine(UpgradeVMCmd cmd) {
-        Long vmId = cmd.getId();
-        Long svcOffId = cmd.getServiceOfferingId();
-        Account caller = UserContext.current().getCaller();
-
-        // Verify input parameters
-        UserVmVO vmInstance = _vmDao.findById(vmId);
-        if (vmInstance == null) {
-            throw new InvalidParameterValueException("unable to find a virtual machine with id " + vmId);
-        }
-
-        _accountMgr.checkAccess(caller, null, true, vmInstance);
-
-        // Check that the specified service offering ID is valid
-        _itMgr.checkIfCanUpgrade(vmInstance, svcOffId);
-
-        _itMgr.upgradeVmDb(vmId, svcOffId);
-
-        return _vmDao.findById(vmInstance.getId());
-    }
-
-
-    @Override
-    public HashMap<Long, VmStatsEntry> getVirtualMachineStatistics(long hostId, String hostName, List<Long> vmIds) throws CloudRuntimeException {
-        HashMap<Long, VmStatsEntry> vmStatsById = new HashMap<Long, VmStatsEntry>();
-
-        if (vmIds.isEmpty()) {
-            return vmStatsById;
-        }
-
-        List<String> vmNames = new ArrayList<String>();
-
-        for (Long vmId : vmIds) {
-            UserVmVO vm = _vmDao.findById(vmId);
-            vmNames.add(vm.getInstanceName());
-        }
-
-        Answer answer = _agentMgr.easySend(hostId, new GetVmStatsCommand(vmNames, _hostDao.findById(hostId).getGuid(), hostName));
-        if (answer == null || !answer.getResult()) {
-            s_logger.warn("Unable to obtain VM statistics.");
-            return null;
-        } else {
-            HashMap<String, VmStatsEntry> vmStatsByName = ((GetVmStatsAnswer) answer).getVmStatsMap();
-
-            if (vmStatsByName == null) {
-                s_logger.warn("Unable to obtain VM statistics.");
-                return null;
-            }
-
-            for (String vmName : vmStatsByName.keySet()) {
-                vmStatsById.put(vmIds.get(vmNames.indexOf(vmName)), vmStatsByName.get(vmName));
-            }
-        }
-
-        return vmStatsById;
-    }
-
-    @Override
-    @DB
-    public UserVm recoverVirtualMachine(RecoverVMCmd cmd) throws ResourceAllocationException, CloudRuntimeException {
-
-        Long vmId = cmd.getId();
-        Account caller = UserContext.current().getCaller();
-
-        // Verify input parameters
-        UserVmVO vm = _vmDao.findById(vmId.longValue());
-
-        if (vm == null) {
-            throw new InvalidParameterValueException("unable to find a virtual machine with id " + vmId);
-        }
-
-        //check permissions
-        _accountMgr.checkAccess(caller, null, true, vm);
-
-        if (vm.getRemoved() != null) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Unable to find vm or vm is removed: " + vmId);
-            }
-            throw new InvalidParameterValueException("Unable to find vm by id " + vmId);
-        }
-
-        if (vm.getState() != State.Destroyed) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("vm is not in the right state: " + vmId);
-            }
-            throw new InvalidParameterValueException("Vm with id " + vmId + " is not in the right state");
-        }
-
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Recovering vm " + vmId);
-        }
-
-        Transaction txn = Transaction.currentTxn();
-        AccountVO account = null;
-        txn.start();
-
-        account = _accountDao.lockRow(vm.getAccountId(), true);
-
-        // if the account is deleted, throw error
-        if (account.getRemoved() != null) {
-            throw new CloudRuntimeException("Unable to recover VM as the account is deleted");
-        }
-
-        // First check that the maximum number of UserVMs for the given accountId will not be exceeded
-        _resourceLimitMgr.checkResourceLimit(account, ResourceType.user_vm);
-
-        _haMgr.cancelDestroy(vm, vm.getHostId());
-
-        try {
-            if (!_itMgr.stateTransitTo(vm, VirtualMachine.Event.RecoveryRequested, null)) {
-                s_logger.debug("Unable to recover the vm because it is not in the correct state: " + vmId);
-                throw new InvalidParameterValueException("Unable to recover the vm because it is not in the correct state: " + vmId);
-            }
-        } catch (NoTransitionException e){
-            throw new InvalidParameterValueException("Unable to recover the vm because it is not in the correct state: " + vmId);
-        }
-
-        // Recover the VM's disks
-        List<VolumeVO> volumes = _volsDao.findByInstance(vmId);
-        for (VolumeVO volume : volumes) {
-            if (volume.getVolumeType().equals(Volume.Type.ROOT)) {
-                // Create an event
-                Long templateId = volume.getTemplateId();
-                Long diskOfferingId = volume.getDiskOfferingId();
-                Long offeringId = null;
-                if (diskOfferingId != null) {
-                    DiskOfferingVO offering = _diskOfferingDao.findById(diskOfferingId);
-                    if (offering != null && (offering.getType() == DiskOfferingVO.Type.Disk)) {
-                        offeringId = offering.getId();
-                    }
-                }
-                UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_VOLUME_CREATE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(), offeringId, templateId,
-                        volume.getSize());
-                _usageEventDao.persist(usageEvent);
-            }
-        }
-
-        _resourceLimitMgr.incrementResourceCount(account.getId(), ResourceType.volume, new Long(volumes.size()));
-
-        _resourceLimitMgr.incrementResourceCount(account.getId(), ResourceType.user_vm);
-
-        txn.commit();
-
-        return _vmDao.findById(vmId);
-    }
-
-    @Override
-    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
-        _name = name;
-
-        ComponentLocator locator = ComponentLocator.getCurrentLocator();
-        _configDao = locator.getDao(ConfigurationDao.class);
-        if (_configDao == null) {
-            throw new ConfigurationException("Unable to get the configuration dao.");
-        }
-
-        Map<String, String> configs = _configDao.getConfiguration("AgentManager", params);
-
-        _instance = configs.get("instance.name");
-        if (_instance == null) {
-            _instance = "DEFAULT";
-        }
-
-        String value = _configDao.getValue(Config.CreatePrivateTemplateFromVolumeWait.toString());
-        _createprivatetemplatefromvolumewait = NumbersUtil.parseInt(value, Integer.parseInt(Config.CreatePrivateTemplateFromVolumeWait.getDefaultValue()));
-
-        value = _configDao.getValue(Config.CreatePrivateTemplateFromSnapshotWait.toString());
-        _createprivatetemplatefromsnapshotwait = NumbersUtil.parseInt(value, Integer.parseInt(Config.CreatePrivateTemplateFromSnapshotWait.getDefaultValue()));
-
-        String workers = configs.get("expunge.workers");
-        int wrks = NumbersUtil.parseInt(workers, 10);
-
-        String time = configs.get("expunge.interval");
-        _expungeInterval = NumbersUtil.parseInt(time, 86400);
-        if ( _expungeInterval < 600 ) {
-        	_expungeInterval = 600;
-        }
-        time = configs.get("expunge.delay");
-        _expungeDelay = NumbersUtil.parseInt(time, _expungeInterval);
-        if ( _expungeDelay < 600 ) {
-        	_expungeDelay = 600;
-        }
-        _executor = Executors.newScheduledThreadPool(wrks, new NamedThreadFactory("UserVm-Scavenger"));
-
-        _itMgr.registerGuru(VirtualMachine.Type.User, this);
-
-        VirtualMachine.State.getStateMachine().registerListener(new UserVmStateListener(_usageEventDao, _networkDao, _nicDao));
-
-        s_logger.info("User VM Manager is configured.");
-
-        return true;
-    }
-
-    @Override
-    public String getName() {
-        return _name;
-    }
-
-    @Override
-    public boolean start() {
-        _executor.scheduleWithFixedDelay(new ExpungeTask(), _expungeInterval, _expungeInterval, TimeUnit.SECONDS);
-        return true;
-    }
-
-    @Override
-    public boolean stop() {
-        _executor.shutdown();
-        return true;
-    }
-
-    protected UserVmManagerImpl() {
-    }
-
-    public String getRandomPrivateTemplateName() {
-        return UUID.randomUUID().toString();
-    }
-
-    @Override
-    public Long convertToId(String vmName) {
-        if (!VirtualMachineName.isValidVmName(vmName, _instance)) {
-            return null;
-        }
-        return VirtualMachineName.getVmId(vmName);
-    }
-
-    @Override
-    public boolean expunge(UserVmVO vm, long callerUserId, Account caller) {
-        UserContext ctx = UserContext.current();
-        ctx.setAccountId(vm.getAccountId());
-
-        try {
-            //expunge the vm
-            if (!_itMgr.advanceExpunge(vm, _accountMgr.getSystemUser(), caller)) {
-                s_logger.info("Did not expunge " + vm);
-                return false;
-            }
-
-            // Only if vm is not expunged already, cleanup it's resources
-            if (vm != null && vm.getRemoved() == null) {
-                // Cleanup vm resources - all the PF/LB/StaticNat rules associated with vm
-                s_logger.debug("Starting cleaning up vm " + vm + " resources...");
-                if (cleanupVmResources(vm.getId())) {
-                    s_logger.debug("Successfully cleaned up vm " + vm + " resources as a part of expunge process");
-                } else {
-                    s_logger.warn("Failed to cleanup resources as a part of vm " + vm + " expunge");
-                    return false;
-                }
-
-                _itMgr.remove(vm, _accountMgr.getSystemUser(), caller);
-            }
-
-            return true;
-
-        } catch (ResourceUnavailableException e) {
-            s_logger.warn("Unable to expunge  " + vm, e);
-            return false;
-        } catch (OperationTimedoutException e) {
-            s_logger.warn("Operation time out on expunging " + vm, e);
-            return false;
-        } catch (ConcurrentOperationException e) {
-            s_logger.warn("Concurrent operations on expunging " + vm, e);
-            return false;
-        }
-    }
-
-    private boolean cleanupVmResources(long vmId) {
-        boolean success = true;
-        //Remove vm from security groups
-        _securityGroupMgr.removeInstanceFromGroups(vmId);
-
-        //Remove vm from instance group
-        removeInstanceFromInstanceGroup(vmId);
-
-        //cleanup firewall rules
-        if (_firewallMgr.revokeFirewallRulesForVm(vmId)) {
-            s_logger.debug("Firewall rules are removed successfully as a part of vm id=" + vmId + " expunge");
-        } else {
-            success = false;
-            s_logger.warn("Fail to remove firewall rules as a part of vm id=" + vmId + " expunge");
-        }
-
-        //cleanup port forwarding rules
-        if (_rulesMgr.revokePortForwardingRulesForVm(vmId)) {
-            s_logger.debug("Port forwarding rules are removed successfully as a part of vm id=" + vmId + " expunge");
-        } else {
-            success = false;
-            s_logger.warn("Fail to remove port forwarding rules as a part of vm id=" + vmId + " expunge");
-        }
-
-        // cleanup load balancer rules
-        if (_lbMgr.removeVmFromLoadBalancers(vmId)) {
-            s_logger.debug("Removed vm id=" + vmId + " from all load balancers as a part of expunge process");
-        } else {
-            success = false;
-            s_logger.warn("Fail to remove vm id=" + vmId + " from load balancers as a part of expunge process");
-        }
-
-        // If vm is assigned to static nat, disable static nat for the ip address and disassociate ip if elasticIP is enabled
-        IPAddressVO ip = _ipAddressDao.findByAssociatedVmId(vmId);
-        try {
-            if (ip != null) {
-                if (_rulesMgr.disableStaticNat(ip.getId(), _accountMgr.getAccount(Account.ACCOUNT_ID_SYSTEM), User.UID_SYSTEM, true)) {
-                    s_logger.debug("Disabled 1-1 nat for ip address " + ip + " as a part of vm id=" + vmId + " expunge");
-                } else {
-                    s_logger.warn("Failed to disable static nat for ip address " + ip + " as a part of vm id=" + vmId + " expunge");
-                    success = false;
-                }
-            }
-        } catch (ResourceUnavailableException e) {
-            success = false;
-            s_logger.warn("Failed to disable static nat for ip address " + ip + " as a part of vm id=" + vmId + " expunge because resource is unavailable", e);
-        }
-
-        return success;
-    }
-
-    @Override
-    public void deletePrivateTemplateRecord(Long templateId) {
-        if (templateId != null) {
-            _templateDao.remove(templateId);
-        }
-    }
-
-    @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 = _volsDao.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 (!_storageMgr.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 = _volsDao.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 = _volsDao.findById(snapshot.getVolumeId());
-            VolumeVO snapshotVolume = _volsDao.findByIdIncludingRemoved(snapshot.getVolumeId());     
-
-            //check permissions
-            _accountMgr.checkAccess(caller, null, true, snapshot);
-
-            if (snapshot.getStatus() != Snapshot.Status.BackedUp) {
-                throw new InvalidParameterValueException("Snapshot id=" + snapshotId + " is not in " + Snapshot.Status.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 = _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 = _templateDao.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() == 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 = _templateDao.persist(privateTemplate);
-        // Increment the number of templates
-        if (template != null) {
-            if(cmd.getDetails() != null) {
-                _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
-    @DB
-    @ActionEvent(eventType = EventTypes.EVENT_TEMPLATE_CREATE, eventDescription = "creating template", async = true)
-    public VMTemplateVO 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();
-        SnapshotCommand cmd = null;
-        VMTemplateVO privateTemplate = null;
-
-        String uniqueName = getRandomPrivateTemplateName();
-
-        StoragePoolVO pool = null;
-        HostVO secondaryStorageHost = null;
-        Long zoneId = null;
-        Long accountId = null;
-        SnapshotVO snapshot = null;
-        String secondaryStorageURL = null;
-        try {
-            if (snapshotId != null) { // create template from snapshot
-                snapshot = _snapshotDao.findById(snapshotId);
-                if (snapshot == null) {
-                    throw new CloudRuntimeException("Unable to find Snapshot for Id " + snapshotId);
-                }
-                zoneId = snapshot.getDataCenterId();
-                secondaryStorageHost = _snapshotMgr.getSecondaryStorageHost(snapshot);
-                secondaryStorageURL = _snapshotMgr.getSecondaryStorageURL(snapshot);
-                String name = command.getTemplateName();
-                String backupSnapshotUUID = snapshot.getBackupSnapshotId();
-                if (backupSnapshotUUID == null) {
-                    throw new CloudRuntimeException("Unable to create private template from snapshot " + snapshotId + " due to there is no backupSnapshotUUID for this snapshot");
-                }
-
-                Long dcId = snapshot.getDataCenterId();
-                accountId = snapshot.getAccountId();
-                volumeId = snapshot.getVolumeId();
-
-                String origTemplateInstallPath = null;
-                List<StoragePoolVO> pools = _storageMgr.ListByDataCenterHypervisor(zoneId, snapshot.getHypervisorType());
-                if (pools == null ||  pools.size() == 0 ) {
-                    throw new CloudRuntimeException("Unable to find storage pools in zone " + zoneId);
-                }
-                pool = pools.get(0);
-                if (snapshot.getVersion() != null && snapshot.getVersion().equalsIgnoreCase("2.1")) {
-                    VolumeVO volume = _volsDao.findByIdIncludingRemoved(volumeId);
-                    if (volume == null) {
-                        throw new CloudRuntimeException("failed to upgrade snapshot " + snapshotId + " due to unable to find orignal volume:" + volumeId + ", try it later ");
-                    }
-                    if ( volume.getTemplateId() == null ) {
-                        _snapshotDao.updateSnapshotVersion(volumeId, "2.1", "2.2");
-                    } else {
-                        VMTemplateVO template = _templateDao.findByIdIncludingRemoved(volume.getTemplateId());
-                        if (template == null) {
-                            throw new CloudRuntimeException("failed to upgrade snapshot " + snapshotId + " due to unalbe to find orignal template :" + volume.getTemplateId() + ", try it later ");
-                        }
-                        Long origTemplateId = template.getId();
-                        Long origTmpltAccountId = template.getAccountId();
-                        if (!_volsDao.lockInLockTable(volumeId.toString(), 10)) {
-                            throw new CloudRuntimeException("failed to upgrade snapshot " + snapshotId + " due to volume:" + volumeId + " is being used, try it later ");
-                        }
-                        cmd = new UpgradeSnapshotCommand(null, secondaryStorageURL, dcId, accountId, volumeId, origTemplateId, origTmpltAccountId, null, snapshot.getBackupSnapshotId(),
-                                snapshot.getName(), "2.1");
-                        if (!_volsDao.lockInLockTable(volumeId.toString(), 10)) {
-                            throw new CloudRuntimeException("Creating template failed due to volume:" + volumeId + " is being used, try it later ");
-                        }
-                        Answer answer = null;
-                        try {
-                            answer = _storageMgr.sendToPool(pool, cmd);
-                            cmd = null;
-                        } catch (StorageUnavailableException e) {
-                        } finally {
-                            _volsDao.unlockFromLockTable(volumeId.toString());
-                        }
-                        if ((answer != null) && answer.getResult()) {
-                            _snapshotDao.updateSnapshotVersion(volumeId, "2.1", "2.2");
-                        } else {
-                            throw new CloudRuntimeException("Unable to upgrade snapshot");
-                        }
-                    }
-                }
-                if( snapshot.getSwiftId() != null && snapshot.getSwiftId() != 0 ) {
-                    _snapshotMgr.downloadSnapshotsFromSwift(snapshot);
-                }
-                cmd = new CreatePrivateTemplateFromSnapshotCommand(pool.getUuid(), secondaryStorageURL, dcId, accountId, snapshot.getVolumeId(), backupSnapshotUUID, snapshot.getName(),
-                        origTemplateInstallPath, templateId, name, _createprivatetemplatefromsnapshotwait);
-            } else if (volumeId != null) {
-                VolumeVO volume = _volsDao.findById(volumeId);
-                if (volume == null) {
-                    throw new CloudRuntimeException("Unable to find volume for Id " + volumeId);
-                }
-                accountId = volume.getAccountId();
-
-                if (volume.getPoolId() == null) {
-                    _templateDao.remove(templateId);
-                    throw new CloudRuntimeException("Volume " + volumeId + " is empty, can't create template on it");
-                }
-                String vmName = _storageMgr.getVmNameOnVolume(volume);
-                zoneId = volume.getDataCenterId();
-                secondaryStorageHost = _storageMgr.getSecondaryStorageHost(zoneId);
-                if (secondaryStorageHost == null) {
-                    throw new CloudRuntimeException("Can not find the secondary storage for zoneId " + zoneId);
-                }
-                secondaryStorageURL = secondaryStorageHost.getStorageUrl();
-
-                pool = _storagePoolDao.findById(volume.getPoolId());
-                cmd = new CreatePrivateTemplateFromVolumeCommand(pool.getUuid(), secondaryStorageURL, templateId, accountId, command.getTemplateName(), uniqueName, volume.getPath(), vmName, _createprivatetemplatefromvolumewait);
-
-            } else {
-                throw new CloudRuntimeException("Creating private Template need to specify snapshotId or volumeId");
-            }
-            // FIXME: before sending the command, check if there's enough capacity
-            // on the storage server to create the template
-
-            // This can be sent to a KVM host too.
-            CreatePrivateTemplateAnswer answer = null;
-            if (snapshotId != null) {
-                if (!_snapshotDao.lockInLockTable(snapshotId.toString(), 10)) {
-                    throw new CloudRuntimeException("Creating template from snapshot failed due to snapshot:" + snapshotId + " is being used, try it later ");
-                }
-            } else {
-                if (!_volsDao.lockInLockTable(volumeId.toString(), 10)) {
-                    throw new CloudRuntimeException("Creating template from volume failed due to volume:" + volumeId + " is being used, try it later ");
-                }
-            }
-            try {
-                answer = (CreatePrivateTemplateAnswer) _storageMgr.sendToPool(pool, cmd);
-            } catch (StorageUnavailableException e) {
-            } finally {
-                if (snapshotId != null) {
-                    _snapshotDao.unlockFromLockTable(snapshotId.toString());
-                } else {
-                    _volsDao.unlockFromLockTable(volumeId.toString());
-                }
-            }
-            if ((answer != null) && answer.getResult()) {
-                privateTemplate = _templateDao.findById(templateId);
-                String answerUniqueName = answer.getUniqueName();
-                if (answerUniqueName != null) {
-                    privateTemplate.setUniqueName(answerUniqueName);
-                } else {
-                    privateTemplate.setUniqueName(uniqueName);
-                }
-                ImageFormat format = answer.getImageFormat();
-                if (format != null) {
-                    privateTemplate.setFormat(format);
-                } else {
-                    // This never occurs.
-                    // Specify RAW format makes it unusable for snapshots.
-                    privateTemplate.setFormat(ImageFormat.RAW);
-                }
-
-                String checkSum = getChecksum(secondaryStorageHost.getId(), answer.getPath());
-
-                Transaction txn = Transaction.currentTxn();
-
-                txn.start();
-
-                privateTemplate.setChecksum(checkSum);
-                _templateDao.update(templateId, privateTemplate);
-
-                // add template zone ref for this template
-                _templateDao.addTemplateToZone(privateTemplate, zoneId);
-                VMTemplateHostVO templateHostVO = new VMTemplateHostVO(secondaryStorageHost.getId(), templateId);
-                templateHostVO.setDownloadPercent(100);
-                templateHostVO.setDownloadState(Status.DOWNLOADED);
-                templateHostVO.setInstallPath(answer.getPath());
-                templateHostVO.setLastUpdated(new Date());
-                templateHostVO.setSize(answer.getVirtualSize());
-                templateHostVO.setPhysicalSize(answer.getphysicalSize());
-                _templateHostDao.persist(templateHostVO);
-
-                UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_TEMPLATE_CREATE, privateTemplate.getAccountId(), secondaryStorageHost.getDataCenterId(), privateTemplate.getId(),
-                        privateTemplate.getName(), null, privateTemplate.getSourceTemplateId(), templateHostVO.getSize());
-                _usageEventDao.persist(usageEvent);
-                txn.commit();
-            }
-        } 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
-                _templateDao.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");
-        }
-    }
-
-    @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;
-    }
-
-    // used for vm transitioning to error state
-    private void updateVmStateForFailedVmCreation(Long vmId) {
-
-        UserVmVO vm = _vmDao.findById(vmId);
-
-
-        if (vm != null) {
-            if (vm.getState().equals(State.Stopped)) {
-                s_logger.debug("Destroying vm " + vm + " as it failed to create");
-                try {
-                    _itMgr.stateTransitTo(vm, VirtualMachine.Event.OperationFailedToError, null);
-                } catch (NoTransitionException e1) {
-                    s_logger.warn(e1.getMessage());
-                }
-                // destroy associated volumes for vm in error state
-                // get all volumes in non destroyed state
-                List<VolumeVO> volumesForThisVm = _volsDao.findUsableVolumesForInstance(vm.getId());
-                for (VolumeVO volume : volumesForThisVm) {
-                    try {
-                        if (volume.getState() != Volume.State.Destroy) {
-                            _storageMgr.destroyVolume(volume);
-                        }
-                    } catch (ConcurrentOperationException e) {
-                        s_logger.warn("Unable to delete volume:" + volume.getId() + " for vm:" + vmId + " whilst transitioning to error state");
-                    }
-                }
-                String msg = "Failed to deploy Vm with Id: " + vmId;
-                _alertMgr.sendAlert(AlertManager.ALERT_TYPE_USERVM, vm.getDataCenterIdToDeployIn(), vm.getPodIdToDeployIn(), msg, msg);
-
-                _resourceLimitMgr.decrementResourceCount(vm.getAccountId(), ResourceType.user_vm);
-            }
-        }
-    }
-
-    protected class ExpungeTask implements Runnable {
-        public ExpungeTask() {
-        }
-
-        @Override
-        public void run() {
-            GlobalLock scanLock = GlobalLock.getInternLock("UserVMExpunge");
-            try {
-                if (scanLock.lock(ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_COOPERATION)) {
-                    try {
-                        List<UserVmVO> vms = _vmDao.findDestroyedVms(new Date(System.currentTimeMillis() - ((long) _expungeDelay << 10)));
-                        if (s_logger.isInfoEnabled()) {
-                            if (vms.size() == 0) {
-                                s_logger.trace("Found " + vms.size() + " vms to expunge.");
-                            } else {
-                                s_logger.info("Found " + vms.size() + " vms to expunge.");
-                            }
-                        }
-                        for (UserVmVO vm : vms) {
-                            try {
-                                expunge(vm, _accountMgr.getSystemUser().getId(), _accountMgr.getSystemAccount());
-                            } catch (Exception e) {
-                                s_logger.warn("Unable to expunge " + vm, e);
-                            }
-                        }
-                    } catch (Exception e) {
-                        s_logger.error("Caught the following Exception", e);
-                    } finally {
-                        scanLock.unlock();
-                    }
-                }
-            } finally {
-                scanLock.releaseRef();
-            }
-        }
-    }
-
-    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_VM_UPDATE, eventDescription = "updating Vm")
-    public UserVm updateVirtualMachine(UpdateVMCmd cmd) {
-        String displayName = cmd.getDisplayName();
-        String group = cmd.getGroup();
-        Boolean ha = cmd.getHaEnable();
-        Long id = cmd.getId();
-        Long osTypeId = cmd.getOsTypeId();
-        String userData = cmd.getUserData();
-
-        // Input validation
-        UserVmVO vmInstance = null;
-
-        // Verify input parameters
-        vmInstance = _vmDao.findById(id.longValue());
-
-        if (vmInstance == null) {
-            throw new InvalidParameterValueException("unable to find virtual machine with id " + id);
-        }
-
-        ServiceOffering offering = _serviceOfferingDao.findById(vmInstance.getServiceOfferingId());
-        if (!offering.getOfferHA() && ha != null && ha) {
-            throw new InvalidParameterValueException("Can't enable ha for the vm as it's created from the Service offering having HA disabled");
-        }
-
-        _accountMgr.checkAccess(UserContext.current().getCaller(), null, true, vmInstance);
-
-        if (displayName == null) {
-            displayName = vmInstance.getDisplayName();
-        }
-
-        if (ha == null) {
-            ha = vmInstance.isHaEnabled();
-        }
-
-        UserVmVO vm = _vmDao.findById(id);
-        if (vm == null) {
-            throw new CloudRuntimeException("Unable to find virual machine with id " + id);
-        }
-
-        if (vm.getState() == State.Error || vm.getState() == State.Expunging) {
-            s_logger.error("vm is not in the right state: " + id);
-            throw new InvalidParameterValueException("Vm with id " + id + " is not in the right state");
-        }
-
-        if (userData != null) {
-            validateUserData(userData);
-            // update userData on domain router.
-        } else {
-            userData = vmInstance.getUserData();
-        }
-
-        String description = "";
-
-        if (displayName != vmInstance.getDisplayName()) {
-            description += "New display name: " + displayName + ". ";
-        }
-
-        if (ha != vmInstance.isHaEnabled()) {
-            if (ha) {
-                description += "Enabled HA. ";
-            } else {
-                description += "Disabled HA. ";
-            }
-        }
-        if (osTypeId == null) {
-            osTypeId = vmInstance.getGuestOSId();
-        } else {
-            description += "Changed Guest OS Type to " + osTypeId + ". ";
-        }
-
-        if (group != null) {
-            if (addInstanceToGroup(id, group)) {
-                description += "Added to group: " + group + ".";
-            }
-        }
-
-        _vmDao.updateVM(id, displayName, ha, osTypeId, userData);
-
-        return _vmDao.findById(id);
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_VM_START, eventDescription = "starting Vm", async = true)
-    public UserVm startVirtualMachine(StartVMCmd cmd) throws ExecutionException, ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException {
-        return startVirtualMachine(cmd.getId(), cmd.getHostId(), null).first();
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_VM_REBOOT, eventDescription = "rebooting Vm", async = true)
-    public UserVm rebootVirtualMachine(RebootVMCmd cmd) throws InsufficientCapacityException, ResourceUnavailableException {
-        Account caller = UserContext.current().getCaller();
-        Long vmId = cmd.getId();
-
-        // Verify input parameters
-        UserVmVO vmInstance = _vmDao.findById(vmId.longValue());
-        if (vmInstance == null) {
-            throw new InvalidParameterValueException("unable to find a virtual machine with id " + vmId);
-        }
-
-        _accountMgr.checkAccess(caller, null, true, vmInstance);
-
-        return rebootVirtualMachine(UserContext.current().getCallerUserId(), vmId);
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_VM_DESTROY, eventDescription = "destroying Vm", async = true)
-    public UserVm destroyVm(DestroyVMCmd cmd) throws ResourceUnavailableException, ConcurrentOperationException {
-        return destroyVm(cmd.getId());
-    }
-
-    @Override
-    @DB
-    public InstanceGroupVO createVmGroup(CreateVMGroupCmd cmd) {
-        Account caller = UserContext.current().getCaller();
-        Long domainId = cmd.getDomainId();
-        String accountName = cmd.getAccountName();
-        String groupName = cmd.getGroupName();
-        Long projectId = cmd.getProjectId();
-
-        Account owner = _accountMgr.finalizeOwner(caller, accountName, domainId, projectId);
-        long accountId = owner.getId();
-
-        // Check if name is already in use by this account
-        boolean isNameInUse = _vmGroupDao.isNameInUse(accountId, groupName);
-
-        if (isNameInUse) {
-            throw new InvalidParameterValueException("Unable to create vm group, a group with name " + groupName + " already exisits for account " + accountId);
-        }
-
-        return createVmGroup(groupName, accountId);
-    }
-
-    @DB
-    protected InstanceGroupVO createVmGroup(String groupName, long accountId) {
-        Account account = null;
-        final Transaction txn = Transaction.currentTxn();
-        txn.start();
-        try {
-            account = _accountDao.acquireInLockTable(accountId); // to ensure duplicate vm group names are not created.
-            if (account == null) {
-                s_logger.warn("Failed to acquire lock on account");
-                return null;
-            }
-            InstanceGroupVO group = _vmGroupDao.findByAccountAndName(accountId, groupName);
-            if (group == null) {
-                group = new InstanceGroupVO(groupName, accountId);
-                group = _vmGroupDao.persist(group);
-            }
-            return group;
-        } finally {
-            if (account != null) {
-                _accountDao.releaseFromLockTable(accountId);
-            }
-            txn.commit();
-        }
-    }
-
-    @Override
-    public boolean deleteVmGroup(DeleteVMGroupCmd cmd) {
-        Account caller = UserContext.current().getCaller();
-        Long groupId = cmd.getId();
-
-        // Verify input parameters
-        InstanceGroupVO group = _vmGroupDao.findById(groupId);
-        if ((group == null) || (group.getRemoved() != null)) {
-            throw new InvalidParameterValueException("unable to find a vm group with id " + groupId);
-        }
-
-        _accountMgr.checkAccess(caller, null, true, group);
-
-        return deleteVmGroup(groupId);
-    }
-
-    @Override
-    public boolean deleteVmGroup(long groupId) {
-        // delete all the mappings from group_vm_map table
-        List<InstanceGroupVMMapVO> groupVmMaps = _groupVMMapDao.listByGroupId(groupId);
-        for (InstanceGroupVMMapVO groupMap : groupVmMaps) {
-            SearchCriteria<InstanceGroupVMMapVO> sc = _groupVMMapDao.createSearchCriteria();
-            sc.addAnd("instanceId", SearchCriteria.Op.EQ, groupMap.getInstanceId());
-            _groupVMMapDao.expunge(sc);
-        }
-
-        if (_vmGroupDao.remove(groupId)) {
-            return true;
-        } else {
-            return false;
-        }
-    }
-
-    @Override
-    @DB
-    public boolean addInstanceToGroup(long userVmId, String groupName) {
-        UserVmVO vm = _vmDao.findById(userVmId);
-
-        InstanceGroupVO group = _vmGroupDao.findByAccountAndName(vm.getAccountId(), groupName);
-        // Create vm group if the group doesn't exist for this account
-        if (group == null) {
-            group = createVmGroup(groupName, vm.getAccountId());
-        }
-
-        if (group != null) {
-            final Transaction txn = Transaction.currentTxn();
-            txn.start();
-            UserVm userVm = _vmDao.acquireInLockTable(userVmId);
-            if (userVm == null) {
-                s_logger.warn("Failed to acquire lock on user vm id=" + userVmId);
-            }
-            try {
-                // don't let the group be deleted when we are assigning vm to it.
-                InstanceGroupVO ngrpLock = _vmGroupDao.lockRow(group.getId(), false);
-                if (ngrpLock == null) {
-                    s_logger.warn("Failed to acquire lock on vm group id=" + group.getId() + " name=" + group.getName());
-                    txn.rollback();
-                    return false;
-                }
-
-                // Currently don't allow to assign a vm to more than one group
-                if (_groupVMMapDao.listByInstanceId(userVmId) != null) {
-                    // Delete all mappings from group_vm_map table
-                    List<InstanceGroupVMMapVO> groupVmMaps = _groupVMMapDao.listByInstanceId(userVmId);
-                    for (InstanceGroupVMMapVO groupMap : groupVmMaps) {
-                        SearchCriteria<InstanceGroupVMMapVO> sc = _groupVMMapDao.createSearchCriteria();
-                        sc.addAnd("instanceId", SearchCriteria.Op.EQ, groupMap.getInstanceId());
-                        _groupVMMapDao.expunge(sc);
-                    }
-                }
-                InstanceGroupVMMapVO groupVmMapVO = new InstanceGroupVMMapVO(group.getId(), userVmId);
-                _groupVMMapDao.persist(groupVmMapVO);
-
-                txn.commit();
-                return true;
-            } finally {
-                if (userVm != null) {
-                    _vmDao.releaseFromLockTable(userVmId);
-                }
-            }
-        }
-        return false;
-    }
-
-    @Override
-    public InstanceGroupVO getGroupForVm(long vmId) {
-        // TODO - in future releases vm can be assigned to multiple groups; but currently return just one group per vm
-        try {
-            List<InstanceGroupVMMapVO> groupsToVmMap = _groupVMMapDao.listByInstanceId(vmId);
-
-            if (groupsToVmMap != null && groupsToVmMap.size() != 0) {
-                InstanceGroupVO group = _vmGroupDao.findById(groupsToVmMap.get(0).getGroupId());
-                return group;
-            } else {
-                return null;
-            }
-        } catch (Exception e) {
-            s_logger.warn("Error trying to get group for a vm: ", e);
-            return null;
-        }
-    }
-
-    @Override
-    public void removeInstanceFromInstanceGroup(long vmId) {
-        try {
-            List<InstanceGroupVMMapVO> groupVmMaps = _groupVMMapDao.listByInstanceId(vmId);
-            for (InstanceGroupVMMapVO groupMap : groupVmMaps) {
-                SearchCriteria<InstanceGroupVMMapVO> sc = _groupVMMapDao.createSearchCriteria();
-                sc.addAnd("instanceId", SearchCriteria.Op.EQ, groupMap.getInstanceId());
-                _groupVMMapDao.expunge(sc);
-            }
-        } catch (Exception e) {
-            s_logger.warn("Error trying to remove vm from group: ", e);
-        }
-    }
-
-    protected boolean validPassword(String password) {
-        if (password == null || password.length() == 0) {
-            return false;
-        }
-        for (int i = 0; i < password.length(); i++) {
-            if (password.charAt(i) == ' ') {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    @Override
-    public UserVm createBasicSecurityGroupVirtualMachine(DataCenter zone, ServiceOffering serviceOffering, VirtualMachineTemplate template, List<Long> securityGroupIdList, Account owner,
-            String hostName, String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, String userData, String sshKeyPair, Map<Long, String> requestedIps, String defaultIp, String keyboard)
-                    throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException {
-
-        Account caller = UserContext.current().getCaller();
-        List<NetworkVO> networkList = new ArrayList<NetworkVO>();
-
-        // Verify that caller can perform actions in behalf of vm owner
-        _accountMgr.checkAccess(caller, null, true, owner);
-
-        // Get default guest network in Basic zone
-        Network defaultNetwork = _networkMgr.getExclusiveGuestNetwork(zone.getId());
-
-        if (defaultNetwork == null) {
-            throw new InvalidParameterValueException("Unable to find a default network to start a vm");
-        } else {
-            networkList.add(_networkDao.findById(defaultNetwork.getId()));
-        }
-
-        boolean isVmWare = (template.getHypervisorType() == HypervisorType.VMware || (hypervisor != null && hypervisor == HypervisorType.VMware));
-
-        if (securityGroupIdList != null && isVmWare) {
-            throw new InvalidParameterValueException("Security group feature is not supported for vmWare hypervisor");
-        } else if (!isVmWare && _networkMgr.isSecurityGroupSupportedInNetwork(defaultNetwork) && _networkMgr.canAddDefaultSecurityGroup()) {
-            //add the default securityGroup only if no security group is specified
-            if(securityGroupIdList == null || securityGroupIdList.isEmpty()){
-                if (securityGroupIdList == null) {
-                    securityGroupIdList = new ArrayList<Long>();
-                }
-                SecurityGroup defaultGroup = _securityGroupMgr.getDefaultSecurityGroup(owner.getId());
-                if (defaultGroup != null) {
-                    securityGroupIdList.add(defaultGroup.getId());
-                } else {
-                    //create default security group for the account
-                    if (s_logger.isDebugEnabled()) {
-                        s_logger.debug("Couldn't find default security group for the account " + owner + " so creating a new one");
-                    }
-                    defaultGroup = _securityGroupMgr.createSecurityGroup(SecurityGroupManager.DEFAULT_GROUP_NAME, SecurityGroupManager.DEFAULT_GROUP_DESCRIPTION, owner.getDomainId(), owner.getId(), owner.getAccountName());
-                    securityGroupIdList.add(defaultGroup.getId());
-                }
-            }
-        }
-
-        return createVirtualMachine(zone, serviceOffering, template, hostName, displayName, owner, diskOfferingId,
-                diskSize, networkList, securityGroupIdList, group, userData, sshKeyPair, hypervisor, caller, requestedIps, defaultIp, keyboard);
-    }
-
-    @Override
-    public UserVm createAdvancedSecurityGroupVirtualMachine(DataCenter zone, ServiceOffering serviceOffering, VirtualMachineTemplate template, List<Long> networkIdList,
-            List<Long> securityGroupIdList, Account owner, String hostName, String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, String userData,
-            String sshKeyPair, Map<Long, String> requestedIps, String defaultIp, String keyboard) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException,
-            ResourceAllocationException {
-
-        Account caller = UserContext.current().getCaller();
-        List<NetworkVO> networkList = new ArrayList<NetworkVO>();
-        boolean isSecurityGroupEnabledNetworkUsed = false;
-        boolean isVmWare = (template.getHypervisorType() == HypervisorType.VMware || (hypervisor != null && hypervisor == HypervisorType.VMware));
-
-        //Verify that caller can perform actions in behalf of vm owner
-        _accountMgr.checkAccess(caller, null, true, owner);
-
-        // If no network is specified, find system security group enabled network
-        if (networkIdList == null || networkIdList.isEmpty()) {
-            NetworkVO networkWithSecurityGroup = _networkMgr.getNetworkWithSecurityGroupEnabled(zone.getId());
-            if (networkWithSecurityGroup == null) {
-                throw new InvalidParameterValueException("No network with security enabled is found in zone id=" + zone.getId());
-            }
-
-            networkList.add(networkWithSecurityGroup);
-            isSecurityGroupEnabledNetworkUsed = true;
-
-        } else if (securityGroupIdList != null && !securityGroupIdList.isEmpty()) {
-            if (isVmWare) {
-                throw new InvalidParameterValueException("Security group feature is not supported for vmWare hypervisor");
-            }
-            // Only one network can be specified, and it should be security group enabled
-            if (networkIdList.size() > 1) {
-                throw new InvalidParameterValueException("Only support one network per VM if security group enabled");
-            }
-
-            NetworkVO network = _networkDao.findById(networkIdList.get(0).longValue());
-
-            if (network == null) {
-                throw new InvalidParameterValueException("Unable to find network by id " + networkIdList.get(0).longValue());
-            }
-
-        

<TRUNCATED>