Skip to content

Commit 9e19ab3

Browse files
committed
allow deploy of VRs on dedicated resources
1 parent 3166e64 commit 9e19ab3

6 files changed

Lines changed: 41 additions & 12 deletions

File tree

engine/schema/src/main/java/com/cloud/capacity/dao/CapacityDao.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,13 @@
2424
import com.cloud.utils.Pair;
2525
import com.cloud.utils.Ternary;
2626
import com.cloud.utils.db.GenericDao;
27+
import org.apache.cloudstack.framework.config.ConfigKey;
2728

2829
public interface CapacityDao extends GenericDao<CapacityVO, Long> {
30+
31+
ConfigKey<Boolean> allowRoutersOnDedicatedResources = new ConfigKey<>("Advanced", Boolean.class, "allow.routers.on.dedicated.resources", "false",
32+
"Allow deploying virtual routers on dedicated Hosts, Clusters, Pods, and Zones", true);
33+
2934
CapacityVO findByHostIdType(Long hostId, short capacityType);
3035

3136
List<CapacityVO> listByHostIdTypes(Long hostId, List<Short> capacityTypes);
@@ -40,7 +45,7 @@ public interface CapacityDao extends GenericDao<CapacityVO, Long> {
4045

4146
List<SummedCapacity> findNonSharedStorageForClusterPodZone(Long zoneId, Long podId, Long clusterId);
4247

43-
Pair<List<Long>, Map<Long, Double>> orderClustersByAggregateCapacity(long id, long vmId, short capacityType, boolean isZone);
48+
Pair<List<Long>, Map<Long, Double>> orderClustersByAggregateCapacity(long id, long vmId, short capacityType, boolean isVr, boolean isZone);
4449

4550
Ternary<Long, Long, Long> findCapacityByZoneAndHostTag(Long zoneId, String hostTag);
4651

engine/schema/src/main/java/com/cloud/capacity/dao/CapacityDaoImpl.java

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626

2727
import javax.inject.Inject;
2828

29+
import org.apache.cloudstack.framework.config.ConfigKey;
30+
import org.apache.cloudstack.framework.config.Configurable;
2931
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
3032
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
3133
import org.apache.commons.collections.CollectionUtils;
@@ -49,7 +51,7 @@
4951
import com.cloud.utils.exception.CloudRuntimeException;
5052

5153
@Component
52-
public class CapacityDaoImpl extends GenericDaoBase<CapacityVO, Long> implements CapacityDao {
54+
public class CapacityDaoImpl extends GenericDaoBase<CapacityVO, Long> implements CapacityDao, Configurable {
5355

5456
private static final String ADD_ALLOCATED_SQL = "UPDATE `cloud`.`op_host_capacity` SET used_capacity = used_capacity + ? WHERE host_id = ? AND capacity_type = ?";
5557
private static final String SUBTRACT_ALLOCATED_SQL =
@@ -87,6 +89,13 @@ public class CapacityDaoImpl extends GenericDaoBase<CapacityVO, Long> implements
8789
"LEFT JOIN dedicated_resources dr_cluster ON dr_cluster.cluster_id IS NOT NULL AND dr_cluster.cluster_id = host.cluster_id " +
8890
"LEFT JOIN dedicated_resources dr_host ON dr_host.host_id IS NOT NULL AND dr_host.host_id = host.id ";
8991

92+
private static final String ORDER_CLUSTERS_BY_AGGREGATE_CAPACITY_INCLUDE_DEDICATED_TO_DOMAIN_JOIN_1 =
93+
"JOIN host ON capacity.host_id = host.id " +
94+
"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 = ? " +
95+
"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 " +
96+
"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 " +
97+
"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 ";
98+
9099
private static final String ORDER_CLUSTERS_BY_AGGREGATE_CAPACITY_JOIN_2 =
91100
" 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 " +
92101
"(dr_pod.affinity_group_id = ag.id OR dr_cluster.affinity_group_id = ag.id OR dr_host.affinity_group_id = ag.id))";
@@ -986,7 +995,7 @@ public boolean removeBy(Short capacityType, Long zoneId, Long podId, Long cluste
986995
}
987996

988997
@Override
989-
public Pair<List<Long>, Map<Long, Double>> orderClustersByAggregateCapacity(long id, long vmId, short capacityTypeForOrdering, boolean isZone) {
998+
public Pair<List<Long>, Map<Long, Double>> orderClustersByAggregateCapacity(long id, long vmId, short capacityTypeForOrdering, boolean isVr, boolean isZone) {
990999
TransactionLegacy txn = TransactionLegacy.currentTxn();
9911000
PreparedStatement pstmt = null;
9921001
List<Long> result = new ArrayList<Long>();
@@ -998,7 +1007,12 @@ public Pair<List<Long>, Map<Long, Double>> orderClustersByAggregateCapacity(long
9981007
sql.append(ORDER_CLUSTERS_BY_AGGREGATE_OVERCOMMIT_CAPACITY_PART1);
9991008
}
10001009

1001-
sql.append(ORDER_CLUSTERS_BY_AGGREGATE_CAPACITY_JOIN_1);
1010+
if (isVr && allowRoutersOnDedicatedResources.value()) {
1011+
sql.append(ORDER_CLUSTERS_BY_AGGREGATE_CAPACITY_INCLUDE_DEDICATED_TO_DOMAIN_JOIN_1);
1012+
} else {
1013+
sql.append(ORDER_CLUSTERS_BY_AGGREGATE_CAPACITY_JOIN_1);
1014+
}
1015+
10021016
if (isZone) {
10031017
sql.append("WHERE capacity.capacity_state = 'Enabled' AND capacity.data_center_id = ?");
10041018
} else {
@@ -1291,4 +1305,13 @@ public float findClusterConsumption(Long clusterId, short capacityType, long com
12911305
return 0;
12921306
}
12931307

1308+
@Override
1309+
public ConfigKey<?>[] getConfigKeys() {
1310+
return new ConfigKey<?>[] {allowRoutersOnDedicatedResources};
1311+
}
1312+
1313+
@Override
1314+
public String getConfigComponentName() {
1315+
return CapacityDaoImpl.class.getSimpleName();
1316+
}
12941317
}

engine/schema/src/test/java/com/cloud/capacity/dao/CapacityDaoImplTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,7 @@ public void testOrderClustersByAggregateCapacityEmptyResult() throws Exception {
250250
when(pstmt.executeQuery()).thenReturn(resultSet);
251251
when(resultSet.next()).thenReturn(false);
252252

253-
Pair<List<Long>, Map<Long, Double>> result = capacityDao.orderClustersByAggregateCapacity(1L, 1L, (short) 1, true);
253+
Pair<List<Long>, Map<Long, Double>> result = capacityDao.orderClustersByAggregateCapacity(1L, 1L, (short) 1, false,true);
254254
assertNotNull(result);
255255
assertTrue(result.first().isEmpty());
256256
assertTrue(result.second().isEmpty());

plugins/deployment-planners/implicit-dedication/src/test/java/org/apache/cloudstack/implicitplanner/ImplicitPlannerTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -366,7 +366,7 @@ private void initializeForTest(VirtualMachineProfileImpl vmProfile, DataCenterDe
366366
clusterCapacityMap.put(2L, 2048D);
367367
clusterCapacityMap.put(3L, 2048D);
368368
Pair<List<Long>, Map<Long, Double>> clustersOrderedByCapacity = new Pair<List<Long>, Map<Long, Double>>(clustersWithEnoughCapacity, clusterCapacityMap);
369-
when(capacityDao.orderClustersByAggregateCapacity(dataCenterId, 12L, Capacity.CAPACITY_TYPE_CPU, true)).thenReturn(clustersOrderedByCapacity);
369+
when(capacityDao.orderClustersByAggregateCapacity(dataCenterId, 12L, Capacity.CAPACITY_TYPE_CPU, false, true)).thenReturn(clustersOrderedByCapacity);
370370

371371
List<Long> disabledClusters = new ArrayList<Long>();
372372
List<Long> clustersWithDisabledPods = new ArrayList<Long>();

server/src/main/java/com/cloud/deploy/FirstFitPlanner.java

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -398,9 +398,10 @@ private List<Long> scanClustersForDestinationInZoneOrPod(long id, boolean isZone
398398
DataCenter dc = dcDao.findById(vm.getDataCenterId());
399399
int requiredCpu = offering.getCpu() * offering.getSpeed();
400400
long requiredRam = offering.getRamSize() * 1024L * 1024L;
401+
boolean isVr = VirtualMachine.Type.DomainRouter.equals(vmProfile.getType());
401402

402403
//list clusters under this zone by cpu and ram capacity
403-
Pair<List<Long>, Map<Long, Double>> clusterCapacityInfo = listClustersByCapacity(id, vmProfile.getId(), requiredCpu, requiredRam, avoid, isZone);
404+
Pair<List<Long>, Map<Long, Double>> clusterCapacityInfo = listClustersByCapacity(id, vmProfile.getId(), requiredCpu, requiredRam, isVr, isZone);
404405
List<Long> prioritizedClusterIds = clusterCapacityInfo.first();
405406
if (!prioritizedClusterIds.isEmpty()) {
406407
if (avoid.getClustersToAvoid() != null) {
@@ -458,7 +459,7 @@ protected List<Long> reorderPods(Pair<List<Long>, Map<Long, Double>> podCapacity
458459
return podIdsByCapacity;
459460
}
460461

461-
protected Pair<List<Long>, Map<Long, Double>> listClustersByCapacity(long id, long vmId, int requiredCpu, long requiredRam, ExcludeList avoid, boolean isZone) {
462+
protected Pair<List<Long>, Map<Long, Double>> listClustersByCapacity(long id, long vmId, int requiredCpu, long requiredRam, boolean isVr, boolean isZone) {
462463
//look at the aggregate available cpu and ram per cluster
463464
//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
464465

@@ -474,7 +475,7 @@ protected Pair<List<Long>, Map<Long, Double>> listClustersByCapacity(long id, lo
474475
}
475476

476477

477-
Pair<List<Long>, Map<Long, Double>> result = getOrderedClustersByCapacity(id, vmId, isZone);
478+
Pair<List<Long>, Map<Long, Double>> result = getOrderedClustersByCapacity(id, vmId, isVr, isZone);
478479
List<Long> clusterIdsOrderedByAggregateCapacity = result.first();
479480
//only keep the clusters that have enough capacity to host this VM
480481
if (logger.isTraceEnabled()) {
@@ -554,14 +555,14 @@ public Map<Long, Double> getPodByCombinedCapacities(List<CapacityVO> capacities,
554555
}
555556

556557

557-
private Pair<List<Long>, Map<Long, Double>> getOrderedClustersByCapacity(long id, long vmId, boolean isZone) {
558+
private Pair<List<Long>, Map<Long, Double>> getOrderedClustersByCapacity(long id, long vmId, boolean isVr, boolean isZone) {
558559
double cpuToMemoryWeight = ConfigurationManager.HostCapacityTypeCpuMemoryWeight.value();
559560
short capacityType = getHostCapacityTypeToOrderCluster(
560561
configDao.getValue(Config.HostCapacityTypeToOrderClusters.key()), cpuToMemoryWeight);
561562

562563
logger.debug("CapacityType: {} is used for Cluster ordering", getCapacityTypeName(capacityType));
563564
if (capacityType >= 0) { // for capacityType other than COMBINED
564-
return capacityDao.orderClustersByAggregateCapacity(id, vmId, capacityType, isZone);
565+
return capacityDao.orderClustersByAggregateCapacity(id, vmId, capacityType, isVr, isZone);
565566
}
566567

567568
Long zoneId = isZone ? id : null;

server/src/test/java/com/cloud/vm/FirstFitPlannerTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -373,7 +373,7 @@ private void initializeForTest(VirtualMachineProfileImpl vmProfile, DataCenterDe
373373
clusterCapacityMap.put(6L, 2048D);
374374

375375
Pair<List<Long>, Map<Long, Double>> clustersOrderedByCapacity = new Pair<List<Long>, Map<Long, Double>>(clustersWithEnoughCapacity, clusterCapacityMap);
376-
when(capacityDao.orderClustersByAggregateCapacity(dataCenterId, 12L, Capacity.CAPACITY_TYPE_CPU, true)).thenReturn(clustersOrderedByCapacity);
376+
when(capacityDao.orderClustersByAggregateCapacity(dataCenterId, 12L, Capacity.CAPACITY_TYPE_CPU, false, true)).thenReturn(clustersOrderedByCapacity);
377377

378378
List<Long> disabledClusters = new ArrayList<Long>();
379379
List<Long> clustersWithDisabledPods = new ArrayList<Long>();

0 commit comments

Comments
 (0)