Skip to content

Commit 7ba5240

Browse files
Damans227abh1sar
andauthored
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 <63767682+abh1sar@users.noreply.github.com>
1 parent 03de62b commit 7ba5240

File tree

2 files changed

+44
-0
lines changed

2 files changed

+44
-0
lines changed

server/src/main/java/org/apache/cloudstack/backup/BackupManagerImpl.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1531,6 +1531,8 @@ public boolean deleteBackup(final Long backupId, final Boolean forced) {
15311531

15321532
validateBackupForZone(backup.getZoneId());
15331533
accountManager.checkAccess(CallContext.current().getCallingAccount(), null, true, vm == null ? backup : vm);
1534+
1535+
checkForPendingBackupJobs(backup);
15341536
final BackupOffering offering = backupOfferingDao.findByIdIncludingRemoved(backup.getBackupOfferingId());
15351537
if (offering == null) {
15361538
throw new CloudRuntimeException(String.format("Backup offering with ID [%s] does not exist.", backup.getBackupOfferingId()));
@@ -1551,6 +1553,18 @@ public boolean deleteBackup(final Long backupId, final Boolean forced) {
15511553
throw new CloudRuntimeException("Failed to delete the backup");
15521554
}
15531555

1556+
private void checkForPendingBackupJobs(final BackupVO backup) {
1557+
String backupUuid = backup.getUuid();
1558+
long pendingJobs = asyncJobManager.countPendingJobs(backupUuid,
1559+
CreateVMFromBackupCmd.class.getName(),
1560+
CreateVMFromBackupCmdByAdmin.class.getName(),
1561+
RestoreBackupCmd.class.getName(),
1562+
RestoreVolumeFromBackupAndAttachToVMCmd.class.getName());
1563+
if (pendingJobs > 0) {
1564+
throw new CloudRuntimeException("Cannot delete Backup while a create Instance from Backup or restore Backup operation is in progress, please try again later.");
1565+
}
1566+
}
1567+
15541568
/**
15551569
* Get the pair: hostIp, datastoreUuid in which to restore the volume, based on the VM to be attached information
15561570
*/

server/src/test/java/org/apache/cloudstack/backup/BackupManagerTest.java

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@
9191
import org.apache.cloudstack.framework.config.impl.ConfigDepotImpl;
9292
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
9393
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
94+
import org.apache.cloudstack.framework.jobs.AsyncJobManager;
9495
import org.apache.cloudstack.framework.jobs.impl.AsyncJobVO;
9596
import org.junit.After;
9697
import org.junit.Assert;
@@ -241,6 +242,9 @@ public class BackupManagerTest {
241242
@Mock
242243
private GuestOSDao _guestOSDao;
243244

245+
@Mock
246+
AsyncJobManager asyncJobManager;
247+
244248
private Gson gson;
245249

246250
private String[] hostPossibleValues = {"127.0.0.1", "hostname"};
@@ -1489,6 +1493,7 @@ public void testDeleteBackupVmNotFound() {
14891493
when(backup.getAccountId()).thenReturn(accountId);
14901494
when(backup.getBackupOfferingId()).thenReturn(backupOfferingId);
14911495
when(backup.getSize()).thenReturn(100L);
1496+
when(backup.getUuid()).thenReturn("backup-uuid");
14921497

14931498
overrideBackupFrameworkConfigValue();
14941499

@@ -1523,6 +1528,31 @@ public void testDeleteBackupVmNotFound() {
15231528
}
15241529
}
15251530

1531+
@Test(expected = CloudRuntimeException.class)
1532+
public void testDeleteBackupBlockedByPendingJobs() {
1533+
Long backupId = 1L;
1534+
Long vmId = 2L;
1535+
1536+
BackupVO backup = mock(BackupVO.class);
1537+
when(backup.getVmId()).thenReturn(vmId);
1538+
when(backup.getUuid()).thenReturn("backup-uuid");
1539+
when(backup.getZoneId()).thenReturn(1L);
1540+
when(backupDao.findByIdIncludingRemoved(backupId)).thenReturn(backup);
1541+
1542+
VMInstanceVO vm = mock(VMInstanceVO.class);
1543+
when(vmInstanceDao.findByIdIncludingRemoved(vmId)).thenReturn(vm);
1544+
1545+
overrideBackupFrameworkConfigValue();
1546+
1547+
when(asyncJobManager.countPendingJobs("backup-uuid",
1548+
"org.apache.cloudstack.api.command.user.vm.CreateVMFromBackupCmd",
1549+
"org.apache.cloudstack.api.command.admin.vm.CreateVMFromBackupCmdByAdmin",
1550+
"org.apache.cloudstack.api.command.user.backup.RestoreBackupCmd",
1551+
"org.apache.cloudstack.api.command.user.backup.RestoreVolumeFromBackupAndAttachToVMCmd")).thenReturn(1L);
1552+
1553+
backupManager.deleteBackup(backupId, false);
1554+
}
1555+
15261556
@Test
15271557
public void testNewBackupResponse() {
15281558
Long vmId = 1L;

0 commit comments

Comments
 (0)