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 82d4c1209b8..3a47f381078 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) { @@ -4099,9 +4102,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 @@ -4149,7 +4156,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()) { @@ -5903,7 +5910,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