You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by ah...@apache.org on 2013/01/09 14:26:47 UTC
[48/50] [abbrv] all built with the latest
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/0bcb6460/server/src/com/cloud/vm/UserVmManagerImpl.java
----------------------------------------------------------------------
diff --cc server/src/com/cloud/vm/UserVmManagerImpl.java
index 61526a6,890c89b..d4fff18
--- a/server/src/com/cloud/vm/UserVmManagerImpl.java
+++ b/server/src/com/cloud/vm/UserVmManagerImpl.java
@@@ -54,8 -36,10 +54,7 @@@ import org.apache.cloudstack.engine.clo
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;
-import org.springframework.context.annotation.Primary;
-import org.springframework.stereotype.Component;
-import com.cloud.acl.ControlledEntity.ACLType;
import com.cloud.agent.AgentManager;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.AttachIsoCommand;
@@@ -237,4315 -240,4432 +236,4313 @@@ import com.cloud.vm.dao.UserVmDao
import com.cloud.vm.dao.UserVmDetailsDao;
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;
- @Inject
- protected GuestOSCategoryDao _guestOSCategoryDao;
-
- protected ScheduledExecutorService _executor = null;
- protected int _expungeInterval;
- protected int _expungeDelay;
-
- protected String _name;
- protected String _instance;
- protected String _zone;
-
- @Inject private ConfigurationDao _configDao;
- private int _createprivatetemplatefromvolumewait;
- private int _createprivatetemplatefromsnapshotwait;
-
- @Inject
- protected OrchestrationService _orchSrvc;
-
- @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;
-
- 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());
- }
-
- if (!_networkMgr.isSecurityGroupSupportedInNetwork(network)) {
- throw new InvalidParameterValueException(
- "Network is not security group enabled: "
- + network.getId());
- }
-
- networkList.add(network);
- isSecurityGroupEnabledNetworkUsed = true;
-
- } else {
- // Verify that all the networks are Direct/Guest/AccountSpecific;
- // can't create combination of SG enabled network and
- // regular networks
- for (Long networkId : networkIdList) {
- NetworkVO network = _networkDao.findById(networkId);
-
- if (network == null) {
- throw new InvalidParameterValueException(
- "Unable to find network by id "
- + networkIdList.get(0).longValue());
- }
-
- boolean isSecurityGroupEnabled = _networkMgr
- .isSecurityGroupSupportedInNetwork(network);
- if (isSecurityGroupEnabled && networkIdList.size() > 1) {
- throw new InvalidParameterValueException(
- "Can't create a vm with multiple networks one of which is Security Group enabled");
- }
-
- if (network.getTrafficType() != TrafficType.Guest
- || network.getGuestType() != Network.GuestType.Shared
- || (network.getGuestType() == Network.GuestType.Shared && !isSecurityGroupEnabled)) {
- throw new InvalidParameterValueException(
- "Can specify only Direct Guest Account specific networks when deploy vm in Security Group enabled zone");
- }
-
- // Perform account permission check
- if (network.getGuestType() != Network.GuestType.Shared) {
- // Check account permissions
- List<NetworkVO> networkMap = _networkDao.listBy(
- owner.getId(), network.getId());
- if (networkMap == null || networkMap.isEmpty()) {
- throw new PermissionDeniedException(
- "Unable to create a vm using network with id "
- + network.getId()
- + ", permission denied");
- }
- }
-
- networkList.add(network);
- }
- }
-
- // if network is security group enabled, and no security group is
- // specified, then add the default security group automatically
- if (isSecurityGroupEnabledNetworkUsed && !isVmWare
- && _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 createAdvancedVirtualMachine(DataCenter zone,
- ServiceOffering serviceOffering, VirtualMachineTemplate template,
- List<Long> networkIdList, 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);
-
- List<HypervisorType> vpcSupportedHTypes = _vpcMgr
- .getSupportedVpcHypervisors();
- if (networkIdList == null || networkIdList.isEmpty()) {
- NetworkVO defaultNetwork = null;
-
- // if no network is passed in
- // Check if default virtual network offering has
- // Availability=Required. If it's true, search for corresponding
- // network
- // * if network is found, use it. If more than 1 virtual network is
- // found, throw an error
- // * if network is not found, create a new one and use it
-
- List<NetworkOfferingVO> requiredOfferings = _networkOfferingDao
- .listByAvailability(Availability.Required, false);
- if (requiredOfferings.size() < 1) {
- throw new InvalidParameterValueException(
- "Unable to find network offering with availability="
- + Availability.Required
- + " to automatically create the network as a part of vm creation");
- }
-
- if (requiredOfferings.get(0).getState() == NetworkOffering.State.Enabled) {
- // get Virtual networks
- List<NetworkVO> virtualNetworks = _networkMgr
- .listNetworksForAccount(owner.getId(), zone.getId(),
- Network.GuestType.Isolated);
-
- if (virtualNetworks.isEmpty()) {
- long physicalNetworkId = _networkMgr.findPhysicalNetworkId(
- zone.getId(), requiredOfferings.get(0).getTags(),
- requiredOfferings.get(0).getTrafficType());
- // Validate physical network
- PhysicalNetwork physicalNetwork = _physicalNetworkDao
- .findById(physicalNetworkId);
- if (physicalNetwork == null) {
- throw new InvalidParameterValueException(
- "Unable to find physical network with id: "
- + physicalNetworkId + " and tag: "
- + requiredOfferings.get(0).getTags());
- }
- s_logger.debug("Creating network for account " + owner
- + " from the network offering id="
- + requiredOfferings.get(0).getId()
- + " as a part of deployVM process");
- Network newNetwork = _networkMgr.createGuestNetwork(
- requiredOfferings.get(0).getId(),
- owner.getAccountName() + "-network",
- owner.getAccountName() + "-network", null, null,
- null, null, owner, null, physicalNetwork,
- zone.getId(), ACLType.Account, null, null);
- defaultNetwork = _networkDao.findById(newNetwork.getId());
- } else if (virtualNetworks.size() > 1) {
- throw new InvalidParameterValueException(
- "More than 1 default Isolated networks are found for account "
- + owner + "; please specify networkIds");
- } else {
- defaultNetwork = virtualNetworks.get(0);
- }
- } else {
- throw new InvalidParameterValueException(
- "Required network offering id="
- + requiredOfferings.get(0).getId()
- + " is not in " + NetworkOffering.State.Enabled);
- }
-
- networkList.add(defaultNetwork);
-
- } else {
- for (Long networkId : networkIdList) {
- NetworkVO network = _networkDao.findById(networkId);
- if (network == null) {
- throw new InvalidParameterValueException(
- "Unable to find network by id "
- + networkIdList.get(0).longValue());
- }
- if (network.getVpcId() != null) {
- // Only ISOs, XenServer, KVM, and VmWare template types are
- // supported for vpc networks
- if (template.getFormat() != ImageFormat.ISO
- && !vpcSupportedHTypes.contains(template
- .getHypervisorType())) {
- throw new InvalidParameterValueException(
- "Can't create vm from template with hypervisor "
- + template.getHypervisorType()
- + " in vpc network " + network);
- }
-
- // Only XenServer, KVM, and VMware hypervisors are supported
- // for vpc networks
- if (!vpcSupportedHTypes.contains(hypervisor)) {
- throw new InvalidParameterValueException(
- "Can't create vm of hypervisor type "
- + hypervisor + " in vpc network");
- }
-
- }
-
- _networkMgr.checkNetworkPermissions(owner, network);
-
- // don't allow to use system networks
- Net
<TRUNCATED>
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/0bcb6460/server/src/com/cloud/vm/VirtualMachineManagerImpl.java
----------------------------------------------------------------------