Skip to content

Commit 762edb0

Browse files
committed
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.
1 parent f2d6356 commit 762edb0

File tree

3 files changed

+17
-15
lines changed

3 files changed

+17
-15
lines changed

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -579,19 +579,19 @@ public VolumeInfo createVolumeFromSnapshot(Volume volume, Snapshot snapshot, Use
579579
VolumeInfo vol = volFactory.getVolume(volume.getId());
580580
long zoneId = volume.getDataCenterId();
581581
DataStore store = dataStoreMgr.getDataStore(pool.getId(), DataStoreRole.Primary);
582-
DataStoreRole dataStoreRole = snapshotHelper.getDataStoreRole(snapshot);
582+
DataStoreRole dataStoreRole = snapshotHelper.getDataStoreRole(snapshot, zoneId);
583583
SnapshotInfo snapInfo = snapshotFactory.getSnapshotWithRoleAndZone(snapshot.getId(), dataStoreRole, zoneId);
584584
boolean kvmSnapshotOnlyInPrimaryStorage = snapshotHelper.isKvmSnapshotOnlyInPrimaryStorage(snapshot, dataStoreRole);
585585
logger.debug("Creating volume from snapshot, with dataStore role {} and on primary storage: {}", dataStoreRole, kvmSnapshotOnlyInPrimaryStorage);
586586

587587
boolean storageSupportSnapshotToTemplateEnabled = snapshotHelper.isStorageSupportSnapshotToTemplate(snapInfo);
588588
try {
589589
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]
590-
dataStoreRole = snapshotHelper.getDataStoreRole(snapshot, zoneId);
591590
snapInfo = snapshotFactory.getSnapshotWithRoleAndZone(snapshot.getId(), dataStoreRole, zoneId);
592591
kvmSnapshotOnlyInPrimaryStorage = snapshotHelper.isKvmSnapshotOnlyInPrimaryStorage(snapshot, dataStoreRole, zoneId);
593592
logger.debug("Creating volume from snapshot for storage supporting snapshot to template, with dataStore role {} and on primary storage: {}", dataStoreRole, kvmSnapshotOnlyInPrimaryStorage);
594593
} else {
594+
dataStoreRole = snapshotHelper.getDataStoreRole(snapshot);
595595
snapInfo = snapshotHelper.backupSnapshotToSecondaryStorageIfNotExists(snapInfo, dataStoreRole, snapshot, kvmSnapshotOnlyInPrimaryStorage);
596596
}
597597
} 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
@@ -1695,16 +1695,12 @@ public VirtualMachineTemplate createPrivateTemplate(CreateTemplateCmd command) t
16951695
AsyncCallFuture<TemplateApiResult> future;
16961696

16971697
if (snapshotId != null) {
1698-
DataStoreRole dataStoreRole = snapshotHelper.getDataStoreRole(snapshot);
1699-
kvmSnapshotOnlyInPrimaryStorage = snapshotHelper.isKvmSnapshotOnlyInPrimaryStorage(snapshot, dataStoreRole);
1698+
DataStoreRole dataStoreRole = snapshotHelper.getDataStoreRole(snapshot, zoneId);
17001699
snapInfo = _snapshotFactory.getSnapshotWithRoleAndZone(snapshotId, dataStoreRole, zoneId);
1701-
logger.debug("Creating template from snapshot, with dataStore role {} and on primary storage: {}", dataStoreRole, kvmSnapshotOnlyInPrimaryStorage);
17021700

17031701
boolean storageSupportsSnapshotToTemplate = snapshotHelper.isStorageSupportSnapshotToTemplate(snapInfo);
17041702
if (storageSupportsSnapshotToTemplate) {
1705-
dataStoreRole = snapshotHelper.getDataStoreRole(snapshot, zoneId);
17061703
kvmSnapshotOnlyInPrimaryStorage = snapshotHelper.isKvmSnapshotOnlyInPrimaryStorage(snapshot, dataStoreRole, zoneId);
1707-
snapInfo = _snapshotFactory.getSnapshotWithRoleAndZone(snapshotId, dataStoreRole, zoneId);
17081704
logger.debug("Creating template from snapshot for storage supporting snapshot to template, with dataStore role {} and on primary storage: {}", dataStoreRole, kvmSnapshotOnlyInPrimaryStorage);
17091705

17101706
ImageStoreVO imageStore = _imgStoreDao.findOneByZoneAndProtocol(zoneId, "nfs");
@@ -1716,13 +1712,19 @@ public VirtualMachineTemplate createPrivateTemplate(CreateTemplateCmd command) t
17161712
if (dataStore != null) {
17171713
store = dataStore;
17181714
}
1719-
} else if (dataStoreRole == DataStoreRole.Image || kvmSnapshotOnlyInPrimaryStorage) {
1720-
snapInfo = snapshotHelper.backupSnapshotToSecondaryStorageIfNotExists(snapInfo, dataStoreRole, snapshot, kvmSnapshotOnlyInPrimaryStorage);
1721-
_accountMgr.checkAccess(caller, null, true, snapInfo);
1722-
DataStore snapStore = snapInfo.getDataStore();
1723-
1724-
if (snapStore != null) {
1725-
store = snapStore; // pick snapshot image store to create template
1715+
} else {
1716+
dataStoreRole = snapshotHelper.getDataStoreRole(snapshot);
1717+
kvmSnapshotOnlyInPrimaryStorage = snapshotHelper.isKvmSnapshotOnlyInPrimaryStorage(snapshot, dataStoreRole);
1718+
snapInfo = _snapshotFactory.getSnapshotWithRoleAndZone(snapshotId, dataStoreRole, zoneId);
1719+
logger.debug("Creating template from snapshot, with dataStore role {} and on primary storage: {}", dataStoreRole, kvmSnapshotOnlyInPrimaryStorage);
1720+
if (dataStoreRole == DataStoreRole.Image || kvmSnapshotOnlyInPrimaryStorage) {
1721+
snapInfo = snapshotHelper.backupSnapshotToSecondaryStorageIfNotExists(snapInfo, dataStoreRole, snapshot, kvmSnapshotOnlyInPrimaryStorage);
1722+
_accountMgr.checkAccess(caller, null, true, snapInfo);
1723+
DataStore snapStore = snapInfo.getDataStore();
1724+
1725+
if (snapStore != null) {
1726+
store = snapStore; // pick snapshot image store to create template
1727+
}
17261728
}
17271729
}
17281730

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)