This is an automated email from the ASF dual-hosted git repository. sureshanaparti pushed a commit to branch 4.22 in repository https://gitbox.apache.org/repos/asf/cloudstack.git
commit 959c5fff6887602f1d8e86977b03ece8cd46757f Merge: 7ff76cb2d7b ca64406a880 Author: Suresh Kumar Anaparti <[email protected]> AuthorDate: Mon Jan 5 15:57:26 2026 +0530 Merge branch '4.20' into 4.22 .../api/storage/ObjectInDataStoreStateMachine.java | 6 +-- .../cache/manager/StorageCacheManagerImpl.java | 2 +- .../storage/motion/AncientDataMotionStrategy.java | 4 +- .../motion/StorageSystemDataMotionStrategy.java | 12 +++--- .../storage/image/SecondaryStorageServiceImpl.java | 4 +- .../storage/image/TemplateServiceImpl.java | 14 +++--- .../cloudstack/storage/test/SnapshotTest.java | 2 +- .../apache/cloudstack/storage/test/VolumeTest.java | 2 +- .../cloudstack/storage/test/VolumeTestVmware.java | 2 +- .../storage/snapshot/DefaultSnapshotStrategy.java | 2 +- .../storage/snapshot/SnapshotServiceImpl.java | 12 +++--- .../storage/datastore/DataObjectManagerImpl.java | 8 ++-- .../datastore/ObjectInDataStoreManagerImpl.java | 16 +++---- .../cloudstack/storage/volume/VolumeObject.java | 2 +- .../storage/volume/VolumeServiceImpl.java | 50 +++++++++++----------- .../storage/volume/VolumeObjectTest.java | 4 +- .../LibvirtMigrateVolumeCommandWrapper.java | 5 ++- plugins/storage/volume/linstor/CHANGELOG.md | 17 +++----- .../kvm/storage/LinstorStorageAdaptor.java | 7 +-- .../storage/datastore/util/LinstorUtil.java | 35 ++++++++++++--- .../storage/motion/StorPoolDataMotionStrategy.java | 4 +- .../storage/snapshot/StorPoolSnapshotStrategy.java | 4 +- .../main/java/com/cloud/test/DatabaseConfig.java | 2 +- ui/src/components/view/DateTimeFilter.vue | 43 +++++++++---------- ui/src/components/view/TestWebhookDeliveryView.vue | 2 +- ui/src/views/tools/CreateWebhook.vue | 2 +- .../com/cloud/utils/cisco/n1kv/vsm/VsmCommand.java | 23 +++++----- 27 files changed, 150 insertions(+), 136 deletions(-) diff --cc engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/ObjectInDataStoreStateMachine.java index b30083cf315,d4ca163e4e6..afa5d4e36db --- a/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/ObjectInDataStoreStateMachine.java +++ b/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/ObjectInDataStoreStateMachine.java @@@ -32,12 -32,10 +32,12 @@@ public interface ObjectInDataStoreState Migrated("The object has been migrated"), Destroying("Template is destroying"), Destroyed("Template is destroyed"), - Failed("Failed to download Template"); + Failed("Failed to download Template"), + Hidden("The object is hidden from the user"); + - String _description; + final String _description; - private State(String description) { + State(String description) { _description = description; } diff --cc engine/storage/datamotion/src/main/java/org/apache/cloudstack/storage/motion/StorageSystemDataMotionStrategy.java index fa8a7a79aa3,21a8655ca86..61d2caa0e06 --- a/engine/storage/datamotion/src/main/java/org/apache/cloudstack/storage/motion/StorageSystemDataMotionStrategy.java +++ b/engine/storage/datamotion/src/main/java/org/apache/cloudstack/storage/motion/StorageSystemDataMotionStrategy.java @@@ -2352,22 -2314,11 +2352,22 @@@ public class StorageSystemDataMotionStr volumeVO.setFormat(ImageFormat.QCOW2); volumeVO.setLastId(srcVolumeInfo.getId()); + if (Objects.equals(srcVolumeInfo.getDiskOfferingId(), destVolumeInfo.getDiskOfferingId())) { + StoragePoolVO srcPoolVO = _storagePoolDao.findById(srcVolumeInfo.getPoolId()); + StoragePoolVO destPoolVO = _storagePoolDao.findById(destVolumeInfo.getPoolId()); + if (srcPoolVO != null && destPoolVO != null && + ((srcPoolVO.isShared() && destPoolVO.isLocal()) || (srcPoolVO.isLocal() && destPoolVO.isShared()))) { + Long offeringId = getSuitableDiskOfferingForVolumeOnPool(volumeVO, destPoolVO); + if (offeringId != null) { + volumeVO.setDiskOfferingId(offeringId); + } + } + } + _volumeDao.update(volumeVO.getId(), volumeVO); - _volumeService.copyPoliciesBetweenVolumesAndDestroySourceVolumeAfterMigration(Event.OperationSuccessed, null, srcVolumeInfo, destVolumeInfo, false); + _volumeService.copyPoliciesBetweenVolumesAndDestroySourceVolumeAfterMigration(Event.OperationSucceeded, null, srcVolumeInfo, destVolumeInfo, false); - // Update the volume ID for snapshots on secondary storage if (!_snapshotDao.listByVolumeId(srcVolumeInfo.getId()).isEmpty()) { _snapshotDao.updateVolumeIds(srcVolumeInfo.getId(), destVolumeInfo.getId()); diff --cc engine/storage/integration-test/src/test/java/org/apache/cloudstack/storage/test/SnapshotTest.java index f07866c8353,0185c0d1934..605a5ffa8f0 --- a/engine/storage/integration-test/src/test/java/org/apache/cloudstack/storage/test/SnapshotTest.java +++ b/engine/storage/integration-test/src/test/java/org/apache/cloudstack/storage/test/SnapshotTest.java @@@ -269,7 -268,7 +269,7 @@@ public class SnapshotTest extends Cloud to.setSize(1000L); CopyCmdAnswer answer = new CopyCmdAnswer(to); templateOnStore.processEvent(Event.CreateOnlyRequested); -- templateOnStore.processEvent(Event.OperationSuccessed, answer); ++ templateOnStore.processEvent(Event.OperationSucceeded, answer); } diff --cc engine/storage/integration-test/src/test/java/org/apache/cloudstack/storage/test/VolumeTest.java index 86421742f83,86421742f83..a2266020047 --- a/engine/storage/integration-test/src/test/java/org/apache/cloudstack/storage/test/VolumeTest.java +++ b/engine/storage/integration-test/src/test/java/org/apache/cloudstack/storage/test/VolumeTest.java @@@ -244,7 -244,7 +244,7 @@@ public class VolumeTest extends CloudSt to.setSize(100L); CopyCmdAnswer answer = new CopyCmdAnswer(to); templateOnStore.processEvent(Event.CreateOnlyRequested); -- templateOnStore.processEvent(Event.OperationSuccessed, answer); ++ templateOnStore.processEvent(Event.OperationSucceeded, answer); } diff --cc engine/storage/integration-test/src/test/java/org/apache/cloudstack/storage/test/VolumeTestVmware.java index c0f43da122b,98af170356f..b2966d6f5c1 --- a/engine/storage/integration-test/src/test/java/org/apache/cloudstack/storage/test/VolumeTestVmware.java +++ b/engine/storage/integration-test/src/test/java/org/apache/cloudstack/storage/test/VolumeTestVmware.java @@@ -247,7 -246,7 +247,7 @@@ public class VolumeTestVmware extends C to.setPath(this.getImageInstallPath()); CopyCmdAnswer answer = new CopyCmdAnswer(to); templateOnStore.processEvent(Event.CreateOnlyRequested); -- templateOnStore.processEvent(Event.OperationSuccessed, answer); ++ templateOnStore.processEvent(Event.OperationSucceeded, answer); } diff --cc engine/storage/src/main/java/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java index e5c8c69ddf5,2986f3f8fab..33e5e5f657e --- a/engine/storage/src/main/java/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java +++ b/engine/storage/src/main/java/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java @@@ -119,9 -111,8 +119,9 @@@ public class ObjectInDataStoreManagerIm stateMachines.addTransition(State.Allocated, Event.MigrateDataRequested, State.Migrating); stateMachines.addTransition(State.Migrating, Event.MigrationFailed, State.Failed); stateMachines.addTransition(State.Migrating, Event.MigrationSucceeded, State.Destroyed); - stateMachines.addTransition(State.Migrating, Event.OperationSuccessed, State.Ready); + stateMachines.addTransition(State.Migrating, Event.OperationSucceeded, State.Ready); stateMachines.addTransition(State.Migrating, Event.OperationFailed, State.Ready); + stateMachines.addTransition(State.Hidden, Event.DestroyRequested, State.Destroying); } @Override diff --cc engine/storage/volume/src/main/java/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java index 52ad19dd468,eeac55be141..c59ae5b18e3 --- a/engine/storage/volume/src/main/java/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java +++ b/engine/storage/volume/src/main/java/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java @@@ -722,7 -704,7 +722,7 @@@ public class VolumeServiceImpl implemen VolumeApiResult res = new VolumeApiResult(volumeInfo); if (result.isSuccess()) { -- // volumeInfo.processEvent(Event.OperationSuccessed, result.getAnswer()); ++ // volumeInfo.processEvent(Event.OperationSucceeded, result.getAnswer()); VolumeVO volume = volDao.findById(volumeInfo.getId()); CopyCmdAnswer answer = (CopyCmdAnswer)result.getAnswer(); diff --cc plugins/storage/volume/storpool/src/main/java/org/apache/cloudstack/storage/snapshot/StorPoolSnapshotStrategy.java index 60c91bc4aed,8a51e2672ea..90c750a1e25 --- a/plugins/storage/volume/storpool/src/main/java/org/apache/cloudstack/storage/snapshot/StorPoolSnapshotStrategy.java +++ b/plugins/storage/volume/storpool/src/main/java/org/apache/cloudstack/storage/snapshot/StorPoolSnapshotStrategy.java @@@ -159,50 -137,15 +159,50 @@@ public class StorPoolSnapshotStrategy i return res; } - private void markSnapshotAsDestroyedIfAlreadyRemoved(Long snapshotId, boolean isSnapshotDeleted) { - if (!isSnapshotDeleted) { - return; + private boolean deleteSnapshot(Long snapshotId, Long zoneId, SnapshotVO snapshotVO, String name, StoragePoolVO storage) { + + boolean res = false; + SpConnectionDesc conn = StorPoolUtil.getSpConnection(storage.getUuid(), storage.getId(), storagePoolDetailsDao, _primaryDataStoreDao); + SpApiResponse resp = StorPoolUtil.snapshotDelete(name, conn); + List<SnapshotInfo> snapshotInfos = snapshotDataFactory.getSnapshots(snapshotId, zoneId); + processResult(snapshotInfos, ObjectInDataStoreStateMachine.Event.DestroyRequested); + if (resp.getError() != null) { + if (resp.getError().getDescr().contains("still exported")) { + processResult(snapshotInfos, Event.OperationFailed); + throw new CloudRuntimeException(String.format("The snapshot [%s] was exported to another cluster. [%s]", name, resp.getError())); + } + final String err = String.format("Failed to clean-up Storpool snapshot %s. Error: %s", name, resp.getError()); + StorPoolUtil.spLog(err); + if (resp.getError().getName().equals("objectDoesNotExist")) { + return true; + } + } else { + res = deleteSnapshotFromDbIfNeeded(snapshotVO, zoneId); + StorPoolUtil.spLog("StorpoolSnapshotStrategy.deleteSnapshot: executed successfully=%s, snapshot uuid=%s, name=%s", res, snapshotVO.getUuid(), name); } - List<SnapshotDataStoreVO> snapshotsOnStore = _snapshotStoreDao.listBySnapshotIdAndState(snapshotId, State.Ready); - for (SnapshotDataStoreVO snapshot : snapshotsOnStore) { - if (snapshot.getInstallPath() != null && snapshot.getInstallPath().contains(StorPoolUtil.SP_DEV_PATH)) { - snapshot.setState(State.Destroyed); - _snapshotStoreDao.update(snapshot.getId(), snapshot); + if (res) { - processResult(snapshotInfos, Event.OperationSuccessed); ++ processResult(snapshotInfos, Event.OperationSucceeded); + cleanUpDestroyedRecords(snapshotId); + } else { + processResult(snapshotInfos, Event.OperationFailed); + } + return res; + } + + private void cleanUpDestroyedRecords(Long snapshotId) { + List<SnapshotDataStoreVO> snapshots = _snapshotStoreDao.listBySnapshotId(snapshotId); + for (SnapshotDataStoreVO snapshot : snapshots) { + if (snapshot.getInstallPath().contains("/dev/storpool-byid") && State.Destroyed.equals(snapshot.getState())) { + _snapshotStoreDao.remove(snapshot.getId()); + } + } + } + + private void processResult(List<SnapshotInfo> snapshotInfos, ObjectInDataStoreStateMachine.Event event) { + for (SnapshotInfo snapshot : snapshotInfos) { + SnapshotObject snapshotObject = (SnapshotObject) snapshot; + if (DataStoreRole.Primary.equals(snapshotObject.getDataStore().getRole())) { + snapshotObject.processEvent(event); } } }
