Skip to content

Commit 60f791e

Browse files
slavkapdhslove
authored andcommitted
Fix of create a template from a StorPool snapshot on another zone (apache#11490)
* Fix of create template from snapshot on another zone When a snapshot has a copy on StorPool primary storage in another zone, but the original snapshot resides on secondary storage, creating a template from the copied snapshot results in the template being created in the first zone. If the snapshot.backup.to.secondary setting is disabled, and a user creates a volume or template from a snapshot, the snapshot is temporarily backed up to secondary storage during the operation. After the operation, this backup should be deleted. However, the snapshot currently remains on both primary and secondary storage. * update snapshot info depending on the data store role
1 parent f57d725 commit 60f791e

File tree

3 files changed

+22
-21
lines changed

3 files changed

+22
-21
lines changed

engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -689,19 +689,18 @@ public VolumeInfo createVolumeFromSnapshot(Volume volume, Snapshot snapshot, Use
689689
VolumeInfo vol = volFactory.getVolume(volume.getId());
690690
long zoneId = volume.getDataCenterId();
691691
DataStore store = dataStoreMgr.getDataStore(pool.getId(), DataStoreRole.Primary);
692-
DataStoreRole dataStoreRole = snapshotHelper.getDataStoreRole(snapshot);
692+
DataStoreRole dataStoreRole = snapshotHelper.getDataStoreRole(snapshot, zoneId);
693693
SnapshotInfo snapInfo = snapshotFactory.getSnapshotWithRoleAndZone(snapshot.getId(), dataStoreRole, zoneId);
694-
boolean kvmSnapshotOnlyInPrimaryStorage = snapshotHelper.isKvmSnapshotOnlyInPrimaryStorage(snapshot, dataStoreRole);
694+
boolean kvmSnapshotOnlyInPrimaryStorage = snapshotHelper.isKvmSnapshotOnlyInPrimaryStorage(snapshot, dataStoreRole, zoneId);
695695
logger.debug("Creating volume from snapshot, with dataStore role {} and on primary storage: {}", dataStoreRole, kvmSnapshotOnlyInPrimaryStorage);
696696

697-
boolean storageSupportSnapshotToTemplateEnabled = snapshotHelper.isStorageSupportSnapshotToTemplate(snapInfo);
697+
boolean storageSupportSnapshotToTemplateEnabled = snapshotHelper.isStorageSupportSnapshotToTemplate(snapInfo); // storageSupportSnapshotToTemplateEnabled is 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]
698698
try {
699-
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]
700-
dataStoreRole = snapshotHelper.getDataStoreRole(snapshot, zoneId);
699+
if (!storageSupportSnapshotToTemplateEnabled) {
700+
dataStoreRole = snapshotHelper.getDataStoreRole(snapshot);
701701
snapInfo = snapshotFactory.getSnapshotWithRoleAndZone(snapshot.getId(), dataStoreRole, zoneId);
702-
kvmSnapshotOnlyInPrimaryStorage = snapshotHelper.isKvmSnapshotOnlyInPrimaryStorage(snapshot, dataStoreRole, zoneId);
703-
logger.debug("Creating volume from snapshot for storage supporting snapshot to template, with dataStore role {} and on primary storage: {}", dataStoreRole, kvmSnapshotOnlyInPrimaryStorage);
704-
} else {
702+
kvmSnapshotOnlyInPrimaryStorage = snapshotHelper.isKvmSnapshotOnlyInPrimaryStorage(snapshot, dataStoreRole);
703+
logger.debug("Creating volume from snapshot, with dataStore role {} and on primary storage: {}", dataStoreRole, kvmSnapshotOnlyInPrimaryStorage);
705704
snapInfo = snapshotHelper.backupSnapshotToSecondaryStorageIfNotExists(snapInfo, dataStoreRole, snapshot, kvmSnapshotOnlyInPrimaryStorage);
706705
}
707706
} catch (CloudRuntimeException e) {

server/src/main/java/com/cloud/template/TemplateManagerImpl.java

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1699,16 +1699,12 @@ public VirtualMachineTemplate createPrivateTemplate(CreateTemplateCmd command) t
16991699
AsyncCallFuture<TemplateApiResult> future;
17001700

17011701
if (snapshotId != null) {
1702-
DataStoreRole dataStoreRole = snapshotHelper.getDataStoreRole(snapshot);
1703-
kvmSnapshotOnlyInPrimaryStorage = snapshotHelper.isKvmSnapshotOnlyInPrimaryStorage(snapshot, dataStoreRole);
1702+
DataStoreRole dataStoreRole = snapshotHelper.getDataStoreRole(snapshot, zoneId);
17041703
snapInfo = _snapshotFactory.getSnapshotWithRoleAndZone(snapshotId, dataStoreRole, zoneId);
1705-
logger.debug("Creating template from snapshot, with dataStore role {} and on primary storage: {}", dataStoreRole, kvmSnapshotOnlyInPrimaryStorage);
17061704

17071705
boolean storageSupportsSnapshotToTemplate = snapshotHelper.isStorageSupportSnapshotToTemplate(snapInfo);
17081706
if (storageSupportsSnapshotToTemplate) {
1709-
dataStoreRole = snapshotHelper.getDataStoreRole(snapshot, zoneId);
17101707
kvmSnapshotOnlyInPrimaryStorage = snapshotHelper.isKvmSnapshotOnlyInPrimaryStorage(snapshot, dataStoreRole, zoneId);
1711-
snapInfo = _snapshotFactory.getSnapshotWithRoleAndZone(snapshotId, dataStoreRole, zoneId);
17121708
logger.debug("Creating template from snapshot for storage supporting snapshot to template, with dataStore role {} and on primary storage: {}", dataStoreRole, kvmSnapshotOnlyInPrimaryStorage);
17131709

17141710
ImageStoreVO imageStore = _imgStoreDao.findOneByZoneAndProtocol(zoneId, "nfs");
@@ -1720,13 +1716,19 @@ public VirtualMachineTemplate createPrivateTemplate(CreateTemplateCmd command) t
17201716
if (dataStore != null) {
17211717
store = dataStore;
17221718
}
1723-
} else if (dataStoreRole == DataStoreRole.Image || kvmSnapshotOnlyInPrimaryStorage) {
1724-
snapInfo = snapshotHelper.backupSnapshotToSecondaryStorageIfNotExists(snapInfo, dataStoreRole, snapshot, kvmSnapshotOnlyInPrimaryStorage);
1725-
_accountMgr.checkAccess(caller, null, true, snapInfo);
1726-
DataStore snapStore = snapInfo.getDataStore();
1727-
1728-
if (snapStore != null) {
1729-
store = snapStore; // pick snapshot image store to create template
1719+
} else {
1720+
dataStoreRole = snapshotHelper.getDataStoreRole(snapshot);
1721+
kvmSnapshotOnlyInPrimaryStorage = snapshotHelper.isKvmSnapshotOnlyInPrimaryStorage(snapshot, dataStoreRole);
1722+
snapInfo = _snapshotFactory.getSnapshotWithRoleAndZone(snapshotId, dataStoreRole, zoneId);
1723+
logger.debug("Creating template from snapshot, with dataStore role {} and on primary storage: {}", dataStoreRole, kvmSnapshotOnlyInPrimaryStorage);
1724+
if (dataStoreRole == DataStoreRole.Image || kvmSnapshotOnlyInPrimaryStorage) {
1725+
snapInfo = snapshotHelper.backupSnapshotToSecondaryStorageIfNotExists(snapInfo, dataStoreRole, snapshot, kvmSnapshotOnlyInPrimaryStorage);
1726+
_accountMgr.checkAccess(caller, null, true, snapInfo);
1727+
DataStore snapStore = snapInfo.getDataStore();
1728+
1729+
if (snapStore != null) {
1730+
store = snapStore; // pick snapshot image store to create template
1731+
}
17301732
}
17311733
}
17321734

server/src/main/java/org/apache/cloudstack/snapshot/SnapshotHelper.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ public void expungeTemporarySnapshot(boolean kvmSnapshotOnlyInPrimaryStorage, Sn
113113
}
114114

115115
List<SnapshotJoinVO> snapshots = snapshotJoinDao.listBySnapshotIdAndZoneId(zoneId, snapInfo.getSnapshotId());
116-
if (kvmSnapshotOnlyInPrimaryStorage || snapshots.size() <= 1) {
116+
if (snapshots.size() <= 1) {
117117
if (snapInfo != null) {
118118
logger.trace(String.format("Snapshot [{}] is not a temporary backup to create a volume from snapshot. Not expunging it.", snapInfo.getId()));
119119
}

0 commit comments

Comments
 (0)