From 68e16c562ba2dc2895e17a8cd7b723fe04f10fac Mon Sep 17 00:00:00 2001 From: Gabriel Date: Tue, 6 Aug 2024 09:10:26 -0300 Subject: [PATCH 1/2] allow deploy of VRs on dedicated resources --- .../com/cloud/capacity/dao/CapacityDao.java | 7 ++++- .../cloud/capacity/dao/CapacityDaoImpl.java | 29 +++++++++++++++++-- .../implicitplanner/ImplicitPlannerTest.java | 2 +- .../com/cloud/deploy/FirstFitPlanner.java | 7 +++-- .../com/cloud/vm/FirstFitPlannerTest.java | 2 +- 5 files changed, 38 insertions(+), 9 deletions(-) diff --git a/engine/schema/src/main/java/com/cloud/capacity/dao/CapacityDao.java b/engine/schema/src/main/java/com/cloud/capacity/dao/CapacityDao.java index 1bb79ce417aa..80dbaadafaff 100644 --- a/engine/schema/src/main/java/com/cloud/capacity/dao/CapacityDao.java +++ b/engine/schema/src/main/java/com/cloud/capacity/dao/CapacityDao.java @@ -24,8 +24,13 @@ import com.cloud.utils.Pair; import com.cloud.utils.Ternary; import com.cloud.utils.db.GenericDao; +import org.apache.cloudstack.framework.config.ConfigKey; public interface CapacityDao extends GenericDao { + + ConfigKey allowRoutersOnDedicatedResources = new ConfigKey<>("Advanced", Boolean.class, "allow.routers.on.dedicated.resources", "false", + "Allow deploying virtual routers on dedicated Hosts, Clusters, Pods, and Zones", true); + CapacityVO findByHostIdType(Long hostId, short capacityType); List listByHostIdTypes(Long hostId, List capacityTypes); @@ -40,7 +45,7 @@ public interface CapacityDao extends GenericDao { List findNonSharedStorageForClusterPodZone(Long zoneId, Long podId, Long clusterId); - Pair, Map> orderClustersByAggregateCapacity(long id, long vmId, short capacityType, boolean isZone); + Pair, Map> orderClustersByAggregateCapacity(long id, long vmId, short capacityType, boolean isVr, boolean isZone); Ternary findCapacityByZoneAndHostTag(Long zoneId, String hostTag); diff --git a/engine/schema/src/main/java/com/cloud/capacity/dao/CapacityDaoImpl.java b/engine/schema/src/main/java/com/cloud/capacity/dao/CapacityDaoImpl.java index 5e7eee4566c1..d13ca5739a0e 100644 --- a/engine/schema/src/main/java/com/cloud/capacity/dao/CapacityDaoImpl.java +++ b/engine/schema/src/main/java/com/cloud/capacity/dao/CapacityDaoImpl.java @@ -26,6 +26,8 @@ import javax.inject.Inject; +import org.apache.cloudstack.framework.config.ConfigKey; +import org.apache.cloudstack.framework.config.Configurable; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; import org.apache.commons.collections.CollectionUtils; @@ -49,7 +51,7 @@ import com.cloud.utils.exception.CloudRuntimeException; @Component -public class CapacityDaoImpl extends GenericDaoBase implements CapacityDao { +public class CapacityDaoImpl extends GenericDaoBase implements CapacityDao, Configurable { private static final String ADD_ALLOCATED_SQL = "UPDATE `cloud`.`op_host_capacity` SET used_capacity = used_capacity + ? WHERE host_id = ? AND capacity_type = ?"; private static final String SUBTRACT_ALLOCATED_SQL = @@ -87,6 +89,13 @@ public class CapacityDaoImpl extends GenericDaoBase implements "LEFT JOIN dedicated_resources dr_cluster ON dr_cluster.cluster_id IS NOT NULL AND dr_cluster.cluster_id = host.cluster_id " + "LEFT JOIN dedicated_resources dr_host ON dr_host.host_id IS NOT NULL AND dr_host.host_id = host.id "; + private static final String ORDER_CLUSTERS_BY_AGGREGATE_CAPACITY_INCLUDE_DEDICATED_TO_DOMAIN_JOIN_1 = + "JOIN host ON capacity.host_id = host.id " + + "LEFT JOIN (SELECT affinity_group.id, agvm.instance_id FROM affinity_group_vm_map agvm JOIN affinity_group ON agvm.affinity_group_id = affinity_group.id AND affinity_group.type='ExplicitDedication') AS ag ON ag.instance_id = ? " + + "LEFT JOIN dedicated_resources dr_pod ON dr_pod.pod_id IS NOT NULL AND dr_pod.pod_id = host.pod_id AND dr_pod.account_id IS NOT NULL " + + "LEFT JOIN dedicated_resources dr_cluster ON dr_cluster.cluster_id IS NOT NULL AND dr_cluster.cluster_id = host.cluster_id AND dr_cluster.account_id IS NOT NULL " + + "LEFT JOIN dedicated_resources dr_host ON dr_host.host_id IS NOT NULL AND dr_host.host_id = host.id AND dr_host.account_id IS NOT NULL "; + private static final String ORDER_CLUSTERS_BY_AGGREGATE_CAPACITY_JOIN_2 = " AND ((ag.id IS NULL AND dr_pod.pod_id IS NULL AND dr_cluster.cluster_id IS NULL AND dr_host.host_id IS NULL) OR " + "(dr_pod.affinity_group_id = ag.id OR dr_cluster.affinity_group_id = ag.id OR dr_host.affinity_group_id = ag.id))"; @@ -975,7 +984,7 @@ public boolean removeBy(Short capacityType, Long zoneId, Long podId, Long cluste } @Override - public Pair, Map> orderClustersByAggregateCapacity(long id, long vmId, short capacityTypeForOrdering, boolean isZone) { + public Pair, Map> orderClustersByAggregateCapacity(long id, long vmId, short capacityTypeForOrdering, boolean isVr, boolean isZone) { TransactionLegacy txn = TransactionLegacy.currentTxn(); PreparedStatement pstmt = null; List result = new ArrayList(); @@ -987,7 +996,12 @@ public Pair, Map> orderClustersByAggregateCapacity(long sql.append(ORDER_CLUSTERS_BY_AGGREGATE_OVERCOMMIT_CAPACITY_PART1); } - sql.append(ORDER_CLUSTERS_BY_AGGREGATE_CAPACITY_JOIN_1); + if (isVr && allowRoutersOnDedicatedResources.value()) { + sql.append(ORDER_CLUSTERS_BY_AGGREGATE_CAPACITY_INCLUDE_DEDICATED_TO_DOMAIN_JOIN_1); + } else { + sql.append(ORDER_CLUSTERS_BY_AGGREGATE_CAPACITY_JOIN_1); + } + if (isZone) { sql.append("WHERE capacity.capacity_state = 'Enabled' AND capacity.data_center_id = ?"); } else { @@ -1219,4 +1233,13 @@ public float findClusterConsumption(Long clusterId, short capacityType, long com return 0; } + @Override + public ConfigKey[] getConfigKeys() { + return new ConfigKey[] {allowRoutersOnDedicatedResources}; + } + + @Override + public String getConfigComponentName() { + return CapacityDaoImpl.class.getSimpleName(); + } } diff --git a/plugins/deployment-planners/implicit-dedication/src/test/java/org/apache/cloudstack/implicitplanner/ImplicitPlannerTest.java b/plugins/deployment-planners/implicit-dedication/src/test/java/org/apache/cloudstack/implicitplanner/ImplicitPlannerTest.java index 2d2b4c78261e..4f99e5bfa89d 100644 --- a/plugins/deployment-planners/implicit-dedication/src/test/java/org/apache/cloudstack/implicitplanner/ImplicitPlannerTest.java +++ b/plugins/deployment-planners/implicit-dedication/src/test/java/org/apache/cloudstack/implicitplanner/ImplicitPlannerTest.java @@ -366,7 +366,7 @@ private void initializeForTest(VirtualMachineProfileImpl vmProfile, DataCenterDe clusterCapacityMap.put(2L, 2048D); clusterCapacityMap.put(3L, 2048D); Pair, Map> clustersOrderedByCapacity = new Pair, Map>(clustersWithEnoughCapacity, clusterCapacityMap); - when(capacityDao.orderClustersByAggregateCapacity(dataCenterId, 12L, Capacity.CAPACITY_TYPE_CPU, true)).thenReturn(clustersOrderedByCapacity); + when(capacityDao.orderClustersByAggregateCapacity(dataCenterId, 12L, Capacity.CAPACITY_TYPE_CPU, false, true)).thenReturn(clustersOrderedByCapacity); List disabledClusters = new ArrayList(); List clustersWithDisabledPods = new ArrayList(); diff --git a/server/src/main/java/com/cloud/deploy/FirstFitPlanner.java b/server/src/main/java/com/cloud/deploy/FirstFitPlanner.java index abaf48400e23..ca9caf159d71 100644 --- a/server/src/main/java/com/cloud/deploy/FirstFitPlanner.java +++ b/server/src/main/java/com/cloud/deploy/FirstFitPlanner.java @@ -388,9 +388,10 @@ private List scanClustersForDestinationInZoneOrPod(long id, boolean isZone DataCenter dc = dcDao.findById(vm.getDataCenterId()); int requiredCpu = offering.getCpu() * offering.getSpeed(); long requiredRam = offering.getRamSize() * 1024L * 1024L; + boolean isVr = VirtualMachine.Type.DomainRouter.equals(vmProfile.getType()); //list clusters under this zone by cpu and ram capacity - Pair, Map> clusterCapacityInfo = listClustersByCapacity(id, vmProfile.getId(), requiredCpu, requiredRam, avoid, isZone); + Pair, Map> clusterCapacityInfo = listClustersByCapacity(id, vmProfile.getId(), requiredCpu, requiredRam, isVr, isZone); List prioritizedClusterIds = clusterCapacityInfo.first(); if (!prioritizedClusterIds.isEmpty()) { if (avoid.getClustersToAvoid() != null) { @@ -448,7 +449,7 @@ protected List reorderPods(Pair, Map> podCapacity return podIdsByCapacity; } - protected Pair, Map> listClustersByCapacity(long id, long vmId, int requiredCpu, long requiredRam, ExcludeList avoid, boolean isZone) { + protected Pair, Map> listClustersByCapacity(long id, long vmId, int requiredCpu, long requiredRam, boolean isVr, boolean isZone) { //look at the aggregate available cpu and ram per cluster //although an aggregate value may be false indicator that a cluster can host a vm, it will at the least eliminate those clusters which definitely cannot @@ -467,7 +468,7 @@ protected Pair, Map> listClustersByCapacity(long id, lo if (logger.isTraceEnabled()) { logger.trace("ClusterId List having enough CPU and RAM capacity: " + clusterIdswithEnoughCapacity); } - Pair, Map> result = capacityDao.orderClustersByAggregateCapacity(id, vmId, capacityType, isZone); + Pair, Map> result = capacityDao.orderClustersByAggregateCapacity(id, vmId, capacityType, isVr, isZone); List clusterIdsOrderedByAggregateCapacity = result.first(); //only keep the clusters that have enough capacity to host this VM if (logger.isTraceEnabled()) { diff --git a/server/src/test/java/com/cloud/vm/FirstFitPlannerTest.java b/server/src/test/java/com/cloud/vm/FirstFitPlannerTest.java index 7df4857f4fdf..632ac540b9e0 100644 --- a/server/src/test/java/com/cloud/vm/FirstFitPlannerTest.java +++ b/server/src/test/java/com/cloud/vm/FirstFitPlannerTest.java @@ -304,7 +304,7 @@ private void initializeForTest(VirtualMachineProfileImpl vmProfile, DataCenterDe clusterCapacityMap.put(6L, 2048D); Pair, Map> clustersOrderedByCapacity = new Pair, Map>(clustersWithEnoughCapacity, clusterCapacityMap); - when(capacityDao.orderClustersByAggregateCapacity(dataCenterId, 12L, Capacity.CAPACITY_TYPE_CPU, true)).thenReturn(clustersOrderedByCapacity); + when(capacityDao.orderClustersByAggregateCapacity(dataCenterId, 12L, Capacity.CAPACITY_TYPE_CPU, false, true)).thenReturn(clustersOrderedByCapacity); List disabledClusters = new ArrayList(); List clustersWithDisabledPods = new ArrayList(); From e15e36639469e9002e2c73f9cb4fdb690aa8a6a0 Mon Sep 17 00:00:00 2001 From: Nicole Schmidt Date: Wed, 5 Feb 2025 10:03:28 -0300 Subject: [PATCH 2/2] Move configuration to Planner hierarchy --- .../cloud/deploy/DeploymentClusterPlanner.java | 8 ++++++++ .../com/cloud/capacity/dao/CapacityDao.java | 6 +----- .../cloud/capacity/dao/CapacityDaoImpl.java | 18 +++--------------- .../implicitplanner/ImplicitPlannerTest.java | 2 +- .../java/com/cloud/deploy/FirstFitPlanner.java | 4 ++-- .../java/com/cloud/vm/FirstFitPlannerTest.java | 2 +- 6 files changed, 16 insertions(+), 24 deletions(-) diff --git a/api/src/main/java/com/cloud/deploy/DeploymentClusterPlanner.java b/api/src/main/java/com/cloud/deploy/DeploymentClusterPlanner.java index 2697311d2b94..23eb84b38702 100644 --- a/api/src/main/java/com/cloud/deploy/DeploymentClusterPlanner.java +++ b/api/src/main/java/com/cloud/deploy/DeploymentClusterPlanner.java @@ -68,6 +68,14 @@ public interface DeploymentClusterPlanner extends DeploymentPlanner { ConfigKey.Kind.Select, "random,firstfit,userdispersing,userconcentratedpod_random,userconcentratedpod_firstfit,firstfitleastconsumed"); + ConfigKey allowRoutersOnDedicatedResources = new ConfigKey<>( + "Advanced", + Boolean.class, + "allow.routers.on.dedicated.resources", + "false", + "Allow deploying virtual routers on dedicated Hosts, Clusters, Pods, and Zones", + true); + /** * This is called to determine list of possible clusters where a virtual * machine can be deployed. diff --git a/engine/schema/src/main/java/com/cloud/capacity/dao/CapacityDao.java b/engine/schema/src/main/java/com/cloud/capacity/dao/CapacityDao.java index 80dbaadafaff..13c43a29bd3e 100644 --- a/engine/schema/src/main/java/com/cloud/capacity/dao/CapacityDao.java +++ b/engine/schema/src/main/java/com/cloud/capacity/dao/CapacityDao.java @@ -24,13 +24,9 @@ import com.cloud.utils.Pair; import com.cloud.utils.Ternary; import com.cloud.utils.db.GenericDao; -import org.apache.cloudstack.framework.config.ConfigKey; public interface CapacityDao extends GenericDao { - ConfigKey allowRoutersOnDedicatedResources = new ConfigKey<>("Advanced", Boolean.class, "allow.routers.on.dedicated.resources", "false", - "Allow deploying virtual routers on dedicated Hosts, Clusters, Pods, and Zones", true); - CapacityVO findByHostIdType(Long hostId, short capacityType); List listByHostIdTypes(Long hostId, List capacityTypes); @@ -45,7 +41,7 @@ public interface CapacityDao extends GenericDao { List findNonSharedStorageForClusterPodZone(Long zoneId, Long podId, Long clusterId); - Pair, Map> orderClustersByAggregateCapacity(long id, long vmId, short capacityType, boolean isVr, boolean isZone); + Pair, Map> orderClustersByAggregateCapacity(long id, long vmId, short capacityType, boolean isVr, boolean allowRoutersOnDedicatedResources, boolean isZone); Ternary findCapacityByZoneAndHostTag(Long zoneId, String hostTag); diff --git a/engine/schema/src/main/java/com/cloud/capacity/dao/CapacityDaoImpl.java b/engine/schema/src/main/java/com/cloud/capacity/dao/CapacityDaoImpl.java index d13ca5739a0e..3f216122c5be 100644 --- a/engine/schema/src/main/java/com/cloud/capacity/dao/CapacityDaoImpl.java +++ b/engine/schema/src/main/java/com/cloud/capacity/dao/CapacityDaoImpl.java @@ -26,8 +26,6 @@ import javax.inject.Inject; -import org.apache.cloudstack.framework.config.ConfigKey; -import org.apache.cloudstack.framework.config.Configurable; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; import org.apache.commons.collections.CollectionUtils; @@ -51,7 +49,7 @@ import com.cloud.utils.exception.CloudRuntimeException; @Component -public class CapacityDaoImpl extends GenericDaoBase implements CapacityDao, Configurable { +public class CapacityDaoImpl extends GenericDaoBase implements CapacityDao { private static final String ADD_ALLOCATED_SQL = "UPDATE `cloud`.`op_host_capacity` SET used_capacity = used_capacity + ? WHERE host_id = ? AND capacity_type = ?"; private static final String SUBTRACT_ALLOCATED_SQL = @@ -984,7 +982,7 @@ public boolean removeBy(Short capacityType, Long zoneId, Long podId, Long cluste } @Override - public Pair, Map> orderClustersByAggregateCapacity(long id, long vmId, short capacityTypeForOrdering, boolean isVr, boolean isZone) { + public Pair, Map> orderClustersByAggregateCapacity(long id, long vmId, short capacityTypeForOrdering, boolean isVr, boolean allowRoutersOnDedicatedResources, boolean isZone) { TransactionLegacy txn = TransactionLegacy.currentTxn(); PreparedStatement pstmt = null; List result = new ArrayList(); @@ -996,7 +994,7 @@ public Pair, Map> orderClustersByAggregateCapacity(long sql.append(ORDER_CLUSTERS_BY_AGGREGATE_OVERCOMMIT_CAPACITY_PART1); } - if (isVr && allowRoutersOnDedicatedResources.value()) { + if (isVr && allowRoutersOnDedicatedResources) { sql.append(ORDER_CLUSTERS_BY_AGGREGATE_CAPACITY_INCLUDE_DEDICATED_TO_DOMAIN_JOIN_1); } else { sql.append(ORDER_CLUSTERS_BY_AGGREGATE_CAPACITY_JOIN_1); @@ -1232,14 +1230,4 @@ public float findClusterConsumption(Long clusterId, short capacityType, long com } return 0; } - - @Override - public ConfigKey[] getConfigKeys() { - return new ConfigKey[] {allowRoutersOnDedicatedResources}; - } - - @Override - public String getConfigComponentName() { - return CapacityDaoImpl.class.getSimpleName(); - } } diff --git a/plugins/deployment-planners/implicit-dedication/src/test/java/org/apache/cloudstack/implicitplanner/ImplicitPlannerTest.java b/plugins/deployment-planners/implicit-dedication/src/test/java/org/apache/cloudstack/implicitplanner/ImplicitPlannerTest.java index 4f99e5bfa89d..cd3ec5e27514 100644 --- a/plugins/deployment-planners/implicit-dedication/src/test/java/org/apache/cloudstack/implicitplanner/ImplicitPlannerTest.java +++ b/plugins/deployment-planners/implicit-dedication/src/test/java/org/apache/cloudstack/implicitplanner/ImplicitPlannerTest.java @@ -366,7 +366,7 @@ private void initializeForTest(VirtualMachineProfileImpl vmProfile, DataCenterDe clusterCapacityMap.put(2L, 2048D); clusterCapacityMap.put(3L, 2048D); Pair, Map> clustersOrderedByCapacity = new Pair, Map>(clustersWithEnoughCapacity, clusterCapacityMap); - when(capacityDao.orderClustersByAggregateCapacity(dataCenterId, 12L, Capacity.CAPACITY_TYPE_CPU, false, true)).thenReturn(clustersOrderedByCapacity); + when(capacityDao.orderClustersByAggregateCapacity(dataCenterId, 12L, Capacity.CAPACITY_TYPE_CPU, false, false, true)).thenReturn(clustersOrderedByCapacity); List disabledClusters = new ArrayList(); List clustersWithDisabledPods = new ArrayList(); diff --git a/server/src/main/java/com/cloud/deploy/FirstFitPlanner.java b/server/src/main/java/com/cloud/deploy/FirstFitPlanner.java index ca9caf159d71..9ca403139697 100644 --- a/server/src/main/java/com/cloud/deploy/FirstFitPlanner.java +++ b/server/src/main/java/com/cloud/deploy/FirstFitPlanner.java @@ -468,7 +468,7 @@ protected Pair, Map> listClustersByCapacity(long id, lo if (logger.isTraceEnabled()) { logger.trace("ClusterId List having enough CPU and RAM capacity: " + clusterIdswithEnoughCapacity); } - Pair, Map> result = capacityDao.orderClustersByAggregateCapacity(id, vmId, capacityType, isVr, isZone); + Pair, Map> result = capacityDao.orderClustersByAggregateCapacity(id, vmId, capacityType, isVr, allowRoutersOnDedicatedResources.value(), isZone); List clusterIdsOrderedByAggregateCapacity = result.first(); //only keep the clusters that have enough capacity to host this VM if (logger.isTraceEnabled()) { @@ -595,6 +595,6 @@ public String getConfigComponentName() { @Override public ConfigKey[] getConfigKeys() { - return new ConfigKey[] {ClusterCPUCapacityDisableThreshold, ClusterMemoryCapacityDisableThreshold, ClusterThresholdEnabled, VmAllocationAlgorithm}; + return new ConfigKey[] {ClusterCPUCapacityDisableThreshold, ClusterMemoryCapacityDisableThreshold, ClusterThresholdEnabled, VmAllocationAlgorithm, allowRoutersOnDedicatedResources}; } } diff --git a/server/src/test/java/com/cloud/vm/FirstFitPlannerTest.java b/server/src/test/java/com/cloud/vm/FirstFitPlannerTest.java index 632ac540b9e0..369e38bc629e 100644 --- a/server/src/test/java/com/cloud/vm/FirstFitPlannerTest.java +++ b/server/src/test/java/com/cloud/vm/FirstFitPlannerTest.java @@ -304,7 +304,7 @@ private void initializeForTest(VirtualMachineProfileImpl vmProfile, DataCenterDe clusterCapacityMap.put(6L, 2048D); Pair, Map> clustersOrderedByCapacity = new Pair, Map>(clustersWithEnoughCapacity, clusterCapacityMap); - when(capacityDao.orderClustersByAggregateCapacity(dataCenterId, 12L, Capacity.CAPACITY_TYPE_CPU, false, true)).thenReturn(clustersOrderedByCapacity); + when(capacityDao.orderClustersByAggregateCapacity(dataCenterId, 12L, Capacity.CAPACITY_TYPE_CPU, false, false,true)).thenReturn(clustersOrderedByCapacity); List disabledClusters = new ArrayList(); List clustersWithDisabledPods = new ArrayList();