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 68bd0563061 Support timeout configuration for Create and Restore NAS
backup (#12964)
68bd0563061 is described below
commit 68bd0563061420d5fefd5de1c7827a25daeeb4ed
Author: Abhisar Sinha <[email protected]>
AuthorDate: Fri Apr 10 10:11:54 2026 +0530
Support timeout configuration for Create and Restore NAS backup (#12964)
* Introduce configurable timeout to Create NAS backup
* use timeout set via "commands.timeout"
---
.../LibvirtRestoreBackupCommandWrapper.java | 6 ++---
.../wrapper/LibvirtTakeBackupCommandWrapper.java | 3 ++-
.../LibvirtRestoreBackupCommandWrapperTest.java | 30 +++++++++++++++-------
3 files changed, 26 insertions(+), 13 deletions(-)
diff --git
a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtRestoreBackupCommandWrapper.java
b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtRestoreBackupCommandWrapper.java
index 46561a9bddf..22dbfbdd67a 100644
---
a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtRestoreBackupCommandWrapper.java
+++
b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtRestoreBackupCommandWrapper.java
@@ -88,7 +88,7 @@ public class LibvirtRestoreBackupCommandWrapper extends
CommandWrapper<RestoreBa
List<PrimaryDataStoreTO> restoreVolumePools =
command.getRestoreVolumePools();
List<String> restoreVolumePaths = command.getRestoreVolumePaths();
Integer mountTimeout = command.getMountTimeout() * 1000;
- int timeout = command.getWait();
+ int timeout = command.getWait() > 0 ? command.getWait() * 1000 :
serverResource.getCmdsTimeout();
KVMStoragePoolManager storagePoolMgr =
serverResource.getStoragePoolMgr();
List<String> backupFiles = command.getBackupFiles();
@@ -270,7 +270,7 @@ public class LibvirtRestoreBackupCommandWrapper extends
CommandWrapper<RestoreBa
return replaceBlockDeviceWithBackup(storagePoolMgr, volumePool,
volumePath, backupPath, timeout, createTargetVolume, size);
}
- int exitValue =
Script.runSimpleBashScriptForExitValue(String.format(RSYNC_COMMAND, backupPath,
volumePath));
+ int exitValue =
Script.runSimpleBashScriptForExitValue(String.format(RSYNC_COMMAND, backupPath,
volumePath), timeout, false);
return exitValue == 0;
}
@@ -278,7 +278,7 @@ public class LibvirtRestoreBackupCommandWrapper extends
CommandWrapper<RestoreBa
KVMStoragePool volumeStoragePool =
storagePoolMgr.getStoragePool(volumePool.getPoolType(), volumePool.getUuid());
QemuImg qemu;
try {
- qemu = new QemuImg(timeout * 1000, true, false);
+ qemu = new QemuImg(timeout, true, false);
String volumeUuid = getVolumeUuidFromPath(volumePath, volumePool);
KVMPhysicalDisk disk = null;
if (createTargetVolume) {
diff --git
a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtTakeBackupCommandWrapper.java
b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtTakeBackupCommandWrapper.java
index 11fa605908a..42953aa9f83 100644
---
a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtTakeBackupCommandWrapper.java
+++
b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtTakeBackupCommandWrapper.java
@@ -52,6 +52,7 @@ public class LibvirtTakeBackupCommandWrapper extends
CommandWrapper<TakeBackupCo
List<PrimaryDataStoreTO> volumePools = command.getVolumePools();
final List<String> volumePaths = command.getVolumePaths();
KVMStoragePoolManager storagePoolMgr =
libvirtComputingResource.getStoragePoolMgr();
+ int timeout = command.getWait() > 0 ? command.getWait() * 1000 :
libvirtComputingResource.getCmdsTimeout();
List<String> diskPaths = new ArrayList<>();
if (Objects.nonNull(volumePaths)) {
@@ -81,7 +82,7 @@ public class LibvirtTakeBackupCommandWrapper extends
CommandWrapper<TakeBackupCo
"-d", diskPaths.isEmpty() ? "" : String.join(",", diskPaths)
});
- Pair<Integer, String> result = Script.executePipedCommands(commands,
libvirtComputingResource.getCmdsTimeout());
+ Pair<Integer, String> result = Script.executePipedCommands(commands,
timeout);
if (result.first() != 0) {
logger.debug("Failed to take VM backup: " + result.second());
diff --git
a/plugins/hypervisors/kvm/src/test/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtRestoreBackupCommandWrapperTest.java
b/plugins/hypervisors/kvm/src/test/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtRestoreBackupCommandWrapperTest.java
index c077c9cf0dc..ef6b5c08189 100644
---
a/plugins/hypervisors/kvm/src/test/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtRestoreBackupCommandWrapperTest.java
+++
b/plugins/hypervisors/kvm/src/test/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtRestoreBackupCommandWrapperTest.java
@@ -391,7 +391,15 @@ public class LibvirtRestoreBackupCommandWrapperTest {
try (MockedStatic<Script> scriptMock = mockStatic(Script.class)) {
scriptMock.when(() ->
Script.runSimpleBashScriptForExitValue(anyString(), anyInt(),
any(Boolean.class)))
- .thenReturn(0); // Mount success
+ .thenAnswer(invocation -> {
+ String command = invocation.getArgument(0);
+ if (command.contains("mount")) {
+ return 0; // mount success
+ } else if (command.contains("rsync")) {
+ return 1; // Rsync failure
+ }
+ return 0; // Other commands success
+ });
scriptMock.when(() ->
Script.runSimpleBashScriptForExitValue(anyString()))
.thenAnswer(invocation -> {
String command = invocation.getArgument(0);
@@ -399,8 +407,6 @@ public class LibvirtRestoreBackupCommandWrapperTest {
return 0; // File exists
} else if (command.contains("qemu-img check")) {
return 0; // File is valid
- } else if (command.contains("rsync")) {
- return 1; // Rsync failure
}
return 0; // Other commands success
});
@@ -444,7 +450,15 @@ public class LibvirtRestoreBackupCommandWrapperTest {
try (MockedStatic<Script> scriptMock = mockStatic(Script.class)) {
scriptMock.when(() ->
Script.runSimpleBashScriptForExitValue(anyString(), anyInt(),
any(Boolean.class)))
- .thenReturn(0); // Mount success
+ .thenAnswer(invocation -> {
+ String command = invocation.getArgument(0);
+ if (command.contains("mount")) {
+ return 0; // Mount success
+ } else if (command.contains("rsync")) {
+ return 0; // Rsync success
+ }
+ return 0; // Other commands success
+ });
scriptMock.when(() ->
Script.runSimpleBashScriptForExitValue(anyString()))
.thenAnswer(invocation -> {
String command = invocation.getArgument(0);
@@ -452,8 +466,6 @@ public class LibvirtRestoreBackupCommandWrapperTest {
return 0; // File exists
} else if (command.contains("qemu-img check")) {
return 0; // File is valid
- } else if (command.contains("rsync")) {
- return 0; // Rsync success
} else if (command.contains("virsh attach-disk")) {
return 1; // Attach failure
}
@@ -539,10 +551,10 @@ public class LibvirtRestoreBackupCommandWrapperTest {
filesMock.when(() ->
Files.createTempDirectory(anyString())).thenReturn(tempPath);
try (MockedStatic<Script> scriptMock = mockStatic(Script.class)) {
- scriptMock.when(() ->
Script.runSimpleBashScriptForExitValue(anyString(), anyInt(),
any(Boolean.class)))
- .thenReturn(0); // Mount success
scriptMock.when(() ->
Script.runSimpleBashScriptForExitValue(anyString()))
- .thenReturn(0); // All other commands success
+ .thenReturn(0); // All commands success
+ scriptMock.when(() ->
Script.runSimpleBashScriptForExitValue(anyString(), anyInt(),
any(Boolean.class)))
+ .thenReturn(0); // All commands success
filesMock.when(() ->
Files.deleteIfExists(any(Path.class))).thenReturn(true);