Skip to content

Commit 68bd056

Browse files
authored
Support timeout configuration for Create and Restore NAS backup (#12964)
* Introduce configurable timeout to Create NAS backup * use timeout set via "commands.timeout"
1 parent 4ba4bd3 commit 68bd056

File tree

3 files changed

+26
-13
lines changed

3 files changed

+26
-13
lines changed

plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtRestoreBackupCommandWrapper.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ public Answer execute(RestoreBackupCommand command, LibvirtComputingResource ser
8888
List<PrimaryDataStoreTO> restoreVolumePools = command.getRestoreVolumePools();
8989
List<String> restoreVolumePaths = command.getRestoreVolumePaths();
9090
Integer mountTimeout = command.getMountTimeout() * 1000;
91-
int timeout = command.getWait();
91+
int timeout = command.getWait() > 0 ? command.getWait() * 1000 : serverResource.getCmdsTimeout();
9292
KVMStoragePoolManager storagePoolMgr = serverResource.getStoragePoolMgr();
9393
List<String> backupFiles = command.getBackupFiles();
9494

@@ -270,15 +270,15 @@ private boolean replaceVolumeWithBackup(KVMStoragePoolManager storagePoolMgr, Pr
270270
return replaceBlockDeviceWithBackup(storagePoolMgr, volumePool, volumePath, backupPath, timeout, createTargetVolume, size);
271271
}
272272

273-
int exitValue = Script.runSimpleBashScriptForExitValue(String.format(RSYNC_COMMAND, backupPath, volumePath));
273+
int exitValue = Script.runSimpleBashScriptForExitValue(String.format(RSYNC_COMMAND, backupPath, volumePath), timeout, false);
274274
return exitValue == 0;
275275
}
276276

277277
private boolean replaceBlockDeviceWithBackup(KVMStoragePoolManager storagePoolMgr, PrimaryDataStoreTO volumePool, String volumePath, String backupPath, int timeout, boolean createTargetVolume, Long size) {
278278
KVMStoragePool volumeStoragePool = storagePoolMgr.getStoragePool(volumePool.getPoolType(), volumePool.getUuid());
279279
QemuImg qemu;
280280
try {
281-
qemu = new QemuImg(timeout * 1000, true, false);
281+
qemu = new QemuImg(timeout, true, false);
282282
String volumeUuid = getVolumeUuidFromPath(volumePath, volumePool);
283283
KVMPhysicalDisk disk = null;
284284
if (createTargetVolume) {

plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtTakeBackupCommandWrapper.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ public Answer execute(TakeBackupCommand command, LibvirtComputingResource libvir
5252
List<PrimaryDataStoreTO> volumePools = command.getVolumePools();
5353
final List<String> volumePaths = command.getVolumePaths();
5454
KVMStoragePoolManager storagePoolMgr = libvirtComputingResource.getStoragePoolMgr();
55+
int timeout = command.getWait() > 0 ? command.getWait() * 1000 : libvirtComputingResource.getCmdsTimeout();
5556

5657
List<String> diskPaths = new ArrayList<>();
5758
if (Objects.nonNull(volumePaths)) {
@@ -81,7 +82,7 @@ public Answer execute(TakeBackupCommand command, LibvirtComputingResource libvir
8182
"-d", diskPaths.isEmpty() ? "" : String.join(",", diskPaths)
8283
});
8384

84-
Pair<Integer, String> result = Script.executePipedCommands(commands, libvirtComputingResource.getCmdsTimeout());
85+
Pair<Integer, String> result = Script.executePipedCommands(commands, timeout);
8586

8687
if (result.first() != 0) {
8788
logger.debug("Failed to take VM backup: " + result.second());

plugins/hypervisors/kvm/src/test/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtRestoreBackupCommandWrapperTest.java

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -391,16 +391,22 @@ public void testExecuteWithRsyncFailure() throws Exception {
391391

392392
try (MockedStatic<Script> scriptMock = mockStatic(Script.class)) {
393393
scriptMock.when(() -> Script.runSimpleBashScriptForExitValue(anyString(), anyInt(), any(Boolean.class)))
394-
.thenReturn(0); // Mount success
394+
.thenAnswer(invocation -> {
395+
String command = invocation.getArgument(0);
396+
if (command.contains("mount")) {
397+
return 0; // mount success
398+
} else if (command.contains("rsync")) {
399+
return 1; // Rsync failure
400+
}
401+
return 0; // Other commands success
402+
});
395403
scriptMock.when(() -> Script.runSimpleBashScriptForExitValue(anyString()))
396404
.thenAnswer(invocation -> {
397405
String command = invocation.getArgument(0);
398406
if (command.contains("ls ")) {
399407
return 0; // File exists
400408
} else if (command.contains("qemu-img check")) {
401409
return 0; // File is valid
402-
} else if (command.contains("rsync")) {
403-
return 1; // Rsync failure
404410
}
405411
return 0; // Other commands success
406412
});
@@ -444,16 +450,22 @@ public void testExecuteWithAttachVolumeFailure() throws Exception {
444450

445451
try (MockedStatic<Script> scriptMock = mockStatic(Script.class)) {
446452
scriptMock.when(() -> Script.runSimpleBashScriptForExitValue(anyString(), anyInt(), any(Boolean.class)))
447-
.thenReturn(0); // Mount success
453+
.thenAnswer(invocation -> {
454+
String command = invocation.getArgument(0);
455+
if (command.contains("mount")) {
456+
return 0; // Mount success
457+
} else if (command.contains("rsync")) {
458+
return 0; // Rsync success
459+
}
460+
return 0; // Other commands success
461+
});
448462
scriptMock.when(() -> Script.runSimpleBashScriptForExitValue(anyString()))
449463
.thenAnswer(invocation -> {
450464
String command = invocation.getArgument(0);
451465
if (command.contains("ls ")) {
452466
return 0; // File exists
453467
} else if (command.contains("qemu-img check")) {
454468
return 0; // File is valid
455-
} else if (command.contains("rsync")) {
456-
return 0; // Rsync success
457469
} else if (command.contains("virsh attach-disk")) {
458470
return 1; // Attach failure
459471
}
@@ -539,10 +551,10 @@ public void testExecuteWithMultipleVolumes() throws Exception {
539551
filesMock.when(() -> Files.createTempDirectory(anyString())).thenReturn(tempPath);
540552

541553
try (MockedStatic<Script> scriptMock = mockStatic(Script.class)) {
542-
scriptMock.when(() -> Script.runSimpleBashScriptForExitValue(anyString(), anyInt(), any(Boolean.class)))
543-
.thenReturn(0); // Mount success
544554
scriptMock.when(() -> Script.runSimpleBashScriptForExitValue(anyString()))
545-
.thenReturn(0); // All other commands success
555+
.thenReturn(0); // All commands success
556+
scriptMock.when(() -> Script.runSimpleBashScriptForExitValue(anyString(), anyInt(), any(Boolean.class)))
557+
.thenReturn(0); // All commands success
546558

547559
filesMock.when(() -> Files.deleteIfExists(any(Path.class))).thenReturn(true);
548560

0 commit comments

Comments
 (0)