Skip to content

Commit 582187a

Browse files
committed
preferred arch config
New zone-scope config added system.vm.preferred.architecture to allow deployment using specific architecture for system VMs including VRs. Refactor and added checks for deployements Signed-off-by: Abhishek Kumar <[email protected]>
1 parent a2a7f5d commit 582187a

File tree

10 files changed

+155
-66
lines changed

10 files changed

+155
-66
lines changed

engine/api/src/main/java/com/cloud/vm/VirtualMachineManager.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,4 +309,8 @@ static String getHypervisorHostname(String name) {
309309

310310
Map<Long, Boolean> getDiskOfferingSuitabilityForVm(long vmId, List<Long> diskOfferingIds);
311311

312+
void checkDeploymentPlan(VirtualMachine virtualMachine, VirtualMachineTemplate template,
313+
ServiceOffering serviceOffering, Account systemAccount, DeploymentPlan plan)
314+
throws InsufficientServerCapacityException;
315+
312316
}

engine/components-api/src/main/java/com/cloud/resource/ResourceManager.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,14 @@ public interface ResourceManager extends ResourceService, Configurable {
6161
+ "To force-stop VMs, choose 'ForceStop' strategy",
6262
true, ConfigKey.Scope.Global, null, null, null, null, null, ConfigKey.Kind.Select, "Error,Migration,ForceStop");
6363

