diff --git a/client/pom.xml b/client/pom.xml index 32a547187a4..0ee1114949b 100644 --- a/client/pom.xml +++ b/client/pom.xml @@ -145,6 +145,11 @@ cloud-plugin-planner-user-dispersing ${project.version} + + org.apache.cloudstack + cloud-plugin-planner-ha + ${project.version} + org.apache.cloudstack cloud-plugin-planner-user-concentrated-pod diff --git a/client/tomcatconf/applicationContext.xml.in b/client/tomcatconf/applicationContext.xml.in index 4fb13c056fc..2cf97607fb6 100644 --- a/client/tomcatconf/applicationContext.xml.in +++ b/client/tomcatconf/applicationContext.xml.in @@ -720,6 +720,10 @@ + + + + @@ -728,6 +732,7 @@ + diff --git a/client/tomcatconf/componentContext.xml.in b/client/tomcatconf/componentContext.xml.in index 09b2261ab38..dbacb4b9439 100644 --- a/client/tomcatconf/componentContext.xml.in +++ b/client/tomcatconf/componentContext.xml.in @@ -189,6 +189,15 @@ + + + + + + + + + diff --git a/client/tomcatconf/nonossComponentContext.xml.in b/client/tomcatconf/nonossComponentContext.xml.in index 17cf99c8f2f..a9aba7ef554 100644 --- a/client/tomcatconf/nonossComponentContext.xml.in +++ b/client/tomcatconf/nonossComponentContext.xml.in @@ -289,6 +289,15 @@ + + + + + + + + + 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 ffb7dc59473..2b713b71faa 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 @@ -184,7 +184,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/deployment-planners/ha/pom.xml b/plugins/deployment-planners/ha/pom.xml new file mode 100644 index 00000000000..27bb750f769 --- /dev/null +++ b/plugins/deployment-planners/ha/pom.xml @@ -0,0 +1,29 @@ + + + 4.0.0 + cloud-plugin-planner-ha + Apache CloudStack Plugin - HA Planner + + org.apache.cloudstack + cloudstack-plugins + 4.2.1-SNAPSHOT + ../../pom.xml + + diff --git a/plugins/deployment-planners/ha/src/com/cloud/deploy/HAPlanner.java b/plugins/deployment-planners/ha/src/com/cloud/deploy/HAPlanner.java new file mode 100644 index 00000000000..d6278c5ab0c --- /dev/null +++ b/plugins/deployment-planners/ha/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 { +} diff --git a/plugins/deployment-planners/ha/src/com/cloud/deploy/SkipHeuresticsPlanner.java b/plugins/deployment-planners/ha/src/com/cloud/deploy/SkipHeuresticsPlanner.java new file mode 100644 index 00000000000..4669df58baf --- /dev/null +++ b/plugins/deployment-planners/ha/src/com/cloud/deploy/SkipHeuresticsPlanner.java @@ -0,0 +1,64 @@ +// 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.deploy.DeploymentPlan; +import com.cloud.deploy.FirstFitPlanner; +import com.cloud.deploy.HAPlanner; +import com.cloud.vm.VirtualMachine; +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; + + } + +} diff --git a/plugins/pom.xml b/plugins/pom.xml index db5e4f6845b..55d42971adc 100755 --- a/plugins/pom.xml +++ b/plugins/pom.xml @@ -40,6 +40,7 @@ deployment-planners/user-concentrated-pod deployment-planners/user-dispersing deployment-planners/implicit-dedication + deployment-planners/ha host-allocators/random dedicated-resources hypervisors/ovm diff --git a/server/src/com/cloud/deploy/DeploymentPlanningManager.java b/server/src/com/cloud/deploy/DeploymentPlanningManager.java index 9458df2946f..b16961b6f0a 100644 --- a/server/src/com/cloud/deploy/DeploymentPlanningManager.java +++ b/server/src/com/cloud/deploy/DeploymentPlanningManager.java @@ -41,7 +41,7 @@ public interface DeploymentPlanningManager extends Manager { * */ DeployDestination planDeployment(VirtualMachineProfile vmProfile, DeploymentPlan plan, - ExcludeList avoids) throws InsufficientServerCapacityException, AffinityConflictException; + ExcludeList avoids, DeploymentPlanner planner) throws InsufficientServerCapacityException, AffinityConflictException; String finalizeReservation(DeployDestination plannedDestination, VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoids) diff --git a/server/src/com/cloud/deploy/DeploymentPlanningManagerImpl.java b/server/src/com/cloud/deploy/DeploymentPlanningManagerImpl.java index 23622dc5e84..4c41cbb7b27 100644 --- a/server/src/com/cloud/deploy/DeploymentPlanningManagerImpl.java +++ b/server/src/com/cloud/deploy/DeploymentPlanningManagerImpl.java @@ -31,7 +31,7 @@ import javax.naming.ConfigurationException; import org.apache.cloudstack.affinity.AffinityGroupProcessor; import org.apache.cloudstack.affinity.AffinityGroupService; -import org.apache.cloudstack.affinity.AffinityGroupVMMapVO; +import org.apache.cloudstack.affinity.AffinityGroupVMMapVO; import org.apache.cloudstack.affinity.AffinityGroupVO; import org.apache.cloudstack.affinity.dao.AffinityGroupDao; import org.apache.cloudstack.affinity.dao.AffinityGroupVMMapDao; @@ -56,11 +56,11 @@ import com.cloud.dc.ClusterDetailsVO; import com.cloud.dc.ClusterVO; import com.cloud.dc.DataCenter; import com.cloud.dc.DataCenterVO; -import com.cloud.dc.DedicatedResourceVO; +import com.cloud.dc.DedicatedResourceVO; import com.cloud.dc.Pod; import com.cloud.dc.dao.ClusterDao; import com.cloud.dc.dao.DataCenterDao; -import com.cloud.dc.dao.DedicatedResourceDao; +import com.cloud.dc.dao.DedicatedResourceDao; import com.cloud.dc.dao.HostPodDao; import com.cloud.deploy.DeploymentPlanner.ExcludeList; import com.cloud.deploy.DeploymentPlanner.PlannerResourceUsage; @@ -68,7 +68,6 @@ import com.cloud.deploy.dao.PlannerHostReservationDao; import com.cloud.exception.AffinityConflictException; import com.cloud.exception.ConnectionException; import com.cloud.exception.InsufficientServerCapacityException; -import com.cloud.exception.PermissionDeniedException; import com.cloud.host.Host; import com.cloud.host.HostVO; import com.cloud.host.Status; @@ -99,7 +98,7 @@ import com.cloud.utils.component.ManagerBase; import com.cloud.utils.db.DB; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.Transaction; -import com.cloud.utils.exception.CloudRuntimeException; +import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.fsm.StateListener; import com.cloud.vm.DiskProfile; import com.cloud.vm.ReservationContext; @@ -173,7 +172,7 @@ public class DeploymentPlanningManagerImpl extends ManagerBase implements Deploy @Inject protected HostDao _hostDao; @Inject protected HostPodDao _podDao; @Inject protected ClusterDao _clusterDao; - @Inject protected DedicatedResourceDao _dedicatedDao; + @Inject protected DedicatedResourceDao _dedicatedDao; @Inject protected GuestOSDao _guestOSDao = null; @Inject protected GuestOSCategoryDao _guestOSCategoryDao = null; @Inject protected DiskOfferingDao _diskOfferingDao; @@ -207,13 +206,13 @@ public class DeploymentPlanningManagerImpl extends ManagerBase implements Deploy @Override public DeployDestination planDeployment(VirtualMachineProfile vmProfile, - DeploymentPlan plan, ExcludeList avoids) throws InsufficientServerCapacityException, + DeploymentPlan plan, ExcludeList avoids, DeploymentPlanner planner) throws InsufficientServerCapacityException, AffinityConflictException { // call affinitygroup chain VirtualMachine vm = vmProfile.getVirtualMachine(); long vmGroupCount = _affinityGroupVMMapDao.countAffinityGroupsForVm(vm.getId()); - DataCenter dc = _dcDao.findById(vm.getDataCenterId()); + DataCenter dc = _dcDao.findById(vm.getDataCenterId()); if (vmGroupCount > 0) { for (AffinityGroupProcessor processor : _affinityProcessors) { @@ -223,14 +222,14 @@ public class DeploymentPlanningManagerImpl extends ManagerBase implements Deploy if (vm.getType() == VirtualMachine.Type.User) { checkForNonDedicatedResources(vmProfile, dc, avoids); - } + } if (s_logger.isDebugEnabled()) { s_logger.debug("Deploy avoids pods: " + avoids.getPodsToAvoid() + ", clusters: " + avoids.getClustersToAvoid() + ", hosts: " + avoids.getHostsToAvoid()); } // call planners - //DataCenter dc = _dcDao.findById(vm.getDataCenterId()); + //DataCenter dc = _dcDao.findById(vm.getDataCenterId()); // check if datacenter is in avoid set if (avoids.shouldAvoid(dc)) { if (s_logger.isDebugEnabled()) { @@ -242,19 +241,21 @@ 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; + } } } @@ -305,7 +306,7 @@ public class DeploymentPlanningManagerImpl extends ManagerBase implements Deploy List suitableHosts = new ArrayList(); suitableHosts.add(host); Pair> potentialResources = findPotentialDeploymentResources( - suitableHosts, suitableVolumeStoragePools, avoids, getPlannerUsage(planner,vmProfile, plan ,avoids)); + suitableHosts, suitableVolumeStoragePools, avoids, getPlannerUsage(planner,vmProfile, plan ,avoids)); if (potentialResources != null) { Pod pod = _podDao.findById(host.getPodId()); Cluster cluster = _clusterDao.findById(host.getClusterId()); @@ -359,13 +360,13 @@ public class DeploymentPlanningManagerImpl extends ManagerBase implements Deploy vmProfile, lastPlan, avoids, HostAllocator.RETURN_UPTO_ALL); Map> suitableVolumeStoragePools = result.first(); List readyAndReusedVolumes = result.second(); - + // choose the potential pool for this VM for this host if (!suitableVolumeStoragePools.isEmpty()) { List suitableHosts = new ArrayList(); suitableHosts.add(host); Pair> potentialResources = findPotentialDeploymentResources( - suitableHosts, suitableVolumeStoragePools, avoids, getPlannerUsage(planner,vmProfile, plan ,avoids)); + suitableHosts, suitableVolumeStoragePools, avoids, getPlannerUsage(planner,vmProfile, plan ,avoids)); if (potentialResources != null) { Pod pod = _podDao.findById(host.getPodId()); Cluster cluster = _clusterDao.findById(host.getClusterId()); @@ -415,7 +416,7 @@ public class DeploymentPlanningManagerImpl extends ManagerBase implements Deploy resetAvoidSet(plannerAvoidOutput, plannerAvoidInput); dest = checkClustersforDestination(clusterList, vmProfile, plan, avoids, dc, - getPlannerUsage(planner, vmProfile, plan, avoids), plannerAvoidOutput); + getPlannerUsage(planner, vmProfile, plan, avoids), plannerAvoidOutput); if (dest != null) { return dest; } @@ -450,7 +451,7 @@ public class DeploymentPlanningManagerImpl extends ManagerBase implements Deploy return dest; } - private void checkForNonDedicatedResources(VirtualMachineProfile vmProfile, DataCenter dc, ExcludeList avoids) { + private void checkForNonDedicatedResources(VirtualMachineProfile vmProfile, DataCenter dc, ExcludeList avoids) { boolean isExplicit = false; VirtualMachine vm = vmProfile.getVirtualMachine(); @@ -485,16 +486,16 @@ public class DeploymentPlanningManagerImpl extends ManagerBase implements Deploy } // check affinity group of type Explicit dedication exists. If No put - // dedicated pod/cluster/host in avoid list - List vmGroupMappings = _affinityGroupVMMapDao.findByVmIdType(vm.getId(), "ExplicitDedication"); - - if (vmGroupMappings != null && !vmGroupMappings.isEmpty()){ - isExplicit = true; - } - - if (!isExplicit) { - //add explicitly dedicated resources in avoidList - + // dedicated pod/cluster/host in avoid list + List vmGroupMappings = _affinityGroupVMMapDao.findByVmIdType(vm.getId(), "ExplicitDedication"); + + if (vmGroupMappings != null && !vmGroupMappings.isEmpty()){ + isExplicit = true; + } + + if (!isExplicit) { + //add explicitly dedicated resources in avoidList + List allPodsInDc = _podDao.listAllPods(dc.getId()); List allDedicatedPods = _dedicatedDao.listAllPods(); allPodsInDc.retainAll(allDedicatedPods); @@ -508,10 +509,10 @@ public class DeploymentPlanningManagerImpl extends ManagerBase implements Deploy List allHostsInDc = _hostDao.listAllHosts(dc.getId()); List allDedicatedHosts = _dedicatedDao.listAllHosts(); allHostsInDc.retainAll(allDedicatedHosts); - avoids.addHostList(allHostsInDc); - } - } - + avoids.addHostList(allHostsInDc); + } + } + private void resetAvoidSet(ExcludeList avoidSet, ExcludeList removeSet) { if (avoidSet.getDataCentersToAvoid() != null && removeSet.getDataCentersToAvoid() != null) { avoidSet.getDataCentersToAvoid().removeAll(removeSet.getDataCentersToAvoid()); @@ -530,9 +531,9 @@ public class DeploymentPlanningManagerImpl extends ManagerBase implements Deploy } } - private PlannerResourceUsage getPlannerUsage(DeploymentPlanner planner, VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoids) throws InsufficientServerCapacityException { + private PlannerResourceUsage getPlannerUsage(DeploymentPlanner planner, VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoids) throws InsufficientServerCapacityException { if (planner != null && planner instanceof DeploymentClusterPlanner) { - return ((DeploymentClusterPlanner) planner).getResourceUsage(vmProfile, plan, avoids); + return ((DeploymentClusterPlanner) planner).getResourceUsage(vmProfile, plan, avoids); } else { return DeploymentPlanner.PlannerResourceUsage.Shared; } diff --git a/server/src/com/cloud/deploy/FirstFitPlanner.java b/server/src/com/cloud/deploy/FirstFitPlanner.java index 7124de28d7b..16924cc3ffb 100755 --- a/server/src/com/cloud/deploy/FirstFitPlanner.java +++ b/server/src/com/cloud/deploy/FirstFitPlanner.java @@ -263,7 +263,12 @@ public class FirstFitPlanner extends PlannerBase implements DeploymentClusterPla return capacityList; } - private void removeClustersCrossingThreshold(List clusterListForVmAllocation, ExcludeList avoid, + /** + * This method should remove the clusters crossing capacity threshold + * to avoid further vm allocation on it + * + */ + protected void removeClustersCrossingThreshold(List clusterListForVmAllocation, ExcludeList avoid, VirtualMachineProfile vmProfile, DeploymentPlan plan) { List capacityList = getCapacitiesForCheckingThreshold(); diff --git a/server/src/com/cloud/ha/HighAvailabilityManagerImpl.java b/server/src/com/cloud/ha/HighAvailabilityManagerImpl.java index 061304e9820..d3cf1485483 100755 --- a/server/src/com/cloud/ha/HighAvailabilityManagerImpl.java +++ b/server/src/com/cloud/ha/HighAvailabilityManagerImpl.java @@ -29,6 +29,7 @@ import javax.ejb.Local; import javax.inject.Inject; import javax.naming.ConfigurationException; +import com.cloud.deploy.HAPlanner; import org.apache.log4j.Logger; import org.apache.log4j.NDC; @@ -132,6 +133,14 @@ 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 @@ -530,8 +539,18 @@ public class HighAvailabilityManagerImpl extends ManagerBase implements HighAvai if (_haTag != null) { params.put(VirtualMachineProfile.Param.HaTag, _haTag); } - VMInstanceVO started = _itMgr.advanceStart(vm, params, _accountMgr.getSystemUser(), _accountMgr.getSystemAccount()); + // First try starting the vm with its original planner, if it doesn't succeed send HAPlanner as its an emergency. + VMInstanceVO started = null; + try{ + started = _itMgr.advanceStart(vm, params, _accountMgr.getSystemUser(), _accountMgr.getSystemAccount(), null); + }finally { + // Send HAPlanner. + if(started == null){ + s_logger.warn("Failed to deploy vm " + vmId + " with original planner, sending HAPlanner"); + started = _itMgr.advanceStart(vm, params, _accountMgr.getSystemUser(), _accountMgr.getSystemAccount(), _haPlanners.get(0)); + } + } if (started != null) { s_logger.info("VM is now restarted: " + vmId + " on " + started.getHostId()); return null; @@ -571,11 +590,21 @@ public class HighAvailabilityManagerImpl extends ManagerBase implements HighAvai work.setStep(Step.Migrating); _haDao.update(work.getId(), work); - if (!_itMgr.migrateAway(work.getType(), vmId, srcHostId)) { - s_logger.warn("Unable to migrate vm from " + srcHostId); - _resourceMgr.maintenanceFailed(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 { + result = _itMgr.migrateAway(work.getType(), vmId, srcHostId, null); + }finally{ + if(!result){ + s_logger.warn("Failed to deploy vm " + vmId + " with original planner, sending HAPlanner"); + if (!_itMgr.migrateAway(work.getType(), vmId, srcHostId, _haPlanners.get(0))) { + s_logger.warn("Unable to migrate vm from " + srcHostId); + _resourceMgr.maintenanceFailed(srcHostId); + } + } + return null; } - return null; + } catch (InsufficientServerCapacityException e) { s_logger.warn("Insufficient capacity for migrating a VM."); _resourceMgr.maintenanceFailed(srcHostId); diff --git a/server/src/com/cloud/storage/StoragePoolAutomationImpl.java b/server/src/com/cloud/storage/StoragePoolAutomationImpl.java index f6b39f1fe47..972128348e5 100644 --- a/server/src/com/cloud/storage/StoragePoolAutomationImpl.java +++ b/server/src/com/cloud/storage/StoragePoolAutomationImpl.java @@ -33,10 +33,8 @@ import com.cloud.agent.AgentManager; import com.cloud.agent.api.Answer; import com.cloud.agent.api.ModifyStoragePoolCommand; import com.cloud.alert.AlertManager; -import com.cloud.host.Host; import com.cloud.host.HostVO; import com.cloud.host.Status; -import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.resource.ResourceManager; import com.cloud.server.ManagementServer; import com.cloud.storage.dao.StoragePoolHostDao; @@ -250,7 +248,7 @@ public class StoragePoolAutomationImpl implements StoragePoolAutomation { if (restart) { if (this.vmMgr.advanceStart(consoleProxy, null, user, - account) == null) { + account, null) == null) { String errorMsg = "There was an error starting the console proxy id: " + vmInstance.getId() + " on another storage pool, cannot enable primary storage maintenance"; @@ -298,7 +296,7 @@ public class StoragePoolAutomationImpl implements StoragePoolAutomation { } if (restart) { - if (vmMgr.advanceStart(secStrgVm, null, user, account) == null) { + if (vmMgr.advanceStart(secStrgVm, null, user, account, null) == null) { String errorMsg = "There was an error starting the ssvm id: " + vmInstance.getId() + " on another storage pool, cannot enable primary storage maintenance"; @@ -329,7 +327,7 @@ public class StoragePoolAutomationImpl implements StoragePoolAutomation { } if (restart) { - if (vmMgr.advanceStart(domR, null, user, account) == null) { + if (vmMgr.advanceStart(domR, null, user, account, null) == null) { String errorMsg = "There was an error starting the domain router id: " + vmInstance.getId() + " on another storage pool, cannot enable primary storage maintenance"; @@ -413,7 +411,7 @@ public class StoragePoolAutomationImpl implements StoragePoolAutomation { ConsoleProxyVO consoleProxy = _consoleProxyDao .findById(vmInstance.getId()); - if (vmMgr.advanceStart(consoleProxy, null, user, account) == null) { + if (vmMgr.advanceStart(consoleProxy, null, user, account, null) == null) { String msg = "There was an error starting the console proxy id: " + vmInstance.getId() + " on storage pool, cannot complete primary storage maintenance"; @@ -431,7 +429,7 @@ public class StoragePoolAutomationImpl implements StoragePoolAutomation { VirtualMachine.Type.SecondaryStorageVm)) { SecondaryStorageVmVO ssVm = _secStrgDao.findById(vmInstance .getId()); - if (vmMgr.advanceStart(ssVm, null, user, account) == null) { + if (vmMgr.advanceStart(ssVm, null, user, account, null) == null) { String msg = "There was an error starting the ssvm id: " + vmInstance.getId() + " on storage pool, cannot complete primary storage maintenance"; @@ -448,7 +446,7 @@ public class StoragePoolAutomationImpl implements StoragePoolAutomation { if (vmInstance.getType().equals( VirtualMachine.Type.DomainRouter)) { DomainRouterVO domR = _domrDao.findById(vmInstance.getId()); - if (vmMgr.advanceStart(domR, null, user, account) == null) { + if (vmMgr.advanceStart(domR, null, user, account, null) == null) { String msg = "There was an error starting the domR id: " + vmInstance.getId() + " on storage pool, cannot complete primary storage maintenance"; @@ -465,7 +463,7 @@ public class StoragePoolAutomationImpl implements StoragePoolAutomation { if (vmInstance.getType().equals(VirtualMachine.Type.User)) { UserVmVO userVm = userVmDao.findById(vmInstance.getId()); - if (vmMgr.advanceStart(userVm, null, user, account) == null) { + if (vmMgr.advanceStart(userVm, null, user, account, null) == null) { String msg = "There was an error starting the user vm id: " + vmInstance.getId() diff --git a/server/src/com/cloud/vm/VirtualMachineManager.java b/server/src/com/cloud/vm/VirtualMachineManager.java index 6320956b9b3..88d03fd716c 100644 --- a/server/src/com/cloud/vm/VirtualMachineManager.java +++ b/server/src/com/cloud/vm/VirtualMachineManager.java @@ -96,9 +96,9 @@ public interface VirtualMachineManager extends Manager { boolean stateTransitTo(VMInstanceVO vm, VirtualMachine.Event e, Long hostId) throws NoTransitionException; - T advanceStart(T vm, Map params, User caller, Account account) throws InsufficientCapacityException, ResourceUnavailableException, ConcurrentOperationException, OperationTimedoutException; + T advanceStart(T vm, Map params, User caller, Account account, DeploymentPlanner planner) throws InsufficientCapacityException, ResourceUnavailableException, ConcurrentOperationException, OperationTimedoutException; - T advanceStart(T vm, Map params, User caller, Account account, DeploymentPlan planToDeploy) throws InsufficientCapacityException, ResourceUnavailableException, ConcurrentOperationException, OperationTimedoutException; + T advanceStart(T vm, Map params, User caller, Account account, DeploymentPlan planToDeploy, DeploymentPlanner planner) throws InsufficientCapacityException, ResourceUnavailableException, ConcurrentOperationException, OperationTimedoutException; boolean advanceStop(T vm, boolean forced, User caller, Account account) throws ResourceUnavailableException, OperationTimedoutException, ConcurrentOperationException; @@ -108,7 +108,7 @@ public interface VirtualMachineManager extends Manager { boolean destroy(T vm, User caller, Account account) throws AgentUnavailableException, OperationTimedoutException, ConcurrentOperationException; - boolean migrateAway(VirtualMachine.Type type, long vmid, long hostId) throws InsufficientServerCapacityException, VirtualMachineMigrationException; + boolean migrateAway(VirtualMachine.Type type, long vmid, long hostId, DeploymentPlanner planner) throws InsufficientServerCapacityException, VirtualMachineMigrationException; T migrate(T vm, long srcHostId, DeployDestination dest) throws ResourceUnavailableException, ConcurrentOperationException, ManagementServerException, VirtualMachineMigrationException; diff --git a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java index d46bbb0b319..31a45e610c3 100755 --- a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java +++ b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java @@ -74,7 +74,6 @@ import com.cloud.agent.api.StopCommand; import com.cloud.agent.api.to.DiskTO; import com.cloud.agent.api.to.NicTO; import com.cloud.agent.api.to.VirtualMachineTO; -import com.cloud.agent.api.to.VolumeTO; import com.cloud.agent.manager.Commands; import com.cloud.agent.manager.allocator.HostAllocator; import com.cloud.alert.AlertManager; @@ -575,7 +574,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac public T start(T vm, Map params, User caller, Account account, DeploymentPlan planToDeploy) throws InsufficientCapacityException, ResourceUnavailableException { try { - return advanceStart(vm, params, caller, account, planToDeploy); + return advanceStart(vm, params, caller, account, planToDeploy, null); } catch (ConcurrentOperationException e) { throw new CloudRuntimeException("Unable to start a VM due to concurrent operation", e); } @@ -708,13 +707,13 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac } @Override - public T advanceStart(T vm, Map params, User caller, Account account) throws InsufficientCapacityException, + public T advanceStart(T vm, Map params, User caller, Account account, DeploymentPlanner planner) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException { - return advanceStart(vm, params, caller, account, null); + return advanceStart(vm, params, caller, account, null, planner); } @Override - public T advanceStart(T vm, Map params, User caller, Account account, DeploymentPlan planToDeploy) + public T advanceStart(T vm, Map params, User caller, Account account, DeploymentPlan planToDeploy, DeploymentPlanner planner) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException { long vmId = vm.getId(); VirtualMachineGuru vmGuru = getVmGuru(vm); @@ -823,7 +822,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac VirtualMachineProfileImpl vmProfile = new VirtualMachineProfileImpl(vm, template, offering, account, 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( @@ -1876,7 +1875,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac } @Override - public boolean migrateAway(VirtualMachine.Type vmType, long vmId, long srcHostId) throws InsufficientServerCapacityException, VirtualMachineMigrationException { + public boolean migrateAway(VirtualMachine.Type vmType, long vmId, long srcHostId, DeploymentPlanner planner) throws InsufficientServerCapacityException, VirtualMachineMigrationException { VirtualMachineGuru vmGuru = _vmGurus.get(vmType); VMInstanceVO vm = vmGuru.findById(vmId); if (vm == null) { @@ -1902,7 +1901,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( @@ -3156,7 +3155,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( diff --git a/server/src/com/cloud/vm/snapshot/VMSnapshotManagerImpl.java b/server/src/com/cloud/vm/snapshot/VMSnapshotManagerImpl.java index ce4626908ba..8e277165a41 100644 --- a/server/src/com/cloud/vm/snapshot/VMSnapshotManagerImpl.java +++ b/server/src/com/cloud/vm/snapshot/VMSnapshotManagerImpl.java @@ -713,7 +713,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 { - vm = _itMgr.advanceStart(userVm, new HashMap(), callerUser, owner); + vm = _itMgr.advanceStart(userVm, new HashMap(), callerUser, owner, null); hostId = vm.getHostId(); } catch (Exception e) { s_logger.error("Start VM " + userVm.getInstanceName() + " before reverting failed due to " + e.getMessage()); diff --git a/server/test/com/cloud/vm/DeploymentPlanningManagerImplTest.java b/server/test/com/cloud/vm/DeploymentPlanningManagerImplTest.java index fbfeecc81df..7572f0e777a 100644 --- a/server/test/com/cloud/vm/DeploymentPlanningManagerImplTest.java +++ b/server/test/com/cloud/vm/DeploymentPlanningManagerImplTest.java @@ -40,7 +40,7 @@ import com.cloud.dc.ClusterVO; import com.cloud.dc.DataCenterVO; import com.cloud.dc.dao.ClusterDao; import com.cloud.dc.dao.DataCenterDao; -import com.cloud.dc.dao.DedicatedResourceDao; +import com.cloud.dc.dao.DedicatedResourceDao; import com.cloud.dc.dao.HostPodDao; import com.cloud.deploy.DataCenterDeployment; import com.cloud.deploy.DeployDestination; @@ -116,9 +116,9 @@ public class DeploymentPlanningManagerImplTest { @Inject ClusterDao _clusterDao; - @Inject - DedicatedResourceDao _dedicatedDao; - + @Inject + DedicatedResourceDao _dedicatedDao; + private static long domainId = 5L; private static long dataCenterId = 1L; @@ -163,7 +163,7 @@ public class DeploymentPlanningManagerImplTest { DataCenterDeployment plan = new DataCenterDeployment(dataCenterId); Mockito.when(avoids.shouldAvoid((DataCenterVO) Mockito.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); } @@ -178,7 +178,7 @@ public class DeploymentPlanningManagerImplTest { Mockito.when(avoids.shouldAvoid((DataCenterVO) Mockito.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); } @@ -193,7 +193,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); } @@ -258,11 +258,11 @@ public class DeploymentPlanningManagerImplTest { } @Bean - public DedicatedResourceDao dedicatedResourceDao() { - return Mockito.mock(DedicatedResourceDao.class); - } - - @Bean + public DedicatedResourceDao dedicatedResourceDao() { + return Mockito.mock(DedicatedResourceDao.class); + } + + @Bean public GuestOSDao guestOSDao() { return Mockito.mock(GuestOSDao.class); } diff --git a/server/test/com/cloud/vm/MockVirtualMachineManagerImpl.java b/server/test/com/cloud/vm/MockVirtualMachineManagerImpl.java index 14ef48b1118..7dd30d7a749 100755 --- a/server/test/com/cloud/vm/MockVirtualMachineManagerImpl.java +++ b/server/test/com/cloud/vm/MockVirtualMachineManagerImpl.java @@ -133,7 +133,7 @@ public class MockVirtualMachineManagerImpl extends ManagerBase implements Virtua } @Override - public boolean migrateAway(Type type, long vmid, long hostId) throws InsufficientServerCapacityException, VirtualMachineMigrationException { + public boolean migrateAway(Type type, long vmid, long hostId, DeploymentPlanner planner) throws InsufficientServerCapacityException, VirtualMachineMigrationException { // TODO Auto-generated method stub return false; } @@ -201,14 +201,14 @@ public class MockVirtualMachineManagerImpl extends ManagerBase implements Virtua } @Override - public T advanceStart(T vm, Map params, User caller, Account account) throws InsufficientCapacityException, ResourceUnavailableException, + public T advanceStart(T vm, Map params, User caller, Account account, DeploymentPlanner planner) throws InsufficientCapacityException, ResourceUnavailableException, ConcurrentOperationException, OperationTimedoutException { // TODO Auto-generated method stub return null; } @Override - public T advanceStart(T vm, Map params, User caller, Account account, DeploymentPlan planToDeploy) throws InsufficientCapacityException, + public T advanceStart(T vm, Map params, User caller, Account account, DeploymentPlan planToDeploy, DeploymentPlanner planner) throws InsufficientCapacityException, ResourceUnavailableException, ConcurrentOperationException, OperationTimedoutException { // TODO Auto-generated method stub return null;