Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,14 @@ public interface DeploymentClusterPlanner extends DeploymentPlanner {
ConfigKey.Kind.Select,
"random,firstfit,userdispersing,firstfitleastconsumed");

ConfigKey<Boolean> 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.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import com.cloud.utils.db.GenericDao;

public interface CapacityDao extends GenericDao<CapacityVO, Long> {

CapacityVO findByHostIdType(Long hostId, short capacityType);

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

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

Pair<List<Long>, Map<Long, Double>> orderClustersByAggregateCapacity(long id, long vmId, short capacityType, boolean isZone);
Pair<List<Long>, Map<Long, Double>> orderClustersByAggregateCapacity(long id, long vmId, Long ownerId, short capacityType, boolean isVr, boolean allowRoutersOnDedicatedResources, boolean isZone);

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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,13 @@ public class CapacityDaoImpl extends GenericDaoBase<CapacityVO, Long> 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_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 AND dr_pod.account_id != ownerId " +
"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 AND dr_cluster.account_id != ownerId " +
"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 AND dr_host.account_id != ownerId ";

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))";
Expand Down Expand Up @@ -986,7 +993,7 @@ public boolean removeBy(Short capacityType, Long zoneId, Long podId, Long cluste
}

@Override
public Pair<List<Long>, Map<Long, Double>> orderClustersByAggregateCapacity(long id, long vmId, short capacityTypeForOrdering, boolean isZone) {
public Pair<List<Long>, Map<Long, Double>> orderClustersByAggregateCapacity(long id, long vmId, Long ownerId, short capacityTypeForOrdering, boolean isVr, boolean allowRoutersOnDedicatedResources, boolean isZone) {
TransactionLegacy txn = TransactionLegacy.currentTxn();
PreparedStatement pstmt = null;
List<Long> result = new ArrayList<Long>();
Expand All @@ -998,7 +1005,12 @@ public Pair<List<Long>, Map<Long, Double>> orderClustersByAggregateCapacity(long
sql.append(ORDER_CLUSTERS_BY_AGGREGATE_OVERCOMMIT_CAPACITY_PART1);
}

sql.append(ORDER_CLUSTERS_BY_AGGREGATE_CAPACITY_JOIN_1);
if (isVr && allowRoutersOnDedicatedResources) {
sql.append(ORDER_CLUSTERS_BY_AGGREGATE_CAPACITY_INCLUDE_DEDICATED_JOIN_1.replace("ownerId", ownerId.toString()));
} 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 {
Expand Down Expand Up @@ -1290,5 +1302,4 @@ public float findClusterConsumption(Long clusterId, short capacityType, long com
}
return 0;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ public void testOrderClustersByAggregateCapacityEmptyResult() throws Exception {
when(pstmt.executeQuery()).thenReturn(resultSet);
when(resultSet.next()).thenReturn(false);

Pair<List<Long>, Map<Long, Double>> result = capacityDao.orderClustersByAggregateCapacity(1L, 1L, (short) 1, true);
Pair<List<Long>, Map<Long, Double>> result = capacityDao.orderClustersByAggregateCapacity(1L, 1L, 1L, (short) 1, false, false, true);
assertNotNull(result);
assertTrue(result.first().isEmpty());
assertTrue(result.second().isEmpty());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,7 @@ private void initializeForTest(VirtualMachineProfileImpl vmProfile, DataCenterDe
clusterCapacityMap.put(2L, 2048D);
clusterCapacityMap.put(3L, 2048D);
Pair<List<Long>, Map<Long, Double>> clustersOrderedByCapacity = new Pair<List<Long>, Map<Long, Double>>(clustersWithEnoughCapacity, clusterCapacityMap);
when(capacityDao.orderClustersByAggregateCapacity(dataCenterId, 12L, Capacity.CAPACITY_TYPE_CPU, true)).thenReturn(clustersOrderedByCapacity);
when(capacityDao.orderClustersByAggregateCapacity(dataCenterId, 12L, 1L, Capacity.CAPACITY_TYPE_CPU, false, false, true)).thenReturn(clustersOrderedByCapacity);

List<Long> disabledClusters = new ArrayList<Long>();
List<Long> clustersWithDisabledPods = new ArrayList<Long>();
Expand Down
14 changes: 8 additions & 6 deletions server/src/main/java/com/cloud/deploy/FirstFitPlanner.java
Original file line number Diff line number Diff line change
Expand Up @@ -398,9 +398,11 @@ private List<Long> 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());
Long ownerId = vm.getAccountId();

//list clusters under this zone by cpu and ram capacity
Pair<List<Long>, Map<Long, Double>> clusterCapacityInfo = listClustersByCapacity(id, vmProfile.getId(), requiredCpu, requiredRam, avoid, isZone);
Pair<List<Long>, Map<Long, Double>> clusterCapacityInfo = listClustersByCapacity(id, vmProfile.getId(), ownerId, requiredCpu, requiredRam, isVr, isZone);
List<Long> prioritizedClusterIds = clusterCapacityInfo.first();
if (!prioritizedClusterIds.isEmpty()) {
if (avoid.getClustersToAvoid() != null) {
Expand Down Expand Up @@ -458,7 +460,7 @@ protected List<Long> reorderPods(Pair<List<Long>, Map<Long, Double>> podCapacity
return podIdsByCapacity;
}

protected Pair<List<Long>, Map<Long, Double>> listClustersByCapacity(long id, long vmId, int requiredCpu, long requiredRam, ExcludeList avoid, boolean isZone) {
protected Pair<List<Long>, Map<Long, Double>> listClustersByCapacity(long id, long vmId, Long ownerId, 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

Expand All @@ -474,7 +476,7 @@ protected Pair<List<Long>, Map<Long, Double>> listClustersByCapacity(long id, lo
}


Pair<List<Long>, Map<Long, Double>> result = getOrderedClustersByCapacity(id, vmId, isZone);
Pair<List<Long>, Map<Long, Double>> result = getOrderedClustersByCapacity(id, vmId, ownerId, isVr, isZone);
List<Long> clusterIdsOrderedByAggregateCapacity = result.first();
//only keep the clusters that have enough capacity to host this VM
if (logger.isTraceEnabled()) {
Expand Down Expand Up @@ -554,14 +556,14 @@ public Map<Long, Double> getPodByCombinedCapacities(List<CapacityVO> capacities,
}


private Pair<List<Long>, Map<Long, Double>> getOrderedClustersByCapacity(long id, long vmId, boolean isZone) {
private Pair<List<Long>, Map<Long, Double>> getOrderedClustersByCapacity(long id, long vmId, Long ownerId, boolean isVr, boolean isZone) {
double cpuToMemoryWeight = ConfigurationManager.HostCapacityTypeCpuMemoryWeight.value();
short capacityType = getHostCapacityTypeToOrderCluster(
configDao.getValue(Config.HostCapacityTypeToOrderClusters.key()), cpuToMemoryWeight);

logger.debug("CapacityType: {} is used for Cluster ordering", getCapacityTypeName(capacityType));
if (capacityType >= 0) { // for capacityType other than COMBINED
return capacityDao.orderClustersByAggregateCapacity(id, vmId, capacityType, isZone);
return capacityDao.orderClustersByAggregateCapacity(id, vmId, ownerId, capacityType, isVr, allowRoutersOnDedicatedResources.value(), isZone);
}

Long zoneId = isZone ? id : null;
Expand Down Expand Up @@ -694,6 +696,6 @@ public String getConfigComponentName() {

@Override
public ConfigKey<?>[] getConfigKeys() {
return new ConfigKey<?>[] {ClusterCPUCapacityDisableThreshold, ClusterMemoryCapacityDisableThreshold, ClusterThresholdEnabled, VmAllocationAlgorithm};
return new ConfigKey<?>[] {ClusterCPUCapacityDisableThreshold, ClusterMemoryCapacityDisableThreshold, ClusterThresholdEnabled, VmAllocationAlgorithm, allowRoutersOnDedicatedResources};
}
}
2 changes: 1 addition & 1 deletion server/src/test/java/com/cloud/vm/FirstFitPlannerTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -373,7 +373,7 @@ private void initializeForTest(VirtualMachineProfileImpl vmProfile, DataCenterDe
clusterCapacityMap.put(6L, 2048D);

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

List<Long> disabledClusters = new ArrayList<Long>();
List<Long> clustersWithDisabledPods = new ArrayList<Long>();
Expand Down