64+
ConfigKey<String> SystemVmPreferredArchitecture = new ConfigKey<>("Advanced"
65+
, String.class
66+
, "system.vm.preferred.architecture"
67+
, ""
68+
, "Preferred architecture for the system VMs including virtual routers"
69+
, true
70+
, ConfigKey.Scope.Zone);
71+
6472
/**
6573
* Register a listener for different types of resource life cycle events.
6674
* There can only be one type of listener per type of host.

engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6081,4 +6081,18 @@ public Map<Long, Boolean> getDiskOfferingSuitabilityForVm(long vmId, List<Long>
60816081
}
60826082
return result;
60836083
}
6084+
6085+
@Override
6086+
public void checkDeploymentPlan(VirtualMachine virtualMachine, VirtualMachineTemplate template,
6087+
ServiceOffering serviceOffering, Account systemAccount, DeploymentPlan plan)
6088+
throws InsufficientServerCapacityException {
6089+
final VirtualMachineProfileImpl vmProfile =
6090+
new VirtualMachineProfileImpl(virtualMachine, template, serviceOffering, systemAccount, null);
6091+
DeployDestination destination =
6092+
_dpMgr.planDeployment(vmProfile, plan, new DeploymentPlanner.ExcludeList(), null);
6093+
if (destination == null) {
6094+
throw new InsufficientServerCapacityException(String.format("Unable to create a deployment for %s",
6095+
vmProfile), DataCenter.class, plan.getDataCenterId(), areAffinityGroupsAssociated(vmProfile));
6096+
}
6097+
}
60846098
}

engine/schema/src/main/java/com/cloud/storage/dao/VMTemplateDao.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,11 +74,11 @@ public interface VMTemplateDao extends GenericDao<VMTemplateVO, Long>, StateDao<
7474

7575
VMTemplateVO findSystemVMReadyTemplate(long zoneId, HypervisorType hypervisorType);
7676

77-
List<VMTemplateVO> findSystemVMReadyTemplates(long zoneId, HypervisorType hypervisorType);
77+
List<VMTemplateVO> findSystemVMReadyTemplates(long zoneId, HypervisorType hypervisorType, String preferredArch);
7878

7979
VMTemplateVO findRoutingTemplate(HypervisorType type, String templateName);
8080

81-
List<VMTemplateVO> findRoutingTemplates(HypervisorType type, String templateName);
81+
List<VMTemplateVO> findRoutingTemplates(HypervisorType type, String templateName, String preferredArch);
8282

8383
VMTemplateVO findLatestTemplateByTypeAndHypervisorAndArch(HypervisorType hypervisorType, CPU.CPUArch arch, Storage.TemplateType type);
8484

engine/schema/src/main/java/com/cloud/storage/dao/VMTemplateDaoImpl.java

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
3131
import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO;
3232
import org.apache.commons.collections.CollectionUtils;
33+
import org.apache.commons.lang3.StringUtils;
3334
import org.springframework.stereotype.Component;
3435

3536
import com.cloud.cpu.CPU;
@@ -585,8 +586,31 @@ public VMTemplateVO findSystemVMReadyTemplate(long zoneId, HypervisorType hyperv
585586
.orElse(null);
586587
}
587588

589+
private List<VMTemplateVO> getSortedTemplatesListWithPreferredArch(
590+
Map<Pair<HypervisorType, CPU.CPUArch>, VMTemplateVO> uniqueTemplates, String preferredArch) {
591+
List<VMTemplateVO> result = new ArrayList<>(uniqueTemplates.values());
592+
if (StringUtils.isNotBlank(preferredArch)) {
593+
result.sort((t1, t2) -> {
594+
boolean t1Preferred = t1.getArch().getType().equalsIgnoreCase(preferredArch);
595+
boolean t2Preferred = t2.getArch().getType().equalsIgnoreCase(preferredArch);
596+
if (t1Preferred && !t2Preferred) {
597+
return -1; // t1 comes before t2
598+
} else if (!t1Preferred && t2Preferred) {
599+
return 1; // t2 comes before t1
600+
} else {
601+
// Both are either preferred or not preferred; use template id as a secondary sorting key.
602+
return Long.compare(t1.getId(), t2.getId());
603+
}
604+
});
605+
} else {
606+
result.sort(Comparator.comparing(VMTemplateVO::getId).reversed());
607+
}
608+
return result;
609+
}
588610

589-
private List<VMTemplateVO> listAllReadySystemVMTemplatesWithArch(Long zoneId, HypervisorType hypervisorType) {
611+
@Override
612+
public List<VMTemplateVO> findSystemVMReadyTemplates(long zoneId, HypervisorType hypervisorType,
613+
String preferredArch) {
590614
List<Pair<HypervisorType, CPU.CPUArch>> availableHypervisors = _hostDao.listDistinctHypervisorArchTypes(zoneId);
591615
if (CollectionUtils.isEmpty(availableHypervisors)) {
592616
return Collections.emptyList();
@@ -612,18 +636,7 @@ private List<VMTemplateVO> listAllReadySystemVMTemplatesWithArch(Long zoneId, Hy
612636
uniqueTemplates.put(key, template);
613637
}
614638
}
615-
List<VMTemplateVO> result = new ArrayList<>(uniqueTemplates.values());
616-
result.sort(Comparator.comparing(VMTemplateVO::getId).reversed());
617-
return result;
618-
}
619-
620-
@Override
621-
public List<VMTemplateVO> findSystemVMReadyTemplates(long zoneId, HypervisorType hypervisorType) {
622-
List<VMTemplateVO> templates = listAllReadySystemVMTemplatesWithArch(zoneId, hypervisorType);
623-
if (CollectionUtils.isEmpty(templates)) {
624-
return null;
625-
}
626-
return templates;
639+
return getSortedTemplatesListWithPreferredArch(uniqueTemplates, preferredArch);
627640
}
628641

629642
@Override
@@ -664,7 +677,7 @@ public VMTemplateVO findRoutingTemplate(HypervisorType hType, String templateNam
664677
}
665678

666679
@Override
667-
public List<VMTemplateVO> findRoutingTemplates(HypervisorType hType, String templateName) {
680+
public List<VMTemplateVO> findRoutingTemplates(HypervisorType hType, String templateName, String preferredArch) {
668681
SearchCriteria<VMTemplateVO> sc = tmpltTypeHyperSearch2.create();
669682
sc.setParameters("templateType", TemplateType.ROUTING);
670683
sc.setParameters("hypervisorType", hType);
@@ -690,7 +703,7 @@ public List<VMTemplateVO> findRoutingTemplates(HypervisorType hType, String temp
690703
uniqueTemplates.put(key, template);
691704
}
692705
}
693-
return new ArrayList<>(uniqueTemplates.values());
706+
return getSortedTemplatesListWithPreferredArch(uniqueTemplates, preferredArch);
694707
}
695708

696709
@Override

plugins/network-elements/internal-loadbalancer/src/main/java/org/apache/cloudstack/network/lb/InternalLoadBalancerVMManagerImpl.java

Lines changed: 43 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -749,22 +749,51 @@ protected String getRouterTemplateForHypervisor(HypervisorType hypervisorType, l
749749
return templateName;
750750
}
751751

752-
protected DomainRouterVO deployInternalLbVmWithTemplates(final long id, final DeploymentPlan plan, final long internalLbProviderId,
753-
final Account owner, final long userId, final Long vpcId, final ServiceOffering routerOffering,
754-
final LinkedHashMap<Network, List<? extends NicProfile>> networks,
755-
final List<VMTemplateVO> templates) throws InsufficientCapacityException {
752+
protected DomainRouterVO createOrUpdateInternalLb(DomainRouterVO internalLbVm, final long id,
753+
final long internalLbProviderId, final Account owner, final long userId, final Long vpcId,
754+
final ServiceOffering routerOffering,
755+
final LinkedHashMap<Network, List<? extends NicProfile>> networks,
756+
final VMTemplateVO template) {
757+
if (internalLbVm == null) {
758+
internalLbVm = new DomainRouterVO(id, routerOffering.getId(), internalLbProviderId,
759+
VirtualMachineName.getSystemVmName(id, _instance, InternalLbVmNamePrefix),
760+
template.getId(), template.getHypervisorType(), template.getGuestOSId(),
761+
owner.getDomainId(), owner.getId(), userId, false,
762+
RedundantState.UNKNOWN, false, false,
763+
VirtualMachine.Type.InternalLoadBalancerVm, vpcId);
764+
internalLbVm.setRole(Role.INTERNAL_LB_VM);
765+
internalLbVm.setLimitCpuUse(routerOffering.getLimitCpuUse());
766+
internalLbVm.setDynamicallyScalable(template.isDynamicallyScalable());
767+
return _internalLbVmDao.persist(internalLbVm);
768+
}
769+
internalLbVm.setTemplateId(template.getId());
770+
internalLbVm.setDynamicallyScalable(template.isDynamicallyScalable());
771+
_internalLbVmDao.update(internalLbVm.getId(), internalLbVm);
772+
return internalLbVm;
773+
}
774+
775+
protected DomainRouterVO deployInternalLbVmWithTemplates(DomainRouterVO internalLbVm, final long id,
776+
final DeploymentPlan plan, final long internalLbProviderId, final Account owner, final long userId,
777+
final Long vpcId, final ServiceOffering routerOffering,
778+
final LinkedHashMap<Network, List<? extends NicProfile>> networks, final List<VMTemplateVO> templates)
779+
throws InsufficientCapacityException {
756780
for (final Iterator<VMTemplateVO> templatesIterator = templates.iterator(); templatesIterator.hasNext();) {
757781
final VMTemplateVO template = templatesIterator.next();
758782
try {
759-
DomainRouterVO internalLbVm = new DomainRouterVO(id, routerOffering.getId(), internalLbProviderId,
783+
internalLbVm = new DomainRouterVO(id, routerOffering.getId(), internalLbProviderId,
760784
VirtualMachineName.getSystemVmName(id, _instance, InternalLbVmNamePrefix),
761785
template.getId(), template.getHypervisorType(), template.getGuestOSId(),
762786
owner.getDomainId(), owner.getId(), userId, false,
763-
RedundantState.UNKNOWN, false, false, VirtualMachine.Type.InternalLoadBalancerVm, vpcId);
787+
RedundantState.UNKNOWN, false, false,
788+
VirtualMachine.Type.InternalLoadBalancerVm, vpcId);
764789
internalLbVm.setRole(Role.INTERNAL_LB_VM);
765790
internalLbVm = _internalLbVmDao.persist(internalLbVm);
766791
_itMgr.allocate(internalLbVm.getInstanceName(), template, routerOffering, networks, plan, null);
767-
return _internalLbVmDao.findById(internalLbVm.getId());
792+
internalLbVm = _internalLbVmDao.findById(internalLbVm.getId());
793+
if (templatesIterator.hasNext()) {
794+
_itMgr.checkDeploymentPlan(internalLbVm, template, routerOffering, owner, plan);
795+
}
796+
return internalLbVm;
768797
} catch (InsufficientCapacityException ex) {
769798
if (templatesIterator.hasNext()) {
770799
logger.debug("Failed to allocate the VR with hypervisor {} and {}, retrying with another template", template.getHypervisorType(), template);
@@ -806,14 +835,17 @@ protected DomainRouterVO deployInternalLbVm(final Account owner, final DeployDes
806835
logger.debug("Creating the internal lb vm {} in datacenter {} with hypervisor type {}",
807836
id, dest.getDataCenter(), hType);
808837
}
809-
final String templateName = getRouterTemplateForHypervisor(hType, dest.getDataCenter().getId());
810-
final List<VMTemplateVO> templates = _templateDao.findRoutingTemplates(hType, templateName);
838+
final long zoneId = dest.getDataCenter().getId();
839+
final String templateName = getRouterTemplateForHypervisor(hType, zoneId);
840+
final String preferredArch = ResourceManager.SystemVmPreferredArchitecture.valueIn(zoneId);
841+
final List<VMTemplateVO> templates = _templateDao.findRoutingTemplates(hType, templateName,
842+
preferredArch);
811843
if (CollectionUtils.isEmpty(templates)) {
812844
logger.debug("{} won't support system vm, skip it", hType);
813845
continue;
814846
}
815-
internalLbVm = deployInternalLbVmWithTemplates(id, plan, internalLbProviderId, owner, userId, vpcId,
816-
routerOffering, networks, templates);
847+
internalLbVm = deployInternalLbVmWithTemplates(internalLbVm, id, plan, internalLbProviderId, owner,
848+
userId, vpcId, routerOffering, networks, templates);
817849
} catch (final InsufficientCapacityException ex) {
818850
if (allocateRetry < 2 && iter.hasNext()) {
819851
logger.debug("Failed to allocate the Internal lb vm with hypervisor type {}, retrying one more time", hType);

server/src/main/java/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,6 @@
7474
import com.cloud.deploy.DataCenterDeployment;
7575
import com.cloud.deploy.DeployDestination;
7676
import com.cloud.deploy.DeploymentPlanner;
77-
import com.cloud.deploy.DeploymentPlanningManager;
7877
import com.cloud.event.ActionEvent;
7978
import com.cloud.event.EventTypes;
8079
import com.cloud.exception.ConcurrentOperationException;
@@ -146,7 +145,6 @@
146145
import com.cloud.vm.VirtualMachineManager;
147146
import com.cloud.vm.VirtualMachineName;
148147
import com.cloud.vm.VirtualMachineProfile;
149-
import com.cloud.vm.VirtualMachineProfileImpl;
150148
import com.cloud.vm.dao.ConsoleProxyDao;
151149
import com.cloud.vm.dao.UserVmDetailsDao;
152150
import com.cloud.vm.dao.VMInstanceDao;
@@ -229,8 +227,6 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy
229227
private CAManager caManager;
230228
@Inject
231229
private NetworkOrchestrationService networkMgr;
232-
@Inject
233-
DeploymentPlanningManager deploymentPlanningManager;
234230

235231
private ConsoleProxyListener consoleProxyListener;
236232

@@ -576,7 +572,8 @@ public ConsoleProxyVO startNew(long dataCenterId) throws ConcurrentOperationExce
576572
}
577573

578574
HypervisorType availableHypervisor = resourceManager.getAvailableHypervisor(dataCenterId);
579-
List<VMTemplateVO> templates = vmTemplateDao.findSystemVMReadyTemplates(dataCenterId, availableHypervisor);
575+
List<VMTemplateVO> templates = vmTemplateDao.findSystemVMReadyTemplates(dataCenterId, availableHypervisor,
576+
ResourceManager.SystemVmPreferredArchitecture.valueIn(dataCenterId));
580577
if (CollectionUtils.isEmpty(templates)) {
581578
throw new CloudRuntimeException("Not able to find the System templates or not downloaded in zone " + dataCenterId);
582579
}
@@ -727,11 +724,10 @@ protected Map<String, Object> createProxyInstance(long dataCenterId, List<VMTemp
727724
VMTemplateVO template = templateIterator.next();
728725
proxy = createOrUpdateConsoleProxy(proxy, dataCenterId, id, name, serviceOffering, template, systemAcct);
729726
try {
730-
virtualMachineManager.allocate(name, template, serviceOffering, networks, plan, null);
727+
virtualMachineManager.allocate(name, template, serviceOffering, networks, plan,
728+
template.getHypervisorType());
731729
proxy = consoleProxyDao.findById(proxy.getId());
732-
final VirtualMachineProfileImpl vmProfile =
733-
new VirtualMachineProfileImpl(proxy, template, serviceOffering, systemAcct, null);
734-
deploymentPlanningManager.planDeployment(vmProfile, plan, new DeploymentPlanner.ExcludeList(), null);
730+
virtualMachineManager.checkDeploymentPlan(proxy, template, serviceOffering, systemAcct, plan);
735731
break;
736732
} catch (InsufficientCapacityException e) {
737733
if (templateIterator.hasNext()) {
@@ -902,7 +898,8 @@ public boolean isZoneReady(Map<Long, ZoneHostInfo> zoneHostInfoMap, DataCenter d
902898
}
903899
ZoneHostInfo zoneHostInfo = zoneHostInfoMap.get(dataCenter.getId());
904900
if (zoneHostInfo != null && isZoneHostReady(zoneHostInfo)) {
905-
List<VMTemplateVO> templates = vmTemplateDao.findSystemVMReadyTemplates(dataCenter.getId(), HypervisorType.Any);
901+
List<VMTemplateVO> templates = vmTemplateDao.findSystemVMReadyTemplates(dataCenter.getId(),
902+
HypervisorType.Any, null);
906903
if (CollectionUtils.isEmpty(templates)) {
907904
if (logger.isDebugEnabled()) {
908905
logger.debug("System vm template is not ready at data center {}, wait until it is ready to launch console proxy vm", dataCenter);

0 commit comments

Comments
 (0)