Search in sources :

Example 11 with VirtualMachineMigrationException

use of com.cloud.exception.VirtualMachineMigrationException in project cloudstack by apache.

the class UserVmManagerImpl method migrateVirtualMachineWithVolume.

@Override
@ActionEvent(eventType = EventTypes.EVENT_VM_MIGRATE, eventDescription = "migrating VM", async = true)
public VirtualMachine migrateVirtualMachineWithVolume(Long vmId, Host destinationHost, Map<String, String> volumeToPool) throws ResourceUnavailableException, ConcurrentOperationException, ManagementServerException, VirtualMachineMigrationException {
    // Access check - only root administrator can migrate VM.
    Account caller = CallContext.current().getCallingAccount();
    if (!_accountMgr.isRootAdmin(caller.getId())) {
        if (s_logger.isDebugEnabled()) {
            s_logger.debug("Caller is not a root admin, permission denied to migrate the VM");
        }
        throw new PermissionDeniedException("No permission to migrate VM, Only Root Admin can migrate a VM!");
    }
    VMInstanceVO vm = _vmInstanceDao.findById(vmId);
    if (vm == null) {
        throw new InvalidParameterValueException("Unable to find the vm by id " + vmId);
    }
    if (vm.getState() != State.Running) {
        if (s_logger.isDebugEnabled()) {
            s_logger.debug("VM is not Running, unable to migrate the vm " + vm);
        }
        CloudRuntimeException ex = new CloudRuntimeException("VM is not Running, unable to migrate the vm with" + " specified id");
        ex.addProxyObject(vm.getUuid(), "vmId");
        throw ex;
    }
    if (serviceOfferingDetailsDao.findDetail(vm.getServiceOfferingId(), GPU.Keys.pciDevice.toString()) != null) {
        throw new InvalidParameterValueException("Live Migration of GPU enabled VM is not supported");
    }
    if (!vm.getHypervisorType().equals(HypervisorType.XenServer) && !vm.getHypervisorType().equals(HypervisorType.VMware) && !vm.getHypervisorType().equals(HypervisorType.KVM) && !vm.getHypervisorType().equals(HypervisorType.Ovm) && !vm.getHypervisorType().equals(HypervisorType.Hyperv) && !vm.getHypervisorType().equals(HypervisorType.Simulator)) {
        throw new InvalidParameterValueException("Unsupported hypervisor type for vm migration, we support" + " XenServer/VMware/KVM only");
    }
    long srcHostId = vm.getHostId();
    Host srcHost = _resourceMgr.getHost(srcHostId);
    if (srcHost == null) {
        throw new InvalidParameterValueException("Cannot migrate VM, there is not Host with id: " + srcHostId);
    }
    // Check if src and destination hosts are valid and migrating to same host
    if (destinationHost.getId() == srcHostId) {
        throw new InvalidParameterValueException("Cannot migrate VM, VM is already present on this host, please" + " specify valid destination host to migrate the VM");
    }
    // Check if the source and destination hosts are of the same type and support storage motion.
    if (!(srcHost.getHypervisorType().equals(destinationHost.getHypervisorType()))) {
        throw new CloudRuntimeException("The source and destination hosts are not of the same type. " + "Source hypervisor type and version: " + srcHost.getHypervisorType().toString() + " " + srcHost.getHypervisorVersion() + ", Destination hypervisor type and version: " + destinationHost.getHypervisorType().toString() + " " + destinationHost.getHypervisorVersion());
    }
    HypervisorCapabilitiesVO capabilities = _hypervisorCapabilitiesDao.findByHypervisorTypeAndVersion(srcHost.getHypervisorType(), srcHost.getHypervisorVersion());
    if (!capabilities.isStorageMotionSupported()) {
        throw new CloudRuntimeException("Migration with storage isn't supported on hypervisor " + srcHost.getHypervisorType() + " of version " + srcHost.getHypervisorVersion());
    }
    // Check if destination host is up.
    if (destinationHost.getState() != com.cloud.host.Status.Up || destinationHost.getResourceState() != ResourceState.Enabled) {
        throw new CloudRuntimeException("Cannot migrate VM, destination host is not in correct state, has " + "status: " + destinationHost.getState() + ", state: " + destinationHost.getResourceState());
    }
    // Check that Vm does not have VM Snapshots
    if (_vmSnapshotDao.findByVm(vmId).size() > 0) {
        throw new InvalidParameterValueException("VM with VM Snapshots cannot be migrated with storage, please remove all VM snapshots");
    }
    List<VolumeVO> vmVolumes = _volsDao.findUsableVolumesForInstance(vm.getId());
    Map<Long, Long> volToPoolObjectMap = new HashMap<Long, Long>();
    if (!isVMUsingLocalStorage(vm) && destinationHost.getClusterId().equals(srcHost.getClusterId())) {
        if (volumeToPool.isEmpty()) {
            // then fail the call. migrateVirtualMachine api should have been used.
            throw new InvalidParameterValueException("Migration of the vm " + vm + "from host " + srcHost + " to destination host " + destinationHost + " doesn't involve migrating the volumes.");
        }
    }
    if (!volumeToPool.isEmpty()) {
        // Check if all the volumes and pools passed as parameters are valid.
        for (Map.Entry<String, String> entry : volumeToPool.entrySet()) {
            VolumeVO volume = _volsDao.findByUuid(entry.getKey());
            StoragePoolVO pool = _storagePoolDao.findByUuid(entry.getValue());
            if (volume == null) {
                throw new InvalidParameterValueException("There is no volume present with the given id " + entry.getKey());
            } else if (pool == null) {
                throw new InvalidParameterValueException("There is no storage pool present with the given id " + entry.getValue());
            } else if (pool.isInMaintenance()) {
                throw new InvalidParameterValueException("Cannot migrate volume " + volume + "to the destination storage pool " + pool.getName() + " as the storage pool is in maintenance mode.");
            } else {
                // Verify the volume given belongs to the vm.
                if (!vmVolumes.contains(volume)) {
                    throw new InvalidParameterValueException("There volume " + volume + " doesn't belong to " + "the virtual machine " + vm + " that has to be migrated");
                }
                volToPoolObjectMap.put(Long.valueOf(volume.getId()), Long.valueOf(pool.getId()));
            }
        }
    }
    // Check if all the volumes are in the correct state.
    for (VolumeVO volume : vmVolumes) {
        if (volume.getState() != Volume.State.Ready) {
            throw new CloudRuntimeException("Volume " + volume + " of the VM is not in Ready state. Cannot " + "migrate the vm with its volumes.");
        }
    }
    // Check max guest vm limit for the destinationHost.
    HostVO destinationHostVO = _hostDao.findById(destinationHost.getId());
    if (_capacityMgr.checkIfHostReachMaxGuestLimit(destinationHostVO)) {
        throw new VirtualMachineMigrationException("Host name: " + destinationHost.getName() + ", hostId: " + destinationHost.getId() + " already has max running vms (count includes system VMs). Cannot" + " migrate to this host");
    }
    checkHostsDedication(vm, srcHostId, destinationHost.getId());
    _itMgr.migrateWithStorage(vm.getUuid(), srcHostId, destinationHost.getId(), volToPoolObjectMap);
    return _vmDao.findById(vm.getId());
}
Also used : HypervisorCapabilitiesVO(com.cloud.hypervisor.HypervisorCapabilitiesVO) Account(com.cloud.user.Account) LinkedHashMap(java.util.LinkedHashMap) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) Host(com.cloud.host.Host) HostVO(com.cloud.host.HostVO) VolumeVO(com.cloud.storage.VolumeVO) InvalidParameterValueException(com.cloud.exception.InvalidParameterValueException) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) StoragePoolVO(org.apache.cloudstack.storage.datastore.db.StoragePoolVO) PermissionDeniedException(com.cloud.exception.PermissionDeniedException) VirtualMachineMigrationException(com.cloud.exception.VirtualMachineMigrationException) Map(java.util.Map) LinkedHashMap(java.util.LinkedHashMap) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) ActionEvent(com.cloud.event.ActionEvent)

