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


The following commit(s) were added to refs/heads/4.22 by this push:
     new 7ba5240b311 Block backup deletion while create-VM-from-backup or 
restore jobs are in progress (#12792)
7ba5240b311 is described below

commit 7ba5240b311f4b66ff4d2c2ced0a14292d7cd62f
Author: Daman Arora <[email protected]>
AuthorDate: Wed Apr 8 22:39:01 2026 -0700

    Block backup deletion while create-VM-from-backup or restore jobs are in 
progress (#12792)
    
    * Block backup deletion while create-VM-from-backup or restore jobs are in 
progress
    
    * Add tests
    
    * Fix exception message
    
    * Update test
    
    Co-authored-by: Abhisar Sinha <[email protected]>
---
 .../cloudstack/backup/BackupManagerImpl.java       | 14 ++++++++++
 .../cloudstack/backup/BackupManagerTest.java       | 30 ++++++++++++++++++++++
 2 files changed, 44 insertions(+)

diff --git 
a/server/src/main/java/org/apache/cloudstack/backup/BackupManagerImpl.java 
b/server/src/main/java/org/apache/cloudstack/backup/BackupManagerImpl.java
index d5663ed3272..e9ed8e42eaa 100644
--- a/server/src/main/java/org/apache/cloudstack/backup/BackupManagerImpl.java
+++ b/server/src/main/java/org/apache/cloudstack/backup/BackupManagerImpl.java
@@ -1531,6 +1531,8 @@ public class BackupManagerImpl extends ManagerBase 
implements BackupManager {
 
         validateBackupForZone(backup.getZoneId());
         accountManager.checkAccess(CallContext.current().getCallingAccount(), 
null, true, vm == null ? backup : vm);
+
+        checkForPendingBackupJobs(backup);
         final BackupOffering offering = 
backupOfferingDao.findByIdIncludingRemoved(backup.getBackupOfferingId());
         if (offering == null) {
             throw new CloudRuntimeException(String.format("Backup offering 
with ID [%s] does not exist.", backup.getBackupOfferingId()));
@@ -1551,6 +1553,18 @@ public class BackupManagerImpl extends ManagerBase 
implements BackupManager {
         throw new CloudRuntimeException("Failed to delete the backup");
     }
 
+    private void checkForPendingBackupJobs(final BackupVO backup) {
+        String backupUuid = backup.getUuid();
+        long pendingJobs = asyncJobManager.countPendingJobs(backupUuid,
+                CreateVMFromBackupCmd.class.getName(),
+                CreateVMFromBackupCmdByAdmin.class.getName(),
+                RestoreBackupCmd.class.getName(),
+                RestoreVolumeFromBackupAndAttachToVMCmd.class.getName());
+        if (pendingJobs > 0) {
+            throw new CloudRuntimeException("Cannot delete Backup while a 
create Instance from Backup or restore Backup operation is in progress, please 
try again later.");
+        }
+    }
+
     /**
      * Get the pair: hostIp, datastoreUuid in which to restore the volume, 
based on the VM to be attached information
      */
diff --git 
a/server/src/test/java/org/apache/cloudstack/backup/BackupManagerTest.java 
b/server/src/test/java/org/apache/cloudstack/backup/BackupManagerTest.java
index 8b13fd47494..2c9d11612c4 100644
--- a/server/src/test/java/org/apache/cloudstack/backup/BackupManagerTest.java
+++ b/server/src/test/java/org/apache/cloudstack/backup/BackupManagerTest.java
@@ -91,6 +91,7 @@ import org.apache.cloudstack.framework.config.ConfigKey;
 import org.apache.cloudstack.framework.config.impl.ConfigDepotImpl;
 import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
 import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
+import org.apache.cloudstack.framework.jobs.AsyncJobManager;
 import org.apache.cloudstack.framework.jobs.impl.AsyncJobVO;
 import org.junit.After;
 import org.junit.Assert;
@@ -241,6 +242,9 @@ public class BackupManagerTest {
     @Mock
     private GuestOSDao _guestOSDao;
 
+    @Mock
+    AsyncJobManager asyncJobManager;
+
     private Gson gson;
 
     private String[] hostPossibleValues = {"127.0.0.1", "hostname"};
@@ -1489,6 +1493,7 @@ public class BackupManagerTest {
         when(backup.getAccountId()).thenReturn(accountId);
         when(backup.getBackupOfferingId()).thenReturn(backupOfferingId);
         when(backup.getSize()).thenReturn(100L);
+        when(backup.getUuid()).thenReturn("backup-uuid");
 
         overrideBackupFrameworkConfigValue();
 
@@ -1523,6 +1528,31 @@ public class BackupManagerTest {
         }
     }
 
+    @Test(expected = CloudRuntimeException.class)
+    public void testDeleteBackupBlockedByPendingJobs() {
+        Long backupId = 1L;
+        Long vmId = 2L;
+
+        BackupVO backup = mock(BackupVO.class);
+        when(backup.getVmId()).thenReturn(vmId);
+        when(backup.getUuid()).thenReturn("backup-uuid");
+        when(backup.getZoneId()).thenReturn(1L);
+        when(backupDao.findByIdIncludingRemoved(backupId)).thenReturn(backup);
+
+        VMInstanceVO vm = mock(VMInstanceVO.class);
+        when(vmInstanceDao.findByIdIncludingRemoved(vmId)).thenReturn(vm);
+
+        overrideBackupFrameworkConfigValue();
+
+        when(asyncJobManager.countPendingJobs("backup-uuid",
+                
"org.apache.cloudstack.api.command.user.vm.CreateVMFromBackupCmd",
+                
"org.apache.cloudstack.api.command.admin.vm.CreateVMFromBackupCmdByAdmin",
+                
"org.apache.cloudstack.api.command.user.backup.RestoreBackupCmd",
+                
"org.apache.cloudstack.api.command.user.backup.RestoreVolumeFromBackupAndAttachToVMCmd")).thenReturn(1L);
+
+        backupManager.deleteBackup(backupId, false);
+    }
+
     @Test
     public void testNewBackupResponse() {
         Long vmId = 1L;

Reply via email to