Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow deploy of VRs on dedicated resources #9531

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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 @@ -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<CapacityVO, Long> {

ConfigKey<Boolean> allowRoutersOnDedicatedResources = new ConfigKey<>("Advanced", Boolean.class, "allow.routers.on.dedicated.resources", "false",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a bit weary having Daos be Configurables. Can this be setting be moved to the Planner-hierarchy somehow?

"Allow deploying virtual routers on dedicated Hosts, Clusters, Pods, and Zones", true);

CapacityVO findByHostIdType(Long hostId, short capacityType);

List<Long> listClustersInZoneOrPodByHostCapacities(long id, long vmId, int requiredCpu, long requiredRam, short capacityTypeForOrdering, boolean isZone);
Expand All @@ -38,7 +43,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, short capacityType, boolean isVr, 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 @@ -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;
Expand All @@ -49,7 +51,7 @@
import com.cloud.utils.exception.CloudRuntimeException;

@Component
public class CapacityDaoImpl extends GenericDaoBase<CapacityVO, Long> implements CapacityDao {
public class CapacityDaoImpl extends GenericDaoBase<CapacityVO, Long> 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 =
Expand Down Expand Up @@ -87,6 +89,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_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))";
Expand Down Expand Up @@ -963,7 +972,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, short capacityTypeForOrdering, boolean isVr, boolean isZone) {
TransactionLegacy txn = TransactionLegacy.currentTxn();
PreparedStatement pstmt = null;
List<Long> result = new ArrayList<Long>();
Expand All @@ -975,7 +984,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.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 {
Expand Down Expand Up @@ -1207,4 +1221,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();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -368,7 +368,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, Capacity.CAPACITY_TYPE_CPU, false, true)).thenReturn(clustersOrderedByCapacity);

List<Long> disabledClusters = new ArrayList<Long>();
List<Long> clustersWithDisabledPods = new ArrayList<Long>();
Expand Down
7 changes: 4 additions & 3 deletions server/src/main/java/com/cloud/deploy/FirstFitPlanner.java
Original file line number Diff line number Diff line change
Expand Up @@ -388,9 +388,10 @@ 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());

//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(), requiredCpu, requiredRam, isVr, isZone);
List<Long> prioritizedClusterIds = clusterCapacityInfo.first();
if (!prioritizedClusterIds.isEmpty()) {
if (avoid.getClustersToAvoid() != null) {
Expand Down Expand Up @@ -448,7 +449,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, 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 @@ -467,7 +468,7 @@ protected Pair<List<Long>, Map<Long, Double>> listClustersByCapacity(long id, lo
if (logger.isTraceEnabled()) {
logger.trace("ClusterId List having enough CPU and RAM capacity: " + clusterIdswithEnoughCapacity);
}
Pair<List<Long>, Map<Long, Double>> result = capacityDao.orderClustersByAggregateCapacity(id, vmId, capacityType, isZone);
Pair<List<Long>, Map<Long, Double>> result = capacityDao.orderClustersByAggregateCapacity(id, vmId, capacityType, isVr, isZone);
List<Long> clusterIdsOrderedByAggregateCapacity = result.first();
//only keep the clusters that have enough capacity to host this VM
if (logger.isTraceEnabled()) {
Expand Down
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 @@ -306,7 +306,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, Capacity.CAPACITY_TYPE_CPU, false, true)).thenReturn(clustersOrderedByCapacity);

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