tweak logic to consider tags and rule tags at zone and cluster scope

This commit is contained in:
Pearl Dsilva 2026-01-16 15:01:44 -05:00
parent dc5ba75f6c
commit f48cc9cc8a
1 changed files with 62 additions and 27 deletions

View File

@ -767,6 +767,7 @@ import com.cloud.storage.ScopeType;
import com.cloud.storage.Storage; import com.cloud.storage.Storage;
import com.cloud.storage.StorageManager; import com.cloud.storage.StorageManager;
import com.cloud.storage.StoragePool; import com.cloud.storage.StoragePool;
import com.cloud.storage.StoragePoolStatus;
import com.cloud.storage.VMTemplateVO; import com.cloud.storage.VMTemplateVO;
import com.cloud.storage.Volume; import com.cloud.storage.Volume;
import com.cloud.storage.VolumeApiServiceImpl; import com.cloud.storage.VolumeApiServiceImpl;
@ -1998,42 +1999,76 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
return suitablePools; return suitablePools;
} }
HypervisorType hypervisorType = getHypervisorType(null, srcPool);
List<ClusterVO> clusters = _clusterDao.listByDcHyType(srcPool.getDataCenterId(), hypervisorType.toString());
DiskOfferingVO diskOffering = _diskOfferingDao.findById(diskOfferingId); DiskOfferingVO diskOffering = _diskOfferingDao.findById(diskOfferingId);
DiskProfile diskProfile = new DiskProfile(volume, diskOffering, hypervisorType); String[] tagsArray = diskOffering.getTagsArray();
List<String> tags = (tagsArray != null && tagsArray.length > 0) ? Arrays.asList(tagsArray) : new ArrayList<>();
ExcludeList avoid = new ExcludeList(); HypervisorType hypervisorType = getHypervisorType(null, srcPool);
Long dcId = srcPool.getDataCenterId();
Set<Long> allPoolIds = allPools.stream() logger.debug("Finding suitable pools for detached volume {} with offering tags: {}, hypervisor: {}",
.map(StoragePool::getId) volume.getUuid(), tags, hypervisorType);
.collect(Collectors.toSet());
Set<Long> addedPoolIds = new HashSet<>();
for (Cluster cluster : clusters) { // Create a map for quick lookup and deduplication
DataCenterDeployment plan = new DataCenterDeployment(srcPool.getDataCenterId(), cluster.getPodId(), cluster.getId(), Map<Long, StoragePool> allPoolsMap = allPools.stream()
null, null, null, null); .collect(Collectors.toMap(StoragePool::getId, pool -> pool));
Set<Long> matchingPoolIds = new HashSet<>();
for (StoragePoolAllocator allocator : _storagePoolAllocators) { List<StoragePoolVO> zonePoolsLiteral = _poolDao.findZoneWideStoragePoolsByTags(dcId,
try { tags.isEmpty() ? null : tags.toArray(new String[0]), true);
List<StoragePool> pools = allocator.allocateToPool(diskProfile, null, plan, avoid, StoragePoolAllocator.RETURN_UPTO_ALL, for (StoragePoolVO pool : zonePoolsLiteral) {
false, null); if (pool.getHypervisor() == null || pool.getHypervisor().equals(HypervisorType.Any) ||
if (CollectionUtils.isNotEmpty(pools)) { pool.getHypervisor().equals(hypervisorType)) {
for (StoragePool pool : pools) { matchingPoolIds.add(pool.getId());
if (allPoolIds.contains(pool.getId()) && !addedPoolIds.contains(pool.getId())) { logger.debug("Found zone-wide pool with literal tags: {} ({})", pool.getName(), pool.getId());
suitablePools.add(pool); }
addedPoolIds.add(pool.getId()); }
}
} List<StoragePoolVO> zonePoolsRules = _poolJoinDao.findStoragePoolByScopeAndRuleTags(dcId, null, null,
} ScopeType.ZONE, tags);
} catch (Exception e) { for (StoragePoolVO pool : zonePoolsRules) {
logger.warn("Allocator {} failed to find storage pools for detached volume {} due to {}", StoragePoolVO poolVO = _poolDao.findById(pool.getId());
allocator.getClass().getSimpleName(), volume.getId(), e.getMessage()); if (poolVO != null && (poolVO.getHypervisor() == null || poolVO.getHypervisor().equals(HypervisorType.Any) ||
poolVO.getHypervisor().equals(hypervisorType))) {
matchingPoolIds.add(pool.getId());
logger.debug("Found zone-wide pool with rule-based tags: {} ({})", pool.getName(), pool.getId());
}
}
List<ClusterVO> clusters = _clusterDao.listByDcHyType(dcId, hypervisorType.toString());
for (ClusterVO cluster : clusters) {
List<StoragePoolVO> clusterPoolsLiteral = _poolDao.findPoolsByTags(dcId, cluster.getPodId(),
cluster.getId(), tags.isEmpty() ? null : tags.toArray(new String[0]), true,
VolumeApiServiceImpl.storageTagRuleExecutionTimeout.value());
for (StoragePoolVO pool : clusterPoolsLiteral) {
matchingPoolIds.add(pool.getId());
logger.debug("Found cluster-scoped pool with literal tags: {} ({}) in cluster {}",
pool.getName(), pool.getId(), cluster.getName());
}
List<StoragePoolVO> clusterPoolsRules = _poolJoinDao.findStoragePoolByScopeAndRuleTags(dcId,
cluster.getPodId(), cluster.getId(), ScopeType.CLUSTER, tags);
for (StoragePoolVO pool : clusterPoolsRules) {
matchingPoolIds.add(pool.getId());
logger.debug("Found cluster-scoped pool with rule-based tags: {} ({}) in cluster {}",
pool.getName(), pool.getId(), cluster.getName());
}
}
for (Long poolId : matchingPoolIds) {
if (allPoolsMap.containsKey(poolId)) {
StoragePool pool = allPoolsMap.get(poolId);
if (StoragePoolStatus.Up.equals(pool.getStatus())) {
suitablePools.add(pool);
logger.debug("Added pool {} to suitable pools", pool.getName());
} else {
logger.debug("Skipping pool {} - status is {}, not Up", pool.getName(), pool.getStatus());
} }
} }
} }
logger.debug("Found {} suitable pools out of {} total pools for detached volume {}",
suitablePools.size(), allPools.size(), volume.getUuid());
return suitablePools; return suitablePools;
} }