Fix CKS cluster creation not honoring the CKS ISO arch (#11902)

* Fix CKS cluster creation not honouring the CKS ISO arch

* Fix arch type reference to choose right template

* Include template name on the CKS clusters response

---------

Co-authored-by: Harikrishna Patnala <harikrishna.patnala@gmail.com>
This commit is contained in:
Nicolas Vazquez 2025-10-27 02:28:46 -03:00 committed by GitHub
parent f52a27cce6
commit 2dbc86abfa
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 35 additions and 12 deletions

View File

@ -556,7 +556,7 @@ public class KubernetesClusterManagerImpl extends ManagerBase implements Kuberne
if (cksIso == null) {
return systemVMPreferredArchitecture;
}
String cksIsoArchName = cksIso.getArch().name();
String cksIsoArchName = cksIso.getArch().getType();
return cksIsoArchName.equals(systemVMPreferredArchitecture) ? systemVMPreferredArchitecture : cksIsoArchName;
}
@ -807,6 +807,7 @@ public class KubernetesClusterManagerImpl extends ManagerBase implements Kuberne
VMTemplateVO template = ApiDBUtils.findTemplateById(kubernetesCluster.getTemplateId());
if (template != null) {
response.setTemplateId(template.getUuid());
response.setTemplateName(template.getName());
}
ServiceOfferingVO offering = serviceOfferingDao.findByIdIncludingRemoved(kubernetesCluster.getServiceOfferingId());
if (offering != null) {

View File

@ -36,6 +36,7 @@ import java.util.stream.Collectors;
import javax.inject.Inject;
import com.cloud.cpu.CPU;
import com.cloud.deploy.DataCenterDeployment;
import com.cloud.deploy.DeploymentPlan;
import com.cloud.dc.DedicatedResourceVO;
@ -177,7 +178,7 @@ public class KubernetesClusterResourceModifierActionWorker extends KubernetesClu
}
protected DeployDestination plan(final long nodesCount, final DataCenter zone, final ServiceOffering offering,
final Long domainId, final Long accountId, final Hypervisor.HypervisorType hypervisorType) throws InsufficientServerCapacityException {
final Long domainId, final Long accountId, final Hypervisor.HypervisorType hypervisorType, CPU.CPUArch arch) throws InsufficientServerCapacityException {
final int cpu_requested = offering.getCpu() * offering.getSpeed();
final long ram_requested = offering.getRamSize() * 1024L * 1024L;
boolean useDedicatedHosts = false;
@ -201,6 +202,15 @@ public class KubernetesClusterResourceModifierActionWorker extends KubernetesClu
if (hypervisorType != null) {
hosts = hosts.stream().filter(x -> x.getHypervisorType() == hypervisorType).collect(Collectors.toList());
}
if (arch != null) {
hosts = hosts.stream().filter(x -> x.getArch().equals(arch)).collect(Collectors.toList());
}
if (CollectionUtils.isEmpty(hosts)) {
String msg = String.format("Cannot find enough capacity for Kubernetes cluster(requested cpu=%d memory=%s) with offering: %s hypervisor: %s and arch: %s",
cpu_requested * nodesCount, toHumanReadableSize(ram_requested * nodesCount), offering.getName(), clusterTemplate.getHypervisorType().toString(), arch.getType());
logAndThrow(Level.WARN, msg, new InsufficientServerCapacityException(msg, DataCenter.class, zone.getId()));
}
final Map<String, Pair<HostVO, Integer>> hosts_with_resevered_capacity = new ConcurrentHashMap<String, Pair<HostVO, Integer>>();
for (HostVO h : hosts) {
hosts_with_resevered_capacity.put(h.getUuid(), new Pair<HostVO, Integer>(h, 0));
@ -254,8 +264,8 @@ public class KubernetesClusterResourceModifierActionWorker extends KubernetesClu
}
return new DeployDestination(zone, null, null, null);
}
String msg = String.format("Cannot find enough capacity for Kubernetes cluster(requested cpu=%d memory=%s) with offering: %s and hypervisor: %s",
cpu_requested * nodesCount, toHumanReadableSize(ram_requested * nodesCount), offering.getName(), clusterTemplate.getHypervisorType().toString());
String msg = String.format("Cannot find enough capacity for Kubernetes cluster(requested cpu=%d memory=%s) with offering: %s hypervisor: %s and arch: %s",
cpu_requested * nodesCount, toHumanReadableSize(ram_requested * nodesCount), offering.getName(), clusterTemplate.getHypervisorType().toString(), arch.getType());
logger.warn(msg);
throw new InsufficientServerCapacityException(msg, DataCenter.class, zone.getId());
@ -265,7 +275,7 @@ public class KubernetesClusterResourceModifierActionWorker extends KubernetesClu
* Plan Kubernetes Cluster Deployment
* @return a map of DeployDestination per node type
*/
protected Map<String, DeployDestination> planKubernetesCluster(Long domainId, Long accountId, Hypervisor.HypervisorType hypervisorType) throws InsufficientServerCapacityException {
protected Map<String, DeployDestination> planKubernetesCluster(Long domainId, Long accountId, Hypervisor.HypervisorType hypervisorType, CPU.CPUArch arch) throws InsufficientServerCapacityException {
Map<String, DeployDestination> destinationMap = new HashMap<>();
DataCenter zone = dataCenterDao.findById(kubernetesCluster.getZoneId());
if (logger.isDebugEnabled()) {
@ -286,7 +296,7 @@ public class KubernetesClusterResourceModifierActionWorker extends KubernetesClu
if (logger.isDebugEnabled()) {
logger.debug("Checking deployment destination for {} nodes on Kubernetes cluster : {} in zone : {}", nodeType.name(), kubernetesCluster.getName(), zone.getName());
}
DeployDestination planForNodeType = plan(nodes, zone, nodeOffering, domainId, accountId, hypervisorType);
DeployDestination planForNodeType = plan(nodes, zone, nodeOffering, domainId, accountId, hypervisorType, arch);
destinationMap.put(nodeType.name(), planForNodeType);
}
return destinationMap;
@ -322,7 +332,7 @@ public class KubernetesClusterResourceModifierActionWorker extends KubernetesClu
if (Objects.nonNull(domainId) && !listDedicatedHostsInDomain(domainId).isEmpty()) {
DeployDestination dest = null;
try {
Map<String, DeployDestination> destinationMap = planKubernetesCluster(domainId, accountId, vm.getHypervisorType());
Map<String, DeployDestination> destinationMap = planKubernetesCluster(domainId, accountId, vm.getHypervisorType(), clusterTemplate.getArch());
dest = destinationMap.get(nodeType.name());
} catch (InsufficientCapacityException e) {
logTransitStateAndThrow(Level.ERROR, String.format("Provisioning the cluster failed due to insufficient capacity in the Kubernetes cluster: %s", kubernetesCluster.getUuid()), kubernetesCluster.getId(), KubernetesCluster.Event.CreateFailed, e);

View File

@ -341,9 +341,9 @@ public class KubernetesClusterScaleWorker extends KubernetesClusterResourceModif
VMTemplateVO clusterTemplate = templateDao.findById(kubernetesCluster.getTemplateId());
try {
if (originalState.equals(KubernetesCluster.State.Running)) {
plan(newVmRequiredCount, zone, clusterServiceOffering, kubernetesCluster.getDomainId(), kubernetesCluster.getAccountId(), clusterTemplate.getHypervisorType());
plan(newVmRequiredCount, zone, clusterServiceOffering, kubernetesCluster.getDomainId(), kubernetesCluster.getAccountId(), clusterTemplate.getHypervisorType(), clusterTemplate.getArch());
} else {
plan(kubernetesCluster.getTotalNodeCount() + newVmRequiredCount, zone, clusterServiceOffering, kubernetesCluster.getDomainId(), kubernetesCluster.getAccountId(), clusterTemplate.getHypervisorType());
plan(kubernetesCluster.getTotalNodeCount() + newVmRequiredCount, zone, clusterServiceOffering, kubernetesCluster.getDomainId(), kubernetesCluster.getAccountId(), clusterTemplate.getHypervisorType(), clusterTemplate.getArch());
}
} catch (InsufficientCapacityException e) {
logTransitStateToFailedIfNeededAndThrow(Level.WARN, String.format("Scaling failed for Kubernetes cluster : %s in zone : %s, insufficient capacity", kubernetesCluster.getName(), zone.getName()));

View File

@ -749,7 +749,7 @@ public class KubernetesClusterStartWorker extends KubernetesClusterResourceModif
DeployDestination dest = null;
try {
VMTemplateVO clusterTemplate = templateDao.findById(kubernetesCluster.getTemplateId());
Map<String, DeployDestination> destinationMap = planKubernetesCluster(domainId, accountId, clusterTemplate.getHypervisorType());
Map<String, DeployDestination> destinationMap = planKubernetesCluster(domainId, accountId, clusterTemplate.getHypervisorType(), clusterTemplate.getArch());
dest = destinationMap.get(WORKER.name());
} catch (InsufficientCapacityException e) {
logTransitStateAndThrow(Level.ERROR, String.format("Provisioning the cluster failed due to insufficient capacity in the Kubernetes cluster: %s", kubernetesCluster.getUuid()), kubernetesCluster.getId(), KubernetesCluster.Event.CreateFailed, e);

View File

@ -91,6 +91,10 @@ public class KubernetesClusterResponse extends BaseResponseWithAnnotations imple
@Param(description = "the ID of the template of the Kubernetes cluster")
private String templateId;
@SerializedName(ApiConstants.TEMPLATE_NAME)
@Param(description = "the name of the template of the Kubernetes cluster")
private String templateName;
@SerializedName(ApiConstants.NETWORK_ID)
@Param(description = "the ID of the network of the Kubernetes cluster")
private String networkId;
@ -267,6 +271,14 @@ public class KubernetesClusterResponse extends BaseResponseWithAnnotations imple
this.templateId = templateId;
}
public String getTemplateName() {
return templateName;
}
public void setTemplateName(String templateName) {
this.templateName = templateName;
}
public String getNetworkId() {
return networkId;
}

View File

@ -430,7 +430,7 @@ public class KubernetesClusterManagerImplTest {
VMTemplateVO cksIso = Mockito.mock(VMTemplateVO.class);
Mockito.when(cksIso.getArch()).thenReturn(CPU.CPUArch.arm64);
String cksClusterPreferredArch = kubernetesClusterManager.getCksClusterPreferredArch(systemVMArch, cksIso);
Assert.assertEquals(CPU.CPUArch.arm64.name(), cksClusterPreferredArch);
Assert.assertEquals(CPU.CPUArch.arm64.getType(), cksClusterPreferredArch);
}
@Test
@ -439,6 +439,6 @@ public class KubernetesClusterManagerImplTest {
VMTemplateVO cksIso = Mockito.mock(VMTemplateVO.class);
Mockito.when(cksIso.getArch()).thenReturn(CPU.CPUArch.amd64);
String cksClusterPreferredArch = kubernetesClusterManager.getCksClusterPreferredArch(systemVMArch, cksIso);
Assert.assertEquals(CPU.CPUArch.amd64.name(), cksClusterPreferredArch);
Assert.assertEquals(CPU.CPUArch.amd64.getType(), cksClusterPreferredArch);
}
}