From d2e04a495d77b245a28e9cdd65efe5ac12338a5c Mon Sep 17 00:00:00 2001 From: nwin Date: Thu, 21 Nov 2024 19:32:51 +0100 Subject: [PATCH] readd managedsave to current --- src/components/vm/overview/vmOverviewCard.jsx | 2 +- src/components/vm/vmActions.jsx | 65 +++++++++++++++++++ src/components/vms/hostvmslist.jsx | 2 + src/helpers.js | 1 + src/libvirtApi/domain.js | 27 ++++++++ 5 files changed, 96 insertions(+), 1 deletion(-) diff --git a/src/components/vm/overview/vmOverviewCard.jsx b/src/components/vm/overview/vmOverviewCard.jsx index 2cd8aa14e..fa142e338 100644 --- a/src/components/vm/overview/vmOverviewCard.jsx +++ b/src/components/vm/overview/vmOverviewCard.jsx @@ -165,7 +165,7 @@ class VmOverviewCard extends React.Component { {_("State")} store.dispatch(updateVm({ connectionName: vm.connectionName, diff --git a/src/components/vm/vmActions.jsx b/src/components/vm/vmActions.jsx index cf5868bcd..91aa86ef2 100644 --- a/src/components/vm/vmActions.jsx +++ b/src/components/vm/vmActions.jsx @@ -50,6 +50,8 @@ import { domainCanPause, domainCanShutdown, domainForceOff, + domainCanSuspendToDisk, + domainCanSuspenImageRemove, domainForceReboot, domainInstall, domainPause, @@ -59,6 +61,9 @@ import { domainShutdown, domainStart, domainAddTPM, + domainSuspendToDisk, + domainSuspendImageRemove, + domainHasSuspendImage } from '../../libvirtApi/domain.js'; import store from "../../store.js"; @@ -183,6 +188,43 @@ const onSendNMI = (vm) => domainSendNMI({ name: vm.name, id: vm.id, connectionNa ); }); +const onSuspendToDisk = (vm) => domainSuspendToDisk({ name: vm.name, id: vm.id, connectionName: vm.connectionName, flags: vm.state == 'running' ? 2 : 4 }).catch(ex => { + store.dispatch( + updateVm({ + connectionName: vm.connectionName, + name: vm.name, + error: { + text: cockpit.format(_("VM $0 failed to save "), vm.name), + detail: ex.message, + } + }) + ); +}); + +const onSuspendImageRemove = (vm) => domainSuspendImageRemove({ name: vm.name, id: vm.id, connectionName: vm.connectionName }) + .then(() => domainHasSuspendImage({ name: vm.name, id: vm.id, connectionName: vm.connectionName })) + .then((SuspendImage) => { + store.dispatch( + updateVm({ + connectionName: vm.connectionName, + name: vm.name, + suspendImage: SuspendImage[0], + }) + ); + }) + .catch(ex => { + store.dispatch( + updateVm({ + connectionName: vm.connectionName, + name: vm.name, + error: { + text: cockpit.format(_("VM $0 failed to remove save image "), vm.name), + detail: ex.message, + } + }) + ); + }); + const onAddTPM = (vm, onAddErrorNotification) => domainAddTPM({ connectionName: vm.connectionName, vmName: vm.name }) .catch(ex => onAddErrorNotification({ text: cockpit.format(_("Failed to add TPM to VM $0"), vm.name), @@ -208,6 +250,7 @@ const VmActions = ({ vm, vms, onAddErrorNotification, isDetailsPage }) => { const id = `${vmId(vm.name)}-${vm.connectionName}`; const state = vm.state; + const suspendImage = vm.suspendImage; const hasInstallPhase = vm.metadata && vm.metadata.hasInstallPhase; const dropdownItems = []; @@ -235,6 +278,28 @@ const VmActions = ({ vm, vms, onAddErrorNotification, isDetailsPage }) => { dropdownItems.push(); } + if (domainCanSuspendToDisk(state)) { + dropdownItems.push( + onSuspendToDisk(vm)}> + {_("Suspend to disk")} + + ); + dropdownItems.push(); + } + + if (domainCanSuspenImageRemove(state, suspendImage)) { + dropdownItems.push( + onSuspendImageRemove(vm)}> + {_("Remove Suspend Image")} + + ); + dropdownItems.push(); + } + if (domainCanShutdown(state)) { shutdown = (