Aggregations

VirtualMachineMigrationException (com.cloud.exception.VirtualMachineMigrationException)11 ConcurrentOperationException (com.cloud.exception.ConcurrentOperationException)9 InvalidParameterValueException (com.cloud.exception.InvalidParameterValueException)9 ManagementServerException (com.cloud.exception.ManagementServerException)9 ResourceUnavailableException (com.cloud.exception.ResourceUnavailableException)9 Host (com.cloud.host.Host)6 VirtualMachine (com.cloud.vm.VirtualMachine)6 ServerApiException (org.apache.cloudstack.api.ServerApiException)6 UserVm (com.cloud.uservm.UserVm)5 UserVmResponse (org.apache.cloudstack.api.response.UserVmResponse)4 PermissionDeniedException (com.cloud.exception.PermissionDeniedException)3 HostVO (com.cloud.host.HostVO)3 Account (com.cloud.user.Account)3 ServerApiException (com.cloud.api.ServerApiException)2 ActionEvent (com.cloud.event.ActionEvent)2 StoragePool (com.cloud.storage.StoragePool)2 CloudRuntimeException (com.cloud.utils.exception.CloudRuntimeException)2 SystemVmResponse (org.apache.cloudstack.api.response.SystemVmResponse)2 SystemVmInstanceResponse (com.cloud.api.response.SystemVmInstanceResponse)1 UserVmResponse (com.cloud.api.response.UserVmResponse)1