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>