This is an automated email from the ASF dual-hosted git repository.

dahn pushed a commit to branch 4.19
in repository https://gitbox.apache.org/repos/asf/cloudstack.git


The following commit(s) were added to refs/heads/4.19 by this push:
     new 32cc45e8405 [UI] Allow quiescevm and asyncbackup flags while taking 
volume snapshot from UI when these are supported for the volume (#10265)
32cc45e8405 is described below

commit 32cc45e84059865c08270466218d8706e30f7bf4
Author: Suresh Kumar Anaparti <sureshkumar.anapa...@gmail.com>
AuthorDate: Fri May 2 14:15:50 2025 +0530

    [UI] Allow quiescevm and asyncbackup flags while taking volume snapshot 
from UI when these are supported for the volume (#10265)
---
 .../storage/vmsnapshot/StorageVMSnapshotStrategy.java       | 13 +++++++++----
 .../storage/vmsnapshot/VMSnapshotStrategyKVMTest.java       |  4 +++-
 .../com/cloud/storage/snapshot/SnapshotManagerImpl.java     |  2 +-
 ui/src/config/section/compute.js                            |  8 +++++++-
 ui/src/views/compute/CreateSnapshotWizard.vue               | 13 ++++++++++---
 ui/src/views/storage/TakeSnapshot.vue                       |  9 +++++++--
 6 files changed, 37 insertions(+), 12 deletions(-)

diff --git 
a/engine/storage/snapshot/src/main/java/org/apache/cloudstack/storage/vmsnapshot/StorageVMSnapshotStrategy.java
 
b/engine/storage/snapshot/src/main/java/org/apache/cloudstack/storage/vmsnapshot/StorageVMSnapshotStrategy.java
index f5d70817333..64d8f0a0df0 100644
--- 
a/engine/storage/snapshot/src/main/java/org/apache/cloudstack/storage/vmsnapshot/StorageVMSnapshotStrategy.java
+++ 
b/engine/storage/snapshot/src/main/java/org/apache/cloudstack/storage/vmsnapshot/StorageVMSnapshotStrategy.java
@@ -183,7 +183,7 @@ public class StorageVMSnapshotStrategy extends 
DefaultVMSnapshotStrategy {
                 thawAnswer = (FreezeThawVMAnswer) agentMgr.send(hostId, 
thawCmd);
                 if (thawAnswer != null && thawAnswer.getResult()) {
                     s_logger.info(String.format(
-                            "Virtual machne is thawed. The freeze of virtual 
machine took %s milliseconds.",
+                            "Virtual machine is thawed. The freeze of virtual 
machine took %s milliseconds.",
                             
TimeUnit.MILLISECONDS.convert(elapsedTime(startFreeze), TimeUnit.NANOSECONDS)));
                 }
             } else {
@@ -429,9 +429,14 @@ public class StorageVMSnapshotStrategy extends 
DefaultVMSnapshotStrategy {
         String snapshotName = vmSnapshot.getId() + "_" + vol.getUuid();
         SnapshotVO snapshot = new SnapshotVO(vol.getDataCenterId(), 
vol.getAccountId(), vol.getDomainId(), vol.getId(), vol.getDiskOfferingId(),
                               snapshotName, (short) 
Snapshot.Type.GROUP.ordinal(),  Snapshot.Type.GROUP.name(),  vol.getSize(), 
vol.getMinIops(),  vol.getMaxIops(), Hypervisor.HypervisorType.KVM, null);
+        VMSnapshotOptions options = ((VMSnapshotVO) vmSnapshot).getOptions();
+        boolean quiescevm = false;
+        if (options != null) {
+            quiescevm = options.needQuiesceVM();
+        }
 
         snapshot = snapshotDao.persist(snapshot);
-        vol.addPayload(setPayload(vol, snapshot));
+        vol.addPayload(setPayload(vol, snapshot, quiescevm));
         SnapshotInfo snapshotInfo = 
snapshotDataFactory.getSnapshot(snapshot.getId(), vol.getDataStore());
         snapshotInfo.addPayload(vol.getpayload());
         SnapshotStrategy snapshotStrategy = 
storageStrategyFactory.getSnapshotStrategy(snapshotInfo, 
SnapshotOperation.TAKE);
@@ -449,14 +454,14 @@ public class StorageVMSnapshotStrategy extends 
DefaultVMSnapshotStrategy {
         return snapshotInfo;
     }
 
-    protected CreateSnapshotPayload setPayload(VolumeInfo vol, SnapshotVO 
snapshotCreate) {
+    protected CreateSnapshotPayload setPayload(VolumeInfo vol, SnapshotVO 
snapshotCreate, boolean quiescevm) {
         CreateSnapshotPayload payload = new CreateSnapshotPayload();
         payload.setSnapshotId(snapshotCreate.getId());
         payload.setSnapshotPolicyId(SnapshotVO.MANUAL_POLICY_ID);
         payload.setLocationType(snapshotCreate.getLocationType());
         payload.setAccount(accountService.getAccount(vol.getAccountId()));
         payload.setAsyncBackup(false);
-        payload.setQuiescevm(false);
+        payload.setQuiescevm(quiescevm);
         return payload;
     }
 }
diff --git 
a/engine/storage/snapshot/src/test/java/org/apache/cloudstack/storage/vmsnapshot/VMSnapshotStrategyKVMTest.java
 
b/engine/storage/snapshot/src/test/java/org/apache/cloudstack/storage/vmsnapshot/VMSnapshotStrategyKVMTest.java
index d438fef5638..21aba803989 100644
--- 
a/engine/storage/snapshot/src/test/java/org/apache/cloudstack/storage/vmsnapshot/VMSnapshotStrategyKVMTest.java
+++ 
b/engine/storage/snapshot/src/test/java/org/apache/cloudstack/storage/vmsnapshot/VMSnapshotStrategyKVMTest.java
@@ -37,6 +37,7 @@ import 
org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo;
 import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotStrategy;
 import 
org.apache.cloudstack.engine.subsystem.api.storage.SnapshotStrategy.SnapshotOperation;
 import 
org.apache.cloudstack.engine.subsystem.api.storage.StorageStrategyFactory;
+import org.apache.cloudstack.engine.subsystem.api.storage.VMSnapshotOptions;
 import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
 import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
 import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
@@ -151,7 +152,7 @@ public class VMSnapshotStrategyKVMTest extends TestCase{
 
     @Test
     public void testCreateDiskSnapshotBasedOnStrategy() throws Exception {
-        VMSnapshot vmSnapshot = Mockito.mock(VMSnapshot.class);
+        VMSnapshotVO vmSnapshot = Mockito.mock(VMSnapshotVO.class);
         List<SnapshotInfo> forRollback = new ArrayList<>();
         VolumeInfo vol = Mockito.mock(VolumeInfo.class);
         SnapshotInfo snapshotInfo = Mockito.mock(SnapshotInfo.class);
@@ -162,6 +163,7 @@ public class VMSnapshotStrategyKVMTest extends TestCase{
         SnapshotVO snapshot = new SnapshotVO(vol.getDataCenterId(), 
vol.getAccountId(), vol.getDomainId(),
                                vol.getId(),vol.getDiskOfferingId(), vmUuid + 
"_" + volUuid,(short) SnapshotVO.MANUAL_POLICY_ID,
                                
"MANUAL",vol.getSize(),vol.getMinIops(),vol.getMaxIops(), 
Hypervisor.HypervisorType.KVM, null);
+        when(vmSnapshot.getOptions()).thenReturn(new VMSnapshotOptions(true));
         when(vmSnapshot.getUuid()).thenReturn(vmUuid);
         when(vol.getUuid()).thenReturn(volUuid);
         when(_snapshotDao.persist(any())).thenReturn(snapshot);
diff --git 
a/server/src/main/java/com/cloud/storage/snapshot/SnapshotManagerImpl.java 
b/server/src/main/java/com/cloud/storage/snapshot/SnapshotManagerImpl.java
index 940860dd04d..ab4a71903f6 100755
--- a/server/src/main/java/com/cloud/storage/snapshot/SnapshotManagerImpl.java
+++ b/server/src/main/java/com/cloud/storage/snapshot/SnapshotManagerImpl.java
@@ -1416,7 +1416,7 @@ public class SnapshotManagerImpl extends 
MutualExclusiveIdsManagerBase implement
             }
         } catch (CloudRuntimeException cre) {
             if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Failed to create snapshot" + 
cre.getLocalizedMessage());
+                s_logger.debug("Failed to create snapshot - " + 
cre.getLocalizedMessage());
             }
             _resourceLimitMgr.decrementResourceCount(snapshotOwner.getId(), 
ResourceType.snapshot);
             _resourceLimitMgr.decrementResourceCount(snapshotOwner.getId(), 
ResourceType.secondary_storage, new Long(volume.getSize()));
diff --git a/ui/src/config/section/compute.js b/ui/src/config/section/compute.js
index 2887044a535..b7c2a342d09 100644
--- a/ui/src/config/section/compute.js
+++ b/ui/src/config/section/compute.js
@@ -184,7 +184,13 @@ export default {
           label: 'label.action.vmsnapshot.create',
           docHelp: 
'adminguide/virtual_machines.html#virtual-machine-snapshots',
           dataView: true,
-          args: ['virtualmachineid', 'name', 'description', 'snapshotmemory', 
'quiescevm'],
+          args: (record, store) => {
+            var args = ['virtualmachineid', 'name', 'description', 
'snapshotmemory']
+            if (['KVM', 'VMware'].includes(record.hypervisor)) {
+              args.push('quiescevm')
+            }
+            return args
+          },
           show: (record) => {
             return ((['Running'].includes(record.state) && record.hypervisor 
!== 'LXC') ||
               (['Stopped'].includes(record.state) && ((record.hypervisor !== 
'KVM' && record.hypervisor !== 'LXC') ||
diff --git a/ui/src/views/compute/CreateSnapshotWizard.vue 
b/ui/src/views/compute/CreateSnapshotWizard.vue
index 0da42990efa..d19208a1808 100644
--- a/ui/src/views/compute/CreateSnapshotWizard.vue
+++ b/ui/src/views/compute/CreateSnapshotWizard.vue
@@ -55,13 +55,13 @@
             v-model:value="form.name"
             :placeholder="apiParams.name.description"/>
         </a-form-item>
-        <a-form-item name="quiescevm" ref="quiescevm" v-if="isQuiesceVm">
+        <a-form-item name="quiescevm" ref="quiescevm" v-if="isQuiesceVm && 
hypervisorSupportsQuiesceVm">
           <template #label>
             <tooltip-label :title="$t('label.quiescevm')" 
:tooltip="apiParams.quiescevm.description"/>
           </template>
           <a-switch v-model:checked="form.quiescevm"/>
         </a-form-item>
-        <a-form-item name="asyncbackup" ref="asyncbackup">
+        <a-form-item name="asyncbackup" ref="asyncbackup" 
v-if="!supportsStorageSnapshot">
           <template #label>
             <tooltip-label :title="$t('label.asyncbackup')" 
:tooltip="apiParams.asyncbackup.description"/>
           </template>
@@ -98,6 +98,7 @@ export default {
     return {
       loading: false,
       isQuiesceVm: false,
+      hypervisorSupportsQuiesceVm: false,
       supportsStorageSnapshot: false,
       listVolumes: []
     }
@@ -119,6 +120,9 @@ export default {
     },
     fetchData () {
       this.loading = true
+      if (['KVM', 'VMware'].includes(this.resource.hypervisor)) {
+        this.hypervisorSupportsQuiesceVm = true
+      }
 
       api('listVolumes', { virtualMachineId: this.resource.id, listall: true })
         .then(json => {
@@ -141,7 +145,10 @@ export default {
         if (values.asyncbackup) {
           params.asyncbackup = values.asyncbackup
         }
-        params.quiescevm = values.quiescevm
+        params.quiescevm = false
+        if (values.quiescevm) {
+          params.quiescevm = values.quiescevm
+        }
 
         const title = this.$t('label.action.vmstoragesnapshot.create')
         const description = values.name || values.volumeid
diff --git a/ui/src/views/storage/TakeSnapshot.vue 
b/ui/src/views/storage/TakeSnapshot.vue
index ee0eafbb56a..e378664d7fb 100644
--- a/ui/src/views/storage/TakeSnapshot.vue
+++ b/ui/src/views/storage/TakeSnapshot.vue
@@ -66,10 +66,10 @@
             </a-select-option>
           </a-select>
         </a-form-item>
-        <a-form-item :label="$t('label.asyncbackup')" name="asyncbackup" 
ref="asyncbackup">
+        <a-form-item :label="$t('label.asyncbackup')" name="asyncbackup" 
ref="asyncbackup" v-if="!supportsStorageSnapshot">
           <a-switch v-model:checked="form.asyncbackup" />
         </a-form-item>
-        <a-form-item :label="$t('label.quiescevm')">
+        <a-form-item :label="$t('label.quiescevm')" name="quiescevm" 
ref="quiescevm" v-if="quiescevm && hypervisorSupportsQuiesceVm">
           <a-switch v-model:checked="form.quiescevm" />
         </a-form-item>
         <a-divider/>
@@ -152,6 +152,7 @@ export default {
     return {
       actionLoading: false,
       quiescevm: false,
+      hypervisorSupportsQuiesceVm: false,
       supportsStorageSnapshot: false,
       inputValue: '',
       inputKey: '',
@@ -168,6 +169,10 @@ export default {
   created () {
     this.initForm()
     this.quiescevm = this.resource.quiescevm
+    if (['KVM', 'VMware'].includes(this.resource.hypervisor)) {
+      this.hypervisorSupportsQuiesceVm = true
+    }
+
     this.supportsStorageSnapshot = this.resource.supportsstoragesnapshot
     this.fetchZoneData()
   },

Reply via email to