mirror of https://github.com/apache/cloudstack.git
CLOUDSTACK-4746:
From functionality point of view following will be changes. -> Threshold will not be applied for vms undergoing HA process (say during host going down event). -> Threshold will not be applied for vms undergoing maintenance. -> Threshold will apply for stop-start vm "after" the skip.counting.hours (time till which we reserve the capacity for the stopped vm). Reason being stop-start is a user initiated action and we are giving a time window (skip.counting.hours) till which its guaranteed to start in the same cluster. After that time, threshold check applies bcz we still want to reserve the capacity for urgent situations like HA, putting host into maintenance rather than get it consumed in such user initiated actions. Signed off by : nitin mehta<nitin.mehta@citrix.com>
This commit is contained in:
parent
c4905eafd5
commit
de28812add
|
|
@ -145,6 +145,11 @@
|
|||
<artifactId>cloud-plugin-planner-user-dispersing</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.cloudstack</groupId>
|
||||
<artifactId>cloud-plugin-planner-ha</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.cloudstack</groupId>
|
||||
<artifactId>cloud-plugin-planner-user-concentrated-pod</artifactId>
|
||||
|
|
|
|||
|
|
@ -720,6 +720,10 @@
|
|||
<property name="name" value="FirstFitPlanner"/>
|
||||
</bean>
|
||||
|
||||
<bean id="SkipHeuresticsPlanner" class="com.cloud.deploy.SkipHeuresticsPlanner">
|
||||
<property name="name" value="SkipHeuresticsPlanner"/>
|
||||
</bean>
|
||||
|
||||
<bean id="resourceManagerImpl" class="com.cloud.resource.ResourceManagerImpl" >
|
||||
<property name="PodAllocators" value="#{podAllocators.Adapters}" />
|
||||
<property name="Discoverers" value="#{resourceDiscoverers.Adapters}" />
|
||||
|
|
@ -728,6 +732,7 @@
|
|||
<bean id="highAvailabilityManagerExtImpl" class="com.cloud.ha.HighAvailabilityManagerExtImpl" >
|
||||
<property name="Investigators" value="#{haInvestigators.Adapters}" />
|
||||
<property name="FenceBuilders" value="#{haFenceBuilders.Adapters}" />
|
||||
<property name="HAPlanners" value="#{haPlanners.Adapters}" />
|
||||
</bean>
|
||||
|
||||
<bean id="clusteredVirtualMachineManagerImpl" class="com.cloud.vm.ClusteredVirtualMachineManagerImpl" >
|
||||
|
|
|
|||
|
|
@ -189,6 +189,15 @@
|
|||
</property>
|
||||
</bean>
|
||||
|
||||
<!-- HA adapters -->
|
||||
<bean id="haPlanners" class="com.cloud.utils.component.AdapterList">
|
||||
<property name="Adapters">
|
||||
<list>
|
||||
<ref bean="SkipHeuresticsPlanner" />
|
||||
</list>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<!-- Deployment/allocation adapters -->
|
||||
<bean id="deploymentPlanners" class="com.cloud.utils.component.AdapterList">
|
||||
<property name="Adapters">
|
||||
|
|
|
|||
|
|
@ -289,6 +289,15 @@
|
|||
</property>
|
||||
</bean>
|
||||
|
||||
<!-- HA adapters -->
|
||||
<bean id="haPlanners" class="com.cloud.utils.component.AdapterList">
|
||||
<property name="Adapters">
|
||||
<list>
|
||||
<ref bean="SkipHeuresticsPlanner" />
|
||||
</list>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<!-- Deployment/allocation adapters -->
|
||||
<bean id="deploymentPlanners" class="com.cloud.utils.component.AdapterList">
|
||||
<property name="Adapters">
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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-ha</artifactId>
|
||||
<name>Apache CloudStack Plugin - HA Planner</name>
|
||||
<parent>
|
||||
<groupId>org.apache.cloudstack</groupId>
|
||||
<artifactId>cloudstack-plugins</artifactId>
|
||||
<version>4.2.1-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
</project>
|
||||
|
|
@ -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 {
|
||||
}
|
||||
|
|
@ -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<Long> clusterListForVmAllocation, ExcludeList avoid, VirtualMachineProfile<? extends VirtualMachine> 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<? extends VirtualMachine> 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;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -40,6 +40,7 @@
|
|||
<module>deployment-planners/user-concentrated-pod</module>
|
||||
<module>deployment-planners/user-dispersing</module>
|
||||
<module>deployment-planners/implicit-dedication</module>
|
||||
<module>deployment-planners/ha</module>
|
||||
<module>host-allocators/random</module>
|
||||
<module>dedicated-resources</module>
|
||||
<module>hypervisors/ovm</module>
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ public interface DeploymentPlanningManager extends Manager {
|
|||
*
|
||||
*/
|
||||
DeployDestination planDeployment(VirtualMachineProfile<? extends VirtualMachine> vmProfile, DeploymentPlan plan,
|
||||
ExcludeList avoids) throws InsufficientServerCapacityException, AffinityConflictException;
|
||||
ExcludeList avoids, DeploymentPlanner planner) throws InsufficientServerCapacityException, AffinityConflictException;
|
||||
|
||||
String finalizeReservation(DeployDestination plannedDestination,
|
||||
VirtualMachineProfile<? extends VirtualMachine> vmProfile, DeploymentPlan plan, ExcludeList avoids)
|
||||
|
|
|
|||
|
|
@ -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<? extends VirtualMachine> 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<Host> suitableHosts = new ArrayList<Host>();
|
||||
suitableHosts.add(host);
|
||||
Pair<Host, Map<Volume, StoragePool>> 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<Volume, List<StoragePool>> suitableVolumeStoragePools = result.first();
|
||||
List<Volume> readyAndReusedVolumes = result.second();
|
||||
|
||||
|
||||
// choose the potential pool for this VM for this host
|
||||
if (!suitableVolumeStoragePools.isEmpty()) {
|
||||
List<Host> suitableHosts = new ArrayList<Host>();
|
||||
suitableHosts.add(host);
|
||||
Pair<Host, Map<Volume, StoragePool>> 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<? extends VirtualMachine> vmProfile, DataCenter dc, ExcludeList avoids) {
|
||||
private void checkForNonDedicatedResources(VirtualMachineProfile<? extends VirtualMachine> 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<AffinityGroupVMMapVO> 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<AffinityGroupVMMapVO> vmGroupMappings = _affinityGroupVMMapDao.findByVmIdType(vm.getId(), "ExplicitDedication");
|
||||
|
||||
if (vmGroupMappings != null && !vmGroupMappings.isEmpty()){
|
||||
isExplicit = true;
|
||||
}
|
||||
|
||||
if (!isExplicit) {
|
||||
//add explicitly dedicated resources in avoidList
|
||||
|
||||
List<Long> allPodsInDc = _podDao.listAllPods(dc.getId());
|
||||
List<Long> allDedicatedPods = _dedicatedDao.listAllPods();
|
||||
allPodsInDc.retainAll(allDedicatedPods);
|
||||
|
|
@ -508,10 +509,10 @@ public class DeploymentPlanningManagerImpl extends ManagerBase implements Deploy
|
|||
List<Long> allHostsInDc = _hostDao.listAllHosts(dc.getId());
|
||||
List<Long> 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<? extends VirtualMachine> vmProfile, DeploymentPlan plan, ExcludeList avoids) throws InsufficientServerCapacityException {
|
||||
private PlannerResourceUsage getPlannerUsage(DeploymentPlanner planner, VirtualMachineProfile<? extends VirtualMachine> 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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -263,7 +263,12 @@ public class FirstFitPlanner extends PlannerBase implements DeploymentClusterPla
|
|||
return capacityList;
|
||||
}
|
||||
|
||||
private void removeClustersCrossingThreshold(List<Long> clusterListForVmAllocation, ExcludeList avoid,
|
||||
/**
|
||||
* This method should remove the clusters crossing capacity threshold
|
||||
* to avoid further vm allocation on it
|
||||
*
|
||||
*/
|
||||
protected void removeClustersCrossingThreshold(List<Long> clusterListForVmAllocation, ExcludeList avoid,
|
||||
VirtualMachineProfile<? extends VirtualMachine> vmProfile, DeploymentPlan plan) {
|
||||
|
||||
List<Short> capacityList = getCapacitiesForCheckingThreshold();
|
||||
|
|
|
|||
|
|
@ -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<HAPlanner> _haPlanners;
|
||||
public List<HAPlanner> getHAPlanners() {
|
||||
return _haPlanners;
|
||||
}
|
||||
public void setHAPlanners(List<HAPlanner> _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);
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -96,9 +96,9 @@ public interface VirtualMachineManager extends Manager {
|
|||
|
||||
boolean stateTransitTo(VMInstanceVO vm, VirtualMachine.Event e, Long hostId) throws NoTransitionException;
|
||||
|
||||
<T extends VMInstanceVO> T advanceStart(T vm, Map<VirtualMachineProfile.Param, Object> params, User caller, Account account) throws InsufficientCapacityException, ResourceUnavailableException, ConcurrentOperationException, OperationTimedoutException;
|
||||
<T extends VMInstanceVO> T advanceStart(T vm, Map<VirtualMachineProfile.Param, Object> params, User caller, Account account, DeploymentPlanner planner) throws InsufficientCapacityException, ResourceUnavailableException, ConcurrentOperationException, OperationTimedoutException;
|
||||
|
||||
<T extends VMInstanceVO> T advanceStart(T vm, Map<VirtualMachineProfile.Param, Object> params, User caller, Account account, DeploymentPlan planToDeploy) throws InsufficientCapacityException, ResourceUnavailableException, ConcurrentOperationException, OperationTimedoutException;
|
||||
<T extends VMInstanceVO> T advanceStart(T vm, Map<VirtualMachineProfile.Param, Object> params, User caller, Account account, DeploymentPlan planToDeploy, DeploymentPlanner planner) throws InsufficientCapacityException, ResourceUnavailableException, ConcurrentOperationException, OperationTimedoutException;
|
||||
|
||||
<T extends VMInstanceVO> boolean advanceStop(T vm, boolean forced, User caller, Account account) throws ResourceUnavailableException, OperationTimedoutException, ConcurrentOperationException;
|
||||
|
||||
|
|
@ -108,7 +108,7 @@ public interface VirtualMachineManager extends Manager {
|
|||
|
||||
<T extends VMInstanceVO> 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 extends VMInstanceVO> T migrate(T vm, long srcHostId, DeployDestination dest) throws ResourceUnavailableException, ConcurrentOperationException, ManagementServerException, VirtualMachineMigrationException;
|
||||
|
||||
|
|
|
|||
|
|
@ -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 extends VMInstanceVO> T start(T vm, Map<VirtualMachineProfile.Param, Object> 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 extends VMInstanceVO> T advanceStart(T vm, Map<VirtualMachineProfile.Param, Object> params, User caller, Account account) throws InsufficientCapacityException,
|
||||
public <T extends VMInstanceVO> T advanceStart(T vm, Map<VirtualMachineProfile.Param, Object> 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 extends VMInstanceVO> T advanceStart(T vm, Map<VirtualMachineProfile.Param, Object> params, User caller, Account account, DeploymentPlan planToDeploy)
|
||||
public <T extends VMInstanceVO> T advanceStart(T vm, Map<VirtualMachineProfile.Param, Object> params, User caller, Account account, DeploymentPlan planToDeploy, DeploymentPlanner planner)
|
||||
throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException {
|
||||
long vmId = vm.getId();
|
||||
VirtualMachineGuru<T> vmGuru = getVmGuru(vm);
|
||||
|
|
@ -823,7 +822,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
|||
VirtualMachineProfileImpl<T> vmProfile = new VirtualMachineProfileImpl<T>(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<? extends VMInstanceVO> 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(
|
||||
|
|
|
|||
|
|
@ -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<VirtualMachineProfile.Param, Object>(), callerUser, owner);
|
||||
vm = _itMgr.advanceStart(userVm, new HashMap<VirtualMachineProfile.Param, Object>(), callerUser, owner, null);
|
||||
hostId = vm.getHostId();
|
||||
} catch (Exception e) {
|
||||
s_logger.error("Start VM " + userVm.getInstanceName() + " before reverting failed due to " + e.getMessage());
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 extends VMInstanceVO> T advanceStart(T vm, Map<Param, Object> params, User caller, Account account) throws InsufficientCapacityException, ResourceUnavailableException,
|
||||
public <T extends VMInstanceVO> T advanceStart(T vm, Map<Param, Object> params, User caller, Account account, DeploymentPlanner planner) throws InsufficientCapacityException, ResourceUnavailableException,
|
||||
ConcurrentOperationException, OperationTimedoutException {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends VMInstanceVO> T advanceStart(T vm, Map<Param, Object> params, User caller, Account account, DeploymentPlan planToDeploy) throws InsufficientCapacityException,
|
||||
public <T extends VMInstanceVO> T advanceStart(T vm, Map<Param, Object> params, User caller, Account account, DeploymentPlan planToDeploy, DeploymentPlanner planner) throws InsufficientCapacityException,
|
||||
ResourceUnavailableException, ConcurrentOperationException, OperationTimedoutException {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
|
|
|
|||
Loading…
Reference in New Issue