Merge branch '4.19' of https://github.com/apache/cloudstack into 4.20

This commit is contained in:
Pearl Dsilva 2025-05-02 14:59:05 +05:30
commit 91c1168861
5 changed files with 36 additions and 11 deletions

View File

@ -181,7 +181,7 @@ public class StorageVMSnapshotStrategy extends DefaultVMSnapshotStrategy {
thawAnswer = (FreezeThawVMAnswer) agentMgr.send(hostId, thawCmd);
if (thawAnswer != null && thawAnswer.getResult()) {
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 {
@ -427,9 +427,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);
@ -447,14 +452,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;
}
}

View File

@ -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);

View File

@ -190,7 +190,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') ||

View File

@ -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

View File

@ -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()
},