mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
Fix allocation of VMs with multiple clusters (#8611)
* Fix allocation of VMs with multiple clusters * Readd debug guard
This commit is contained in:
parent
ed86dc973b
commit
00fe25ab01
@ -22,7 +22,6 @@ import java.util.List;
|
|||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import com.cloud.utils.exception.CloudRuntimeException;
|
|
||||||
import org.apache.commons.collections.CollectionUtils;
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
import org.apache.commons.collections.ListUtils;
|
import org.apache.commons.collections.ListUtils;
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
@ -36,7 +35,6 @@ import com.cloud.deploy.DeploymentPlan;
|
|||||||
import com.cloud.deploy.DeploymentPlanner.ExcludeList;
|
import com.cloud.deploy.DeploymentPlanner.ExcludeList;
|
||||||
import com.cloud.host.Host;
|
import com.cloud.host.Host;
|
||||||
import com.cloud.host.Host.Type;
|
import com.cloud.host.Host.Type;
|
||||||
import com.cloud.host.HostVO;
|
|
||||||
import com.cloud.host.dao.HostDao;
|
import com.cloud.host.dao.HostDao;
|
||||||
import com.cloud.offering.ServiceOffering;
|
import com.cloud.offering.ServiceOffering;
|
||||||
import com.cloud.resource.ResourceManager;
|
import com.cloud.resource.ResourceManager;
|
||||||
@ -66,18 +64,20 @@ public class RandomAllocator extends AdapterBase implements HostAllocator {
|
|||||||
Long podId = plan.getPodId();
|
Long podId = plan.getPodId();
|
||||||
Long clusterId = plan.getClusterId();
|
Long clusterId = plan.getClusterId();
|
||||||
ServiceOffering offering = vmProfile.getServiceOffering();
|
ServiceOffering offering = vmProfile.getServiceOffering();
|
||||||
List<? extends Host> hostsCopy = null;
|
List<Host> suitableHosts = new ArrayList<>();
|
||||||
List<Host> suitableHosts = new ArrayList<Host>();
|
|
||||||
|
|
||||||
if (type == Host.Type.Storage) {
|
if (type == Host.Type.Storage) {
|
||||||
return suitableHosts;
|
return suitableHosts;
|
||||||
}
|
}
|
||||||
|
|
||||||
String hostTag = offering.getHostTag();
|
String hostTag = offering.getHostTag();
|
||||||
if (hostTag != null) {
|
String hostTagToLog = hostTag != null ? String.format("and complying with host tags [%s]", hostTag) : "";
|
||||||
s_logger.debug(String.format("Looking for hosts in dc [%s], pod [%s], cluster [%s] and complying with host tag [%s].", dcId, podId, clusterId, hostTag));
|
String paramAsStringToLog = String.format("zone [%s], pod [%s], cluster [%s] %s", dcId, podId, clusterId, hostTagToLog);
|
||||||
} else {
|
|
||||||
s_logger.debug("Looking for hosts in dc: " + dcId + " pod:" + podId + " cluster:" + clusterId);
|
s_logger.debug(String.format("Looking for hosts in %s.", paramAsStringToLog));
|
||||||
}
|
|
||||||
|
List<? extends Host> hostsCopy;
|
||||||
|
|
||||||
if (hosts != null) {
|
if (hosts != null) {
|
||||||
// retain all computing hosts, regardless of whether they support routing...it's random after all
|
// retain all computing hosts, regardless of whether they support routing...it's random after all
|
||||||
hostsCopy = new ArrayList<Host>(hosts);
|
hostsCopy = new ArrayList<Host>(hosts);
|
||||||
@ -88,7 +88,6 @@ public class RandomAllocator extends AdapterBase implements HostAllocator {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// list all computing hosts, regardless of whether they support routing...it's random after all
|
// list all computing hosts, regardless of whether they support routing...it's random after all
|
||||||
hostsCopy = new ArrayList<HostVO>();
|
|
||||||
if (hostTag != null) {
|
if (hostTag != null) {
|
||||||
hostsCopy = _hostDao.listByHostTag(type, clusterId, podId, dcId, hostTag);
|
hostsCopy = _hostDao.listByHostTag(type, clusterId, podId, dcId, hostTag);
|
||||||
} else {
|
} else {
|
||||||
@ -98,14 +97,15 @@ public class RandomAllocator extends AdapterBase implements HostAllocator {
|
|||||||
hostsCopy = ListUtils.union(hostsCopy, _hostDao.findHostsWithTagRuleThatMatchComputeOferringTags(hostTag));
|
hostsCopy = ListUtils.union(hostsCopy, _hostDao.findHostsWithTagRuleThatMatchComputeOferringTags(hostTag));
|
||||||
|
|
||||||
if (hostsCopy.isEmpty()) {
|
if (hostsCopy.isEmpty()) {
|
||||||
s_logger.error(String.format("No suitable host found for vm [%s] with tags [%s].", vmProfile, hostTag));
|
s_logger.info(String.format("No suitable host found for VM [%s] in %s.", vmProfile, paramAsStringToLog));
|
||||||
throw new CloudRuntimeException(String.format("No suitable host found for vm [%s].", vmProfile));
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
s_logger.debug("Random Allocator found " + hostsCopy.size() + " hosts");
|
s_logger.debug("Random Allocator found " + hostsCopy.size() + " hosts");
|
||||||
if (hostsCopy.size() == 0) {
|
if (hostsCopy.isEmpty()) {
|
||||||
return suitableHosts;
|
return suitableHosts;
|
||||||
}
|
}
|
||||||
|
|
||||||
Collections.shuffle(hostsCopy);
|
Collections.shuffle(hostsCopy);
|
||||||
for (Host host : hostsCopy) {
|
for (Host host : hostsCopy) {
|
||||||
if (suitableHosts.size() == returnUpTo) {
|
if (suitableHosts.size() == returnUpTo) {
|
||||||
|
|||||||
@ -25,7 +25,6 @@ import java.util.Map;
|
|||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.naming.ConfigurationException;
|
import javax.naming.ConfigurationException;
|
||||||
|
|
||||||
import com.cloud.utils.exception.CloudRuntimeException;
|
|
||||||
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
|
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
@ -132,8 +131,10 @@ public class FirstFitAllocator extends AdapterBase implements HostAllocator {
|
|||||||
return new ArrayList<Host>();
|
return new ArrayList<Host>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String paramAsStringToLog = String.format("zone [%s], pod [%s], cluster [%s]", dcId, podId, clusterId);
|
||||||
|
|
||||||
if (s_logger.isDebugEnabled()) {
|
if (s_logger.isDebugEnabled()) {
|
||||||
s_logger.debug("Looking for hosts in dc: " + dcId + " pod:" + podId + " cluster:" + clusterId);
|
s_logger.debug(String.format("Looking for hosts in %s.", paramAsStringToLog));
|
||||||
}
|
}
|
||||||
|
|
||||||
String hostTagOnOffering = offering.getHostTag();
|
String hostTagOnOffering = offering.getHostTag();
|
||||||
@ -206,8 +207,8 @@ public class FirstFitAllocator extends AdapterBase implements HostAllocator {
|
|||||||
|
|
||||||
|
|
||||||
if (clusterHosts.isEmpty()) {
|
if (clusterHosts.isEmpty()) {
|
||||||
s_logger.error(String.format("No suitable host found for vm [%s] with tags [%s].", vmProfile, hostTagOnOffering));
|
s_logger.info(String.format("No suitable host found for VM [%s] with tags [%s] in %s.", vmProfile, hostTagOnOffering, paramAsStringToLog));
|
||||||
throw new CloudRuntimeException(String.format("No suitable host found for vm [%s].", vmProfile));
|
return null;
|
||||||
}
|
}
|
||||||
// add all hosts that we are not considering to the avoid list
|
// add all hosts that we are not considering to the avoid list
|
||||||
List<HostVO> allhostsInCluster = _hostDao.listAllUpAndEnabledNonHAHosts(type, clusterId, podId, dcId, null);
|
List<HostVO> allhostsInCluster = _hostDao.listAllUpAndEnabledNonHAHosts(type, clusterId, podId, dcId, null);
|
||||||
|
|||||||
@ -26,6 +26,7 @@ import java.util.Set;
|
|||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.naming.ConfigurationException;
|
import javax.naming.ConfigurationException;
|
||||||
|
|
||||||
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
@ -75,7 +76,7 @@ public class RecreateHostAllocator extends FirstFitRoutingAllocator {
|
|||||||
public List<Host> allocateTo(VirtualMachineProfile vm, DeploymentPlan plan, Type type, ExcludeList avoid, int returnUpTo) {
|
public List<Host> allocateTo(VirtualMachineProfile vm, DeploymentPlan plan, Type type, ExcludeList avoid, int returnUpTo) {
|
||||||
|
|
||||||
List<Host> hosts = super.allocateTo(vm, plan, type, avoid, returnUpTo);
|
List<Host> hosts = super.allocateTo(vm, plan, type, avoid, returnUpTo);
|
||||||
if (hosts != null && !hosts.isEmpty()) {
|
if (CollectionUtils.isNotEmpty(hosts)) {
|
||||||
return hosts;
|
return hosts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1273,7 +1273,7 @@ StateListener<State, VirtualMachine.Event, VirtualMachine>, Configurable {
|
|||||||
List<Host> suitableHosts = findSuitableHosts(vmProfile, potentialPlan, avoid, HostAllocator.RETURN_UPTO_ALL);
|
List<Host> suitableHosts = findSuitableHosts(vmProfile, potentialPlan, avoid, HostAllocator.RETURN_UPTO_ALL);
|
||||||
// if found suitable hosts in this cluster, find suitable storage
|
// if found suitable hosts in this cluster, find suitable storage
|
||||||
// pools for each volume of the VM
|
// pools for each volume of the VM
|
||||||
if (suitableHosts != null && !suitableHosts.isEmpty()) {
|
if (CollectionUtils.isNotEmpty(suitableHosts)) {
|
||||||
if (vmProfile.getHypervisorType() == HypervisorType.BareMetal) {
|
if (vmProfile.getHypervisorType() == HypervisorType.BareMetal) {
|
||||||
DeployDestination dest = new DeployDestination(dc, pod, clusterVO, suitableHosts.get(0));
|
DeployDestination dest = new DeployDestination(dc, pod, clusterVO, suitableHosts.get(0));
|
||||||
return dest;
|
return dest;
|
||||||
@ -1621,18 +1621,17 @@ StateListener<State, VirtualMachine.Event, VirtualMachine>, Configurable {
|
|||||||
List<Host> suitableHosts = new ArrayList<Host>();
|
List<Host> suitableHosts = new ArrayList<Host>();
|
||||||
for (HostAllocator allocator : _hostAllocators) {
|
for (HostAllocator allocator : _hostAllocators) {
|
||||||
suitableHosts = allocator.allocateTo(vmProfile, plan, Host.Type.Routing, avoid, returnUpTo);
|
suitableHosts = allocator.allocateTo(vmProfile, plan, Host.Type.Routing, avoid, returnUpTo);
|
||||||
if (suitableHosts != null && !suitableHosts.isEmpty()) {
|
if (CollectionUtils.isNotEmpty(suitableHosts)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (suitableHosts.isEmpty()) {
|
if (CollectionUtils.isEmpty(suitableHosts)) {
|
||||||
s_logger.debug("No suitable hosts found");
|
s_logger.debug("No suitable hosts found.");
|
||||||
|
} else {
|
||||||
|
reorderHostsByPriority(plan.getHostPriorities(), suitableHosts);
|
||||||
}
|
}
|
||||||
|
|
||||||
// re-order hosts by priority
|
|
||||||
reorderHostsByPriority(plan.getHostPriorities(), suitableHosts);
|
|
||||||
|
|
||||||
return suitableHosts;
|
return suitableHosts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -525,7 +525,7 @@ public class FirstFitPlanner extends AdapterBase implements DeploymentClusterPla
|
|||||||
matchingClusters.addAll(hostDao.findClustersThatMatchHostTagRule(hostTagOnOffering));
|
matchingClusters.addAll(hostDao.findClustersThatMatchHostTagRule(hostTagOnOffering));
|
||||||
|
|
||||||
if (matchingClusters.isEmpty()) {
|
if (matchingClusters.isEmpty()) {
|
||||||
s_logger.error(String.format("No suitable host found for the following compute offering tags [%s].", hostTagOnOffering));
|
s_logger.error(String.format("No suitable host found in any cluster for the following compute offering tags [%s].", hostTagOnOffering));
|
||||||
throw new CloudRuntimeException("No suitable host found.");
|
throw new CloudRuntimeException("No suitable host found.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1590,20 +1590,17 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
|
|||||||
suitableHosts = allocator.allocateTo(vmProfile, plan, Host.Type.Routing, excludes, HostAllocator.RETURN_UPTO_ALL, false);
|
suitableHosts = allocator.allocateTo(vmProfile, plan, Host.Type.Routing, excludes, HostAllocator.RETURN_UPTO_ALL, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (suitableHosts != null && !suitableHosts.isEmpty()) {
|
if (CollectionUtils.isNotEmpty(suitableHosts)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// re-order hosts by priority
|
|
||||||
_dpMgr.reorderHostsByPriority(plan.getHostPriorities(), suitableHosts);
|
_dpMgr.reorderHostsByPriority(plan.getHostPriorities(), suitableHosts);
|
||||||
|
|
||||||
if (s_logger.isDebugEnabled()) {
|
if (suitableHosts.isEmpty()) {
|
||||||
if (suitableHosts.isEmpty()) {
|
s_logger.warn("No suitable hosts found.");
|
||||||
s_logger.debug("No suitable hosts found");
|
} else {
|
||||||
} else {
|
s_logger.debug("Hosts having capacity and suitable for migration: " + suitableHosts);
|
||||||
s_logger.debug("Hosts having capacity and suitable for migration: " + suitableHosts);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Ternary<>(otherHosts, suitableHosts, requiresStorageMotion);
|
return new Ternary<>(otherHosts, suitableHosts, requiresStorageMotion);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user