CLOUDSTACK-4941:

During HA and maintenance call different planners (if the original planners are not able to find capacity) which skip some heurestics
This commit is contained in:
Nitin Mehta 2013-12-18 14:58:37 -08:00
parent 5fb80f90f0
commit 231e7c01f2
22 changed files with 275 additions and 56 deletions

View File

@ -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 {
}

View File

@ -176,6 +176,11 @@
<artifactId>cloud-plugin-planner-user-dispersing</artifactId> <artifactId>cloud-plugin-planner-user-dispersing</artifactId>
<version>${project.version}</version> <version>${project.version}</version>
</dependency> </dependency>
<dependency>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-plugin-planner-skip-heurestics</artifactId>
<version>${project.version}</version>
</dependency>
<dependency> <dependency>
<groupId>org.apache.cloudstack</groupId> <groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-plugin-planner-user-concentrated-pod</artifactId> <artifactId>cloud-plugin-planner-user-concentrated-pod</artifactId>

View File

@ -77,6 +77,11 @@
<property name="excludeKey" value="deployment.planners.exclude" /> <property name="excludeKey" value="deployment.planners.exclude" />
</bean> </bean>
<bean id="haPlannersRegistry"
class="org.apache.cloudstack.spring.lifecycle.registry.ExtensionRegistry">
<property name="excludeKey" value="ha.planners.exclude" />
</bean>
<bean id="podAllocatorsRegistry" <bean id="podAllocatorsRegistry"
class="org.apache.cloudstack.spring.lifecycle.registry.ExtensionRegistry"> class="org.apache.cloudstack.spring.lifecycle.registry.ExtensionRegistry">
<property name="excludeKey" value="pod.allocators.exclude" /> <property name="excludeKey" value="pod.allocators.exclude" />

View File

@ -38,4 +38,9 @@
value="org.apache.cloudstack.affinity.AffinityGroupProcessor" /> value="org.apache.cloudstack.affinity.AffinityGroupProcessor" />
</bean> </bean>
<bean class="org.apache.cloudstack.spring.lifecycle.registry.RegistryLifecycle">
<property name="registry" ref="haPlannersRegistry" />
<property name="typeClass" value="com.cloud.deploy.HAPlanner" />
</bean>
</beans> </beans>

View File

@ -93,10 +93,13 @@ public interface VirtualMachineManager extends Manager {
boolean stateTransitTo(VirtualMachine vm, VirtualMachine.Event e, Long hostId) throws NoTransitionException; boolean stateTransitTo(VirtualMachine vm, VirtualMachine.Event e, Long hostId) throws NoTransitionException;
void advanceStart(String vmUuid, Map<VirtualMachineProfile.Param, Object> params) throws InsufficientCapacityException, ResourceUnavailableException, void advanceStart(String vmUuid, Map<VirtualMachineProfile.Param, Object> params, DeploymentPlanner planner) throws InsufficientCapacityException, ResourceUnavailableException,
ConcurrentOperationException, OperationTimedoutException; ConcurrentOperationException, OperationTimedoutException;
void advanceStart(String vmUuid, Map<VirtualMachineProfile.Param, Object> params, DeploymentPlan planToDeploy) throws InsufficientCapacityException, void advanceStart(String vmUuid, Map<VirtualMachineProfile.Param, Object> params, DeploymentPlan planToDeploy, DeploymentPlanner planner) throws InsufficientCapacityException,
ResourceUnavailableException, ConcurrentOperationException, OperationTimedoutException;
void orchestrateStart(String vmUuid, Map<VirtualMachineProfile.Param, Object> params, DeploymentPlan planToDeploy, DeploymentPlanner planner) throws InsufficientCapacityException,
ResourceUnavailableException, ConcurrentOperationException, OperationTimedoutException; ResourceUnavailableException, ConcurrentOperationException, OperationTimedoutException;
void advanceStop(String vmUuid, boolean cleanupEvenIfUnableToStop) throws ResourceUnavailableException, OperationTimedoutException, ConcurrentOperationException; 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 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; void migrate(String vmUuid, long srcHostId, DeployDestination dest) throws ResourceUnavailableException, ConcurrentOperationException;

View File

@ -39,11 +39,12 @@ public interface DeploymentPlanningManager extends Manager {
* *
* *
*/ */
DeployDestination planDeployment(VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoids) throws InsufficientServerCapacityException, DeployDestination planDeployment(VirtualMachineProfile vmProfile, DeploymentPlan plan,
AffinityConflictException; ExcludeList avoids, DeploymentPlanner planner) throws InsufficientServerCapacityException, AffinityConflictException;
String finalizeReservation(DeployDestination plannedDestination, VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoids) String finalizeReservation(DeployDestination plannedDestination,
throws InsufficientServerCapacityException, AffinityConflictException; VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoids)
throws InsufficientServerCapacityException, AffinityConflictException;
void cleanupVMReservations(); void cleanupVMReservations();
} }

