use of com.cloud.legacymodel.exceptions.VirtualMachineMigrationException in project cosmic by MissionCriticalCloud.
the class UserVmManagerImpl method migrateVirtualMachineWithVolume.
@Override
@ActionEvent(eventType = EventTypes.EVENT_VM_MIGRATE, eventDescription = "migrating VM", async = true)
public VirtualMachine migrateVirtualMachineWithVolume(final Long vmId, final Host destinationHost, final Map<String, String> volumeToPool) throws ResourceUnavailableException, ConcurrentOperationException, ManagementServerException, VirtualMachineMigrationException {
// Access check - only root administrator can migrate VM.
final 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!");
}
final 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);
}
final 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.KVM)) {
throw new InvalidParameterValueException("Unsupported hypervisor type for vm migration, we support" + " XenServer/KVM only");
}
final long srcHostId = vm.getHostId();
final 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());
}
if (srcHost.getHypervisorVersion() != null && !srcHost.getHypervisorVersion().equals(destinationHost.getHypervisorVersion())) {
throw new CloudRuntimeException("The source and destination hosts are not of the same version. " + "Source hypervisor type and version: " + srcHost.getHypervisorType().toString() + " " + srcHost.getHypervisorVersion() + ", Destination hypervisor type and version: " + destinationHost.getHypervisorType().toString() + " " + destinationHost.getHypervisorVersion());
}
final 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() != HostStatus.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");
}
final List<VolumeVO> vmVolumes = _volsDao.findUsableVolumesForInstance(vm.getId());
final Map<Long, Long> volToPoolObjectMap = new HashMap<>();
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 (final Map.Entry<String, String> entry : volumeToPool.entrySet()) {
final VolumeVO volume = _volsDao.findByUuid(entry.getKey());
final 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(volume.getId(), pool.getId());
}
}
}
// Check if all the volumes are in the correct state.
for (final 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.
final 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());
}
use of com.cloud.legacymodel.exceptions.VirtualMachineMigrationException in project cosmic by MissionCriticalCloud.
the class ScaleVMCmdByAdmin method execute.
@Override
public void execute() {
final UserVm result;
try {
result = _userVmService.upgradeVirtualMachine(this);
} catch (final ResourceUnavailableException ex) {
s_logger.warn("Exception: ", ex);
throw new ServerApiException(ApiErrorCode.RESOURCE_UNAVAILABLE_ERROR, ex.getMessage());
} catch (final ConcurrentOperationException ex) {
s_logger.warn("Exception: ", ex);
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
} catch (final ManagementServerException ex) {
s_logger.warn("Exception: ", ex);
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
} catch (final VirtualMachineMigrationException ex) {
s_logger.warn("Exception: ", ex);
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
}
if (result != null) {
final List<UserVmResponse> responseList = _responseGenerator.createUserVmResponse(ResponseView.Full, "virtualmachine", result);
final UserVmResponse response = responseList.get(0);
response.setResponseName(getCommandName());
setResponseObject(response);
} else {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to scale vm");
}
}
use of com.cloud.legacymodel.exceptions.VirtualMachineMigrationException in project cosmic by MissionCriticalCloud.
the class ScaleVMCmd method execute.
@Override
public void execute() {
final UserVm result;
try {
result = _userVmService.upgradeVirtualMachine(this);
} catch (final ResourceUnavailableException ex) {
s_logger.warn("Exception: ", ex);
throw new ServerApiException(ApiErrorCode.RESOURCE_UNAVAILABLE_ERROR, ex.getMessage());
} catch (final ConcurrentOperationException ex) {
s_logger.warn("Exception: ", ex);
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
} catch (final ManagementServerException ex) {
s_logger.warn("Exception: ", ex);
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
} catch (final VirtualMachineMigrationException ex) {
s_logger.warn("Exception: ", ex);
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
}
if (result != null) {
final List<UserVmResponse> responseList = _responseGenerator.createUserVmResponse(ResponseView.Restricted, "virtualmachine", result);
final UserVmResponse response = responseList.get(0);
response.setResponseName(getCommandName());
setResponseObject(response);
} else {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to scale vm");
}
}
use of com.cloud.legacymodel.exceptions.VirtualMachineMigrationException in project cosmic by MissionCriticalCloud.
the class VirtualMachineManagerImpl method migrate.
@Override
public void migrate(final String vmUuid, final long srcHostId, final DeployDestination dest) throws ResourceUnavailableException, ConcurrentOperationException, VirtualMachineMigrationException {
final AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext();
if (jobContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) {
// avoid re-entrance
VmWorkJobVO placeHolder = null;
final VirtualMachine vm = _vmDao.findByUuid(vmUuid);
placeHolder = createPlaceHolderWork(vm.getId());
try {
orchestrateMigrate(vmUuid, srcHostId, dest);
} finally {
if (placeHolder != null) {
_workJobDao.expunge(placeHolder.getId());
}
}
} else {
final Outcome<VirtualMachine> outcome = migrateVmThroughJobQueue(vmUuid, srcHostId, dest);
try {
final VirtualMachine vm = outcome.get();
} catch (final InterruptedException e) {
throw new RuntimeException("Operation is interrupted", e);
} catch (final java.util.concurrent.ExecutionException e) {
throw new RuntimeException("Execution excetion", e);
}
final Object jobResult = _jobMgr.unmarshallResultObject(outcome.getJob());
if (jobResult != null) {
if (jobResult instanceof ResourceUnavailableException) {
throw (ResourceUnavailableException) jobResult;
} else if (jobResult instanceof ConcurrentOperationException) {
throw (ConcurrentOperationException) jobResult;
} else if (jobResult instanceof Throwable) {
final Throwable t = (Throwable) jobResult;
throw new VirtualMachineMigrationException(t.getMessage(), t);
}
}
}
}
use of com.cloud.legacymodel.exceptions.VirtualMachineMigrationException in project cosmic by MissionCriticalCloud.
the class UserVmManagerImpl method upgradeRunningVirtualMachine.
private boolean upgradeRunningVirtualMachine(final Long vmId, final Long newServiceOfferingId, final Map<String, String> customParameters) throws ResourceUnavailableException, ConcurrentOperationException, ManagementServerException, VirtualMachineMigrationException {
final Account caller = CallContext.current().getCallingAccount();
VMInstanceVO vmInstance = _vmInstanceDao.findById(vmId);
if (vmInstance.getHypervisorType() != HypervisorType.XenServer) {
s_logger.info("Scaling the VM dynamically is not supported for VMs running on Hypervisor " + vmInstance.getHypervisorType());
throw new InvalidParameterValueException("Scaling the VM dynamically is not supported for VMs running on Hypervisor " + vmInstance.getHypervisorType());
}
_accountMgr.checkAccess(caller, null, true, vmInstance);
// Check if its a scale "up"
ServiceOfferingVO newServiceOffering = _offeringDao.findById(newServiceOfferingId);
// Check that the specified service offering ID is valid
_itMgr.checkIfCanUpgrade(vmInstance, newServiceOffering);
final ServiceOffering currentServiceOffering = _offeringDao.findByIdIncludingRemoved(vmInstance.getId(), vmInstance.getServiceOfferingId());
final int newCpu = newServiceOffering.getCpu();
final int newMemory = newServiceOffering.getRamSize();
final int currentCpu = currentServiceOffering.getCpu();
final int currentMemory = currentServiceOffering.getRamSize();
final int memoryDiff = newMemory - currentMemory;
final int cpuDiff = newCpu - currentCpu;
// Don't allow to scale when (Any of the new values less than current values) OR (All current and new values are same)
if (newMemory < currentMemory || newCpu < currentCpu || newMemory == currentMemory && newCpu == currentCpu) {
throw new InvalidParameterValueException("Only scaling up the vm is supported, new service offering(cpu=" + newCpu + ",memory=," + newMemory + ")" + " should have at least one value(cpu/ram) greater than old value and no resource value less than older(cpu=" + currentCpu + ",memory=," + currentMemory + ")");
}
// Check resource limits
if (newCpu > currentCpu) {
_resourceLimitMgr.checkResourceLimit(caller, ResourceType.cpu, newCpu - currentCpu);
}
if (newMemory > currentMemory) {
_resourceLimitMgr.checkResourceLimit(caller, ResourceType.memory, newMemory - currentMemory);
}
// Dynamically upgrade the running vms
boolean success = false;
if (vmInstance.getState().equals(State.Running)) {
int retry = _scaleRetry;
final ExcludeList excludes = new ExcludeList();
// Check zone wide flag
final boolean enableDynamicallyScaleVm = EnableDynamicallyScaleVm.valueIn(vmInstance.getDataCenterId());
if (!enableDynamicallyScaleVm) {
throw new PermissionDeniedException("Dynamically scaling virtual machines is disabled for this zone, please contact your admin");
}
// Check vm flag
if (!vmInstance.isDynamicallyScalable()) {
throw new CloudRuntimeException("Unable to Scale the vm: " + vmInstance.getUuid() + " as vm does not have tools to support dynamic scaling");
}
// Check disable threshold for cluster is not crossed
final HostVO host = _hostDao.findById(vmInstance.getHostId());
if (_capacityMgr.checkIfClusterCrossesThreshold(host.getClusterId(), cpuDiff, memoryDiff)) {
throw new CloudRuntimeException("Unable to scale vm: " + vmInstance.getUuid() + " due to insufficient resources");
}
while (retry-- != 0) {
// It's != so that it can match -1.
try {
boolean existingHostHasCapacity = false;
// Increment CPU and Memory count accordingly.
if (newCpu > currentCpu) {
_resourceLimitMgr.incrementResourceCount(caller.getAccountId(), ResourceType.cpu, new Long(newCpu - currentCpu));
}
if (memoryDiff > 0) {
_resourceLimitMgr.incrementResourceCount(caller.getAccountId(), ResourceType.memory, new Long(memoryDiff));
}
// #1 Check existing host has capacity
if (!excludes.shouldAvoid(ApiDBUtils.findHostById(vmInstance.getHostId()))) {
existingHostHasCapacity = _capacityMgr.checkIfHostHasCpuCapability(vmInstance.getHostId(), newCpu) && _capacityMgr.checkIfHostHasCapacity(vmInstance.getHostId(), cpuDiff, memoryDiff * 1024L * 1024L, false, _capacityMgr.getClusterOverProvisioningFactor(host.getClusterId(), Capacity.CAPACITY_TYPE_CPU), _capacityMgr.getClusterOverProvisioningFactor(host.getClusterId(), Capacity.CAPACITY_TYPE_MEMORY), false);
excludes.addHost(vmInstance.getHostId());
}
// #2 migrate the vm if host doesn't have capacity or is in avoid set
if (!existingHostHasCapacity) {
_itMgr.findHostAndMigrate(vmInstance.getUuid(), newServiceOfferingId, excludes);
}
// #3 scale the vm now
_itMgr.upgradeVmDb(vmId, newServiceOfferingId);
vmInstance = _vmInstanceDao.findById(vmId);
_itMgr.reConfigureVm(vmInstance.getUuid(), currentServiceOffering, existingHostHasCapacity);
success = true;
return success;
} catch (final InsufficientCapacityException e) {
s_logger.warn("Received exception while scaling ", e);
} catch (final ResourceUnavailableException e) {
s_logger.warn("Received exception while scaling ", e);
} catch (final ConcurrentOperationException e) {
s_logger.warn("Received exception while scaling ", e);
} catch (final Exception e) {
s_logger.warn("Received exception while scaling ", e);
} finally {
if (!success) {
// rollback
_itMgr.upgradeVmDb(vmId, currentServiceOffering.getId());
// Decrement CPU and Memory count accordingly.
if (newCpu > currentCpu) {
_resourceLimitMgr.decrementResourceCount(caller.getAccountId(), ResourceType.cpu, new Long(newCpu - currentCpu));
}
if (memoryDiff > 0) {
_resourceLimitMgr.decrementResourceCount(caller.getAccountId(), ResourceType.memory, new Long(memoryDiff));
}
}
}
}
}
return success;
}
Aggregations