mirror of https://github.com/apache/cloudstack.git
Global setting to select preferred storage pool (#5249)
* Global setting to select preferred storage pool Currently all the volumes are allocated on storage pools based on the capacity or the algorithm selected. Sometimes we need to deploy all volumes of particular account in a specific storage pool and in that case its not possible. with this change, we can specify the uuid of the preferred storage pool, so that all volumes of the account will be deployed in this pool * code feedback Co-authored-by: Rakesh Venkatesh <rakeshv@apache.org>
This commit is contained in:
parent
0011d45b22
commit
2a4c2c2506
|
|
@ -149,6 +149,9 @@ public interface StorageManager extends StorageService {
|
|||
"If set to true, the disk is created only when there is a suitable storage pool that supports the disk provisioning type specified by the service/disk offering. " +
|
||||
"If set to false, the disk is created with a disk provisioning type supported by the pool. Default value is false, and this is currently supported for VMware only.",
|
||||
true, ConfigKey.Scope.Zone);
|
||||
ConfigKey<String> PreferredStoragePool = new ConfigKey<String>(String.class, "preferred.storage.pool", "Advanced", "",
|
||||
"The UUID of preferred storage pool for allocation.", true, ConfigKey.Scope.Account, null);
|
||||
|
||||
/**
|
||||
* Returns a comma separated list of tags for the specified storage pool
|
||||
* @param poolId
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ import java.util.HashMap;
|
|||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
|
@ -300,6 +301,31 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
|
|||
return _volsDao.persist(newVol);
|
||||
}
|
||||
|
||||
private Optional<StoragePool> getMatchingStoragePool(String preferredPoolId, List<StoragePool> storagePools) {
|
||||
if (preferredPoolId == null) {
|
||||
return Optional.empty();
|
||||
}
|
||||
return storagePools.stream()
|
||||
.filter(pool -> pool.getUuid().equalsIgnoreCase(preferredPoolId))
|
||||
.findFirst();
|
||||
}
|
||||
|
||||
private Optional<StoragePool> getPreferredStoragePool(List<StoragePool> poolList, VirtualMachine vm) {
|
||||
String accountStoragePoolUuid = StorageManager.PreferredStoragePool.valueIn(vm.getAccountId());
|
||||
Optional<StoragePool> storagePool = getMatchingStoragePool(accountStoragePoolUuid, poolList);
|
||||
|
||||
if (storagePool.isPresent()) {
|
||||
s_logger.debug("A storage pool is specified for this account, so we will use this storage pool for allocation: "
|
||||
+ storagePool.get().getUuid());
|
||||
} else {
|
||||
String globalStoragePoolUuid = StorageManager.PreferredStoragePool.value();
|
||||
storagePool = getMatchingStoragePool(globalStoragePoolUuid, poolList);
|
||||
storagePool.ifPresent(pool -> s_logger.debug("A storage pool is specified in global setting, so we will use this storage pool for allocation: "
|
||||
+ pool.getUuid()));
|
||||
}
|
||||
return storagePool;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StoragePool findStoragePool(DiskProfile dskCh, DataCenter dc, Pod pod, Long clusterId, Long hostId, VirtualMachine vm, final Set<StoragePool> avoid) {
|
||||
Long podId = null;
|
||||
|
|
@ -321,9 +347,13 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
|
|||
}
|
||||
DataCenterDeployment plan = new DataCenterDeployment(dc.getId(), podId, clusterId, hostId, null, null);
|
||||
|
||||
final List<StoragePool> poolList = allocator.allocateToPool(dskCh, profile, plan, avoidList, 1);
|
||||
final List<StoragePool> poolList = allocator.allocateToPool(dskCh, profile, plan, avoidList, StoragePoolAllocator.RETURN_UPTO_ALL);
|
||||
if (poolList != null && !poolList.isEmpty()) {
|
||||
return (StoragePool)dataStoreMgr.getDataStore(poolList.get(0).getId(), DataStoreRole.Primary);
|
||||
// Check if the preferred storage pool can be used. If yes, use it.
|
||||
Optional<StoragePool> storagePool = getPreferredStoragePool(poolList, vm);
|
||||
|
||||
return (storagePool.isPresent()) ? (StoragePool) this.dataStoreMgr.getDataStore(storagePool.get().getId(), DataStoreRole.Primary) :
|
||||
(StoragePool)dataStoreMgr.getDataStore(poolList.get(0).getId(), DataStoreRole.Primary);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ import java.util.HashMap;
|
|||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.Timer;
|
||||
import java.util.TreeSet;
|
||||
|
|
@ -1674,7 +1675,7 @@ StateListener<State, VirtualMachine.Event, VirtualMachine>, Configurable {
|
|||
for (StoragePoolAllocator allocator : _storagePoolAllocators) {
|
||||
final List<StoragePool> suitablePools = allocator.allocateToPool(diskProfile, vmProfile, plan, avoid, returnUpTo);
|
||||
if (suitablePools != null && !suitablePools.isEmpty()) {
|
||||
suitableVolumeStoragePools.put(toBeCreated, suitablePools);
|
||||
checkForPreferredStoragePool(suitablePools, vmProfile.getVirtualMachine(), suitableVolumeStoragePools, toBeCreated);
|
||||
foundPotentialPools = true;
|
||||
break;
|
||||
}
|
||||
|
|
@ -1715,6 +1716,43 @@ StateListener<State, VirtualMachine.Event, VirtualMachine>, Configurable {
|
|||
return new Pair<Map<Volume, List<StoragePool>>, List<Volume>>(suitableVolumeStoragePools, readyAndReusedVolumes);
|
||||
}
|
||||
|
||||
private void checkForPreferredStoragePool(List<StoragePool> suitablePools,
|
||||
VirtualMachine vm,
|
||||
Map<Volume, List<StoragePool>> suitableVolumeStoragePools,
|
||||
VolumeVO toBeCreated) {
|
||||
List<StoragePool> pools = new ArrayList<>();
|
||||
Optional<StoragePool> storagePool = getPreferredStoragePool(suitablePools, vm);
|
||||
storagePool.ifPresent(pools::add);
|
||||
|
||||
pools.addAll(suitablePools);
|
||||
suitableVolumeStoragePools.put(toBeCreated, pools);
|
||||
}
|
||||
|
||||
private Optional<StoragePool> getMatchingStoragePool(String preferredPoolId, List<StoragePool> storagePools) {
|
||||
if (preferredPoolId == null) {
|
||||
return Optional.empty();
|
||||
}
|
||||
return storagePools.stream()
|
||||
.filter(pool -> pool.getUuid().equalsIgnoreCase(preferredPoolId))
|
||||
.findFirst();
|
||||
}
|
||||
|
||||
private Optional<StoragePool> getPreferredStoragePool(List<StoragePool> poolList, VirtualMachine vm) {
|
||||
String accountStoragePoolUuid = StorageManager.PreferredStoragePool.valueIn(vm.getAccountId());
|
||||
Optional<StoragePool> storagePool = getMatchingStoragePool(accountStoragePoolUuid, poolList);
|
||||
|
||||
if (storagePool.isPresent()) {
|
||||
s_logger.debug("A storage pool is specified for this account, so we will use this storage pool for allocation: "
|
||||
+ storagePool.get().getUuid());
|
||||
} else {
|
||||
String globalStoragePoolUuid = StorageManager.PreferredStoragePool.value();
|
||||
storagePool = getMatchingStoragePool(globalStoragePoolUuid, poolList);
|
||||
storagePool.ifPresent(pool -> s_logger.debug("A storage pool is specified in global setting, so we will use this storage pool for allocation: "
|
||||
+ pool.getUuid()));
|
||||
}
|
||||
return storagePool;
|
||||
}
|
||||
|
||||
private boolean isEnabledForAllocation(long zoneId, Long podId, Long clusterId) {
|
||||
// Check if the zone exists in the system
|
||||
DataCenterVO zone = _dcDao.findById(zoneId);
|
||||
|
|
|
|||
|
|
@ -3212,7 +3212,8 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
|||
PRIMARY_STORAGE_DOWNLOAD_WAIT,
|
||||
SecStorageMaxMigrateSessions,
|
||||
MaxDataMigrationWaitTime,
|
||||
DiskProvisioningStrictness
|
||||
DiskProvisioningStrictness,
|
||||
PreferredStoragePool
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue