From f52719a9cfbfe3e44c712dc02706e89be361e975 Mon Sep 17 00:00:00 2001 From: Anshul Gangwar Date: Mon, 2 Nov 2015 13:12:46 +0530 Subject: [PATCH] CLOUDSTACK-9707: While using hostid parameter, vm gets deployed on another if the host given is running out of capacity. If host id is specified the deployment should happen on the given host and it should fail if the host is out of capacity. We are retrying deployment on the entire zone without the given host id if we fail once. The retry, which will retry on other hosts, should only be attempted if host id isn't given. Also, introduces global setting allow.deploy.vm.if.deploy.on.given.host.fails with which old behaviour can be restored --- .../cloud/entity/api/VirtualMachineEntity.java | 3 ++- .../engine/cloud/entity/api/VMEntityManager.java | 2 +- .../cloud/entity/api/VMEntityManagerImpl.java | 16 ++++++++++------ .../entity/api/VirtualMachineEntityImpl.java | 4 ++-- server/src/com/cloud/vm/UserVmManagerImpl.java | 12 ++++++++++-- 5 files changed, 25 insertions(+), 12 deletions(-) diff --git a/engine/api/src/org/apache/cloudstack/engine/cloud/entity/api/VirtualMachineEntity.java b/engine/api/src/org/apache/cloudstack/engine/cloud/entity/api/VirtualMachineEntity.java index de91ea79dfb..c004514d084 100644 --- a/engine/api/src/org/apache/cloudstack/engine/cloud/entity/api/VirtualMachineEntity.java +++ b/engine/api/src/org/apache/cloudstack/engine/cloud/entity/api/VirtualMachineEntity.java @@ -106,7 +106,8 @@ public interface VirtualMachineEntity extends CloudStackEntity { * @param reservationId reservation id from reserve call. * */ - void deploy(String reservationId, String caller, Map params) throws InsufficientCapacityException, ResourceUnavailableException; + void deploy(String reservationId, String caller, Map params, boolean deployOnGivenHost) + throws InsufficientCapacityException, ResourceUnavailableException; /** * Stop the virtual machine diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/cloud/entity/api/VMEntityManager.java b/engine/orchestration/src/org/apache/cloudstack/engine/cloud/entity/api/VMEntityManager.java index 7e3edc69243..a87072e2d81 100644 --- a/engine/orchestration/src/org/apache/cloudstack/engine/cloud/entity/api/VMEntityManager.java +++ b/engine/orchestration/src/org/apache/cloudstack/engine/cloud/entity/api/VMEntityManager.java @@ -39,7 +39,7 @@ public interface VMEntityManager { String reserveVirtualMachine(VMEntityVO vmEntityVO, DeploymentPlanner plannerToUse, DeploymentPlan plan, ExcludeList exclude) throws InsufficientCapacityException, ResourceUnavailableException; - void deployVirtualMachine(String reservationId, VMEntityVO vmEntityVO, String caller, Map params) + void deployVirtualMachine(String reservationId, VMEntityVO vmEntityVO, String caller, Map params, boolean deployOnGivenHost) throws InsufficientCapacityException, ResourceUnavailableException; boolean stopvirtualmachine(VMEntityVO vmEntityVO, String caller) throws ResourceUnavailableException; diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/cloud/entity/api/VMEntityManagerImpl.java b/engine/orchestration/src/org/apache/cloudstack/engine/cloud/entity/api/VMEntityManagerImpl.java index 1911645f5a9..ef9c44ab26d 100644 --- a/engine/orchestration/src/org/apache/cloudstack/engine/cloud/entity/api/VMEntityManagerImpl.java +++ b/engine/orchestration/src/org/apache/cloudstack/engine/cloud/entity/api/VMEntityManagerImpl.java @@ -218,7 +218,7 @@ public class VMEntityManagerImpl implements VMEntityManager { } @Override - public void deployVirtualMachine(String reservationId, VMEntityVO vmEntityVO, String caller, Map params) + public void deployVirtualMachine(String reservationId, VMEntityVO vmEntityVO, String caller, Map params, boolean deployOnGivenHost) throws InsufficientCapacityException, ResourceUnavailableException { //grab the VM Id and destination using the reservationId. @@ -233,13 +233,17 @@ public class VMEntityManagerImpl implements VMEntityManager { _itMgr.start(vm.getUuid(), params, reservedPlan, _planningMgr.getDeploymentPlannerByName(vmReservation.getDeploymentPlanner())); } catch (Exception ex) { // Retry the deployment without using the reservation plan - DataCenterDeployment plan = new DataCenterDeployment(0, null, null, null, null, null); + // Retry is only done if host id is not passed in deploy virtual machine api. Otherwise + // the instance may be started on another host instead of the intended one. + if (!deployOnGivenHost) { + DataCenterDeployment plan = new DataCenterDeployment(0, null, null, null, null, null); - if (reservedPlan.getAvoids() != null) { - plan.setAvoids(reservedPlan.getAvoids()); + if (reservedPlan.getAvoids() != null) { + plan.setAvoids(reservedPlan.getAvoids()); + } + + _itMgr.start(vm.getUuid(), params, plan, null); } - - _itMgr.start(vm.getUuid(), params, plan, null); } } else { // no reservation found. Let VirtualMachineManager retry diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/cloud/entity/api/VirtualMachineEntityImpl.java b/engine/orchestration/src/org/apache/cloudstack/engine/cloud/entity/api/VirtualMachineEntityImpl.java index 7a8f624d325..598e61989d1 100644 --- a/engine/orchestration/src/org/apache/cloudstack/engine/cloud/entity/api/VirtualMachineEntityImpl.java +++ b/engine/orchestration/src/org/apache/cloudstack/engine/cloud/entity/api/VirtualMachineEntityImpl.java @@ -207,9 +207,9 @@ public class VirtualMachineEntityImpl implements VirtualMachineEntity { } @Override - public void deploy(String reservationId, String caller, Map params) throws InsufficientCapacityException, + public void deploy(String reservationId, String caller, Map params, boolean deployOnGivenHost) throws InsufficientCapacityException, ResourceUnavailableException { - manager.deployVirtualMachine(reservationId, this.vmEntityVO, caller, params); + manager.deployVirtualMachine(reservationId, this.vmEntityVO, caller, params, deployOnGivenHost); } @Override diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index 11d2adfc798..6129ef96188 100755 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -518,6 +518,9 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir static final ConfigKey VmIpFetchTaskWorkers = new ConfigKey("Advanced", Integer.class, "externaldhcp.vmipfetchtask.workers", "10", "number of worker threads for vm ip fetch task ", true); + static final ConfigKey AllowDeployVmIfGivenHostFails = new ConfigKey("Advanced", Boolean.class, "allow.deploy.vm.if.deploy.on.given.host.fails", "false", + "allow vm to deploy on different host if vm fails to deploy on the given host ", true); + @Override public UserVmVO getVirtualMachine(long vmId) { @@ -4098,9 +4101,13 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir } DataCenterDeployment plan = null; + boolean deployOnGivenHost = false; if (destinationHost != null) { s_logger.debug("Destination Host to deploy the VM is specified, specifying a deployment plan to deploy the VM"); plan = new DataCenterDeployment(vm.getDataCenterId(), destinationHost.getPodId(), destinationHost.getClusterId(), destinationHost.getId(), null, null); + if (!AllowDeployVmIfGivenHostFails.value()) { + deployOnGivenHost = true; + } } // Set parameters @@ -4148,7 +4155,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir } String reservationId = vmEntity.reserve(planner, plan, new ExcludeList(), Long.toString(callerUser.getId())); - vmEntity.deploy(reservationId, Long.toString(callerUser.getId()), params); + vmEntity.deploy(reservationId, Long.toString(callerUser.getId()), params, deployOnGivenHost); Pair> vmParamPair = new Pair(vm, params); if (vm != null && vm.isUpdateParameters()) { @@ -5902,7 +5909,8 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir @Override public ConfigKey[] getConfigKeys() { - return new ConfigKey[] {EnableDynamicallyScaleVm, AllowUserExpungeRecoverVm, VmIpFetchWaitInterval, VmIpFetchTrialMax, VmIpFetchThreadPoolMax, VmIpFetchTaskWorkers}; + return new ConfigKey[] {EnableDynamicallyScaleVm, AllowUserExpungeRecoverVm, VmIpFetchWaitInterval, VmIpFetchTrialMax, VmIpFetchThreadPoolMax, + VmIpFetchTaskWorkers, AllowDeployVmIfGivenHostFails}; } @Override