diff --git a/api/src/com/cloud/deploy/HAPlanner.java b/api/src/com/cloud/deploy/HAPlanner.java new file mode 100644 index 00000000000..aeb5083c522 --- /dev/null +++ b/api/src/com/cloud/deploy/HAPlanner.java @@ -0,0 +1,21 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package com.cloud.deploy; + + +public interface HAPlanner extends DeploymentPlanner { +} \ No newline at end of file diff --git a/client/pom.xml b/client/pom.xml index fc01113c7a0..75b5504ec96 100644 --- a/client/pom.xml +++ b/client/pom.xml @@ -176,6 +176,11 @@ cloud-plugin-planner-user-dispersing ${project.version} + + org.apache.cloudstack + cloud-plugin-planner-skip-heurestics + ${project.version} + org.apache.cloudstack cloud-plugin-planner-user-concentrated-pod diff --git a/core/resources/META-INF/cloudstack/core/spring-core-registry-core-context.xml b/core/resources/META-INF/cloudstack/core/spring-core-registry-core-context.xml index be11a1f711f..5e799c06483 100644 --- a/core/resources/META-INF/cloudstack/core/spring-core-registry-core-context.xml +++ b/core/resources/META-INF/cloudstack/core/spring-core-registry-core-context.xml @@ -77,6 +77,11 @@ + + + + diff --git a/core/resources/META-INF/cloudstack/planner/spring-core-lifecycle-planner-context-inheritable.xml b/core/resources/META-INF/cloudstack/planner/spring-core-lifecycle-planner-context-inheritable.xml index 715f86d9c28..80779e43466 100644 --- a/core/resources/META-INF/cloudstack/planner/spring-core-lifecycle-planner-context-inheritable.xml +++ b/core/resources/META-INF/cloudstack/planner/spring-core-lifecycle-planner-context-inheritable.xml @@ -38,4 +38,9 @@ value="org.apache.cloudstack.affinity.AffinityGroupProcessor" /> + + + + + diff --git a/engine/api/src/com/cloud/vm/VirtualMachineManager.java b/engine/api/src/com/cloud/vm/VirtualMachineManager.java index 4c2222cf412..4f4a6520971 100644 --- a/engine/api/src/com/cloud/vm/VirtualMachineManager.java +++ b/engine/api/src/com/cloud/vm/VirtualMachineManager.java @@ -93,10 +93,13 @@ public interface VirtualMachineManager extends Manager { boolean stateTransitTo(VirtualMachine vm, VirtualMachine.Event e, Long hostId) throws NoTransitionException; - void advanceStart(String vmUuid, Map params) throws InsufficientCapacityException, ResourceUnavailableException, - ConcurrentOperationException, OperationTimedoutException; + void advanceStart(String vmUuid, Map params, DeploymentPlanner planner) throws InsufficientCapacityException, ResourceUnavailableException, + ConcurrentOperationException, OperationTimedoutException; - void advanceStart(String vmUuid, Map params, DeploymentPlan planToDeploy) throws InsufficientCapacityException, + void advanceStart(String vmUuid, Map params, DeploymentPlan planToDeploy, DeploymentPlanner planner) throws InsufficientCapacityException, + ResourceUnavailableException, ConcurrentOperationException, OperationTimedoutException; + + void orchestrateStart(String vmUuid, Map params, DeploymentPlan planToDeploy, DeploymentPlanner planner) throws InsufficientCapacityException, ResourceUnavailableException, ConcurrentOperationException, OperationTimedoutException; void advanceStop(String vmUuid, boolean cleanupEvenIfUnableToStop) throws ResourceUnavailableException, OperationTimedoutException, ConcurrentOperationException; @@ -105,7 +108,7 @@ public interface VirtualMachineManager extends Manager { void destroy(String vmUuid) throws AgentUnavailableException, OperationTimedoutException, ConcurrentOperationException; - void migrateAway(String vmUuid, long hostId) throws InsufficientServerCapacityException; + void migrateAway(String vmUuid, long hostId, DeploymentPlanner planner) throws InsufficientServerCapacityException; void migrate(String vmUuid, long srcHostId, DeployDestination dest) throws ResourceUnavailableException, ConcurrentOperationException; diff --git a/engine/components-api/src/com/cloud/deploy/DeploymentPlanningManager.java b/engine/components-api/src/com/cloud/deploy/DeploymentPlanningManager.java index b61e89ddcea..de2fc0eaf5a 100644 --- a/engine/components-api/src/com/cloud/deploy/DeploymentPlanningManager.java +++ b/engine/components-api/src/com/cloud/deploy/DeploymentPlanningManager.java @@ -39,11 +39,12 @@ public interface DeploymentPlanningManager extends Manager { * * */ - DeployDestination planDeployment(VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoids) throws InsufficientServerCapacityException, - AffinityConflictException; + DeployDestination planDeployment(VirtualMachineProfile vmProfile, DeploymentPlan plan, + ExcludeList avoids, DeploymentPlanner planner) throws InsufficientServerCapacityException, AffinityConflictException; - String finalizeReservation(DeployDestination plannedDestination, VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoids) - throws InsufficientServerCapacityException, AffinityConflictException; + String finalizeReservation(DeployDestination plannedDestination, + VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoids) + throws InsufficientServerCapacityException, AffinityConflictException; void cleanupVMReservations(); } diff --git a/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java b/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java index 75ab47b35d2..f4a86fc8636 100755 --- a/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java +++ b/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java @@ -42,6 +42,7 @@ import javax.naming.ConfigurationException; import org.apache.log4j.Logger; +import com.cloud.deploy.DeploymentPlanner; import org.apache.cloudstack.affinity.dao.AffinityGroupVMMapDao; import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService; @@ -559,7 +560,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac @Override public void start(String vmUuid, Map params, DeploymentPlan planToDeploy) { try { - advanceStart(vmUuid, params, planToDeploy); + advanceStart(vmUuid, params, planToDeploy, null); } catch (ConcurrentOperationException e) { throw new CloudRuntimeException("Unable to start a VM due to concurrent operation", e).add(VirtualMachine.class, vmUuid); } catch (InsufficientCapacityException e) { @@ -700,20 +701,19 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac } @Override - public void advanceStart(String vmUuid, Map params) + public void advanceStart(String vmUuid, Map params, DeploymentPlanner planner) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException { - - advanceStart(vmUuid, params, null); + advanceStart(vmUuid, params, null, planner); } @Override - public void advanceStart(String vmUuid, Map params, DeploymentPlan planToDeploy) throws InsufficientCapacityException, + public void advanceStart(String vmUuid, Map params, DeploymentPlan planToDeploy, DeploymentPlanner planner) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException { AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext(); if (!VmJobEnabled.value() || jobContext.isJobDispatchedBy(VmWorkJobDispatcher.VM_WORK_JOB_DISPATCHER)) { // avoid re-entrance - orchestrateStart(vmUuid, params, planToDeploy); + orchestrateStart(vmUuid, params, planToDeploy, planner); } else { Outcome outcome = startVmThroughJobQueue(vmUuid, params, planToDeploy); @@ -735,8 +735,10 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac } } - private void orchestrateStart(String vmUuid, Map params, DeploymentPlan planToDeploy) throws InsufficientCapacityException, - ConcurrentOperationException, ResourceUnavailableException { + + @Override + public void orchestrateStart(String vmUuid, Map params, DeploymentPlan planToDeploy, DeploymentPlanner planner) + throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException { CallContext cctxt = CallContext.current(); Account account = cctxt.getCallingAccount(); @@ -854,7 +856,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac VirtualMachineProfileImpl vmProfile = new VirtualMachineProfileImpl(vm, template, offering, owner, params); DeployDestination dest = null; try { - dest = _dpMgr.planDeployment(vmProfile, plan, avoids); + dest = _dpMgr.planDeployment(vmProfile, plan, avoids, planner); } catch (AffinityConflictException e2) { s_logger.warn("Unable to create deployment, affinity rules associted to the VM conflict", e2); throw new CloudRuntimeException("Unable to create deployment, affinity rules associted to the VM conflict"); @@ -2037,7 +2039,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac } @Override - public void migrateAway(String vmUuid, long srcHostId) throws InsufficientServerCapacityException { + public void migrateAway(String vmUuid, long srcHostId, DeploymentPlanner planner) throws InsufficientServerCapacityException { VMInstanceVO vm = _vmDao.findByUuid(vmUuid); if (vm == null) { s_logger.debug("Unable to find a VM for " + vmUuid); @@ -2070,7 +2072,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac while (true) { try { - dest = _dpMgr.planDeployment(profile, plan, excludes); + dest = _dpMgr.planDeployment(profile, plan, excludes, planner); } catch (AffinityConflictException e2) { s_logger.warn("Unable to create deployment, affinity rules associted to the VM conflict", e2); throw new CloudRuntimeException("Unable to create deployment, affinity rules associted to the VM conflict"); @@ -3392,7 +3394,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac DeployDestination dest = null; try { - dest = _dpMgr.planDeployment(profile, plan, excludes); + dest = _dpMgr.planDeployment(profile, plan, excludes, null); } catch (AffinityConflictException e2) { s_logger.warn("Unable to create deployment, affinity rules associted to the VM conflict", e2); throw new CloudRuntimeException("Unable to create deployment, affinity rules associted to the VM conflict"); @@ -4712,7 +4714,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac assert (vm != null); if (work instanceof VmWorkStart) { VmWorkStart workStart = (VmWorkStart)work; - orchestrateStart(vm.getUuid(), workStart.getParams(), workStart.getPlan()); + orchestrateStart(vm.getUuid(), workStart.getParams(), workStart.getPlan(), null); return new Pair(JobInfo.Status.SUCCEEDED, null); } else if (work instanceof VmWorkStop) { VmWorkStop workStop = (VmWorkStop)work; 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 40b0f447392..36481ab5a43 100755 --- 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 @@ -189,7 +189,7 @@ public class VMEntityManagerImpl implements VMEntityManager { while (true) { DeployDestination dest = null; try { - dest = _dpMgr.planDeployment(vmProfile, plan, exclude); + dest = _dpMgr.planDeployment(vmProfile, plan, exclude, null); } catch (AffinityConflictException e) { throw new CloudRuntimeException("Unable to create deployment, affinity rules associted to the VM conflict"); } diff --git a/plugins/ha-planners/skip-heurestics/pom.xml b/plugins/ha-planners/skip-heurestics/pom.xml new file mode 100644 index 00000000000..223789a287f --- /dev/null +++ b/plugins/ha-planners/skip-heurestics/pom.xml @@ -0,0 +1,29 @@ + + + 4.0.0 + cloud-plugin-planner-skip-heurestics + Apache CloudStack Plugin - Skip Heurestics Planner + + org.apache.cloudstack + cloudstack-plugins + 4.4.0-SNAPSHOT + ../../pom.xml + + diff --git a/plugins/ha-planners/skip-heurestics/resources/META-INF/cloudstack/skip-heurestics/module.properties b/plugins/ha-planners/skip-heurestics/resources/META-INF/cloudstack/skip-heurestics/module.properties new file mode 100644 index 00000000000..dfe0641ba4a --- /dev/null +++ b/plugins/ha-planners/skip-heurestics/resources/META-INF/cloudstack/skip-heurestics/module.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +name=skip-heurestics +parent=planner diff --git a/plugins/ha-planners/skip-heurestics/resources/META-INF/cloudstack/skip-heurestics/spring-skip-heurestics-context.xml b/plugins/ha-planners/skip-heurestics/resources/META-INF/cloudstack/skip-heurestics/spring-skip-heurestics-context.xml new file mode 100644 index 00000000000..93a015874af --- /dev/null +++ b/plugins/ha-planners/skip-heurestics/resources/META-INF/cloudstack/skip-heurestics/spring-skip-heurestics-context.xml @@ -0,0 +1,26 @@ + + + + + + + + + + diff --git a/plugins/ha-planners/skip-heurestics/src/com/cloud/deploy/SkipHeuresticsPlanner.java b/plugins/ha-planners/skip-heurestics/src/com/cloud/deploy/SkipHeuresticsPlanner.java new file mode 100644 index 00000000000..b67d112f825 --- /dev/null +++ b/plugins/ha-planners/skip-heurestics/src/com/cloud/deploy/SkipHeuresticsPlanner.java @@ -0,0 +1,61 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package com.cloud.deploy; + +import com.cloud.vm.VirtualMachineProfile; +import org.apache.log4j.Logger; + + +import javax.ejb.Local; +import javax.naming.ConfigurationException; +import java.util.List; +import java.util.Map; + +@Local(value=HAPlanner.class) +public class SkipHeuresticsPlanner extends FirstFitPlanner implements HAPlanner { + private static final Logger s_logger = Logger.getLogger(SkipHeuresticsPlanner.class); + + + /** + * This method should remove the clusters crossing capacity threshold + * to avoid further vm allocation on it. + * + * In case of HA, we shouldn't consider this threshold as we have reserved the capacity for such emergencies. + */ + @Override + protected void removeClustersCrossingThreshold(List clusterListForVmAllocation, ExcludeList avoid, + VirtualMachineProfile vmProfile, DeploymentPlan plan){ + if (s_logger.isDebugEnabled()) { + s_logger.debug("Deploying vm during HA process, so skipping disable threshold check"); + } + return; + } + + @Override + public boolean canHandle(VirtualMachineProfile vm, DeploymentPlan plan, ExcludeList avoid) { + return true; + } + + @Override + public boolean configure(String name, Map params) throws ConfigurationException { + super.configure(name, params); + + return true; + + } + +} \ No newline at end of file diff --git a/plugins/pom.xml b/plugins/pom.xml index 17dd8af6765..06cf79f785e 100755 --- a/plugins/pom.xml +++ b/plugins/pom.xml @@ -32,6 +32,7 @@ deployment-planners/user-concentrated-pod deployment-planners/user-dispersing deployment-planners/implicit-dedication + ha-planners/skip-heurestics host-allocators/random dedicated-resources hypervisors/ovm diff --git a/server/resources/META-INF/cloudstack/core/spring-server-core-managers-context.xml b/server/resources/META-INF/cloudstack/core/spring-server-core-managers-context.xml index 35683f0b2d2..d4ee85e4569 100644 --- a/server/resources/META-INF/cloudstack/core/spring-server-core-managers-context.xml +++ b/server/resources/META-INF/cloudstack/core/spring-server-core-managers-context.xml @@ -65,6 +65,7 @@ + diff --git a/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java b/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java index 4b35b0e578d..3b23715800c 100755 --- a/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java +++ b/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java @@ -549,7 +549,7 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy } if (proxy.getState() == VirtualMachine.State.Stopped) { - _itMgr.advanceStart(proxy.getUuid(), null); + _itMgr.advanceStart(proxy.getUuid(), null, null); proxy = _consoleProxyDao.findById(proxy.getId()); } diff --git a/server/src/com/cloud/deploy/DeploymentPlanningManagerImpl.java b/server/src/com/cloud/deploy/DeploymentPlanningManagerImpl.java index ca2ff42e455..8cad796d966 100644 --- a/server/src/com/cloud/deploy/DeploymentPlanningManagerImpl.java +++ b/server/src/com/cloud/deploy/DeploymentPlanningManagerImpl.java @@ -233,8 +233,8 @@ public class DeploymentPlanningManagerImpl extends ManagerBase implements Deploy } @Override - public DeployDestination planDeployment(VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoids) throws InsufficientServerCapacityException, - AffinityConflictException { + public DeployDestination planDeployment(VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoids, DeploymentPlanner planner) + throws InsufficientServerCapacityException, AffinityConflictException { // call affinitygroup chain VirtualMachine vm = vmProfile.getVirtualMachine(); @@ -265,19 +265,20 @@ public class DeploymentPlanningManagerImpl extends ManagerBase implements Deploy } ServiceOffering offering = vmProfile.getServiceOffering(); - String plannerName = offering.getDeploymentPlanner(); - if (plannerName == null) { - if (vm.getHypervisorType() == HypervisorType.BareMetal) { - plannerName = "BareMetalPlanner"; - } else { - plannerName = _configDao.getValue(Config.VmDeploymentPlanner.key()); + if(planner == null){ + String plannerName = offering.getDeploymentPlanner(); + if (plannerName == null) { + if (vm.getHypervisorType() == HypervisorType.BareMetal) { + plannerName = "BareMetalPlanner"; + } else { + plannerName = _configDao.getValue(Config.VmDeploymentPlanner.key()); + } } - } - DeploymentPlanner planner = null; - for (DeploymentPlanner plannerInList : _planners) { - if (plannerName.equals(plannerInList.getName())) { - planner = plannerInList; - break; + for (DeploymentPlanner plannerInList : _planners) { + if (plannerName.equals(plannerInList.getName())) { + planner = plannerInList; + break; + } } } diff --git a/server/src/com/cloud/deploy/FirstFitPlanner.java b/server/src/com/cloud/deploy/FirstFitPlanner.java index b59fceff36b..1c79a67e780 100755 --- a/server/src/com/cloud/deploy/FirstFitPlanner.java +++ b/server/src/com/cloud/deploy/FirstFitPlanner.java @@ -259,7 +259,15 @@ public class FirstFitPlanner extends PlannerBase implements DeploymentClusterPla return capacityList; } - private void removeClustersCrossingThreshold(List clusterListForVmAllocation, ExcludeList avoid, VirtualMachineProfile vmProfile, DeploymentPlan plan) { + /** + * This method should remove the clusters crossing capacity threshold to avoid further vm allocation on it. + * @param clusterListForVmAllocation + * @param avoid + * @param vmProfile + * @param plan + */ + protected void removeClustersCrossingThreshold(List clusterListForVmAllocation, ExcludeList avoid, + VirtualMachineProfile vmProfile, DeploymentPlan plan) { List capacityList = getCapacitiesForCheckingThreshold(); List clustersCrossingThreshold = new ArrayList(); diff --git a/server/src/com/cloud/ha/HighAvailabilityManagerImpl.java b/server/src/com/cloud/ha/HighAvailabilityManagerImpl.java index 8e86bbcd24f..ad33666e373 100755 --- a/server/src/com/cloud/ha/HighAvailabilityManagerImpl.java +++ b/server/src/com/cloud/ha/HighAvailabilityManagerImpl.java @@ -32,6 +32,7 @@ import javax.naming.ConfigurationException; import org.apache.log4j.Logger; import org.apache.log4j.NDC; +import com.cloud.deploy.HAPlanner; import org.apache.cloudstack.engine.orchestration.service.VolumeOrchestrationService; import org.apache.cloudstack.framework.config.dao.ConfigurationDao; import org.apache.cloudstack.managed.context.ManagedContext; @@ -141,6 +142,16 @@ public class HighAvailabilityManagerImpl extends ManagerBase implements HighAvai this.fenceBuilders = fenceBuilders; } + List _haPlanners; + public List getHaPlanners() { + return _haPlanners; + } + + public void setHaPlanners(List haPlanners) { + this._haPlanners = haPlanners; + } + + @Inject AgentManager _agentMgr; @Inject @@ -548,9 +559,20 @@ public class HighAvailabilityManagerImpl extends ManagerBase implements HighAvai if (_haTag != null) { params.put(VirtualMachineProfile.Param.HaTag, _haTag); } - _itMgr.advanceStart(vm.getUuid(), params); + + // First try starting the vm with its original planner, if it doesn't succeed send HAPlanner as its an emergency. + _itMgr.advanceStart(vm.getUuid(), params, null); VMInstanceVO started = _instanceDao.findById(vm.getId()); + if (started != null && started.getState() == VirtualMachine.State.Running) { + s_logger.info("VM is now restarted: " + vmId + " on " + started.getHostId()); + return null; + }else { + s_logger.warn("Failed to deploy vm " + vmId + " with original planner, sending HAPlanner"); + _itMgr.advanceStart(vm.getUuid(), params, _haPlanners.get(0)); + } + + started = _instanceDao.findById(vm.getId()); if (started != null && started.getState() == VirtualMachine.State.Running) { s_logger.info("VM is now restarted: " + vmId + " on " + started.getHostId()); return null; @@ -591,8 +613,14 @@ public class HighAvailabilityManagerImpl extends ManagerBase implements HighAvai _haDao.update(work.getId(), work); VMInstanceVO vm = _instanceDao.findById(vmId); - - _itMgr.migrateAway(vm.getUuid(), srcHostId); + // First try starting the vm with its original planner, if it doesn't succeed send HAPlanner as its an emergency. + boolean result = false; + try { + _itMgr.migrateAway(vm.getUuid(), srcHostId, null); + }catch (InsufficientServerCapacityException e) { + s_logger.warn("Failed to deploy vm " + vmId + " with original planner, sending HAPlanner"); + _itMgr.migrateAway(vm.getUuid(), srcHostId, _haPlanners.get(0)); + } return null; } catch (InsufficientServerCapacityException e) { s_logger.warn("Insufficient capacity for migrating a VM."); diff --git a/server/src/com/cloud/storage/StoragePoolAutomationImpl.java b/server/src/com/cloud/storage/StoragePoolAutomationImpl.java index c76c6477418..8becd75ef26 100644 --- a/server/src/com/cloud/storage/StoragePoolAutomationImpl.java +++ b/server/src/com/cloud/storage/StoragePoolAutomationImpl.java @@ -219,7 +219,7 @@ public class StoragePoolAutomationImpl implements StoragePoolAutomation { if (restart) { - vmMgr.advanceStart(consoleProxy.getUuid(), null); + vmMgr.advanceStart(consoleProxy.getUuid(), null, null); // update work status work.setStartedAfterMaintenance(true); _storagePoolWorkDao.update(work.getId(), work); @@ -245,7 +245,7 @@ public class StoragePoolAutomationImpl implements StoragePoolAutomation { _storagePoolWorkDao.update(work.getId(), work); if (restart) { - vmMgr.advanceStart(secStrgVm.getUuid(), null); + vmMgr.advanceStart(secStrgVm.getUuid(), null, null); // update work status work.setStartedAfterMaintenance(true); _storagePoolWorkDao.update(work.getId(), work); @@ -262,7 +262,7 @@ public class StoragePoolAutomationImpl implements StoragePoolAutomation { _storagePoolWorkDao.update(work.getId(), work); if (restart) { - vmMgr.advanceStart(domR.getUuid(), null); + vmMgr.advanceStart(domR.getUuid(), null, null); // update work status work.setStartedAfterMaintenance(true); _storagePoolWorkDao.update(work.getId(), work); @@ -330,17 +330,21 @@ public class StoragePoolAutomationImpl implements StoragePoolAutomation { // proxy if (vmInstance.getType().equals(VirtualMachine.Type.ConsoleProxy)) { - ConsoleProxyVO consoleProxy = _consoleProxyDao.findById(vmInstance.getId()); - vmMgr.advanceStart(consoleProxy.getUuid(), null); + ConsoleProxyVO consoleProxy = _consoleProxyDao + .findById(vmInstance.getId()); + vmMgr.advanceStart(consoleProxy.getUuid(), null, null); // update work queue work.setStartedAfterMaintenance(true); _storagePoolWorkDao.update(work.getId(), work); } // if the instance is of type ssvm, call the ssvm manager - if (vmInstance.getType().equals(VirtualMachine.Type.SecondaryStorageVm)) { - SecondaryStorageVmVO ssVm = _secStrgDao.findById(vmInstance.getId()); - vmMgr.advanceStart(ssVm.getUuid(), null); + if (vmInstance.getType().equals( + VirtualMachine.Type.SecondaryStorageVm)) { + SecondaryStorageVmVO ssVm = _secStrgDao.findById(vmInstance + .getId()); + vmMgr.advanceStart(ssVm.getUuid(), null, null); + // update work queue work.setStartedAfterMaintenance(true); _storagePoolWorkDao.update(work.getId(), work); @@ -349,7 +353,7 @@ public class StoragePoolAutomationImpl implements StoragePoolAutomation { // if the instance is of type ssvm, call the ssvm manager if (vmInstance.getType().equals(VirtualMachine.Type.DomainRouter)) { DomainRouterVO domR = _domrDao.findById(vmInstance.getId()); - vmMgr.advanceStart(domR.getUuid(), null); + vmMgr.advanceStart(domR.getUuid(), null, null); // update work queue work.setStartedAfterMaintenance(true); _storagePoolWorkDao.update(work.getId(), work); @@ -359,7 +363,7 @@ public class StoragePoolAutomationImpl implements StoragePoolAutomation { if (vmInstance.getType().equals(VirtualMachine.Type.User)) { UserVmVO userVm = userVmDao.findById(vmInstance.getId()); - vmMgr.advanceStart(userVm.getUuid(), null); // update work queue + vmMgr.advanceStart(userVm.getUuid(), null, null); // update work queue work.setStartedAfterMaintenance(true); _storagePoolWorkDao.update(work.getId(), work); } diff --git a/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java b/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java index 8decfd223b5..99de391f231 100755 --- a/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java +++ b/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java @@ -258,7 +258,7 @@ public class SecondaryStorageManagerImpl extends ManagerBase implements Secondar public SecondaryStorageVmVO startSecStorageVm(long secStorageVmId) { try { SecondaryStorageVmVO secStorageVm = _secStorageVmDao.findById(secStorageVmId); - _itMgr.advanceStart(secStorageVm.getUuid(), null); + _itMgr.advanceStart(secStorageVm.getUuid(), null, null); return _secStorageVmDao.findById(secStorageVm.getId()); } catch (StorageUnavailableException e) { s_logger.warn("Exception while trying to start secondary storage vm", e); diff --git a/server/src/com/cloud/vm/snapshot/VMSnapshotManagerImpl.java b/server/src/com/cloud/vm/snapshot/VMSnapshotManagerImpl.java index ece75be5750..93c845a9d26 100644 --- a/server/src/com/cloud/vm/snapshot/VMSnapshotManagerImpl.java +++ b/server/src/com/cloud/vm/snapshot/VMSnapshotManagerImpl.java @@ -429,7 +429,7 @@ public class VMSnapshotManagerImpl extends ManagerBase implements VMSnapshotMana // start or stop VM first, if revert from stopped state to running state, or from running to stopped if (userVm.getState() == VirtualMachine.State.Stopped && vmSnapshotVo.getType() == VMSnapshot.Type.DiskAndMemory) { try { - _itMgr.advanceStart(userVm.getUuid(), new HashMap()); + _itMgr.advanceStart(userVm.getUuid(), new HashMap(), null); vm = _userVMDao.findById(userVm.getId()); hostId = vm.getHostId(); } catch (Exception e) { diff --git a/server/test/com/cloud/vm/DeploymentPlanningManagerImplTest.java b/server/test/com/cloud/vm/DeploymentPlanningManagerImplTest.java index 0d82ff22c15..751a3bdd43f 100644 --- a/server/test/com/cloud/vm/DeploymentPlanningManagerImplTest.java +++ b/server/test/com/cloud/vm/DeploymentPlanningManagerImplTest.java @@ -168,7 +168,7 @@ public class DeploymentPlanningManagerImplTest { DataCenterDeployment plan = new DataCenterDeployment(dataCenterId); Mockito.when(avoids.shouldAvoid((DataCenterVO)Matchers.anyObject())).thenReturn(true); - DeployDestination dest = _dpm.planDeployment(vmProfile, plan, avoids); + DeployDestination dest = _dpm.planDeployment(vmProfile, plan, avoids, null); assertNull("DataCenter is in avoid set, destination should be null! ", dest); } @@ -183,7 +183,7 @@ public class DeploymentPlanningManagerImplTest { Mockito.when(avoids.shouldAvoid((DataCenterVO)Matchers.anyObject())).thenReturn(false); Mockito.when(_planner.canHandle(vmProfile, plan, avoids)).thenReturn(false); - DeployDestination dest = _dpm.planDeployment(vmProfile, plan, avoids); + DeployDestination dest = _dpm.planDeployment(vmProfile, plan, avoids, null); assertNull("Planner cannot handle, destination should be null! ", dest); } @@ -199,7 +199,7 @@ public class DeploymentPlanningManagerImplTest { Mockito.when(_planner.canHandle(vmProfile, plan, avoids)).thenReturn(true); Mockito.when(((DeploymentClusterPlanner)_planner).orderClusters(vmProfile, plan, avoids)).thenReturn(null); - DeployDestination dest = _dpm.planDeployment(vmProfile, plan, avoids); + DeployDestination dest = _dpm.planDeployment(vmProfile, plan, avoids, null); assertNull("Planner cannot handle, destination should be null! ", dest); }