View File

@ -42,6 +42,7 @@ import javax.naming.ConfigurationException;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import com.cloud.deploy.DeploymentPlanner;
import org.apache.cloudstack.affinity.dao.AffinityGroupVMMapDao; import org.apache.cloudstack.affinity.dao.AffinityGroupVMMapDao;
import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.context.CallContext;
import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService; import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
@ -559,7 +560,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
@Override @Override
public void start(String vmUuid, Map<VirtualMachineProfile.Param, Object> params, DeploymentPlan planToDeploy) { public void start(String vmUuid, Map<VirtualMachineProfile.Param, Object> params, DeploymentPlan planToDeploy) {
try { try {
advanceStart(vmUuid, params, planToDeploy); advanceStart(vmUuid, params, planToDeploy, null);
} catch (ConcurrentOperationException e) { } catch (ConcurrentOperationException e) {
throw new CloudRuntimeException("Unable to start a VM due to concurrent operation", e).add(VirtualMachine.class, vmUuid); throw new CloudRuntimeException("Unable to start a VM due to concurrent operation", e).add(VirtualMachine.class, vmUuid);
} catch (InsufficientCapacityException e) { } catch (InsufficientCapacityException e) {
@ -700,20 +701,19 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
} }
@Override @Override
public void advanceStart(String vmUuid, Map<VirtualMachineProfile.Param, Object> params) public void advanceStart(String vmUuid, Map<VirtualMachineProfile.Param, Object> params, DeploymentPlanner planner)
throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException { throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException {
advanceStart(vmUuid, params, null, planner);
advanceStart(vmUuid, params, null);
} }
@Override @Override
public void advanceStart(String vmUuid, Map<VirtualMachineProfile.Param, Object> params, DeploymentPlan planToDeploy) throws InsufficientCapacityException, public void advanceStart(String vmUuid, Map<VirtualMachineProfile.Param, Object> params, DeploymentPlan planToDeploy, DeploymentPlanner planner) throws InsufficientCapacityException,
ConcurrentOperationException, ResourceUnavailableException { ConcurrentOperationException, ResourceUnavailableException {
AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext(); AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext();
if (!VmJobEnabled.value() || jobContext.isJobDispatchedBy(VmWorkJobDispatcher.VM_WORK_JOB_DISPATCHER)) { if (!VmJobEnabled.value() || jobContext.isJobDispatchedBy(VmWorkJobDispatcher.VM_WORK_JOB_DISPATCHER)) {
// avoid re-entrance // avoid re-entrance
orchestrateStart(vmUuid, params, planToDeploy); orchestrateStart(vmUuid, params, planToDeploy, planner);
} else { } else {
Outcome<VirtualMachine> outcome = startVmThroughJobQueue(vmUuid, params, planToDeploy); Outcome<VirtualMachine> outcome = startVmThroughJobQueue(vmUuid, params, planToDeploy);
@ -735,8 +735,10 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
} }
} }
private void orchestrateStart(String vmUuid, Map<VirtualMachineProfile.Param, Object> params, DeploymentPlan planToDeploy) throws InsufficientCapacityException,
ConcurrentOperationException, ResourceUnavailableException { @Override
public void orchestrateStart(String vmUuid, Map<VirtualMachineProfile.Param, Object> params, DeploymentPlan planToDeploy, DeploymentPlanner planner)
throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException {
CallContext cctxt = CallContext.current(); CallContext cctxt = CallContext.current();
Account account = cctxt.getCallingAccount(); Account account = cctxt.getCallingAccount();
@ -854,7 +856,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
VirtualMachineProfileImpl vmProfile = new VirtualMachineProfileImpl(vm, template, offering, owner, params); VirtualMachineProfileImpl vmProfile = new VirtualMachineProfileImpl(vm, template, offering, owner, params);
DeployDestination dest = null; DeployDestination dest = null;
try { try {
dest = _dpMgr.planDeployment(vmProfile, plan, avoids); dest = _dpMgr.planDeployment(vmProfile, plan, avoids, planner);
} catch (AffinityConflictException e2) { } catch (AffinityConflictException e2) {
s_logger.warn("Unable to create deployment, affinity rules associted to the VM conflict", 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"); 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 @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); VMInstanceVO vm = _vmDao.findByUuid(vmUuid);
if (vm == null) { if (vm == null) {
s_logger.debug("Unable to find a VM for " + vmUuid); s_logger.debug("Unable to find a VM for " + vmUuid);
@ -2070,7 +2072,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
while (true) { while (true) {
try { try {
dest = _dpMgr.planDeployment(profile, plan, excludes); dest = _dpMgr.planDeployment(profile, plan, excludes, planner);
} catch (AffinityConflictException e2) { } catch (AffinityConflictException e2) {
s_logger.warn("Unable to create deployment, affinity rules associted to the VM conflict", 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"); 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; DeployDestination dest = null;
try { try {
dest = _dpMgr.planDeployment(profile, plan, excludes); dest = _dpMgr.planDeployment(profile, plan, excludes, null);
} catch (AffinityConflictException e2) { } catch (AffinityConflictException e2) {
s_logger.warn("Unable to create deployment, affinity rules associted to the VM conflict", 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"); 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); assert (vm != null);
if (work instanceof VmWorkStart) { if (work instanceof VmWorkStart) {
VmWorkStart workStart = (VmWorkStart)work; VmWorkStart workStart = (VmWorkStart)work;
orchestrateStart(vm.getUuid(), workStart.getParams(), workStart.getPlan()); orchestrateStart(vm.getUuid(), workStart.getParams(), workStart.getPlan(), null);
return new Pair<JobInfo.Status, String>(JobInfo.Status.SUCCEEDED, null); return new Pair<JobInfo.Status, String>(JobInfo.Status.SUCCEEDED, null);
} else if (work instanceof VmWorkStop) { } else if (work instanceof VmWorkStop) {
VmWorkStop workStop = (VmWorkStop)work; VmWorkStop workStop = (VmWorkStop)work;

View File

@ -189,7 +189,7 @@ public class VMEntityManagerImpl implements VMEntityManager {
while (true) { while (true) {
DeployDestination dest = null; DeployDestination dest = null;
try { try {
dest = _dpMgr.planDeployment(vmProfile, plan, exclude); dest = _dpMgr.planDeployment(vmProfile, plan, exclude, null);
} catch (AffinityConflictException e) { } catch (AffinityConflictException e) {
throw new CloudRuntimeException("Unable to create deployment, affinity rules associted to the VM conflict"); throw new CloudRuntimeException("Unable to create deployment, affinity rules associted to the VM conflict");
} }

View File

@ -0,0 +1,29 @@
<!--
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.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>cloud-plugin-planner-skip-heurestics</artifactId>
<name>Apache CloudStack Plugin - Skip Heurestics Planner</name>
<parent>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloudstack-plugins</artifactId>
<version>4.4.0-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
</project>

View File

@ -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

View File

@ -0,0 +1,26 @@
<!-- 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. -->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<bean id="SkipHeuresticsPlanner" class="com.cloud.deploy.SkipHeuresticsPlanner">
<property name="name" value="SkipHeuresticsPlanner" />
</bean>
</beans>

View File

@ -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<Long> 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<String, Object> params) throws ConfigurationException {
super.configure(name, params);
return true;
}
}

View File

@ -32,6 +32,7 @@
<module>deployment-planners/user-concentrated-pod</module> <module>deployment-planners/user-concentrated-pod</module>
<module>deployment-planners/user-dispersing</module> <module>deployment-planners/user-dispersing</module>
<module>deployment-planners/implicit-dedication</module> <module>deployment-planners/implicit-dedication</module>
<module>ha-planners/skip-heurestics</module>
<module>host-allocators/random</module> <module>host-allocators/random</module>
<module>dedicated-resources</module> <module>dedicated-resources</module>
<module>hypervisors/ovm</module> <module>hypervisors/ovm</module>

View File

@ -65,6 +65,7 @@
<bean id="highAvailabilityManagerExtImpl" class="com.cloud.ha.HighAvailabilityManagerExtImpl"> <bean id="highAvailabilityManagerExtImpl" class="com.cloud.ha.HighAvailabilityManagerExtImpl">
<property name="investigators" value="#{haInvestigatorsRegistry.registered}" /> <property name="investigators" value="#{haInvestigatorsRegistry.registered}" />
<property name="fenceBuilders" value="#{haFenceBuildersRegistry.registered}" /> <property name="fenceBuilders" value="#{haFenceBuildersRegistry.registered}" />
<property name="haPlanners" value="#{haPlannersRegistry.registered}" />
</bean> </bean>
<bean id="ipAddressManagerImpl" class="com.cloud.network.IpAddressManagerImpl"> <bean id="ipAddressManagerImpl" class="com.cloud.network.IpAddressManagerImpl">

View File

@ -549,7 +549,7 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy
} }
if (proxy.getState() == VirtualMachine.State.Stopped) { if (proxy.getState() == VirtualMachine.State.Stopped) {
_itMgr.advanceStart(proxy.getUuid(), null); _itMgr.advanceStart(proxy.getUuid(), null, null);
proxy = _consoleProxyDao.findById(proxy.getId()); proxy = _consoleProxyDao.findById(proxy.getId());
} }

View File

@ -233,8 +233,8 @@ public class DeploymentPlanningManagerImpl extends ManagerBase implements Deploy
} }
@Override @Override
public DeployDestination planDeployment(VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoids) throws InsufficientServerCapacityException, public DeployDestination planDeployment(VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoids, DeploymentPlanner planner)
AffinityConflictException { throws InsufficientServerCapacityException, AffinityConflictException {
// call affinitygroup chain // call affinitygroup chain
VirtualMachine vm = vmProfile.getVirtualMachine(); VirtualMachine vm = vmProfile.getVirtualMachine();
@ -265,19 +265,20 @@ public class DeploymentPlanningManagerImpl extends ManagerBase implements Deploy
} }
ServiceOffering offering = vmProfile.getServiceOffering(); ServiceOffering offering = vmProfile.getServiceOffering();
String plannerName = offering.getDeploymentPlanner(); if(planner == null){
if (plannerName == null) { String plannerName = offering.getDeploymentPlanner();
if (vm.getHypervisorType() == HypervisorType.BareMetal) { if (plannerName == null) {
plannerName = "BareMetalPlanner"; if (vm.getHypervisorType() == HypervisorType.BareMetal) {
} else { plannerName = "BareMetalPlanner";
plannerName = _configDao.getValue(Config.VmDeploymentPlanner.key()); } else {
plannerName = _configDao.getValue(Config.VmDeploymentPlanner.key());
}
} }
} for (DeploymentPlanner plannerInList : _planners) {
DeploymentPlanner planner = null; if (plannerName.equals(plannerInList.getName())) {
for (DeploymentPlanner plannerInList : _planners) { planner = plannerInList;
if (plannerName.equals(plannerInList.getName())) { break;
planner = plannerInList; }
break;
} }
} }

View File

@ -259,7 +259,15 @@ public class FirstFitPlanner extends PlannerBase implements DeploymentClusterPla
return capacityList; return capacityList;
} }
private void removeClustersCrossingThreshold(List<Long> 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<Long> clusterListForVmAllocation, ExcludeList avoid,
VirtualMachineProfile vmProfile, DeploymentPlan plan) {
List<Short> capacityList = getCapacitiesForCheckingThreshold(); List<Short> capacityList = getCapacitiesForCheckingThreshold();
List<Long> clustersCrossingThreshold = new ArrayList<Long>(); List<Long> clustersCrossingThreshold = new ArrayList<Long>();

View File

@ -32,6 +32,7 @@ import javax.naming.ConfigurationException;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.apache.log4j.NDC; import org.apache.log4j.NDC;
import com.cloud.deploy.HAPlanner;
import org.apache.cloudstack.engine.orchestration.service.VolumeOrchestrationService; import org.apache.cloudstack.engine.orchestration.service.VolumeOrchestrationService;
import org.apache.cloudstack.framework.config.dao.ConfigurationDao; import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
import org.apache.cloudstack.managed.context.ManagedContext; import org.apache.cloudstack.managed.context.ManagedContext;
@ -141,6 +142,16 @@ public class HighAvailabilityManagerImpl extends ManagerBase implements HighAvai
this.fenceBuilders = fenceBuilders; this.fenceBuilders = fenceBuilders;
} }
List<HAPlanner> _haPlanners;
public List<HAPlanner> getHaPlanners() {
return _haPlanners;
}
public void setHaPlanners(List<HAPlanner> haPlanners) {
this._haPlanners = haPlanners;
}
@Inject @Inject
AgentManager _agentMgr; AgentManager _agentMgr;
@Inject @Inject
@ -548,9 +559,20 @@ public class HighAvailabilityManagerImpl extends ManagerBase implements HighAvai
if (_haTag != null) { if (_haTag != null) {
params.put(VirtualMachineProfile.Param.HaTag, _haTag); 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()); 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) { if (started != null && started.getState() == VirtualMachine.State.Running) {
s_logger.info("VM is now restarted: " + vmId + " on " + started.getHostId()); s_logger.info("VM is now restarted: " + vmId + " on " + started.getHostId());
return null; return null;
@ -591,8 +613,14 @@ public class HighAvailabilityManagerImpl extends ManagerBase implements HighAvai
_haDao.update(work.getId(), work); _haDao.update(work.getId(), work);
VMInstanceVO vm = _instanceDao.findById(vmId); VMInstanceVO vm = _instanceDao.findById(vmId);
// First try starting the vm with its original planner, if it doesn't succeed send HAPlanner as its an emergency.
_itMgr.migrateAway(vm.getUuid(), srcHostId); 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; return null;
} catch (InsufficientServerCapacityException e) { } catch (InsufficientServerCapacityException e) {
s_logger.warn("Insufficient capacity for migrating a VM."); s_logger.warn("Insufficient capacity for migrating a VM.");

View File

@ -219,7 +219,7 @@ public class StoragePoolAutomationImpl implements StoragePoolAutomation {
if (restart) { if (restart) {
vmMgr.advanceStart(consoleProxy.getUuid(), null); vmMgr.advanceStart(consoleProxy.getUuid(), null, null);
// update work status // update work status
work.setStartedAfterMaintenance(true); work.setStartedAfterMaintenance(true);
_storagePoolWorkDao.update(work.getId(), work); _storagePoolWorkDao.update(work.getId(), work);
@ -245,7 +245,7 @@ public class StoragePoolAutomationImpl implements StoragePoolAutomation {
_storagePoolWorkDao.update(work.getId(), work); _storagePoolWorkDao.update(work.getId(), work);
if (restart) { if (restart) {
vmMgr.advanceStart(secStrgVm.getUuid(), null); vmMgr.advanceStart(secStrgVm.getUuid(), null, null);
// update work status // update work status
work.setStartedAfterMaintenance(true); work.setStartedAfterMaintenance(true);
_storagePoolWorkDao.update(work.getId(), work); _storagePoolWorkDao.update(work.getId(), work);
@ -262,7 +262,7 @@ public class StoragePoolAutomationImpl implements StoragePoolAutomation {
_storagePoolWorkDao.update(work.getId(), work); _storagePoolWorkDao.update(work.getId(), work);
if (restart) { if (restart) {
vmMgr.advanceStart(domR.getUuid(), null); vmMgr.advanceStart(domR.getUuid(), null, null);
// update work status // update work status
work.setStartedAfterMaintenance(true); work.setStartedAfterMaintenance(true);
_storagePoolWorkDao.update(work.getId(), work); _storagePoolWorkDao.update(work.getId(), work);
@ -330,17 +330,21 @@ public class StoragePoolAutomationImpl implements StoragePoolAutomation {
// proxy // proxy
if (vmInstance.getType().equals(VirtualMachine.Type.ConsoleProxy)) { if (vmInstance.getType().equals(VirtualMachine.Type.ConsoleProxy)) {
ConsoleProxyVO consoleProxy = _consoleProxyDao.findById(vmInstance.getId()); ConsoleProxyVO consoleProxy = _consoleProxyDao
vmMgr.advanceStart(consoleProxy.getUuid(), null); .findById(vmInstance.getId());
vmMgr.advanceStart(consoleProxy.getUuid(), null, null);
// update work queue // update work queue
work.setStartedAfterMaintenance(true); work.setStartedAfterMaintenance(true);
_storagePoolWorkDao.update(work.getId(), work); _storagePoolWorkDao.update(work.getId(), work);
} }
// if the instance is of type ssvm, call the ssvm manager // if the instance is of type ssvm, call the ssvm manager
if (vmInstance.getType().equals(VirtualMachine.Type.SecondaryStorageVm)) { if (vmInstance.getType().equals(
SecondaryStorageVmVO ssVm = _secStrgDao.findById(vmInstance.getId()); VirtualMachine.Type.SecondaryStorageVm)) {
vmMgr.advanceStart(ssVm.getUuid(), null); SecondaryStorageVmVO ssVm = _secStrgDao.findById(vmInstance
.getId());
vmMgr.advanceStart(ssVm.getUuid(), null, null);
// update work queue // update work queue
work.setStartedAfterMaintenance(true); work.setStartedAfterMaintenance(true);
_storagePoolWorkDao.update(work.getId(), work); _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 the instance is of type ssvm, call the ssvm manager
if (vmInstance.getType().equals(VirtualMachine.Type.DomainRouter)) { if (vmInstance.getType().equals(VirtualMachine.Type.DomainRouter)) {
DomainRouterVO domR = _domrDao.findById(vmInstance.getId()); DomainRouterVO domR = _domrDao.findById(vmInstance.getId());
vmMgr.advanceStart(domR.getUuid(), null); vmMgr.advanceStart(domR.getUuid(), null, null);
// update work queue // update work queue
work.setStartedAfterMaintenance(true); work.setStartedAfterMaintenance(true);
_storagePoolWorkDao.update(work.getId(), work); _storagePoolWorkDao.update(work.getId(), work);
@ -359,7 +363,7 @@ public class StoragePoolAutomationImpl implements StoragePoolAutomation {
if (vmInstance.getType().equals(VirtualMachine.Type.User)) { if (vmInstance.getType().equals(VirtualMachine.Type.User)) {
UserVmVO userVm = userVmDao.findById(vmInstance.getId()); 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); work.setStartedAfterMaintenance(true);
_storagePoolWorkDao.update(work.getId(), work); _storagePoolWorkDao.update(work.getId(), work);
} }

View File

@ -258,7 +258,7 @@ public class SecondaryStorageManagerImpl extends ManagerBase implements Secondar
public SecondaryStorageVmVO startSecStorageVm(long secStorageVmId) { public SecondaryStorageVmVO startSecStorageVm(long secStorageVmId) {
try { try {
SecondaryStorageVmVO secStorageVm = _secStorageVmDao.findById(secStorageVmId); SecondaryStorageVmVO secStorageVm = _secStorageVmDao.findById(secStorageVmId);
_itMgr.advanceStart(secStorageVm.getUuid(), null); _itMgr.advanceStart(secStorageVm.getUuid(), null, null);
return _secStorageVmDao.findById(secStorageVm.getId()); return _secStorageVmDao.findById(secStorageVm.getId());
} catch (StorageUnavailableException e) { } catch (StorageUnavailableException e) {
s_logger.warn("Exception while trying to start secondary storage vm", e); s_logger.warn("Exception while trying to start secondary storage vm", e);

View File

@ -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 // 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) { if (userVm.getState() == VirtualMachine.State.Stopped && vmSnapshotVo.getType() == VMSnapshot.Type.DiskAndMemory) {
try { try {
_itMgr.advanceStart(userVm.getUuid(), new HashMap<VirtualMachineProfile.Param, Object>()); _itMgr.advanceStart(userVm.getUuid(), new HashMap<VirtualMachineProfile.Param, Object>(), null);
vm = _userVMDao.findById(userVm.getId()); vm = _userVMDao.findById(userVm.getId());
hostId = vm.getHostId(); hostId = vm.getHostId();
} catch (Exception e) { } catch (Exception e) {

View File

@ -168,7 +168,7 @@ public class DeploymentPlanningManagerImplTest {
DataCenterDeployment plan = new DataCenterDeployment(dataCenterId); DataCenterDeployment plan = new DataCenterDeployment(dataCenterId);
Mockito.when(avoids.shouldAvoid((DataCenterVO)Matchers.anyObject())).thenReturn(true); 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); 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(avoids.shouldAvoid((DataCenterVO)Matchers.anyObject())).thenReturn(false);
Mockito.when(_planner.canHandle(vmProfile, plan, avoids)).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); 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(_planner.canHandle(vmProfile, plan, avoids)).thenReturn(true);
Mockito.when(((DeploymentClusterPlanner)_planner).orderClusters(vmProfile, plan, avoids)).thenReturn(null); 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); assertNull("Planner cannot handle, destination should be null! ", dest);
} }