Fix allocation of VMs with multiple clusters (#8611)

* Fix allocation of VMs with multiple clusters

* Readd debug guard
This commit is contained in:
Bryan Lima 2024-06-14 07:54:01 -03:00 committed by GitHub
parent ed86dc973b
commit 00fe25ab01
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 32 additions and 34 deletions

View File

@ -22,7 +22,6 @@ import java.util.List;
import javax.inject.Inject;
import com.cloud.utils.exception.CloudRuntimeException;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.ListUtils;
import org.apache.log4j.Logger;
@ -36,7 +35,6 @@ import com.cloud.deploy.DeploymentPlan;
import com.cloud.deploy.DeploymentPlanner.ExcludeList;
import com.cloud.host.Host;
import com.cloud.host.Host.Type;
import com.cloud.host.HostVO;
import com.cloud.host.dao.HostDao;
import com.cloud.offering.ServiceOffering;
import com.cloud.resource.ResourceManager;
@ -66,18 +64,20 @@ public class RandomAllocator extends AdapterBase implements HostAllocator {
Long podId = plan.getPodId();
Long clusterId = plan.getClusterId();
ServiceOffering offering = vmProfile.getServiceOffering();
List<? extends Host> hostsCopy = null;
List<Host> suitableHosts = new ArrayList<Host>();
List<Host> suitableHosts = new ArrayList<>();
if (type == Host.Type.Storage) {
return suitableHosts;
}
String hostTag = offering.getHostTag();
if (hostTag != null) {
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));
} else {
s_logger.debug("Looking for hosts in dc: " + dcId + " pod:" + podId + " cluster:" + clusterId);
}
String hostTagToLog = hostTag != null ? String.format("and complying with host tags [%s]", hostTag) : "";
String paramAsStringToLog = String.format("zone [%s], pod [%s], cluster [%s] %s", dcId, podId, clusterId, hostTagToLog);
s_logger.debug(String.format("Looking for hosts in %s.", paramAsStringToLog));
List<? extends Host> hostsCopy;
if (hosts != null) {
// retain all computing hosts, regardless of whether they support routing...it's random after all
hostsCopy = new ArrayList<Host>(hosts);
@ -88,7 +88,6 @@ public class RandomAllocator extends AdapterBase implements HostAllocator {
}
} else {
// list all computing hosts, regardless of whether they support routing...it's random after all
hostsCopy = new ArrayList<HostVO>();
if (hostTag != null) {
hostsCopy = _hostDao.listByHostTag(type, clusterId, podId, dcId, hostTag);
} else {
@ -98,14 +97,15 @@ public class RandomAllocator extends AdapterBase implements HostAllocator {
hostsCopy = ListUtils.union(hostsCopy, _hostDao.findHostsWithTagRuleThatMatchComputeOferringTags(hostTag));
if (hostsCopy.isEmpty()) {
s_logger.error(String.format("No suitable host found for vm [%s] with tags [%s].", vmProfile, hostTag));
throw new CloudRuntimeException(String.format("No suitable host found for vm [%s].", vmProfile));
s_logger.info(String.format("No suitable host found for VM [%s] in %s.", vmProfile, paramAsStringToLog));
return null;
}
s_logger.debug("Random Allocator found " + hostsCopy.size() + " hosts");
if (hostsCopy.size() == 0) {
if (hostsCopy.isEmpty()) {
return suitableHosts;
}
Collections.shuffle(hostsCopy);
for (Host host : hostsCopy) {
if (suitableHosts.size() == returnUpTo) {

View File

@ -25,7 +25,6 @@ import java.util.Map;
import javax.inject.Inject;
import javax.naming.ConfigurationException;
import com.cloud.utils.exception.CloudRuntimeException;
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
@ -132,8 +131,10 @@ public class FirstFitAllocator extends AdapterBase implements HostAllocator {
return new ArrayList<Host>();
}
String paramAsStringToLog = String.format("zone [%s], pod [%s], cluster [%s]", dcId, podId, clusterId);
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();
@ -206,8 +207,8 @@ public class FirstFitAllocator extends AdapterBase implements HostAllocator {
if (clusterHosts.isEmpty()) {
s_logger.error(String.format("No suitable host found for vm [%s] with tags [%s].", vmProfile, hostTagOnOffering));
throw new CloudRuntimeException(String.format("No suitable host found for vm [%s].", vmProfile));
s_logger.info(String.format("No suitable host found for VM [%s] with tags [%s] in %s.", vmProfile, hostTagOnOffering, paramAsStringToLog));
return null;
}
// add all hosts that we are not considering to the avoid list
List<HostVO> allhostsInCluster = _hostDao.listAllUpAndEnabledNonHAHosts(type, clusterId, podId, dcId, null);

View File

@ -26,6 +26,7 @@ import java.util.Set;
import javax.inject.Inject;
import javax.naming.ConfigurationException;
import org.apache.commons.collections.CollectionUtils;
import org.apache.log4j.Logger;
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) {
List<Host> hosts = super.allocateTo(vm, plan, type, avoid, returnUpTo);
if (hosts != null && !hosts.isEmpty()) {
if (CollectionUtils.isNotEmpty(hosts)) {
return hosts;
}

View File

@ -1273,7 +1273,7 @@ StateListener<State, VirtualMachine.Event, VirtualMachine>, Configurable {
List<Host> suitableHosts = findSuitableHosts(vmProfile, potentialPlan, avoid, HostAllocator.RETURN_UPTO_ALL);
// if found suitable hosts in this cluster, find suitable storage
// pools for each volume of the VM
if (suitableHosts != null && !suitableHosts.isEmpty()) {
if (CollectionUtils.isNotEmpty(suitableHosts)) {
if (vmProfile.getHypervisorType() == HypervisorType.BareMetal) {
DeployDestination dest = new DeployDestination(dc, pod, clusterVO, suitableHosts.get(0));
return dest;
@ -1621,17 +1621,16 @@ StateListener<State, VirtualMachine.Event, VirtualMachine>, Configurable {
List<Host> suitableHosts = new ArrayList<Host>();
for (HostAllocator allocator : _hostAllocators) {
suitableHosts = allocator.allocateTo(vmProfile, plan, Host.Type.Routing, avoid, returnUpTo);
if (suitableHosts != null && !suitableHosts.isEmpty()) {
if (CollectionUtils.isNotEmpty(suitableHosts)) {
break;
}
}
if (suitableHosts.isEmpty()) {
s_logger.debug("No suitable hosts found");
}
// re-order hosts by priority
if (CollectionUtils.isEmpty(suitableHosts)) {
s_logger.debug("No suitable hosts found.");
} else {
reorderHostsByPriority(plan.getHostPriorities(), suitableHosts);
}
return suitableHosts;
}

View File

@ -525,7 +525,7 @@ public class FirstFitPlanner extends AdapterBase implements DeploymentClusterPla
matchingClusters.addAll(hostDao.findClustersThatMatchHostTagRule(hostTagOnOffering));
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.");
}

View File

@ -1590,21 +1590,18 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
suitableHosts = allocator.allocateTo(vmProfile, plan, Host.Type.Routing, excludes, HostAllocator.RETURN_UPTO_ALL, false);
}
if (suitableHosts != null && !suitableHosts.isEmpty()) {
if (CollectionUtils.isNotEmpty(suitableHosts)) {
break;
}
}
// re-order hosts by priority
_dpMgr.reorderHostsByPriority(plan.getHostPriorities(), suitableHosts);
if (s_logger.isDebugEnabled()) {
if (suitableHosts.isEmpty()) {
s_logger.debug("No suitable hosts found");
s_logger.warn("No suitable hosts found.");
} else {
s_logger.debug("Hosts having capacity and suitable for migration: " + suitableHosts);
}
}
return new Ternary<>(otherHosts, suitableHosts, requiresStorageMotion);
}