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 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 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 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)
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 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 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 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 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 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;
}
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 extends VirtualMachine> 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 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(
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;