mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
Fix for create template from snapshot (for snapshots on primary storage and storage doesn't support create snapshot to template directly) (#11452)
* Fix for create template from snapshot * code improvements, for create volume from snapshot
This commit is contained in:
parent
ba2d70ab21
commit
f671461d4c
@ -579,14 +579,19 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
|
||||
VolumeInfo vol = volFactory.getVolume(volume.getId());
|
||||
long zoneId = volume.getDataCenterId();
|
||||
DataStore store = dataStoreMgr.getDataStore(pool.getId(), DataStoreRole.Primary);
|
||||
DataStoreRole dataStoreRole = snapshotHelper.getDataStoreRole(snapshot, zoneId);
|
||||
DataStoreRole dataStoreRole = snapshotHelper.getDataStoreRole(snapshot);
|
||||
SnapshotInfo snapInfo = snapshotFactory.getSnapshotWithRoleAndZone(snapshot.getId(), dataStoreRole, zoneId);
|
||||
boolean kvmSnapshotOnlyInPrimaryStorage = snapshotHelper.isKvmSnapshotOnlyInPrimaryStorage(snapshot, dataStoreRole);
|
||||
logger.debug("Creating volume from snapshot, with dataStore role {} and on primary storage: {}", dataStoreRole, kvmSnapshotOnlyInPrimaryStorage);
|
||||
|
||||
boolean kvmSnapshotOnlyInPrimaryStorage = snapshotHelper.isKvmSnapshotOnlyInPrimaryStorage(snapshot, dataStoreRole, volume.getDataCenterId());
|
||||
boolean storageSupportSnapshotToTemplateEnabled = snapshotHelper.isStorageSupportSnapshotToTemplate(snapInfo);
|
||||
|
||||
try {
|
||||
if (!storageSupportSnapshotToTemplateEnabled) {
|
||||
if (storageSupportSnapshotToTemplateEnabled) { // true only for StorPool now [TODO: Update to check storage supports snapshot to volume (DataStoreCapabilities.CAN_CREATE_VOLUME_FROM_SNAPSHOT) - may impact other storages, or StorPool storage type only]
|
||||
dataStoreRole = snapshotHelper.getDataStoreRole(snapshot, zoneId);
|
||||
snapInfo = snapshotFactory.getSnapshotWithRoleAndZone(snapshot.getId(), dataStoreRole, zoneId);
|
||||
kvmSnapshotOnlyInPrimaryStorage = snapshotHelper.isKvmSnapshotOnlyInPrimaryStorage(snapshot, dataStoreRole, zoneId);
|
||||
logger.debug("Creating volume from snapshot for storage supporting snapshot to template, with dataStore role {} and on primary storage: {}", dataStoreRole, kvmSnapshotOnlyInPrimaryStorage);
|
||||
} else {
|
||||
snapInfo = snapshotHelper.backupSnapshotToSecondaryStorageIfNotExists(snapInfo, dataStoreRole, snapshot, kvmSnapshotOnlyInPrimaryStorage);
|
||||
}
|
||||
} catch (CloudRuntimeException e) {
|
||||
@ -600,7 +605,7 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
|
||||
}
|
||||
|
||||
// don't try to perform a sync if the DataStoreRole of the snapshot is equal to DataStoreRole.Primary
|
||||
if (!DataStoreRole.Primary.equals(dataStoreRole) || !storageSupportSnapshotToTemplateEnabled) {
|
||||
if (!DataStoreRole.Primary.equals(dataStoreRole) || (kvmSnapshotOnlyInPrimaryStorage && !storageSupportSnapshotToTemplateEnabled)) {
|
||||
try {
|
||||
// sync snapshot to region store if necessary
|
||||
DataStore snapStore = snapInfo.getDataStore();
|
||||
|
||||
@ -1692,18 +1692,21 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
|
||||
if (store == null) {
|
||||
throw new CloudRuntimeException("cannot find an image store for zone " + zoneId);
|
||||
}
|
||||
AsyncCallFuture<TemplateApiResult> future = null;
|
||||
AsyncCallFuture<TemplateApiResult> future;
|
||||
|
||||
if (snapshotId != null) {
|
||||
DataStoreRole dataStoreRole = snapshotHelper.getDataStoreRole(snapshot, zoneId);
|
||||
kvmSnapshotOnlyInPrimaryStorage = snapshotHelper.isKvmSnapshotOnlyInPrimaryStorage(snapshot, dataStoreRole, zoneId);
|
||||
|
||||
DataStoreRole dataStoreRole = snapshotHelper.getDataStoreRole(snapshot);
|
||||
kvmSnapshotOnlyInPrimaryStorage = snapshotHelper.isKvmSnapshotOnlyInPrimaryStorage(snapshot, dataStoreRole);
|
||||
snapInfo = _snapshotFactory.getSnapshotWithRoleAndZone(snapshotId, dataStoreRole, zoneId);
|
||||
boolean kvmIncrementalSnapshot = SnapshotManager.kvmIncrementalSnapshot.valueIn(_hostDao.findClusterIdByVolumeInfo(snapInfo.getBaseVolume()));
|
||||
logger.debug("Creating template from snapshot, with dataStore role {} and on primary storage: {}", dataStoreRole, kvmSnapshotOnlyInPrimaryStorage);
|
||||
|
||||
boolean storageSupportsSnapshotToTemplate = snapshotHelper.isStorageSupportSnapshotToTemplate(snapInfo);
|
||||
if (storageSupportsSnapshotToTemplate) {
|
||||
dataStoreRole = snapshotHelper.getDataStoreRole(snapshot, zoneId);
|
||||
kvmSnapshotOnlyInPrimaryStorage = snapshotHelper.isKvmSnapshotOnlyInPrimaryStorage(snapshot, dataStoreRole, zoneId);
|
||||
snapInfo = _snapshotFactory.getSnapshotWithRoleAndZone(snapshotId, dataStoreRole, zoneId);
|
||||
logger.debug("Creating template from snapshot for storage supporting snapshot to template, with dataStore role {} and on primary storage: {}", dataStoreRole, kvmSnapshotOnlyInPrimaryStorage);
|
||||
|
||||
boolean skipCopyToSecondary = false;
|
||||
boolean keepOnPrimary = snapshotHelper.isStorageSupportSnapshotToTemplate(snapInfo);
|
||||
if (keepOnPrimary) {
|
||||
ImageStoreVO imageStore = _imgStoreDao.findOneByZoneAndProtocol(zoneId, "nfs");
|
||||
if (imageStore == null) {
|
||||
throw new CloudRuntimeException(String.format("Could not find an NFS secondary storage pool on zone %s to use as a temporary location " +
|
||||
@ -1713,7 +1716,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
|
||||
if (dataStore != null) {
|
||||
store = dataStore;
|
||||
}
|
||||
} else if (dataStoreRole == DataStoreRole.Image) {
|
||||
} else if (dataStoreRole == DataStoreRole.Image || kvmSnapshotOnlyInPrimaryStorage) {
|
||||
snapInfo = snapshotHelper.backupSnapshotToSecondaryStorageIfNotExists(snapInfo, dataStoreRole, snapshot, kvmSnapshotOnlyInPrimaryStorage);
|
||||
_accountMgr.checkAccess(caller, null, true, snapInfo);
|
||||
DataStore snapStore = snapInfo.getDataStore();
|
||||
@ -1722,6 +1725,8 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
|
||||
store = snapStore; // pick snapshot image store to create template
|
||||
}
|
||||
}
|
||||
|
||||
boolean kvmIncrementalSnapshot = SnapshotManager.kvmIncrementalSnapshot.valueIn(_hostDao.findClusterIdByVolumeInfo(snapInfo.getBaseVolume()));
|
||||
if (kvmIncrementalSnapshot && DataStoreRole.Image.equals(dataStoreRole)) {
|
||||
snapInfo = snapshotHelper.convertSnapshotIfNeeded(snapInfo);
|
||||
}
|
||||
|
||||
@ -156,7 +156,8 @@ public class SnapshotHelper {
|
||||
public boolean isStorageSupportSnapshotToTemplate(SnapshotInfo snapInfo) {
|
||||
if (DataStoreRole.Primary.equals(snapInfo.getDataStore().getRole())) {
|
||||
Map<String, String> capabilities = snapInfo.getDataStore().getDriver().getCapabilities();
|
||||
return org.apache.commons.collections4.MapUtils.isNotEmpty(capabilities) && capabilities.containsKey(DataStoreCapabilities.CAN_CREATE_TEMPLATE_FROM_SNAPSHOT.toString());
|
||||
return org.apache.commons.collections4.MapUtils.isNotEmpty(capabilities)
|
||||
&& Boolean.parseBoolean(capabilities.get(DataStoreCapabilities.CAN_CREATE_TEMPLATE_FROM_SNAPSHOT.toString()));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -214,22 +215,24 @@ public class SnapshotHelper {
|
||||
* @return true if hypervisor is {@link HypervisorType#KVM} and data store role is {@link DataStoreRole#Primary} and global setting "snapshot.backup.to.secondary" is false,
|
||||
* else false.
|
||||
*/
|
||||
public boolean isKvmSnapshotOnlyInPrimaryStorage(Snapshot snapshot, DataStoreRole dataStoreRole) {
|
||||
return snapshot.getHypervisorType() == Hypervisor.HypervisorType.KVM && dataStoreRole == DataStoreRole.Primary && !backupSnapshotAfterTakingSnapshot;
|
||||
}
|
||||
|
||||
public boolean isKvmSnapshotOnlyInPrimaryStorage(Snapshot snapshot, DataStoreRole dataStoreRole, Long zoneId){
|
||||
List<SnapshotJoinVO> snapshots = snapshotJoinDao.listBySnapshotIdAndZoneId(zoneId, snapshot.getSnapshotId());
|
||||
boolean isKvmSnapshotOnlyInPrimaryStorage = snapshots.stream().filter(s -> s.getStoreRole().equals(DataStoreRole.Image)).count() == 0;
|
||||
boolean isKvmSnapshotOnlyInPrimaryStorage = snapshots.stream().noneMatch(s -> s.getStoreRole().equals(DataStoreRole.Image));
|
||||
|
||||
return snapshot.getHypervisorType() == Hypervisor.HypervisorType.KVM && dataStoreRole == DataStoreRole.Primary && isKvmSnapshotOnlyInPrimaryStorage;
|
||||
}
|
||||
|
||||
public DataStoreRole getDataStoreRole(Snapshot snapshot) {
|
||||
SnapshotDataStoreVO snapshotStore = snapshotDataStoreDao.findOneBySnapshotAndDatastoreRole(snapshot.getId(), DataStoreRole.Primary);
|
||||
|
||||
if (snapshotStore == null) {
|
||||
return DataStoreRole.Image;
|
||||
}
|
||||
|
||||
long storagePoolId = snapshotStore.getDataStoreId();
|
||||
|
||||
StoragePoolVO storagePoolVO = primaryDataStoreDao.findById(storagePoolId);
|
||||
if ((storagePoolTypesToValidateWithBackupSnapshotAfterTakingSnapshot.contains(storagePoolVO.getPoolType()) || snapshot.getHypervisorType() == HypervisorType.KVM)
|
||||
&& !backupSnapshotAfterTakingSnapshot) {
|
||||
@ -237,13 +240,11 @@ public class SnapshotHelper {
|
||||
}
|
||||
|
||||
DataStore dataStore = dataStorageManager.getDataStore(storagePoolId, DataStoreRole.Primary);
|
||||
|
||||
if (dataStore == null) {
|
||||
return DataStoreRole.Image;
|
||||
}
|
||||
|
||||
Map<String, String> mapCapabilities = dataStore.getDriver().getCapabilities();
|
||||
|
||||
if (MapUtils.isNotEmpty(mapCapabilities) && BooleanUtils.toBoolean(mapCapabilities.get(DataStoreCapabilities.STORAGE_SYSTEM_SNAPSHOT.toString()))) {
|
||||
return DataStoreRole.Primary;
|
||||
}
|
||||
@ -255,11 +256,13 @@ public class SnapshotHelper {
|
||||
if (zoneId == null) {
|
||||
getDataStoreRole(snapshot);
|
||||
}
|
||||
|
||||
List<SnapshotJoinVO> snapshots = snapshotJoinDao.listBySnapshotIdAndZoneId(zoneId, snapshot.getId());
|
||||
boolean snapshotOnPrimary = snapshots.stream().anyMatch(s -> s.getStoreRole().equals(DataStoreRole.Primary));
|
||||
if (snapshotOnPrimary) {
|
||||
return DataStoreRole.Primary;
|
||||
}
|
||||
|
||||
return DataStoreRole.Image;
|
||||
}
|
||||
/**
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user