diff --git a/src/components/vm/confirmDialog.jsx b/src/components/vm/confirmDialog.jsx index a0bc44b2b..b7008235b 100644 --- a/src/components/vm/confirmDialog.jsx +++ b/src/components/vm/confirmDialog.jsx @@ -27,6 +27,7 @@ import { useDialogs } from 'dialogs.jsx'; import { distanceToNow } from 'timeformat.js'; import { domainGetStartTime } from '../../libvirtApi/domain.js'; +import { Enum } from '../../libvirtApi/helpers.js'; const _ = cockpit.gettext; @@ -60,18 +61,65 @@ export const ConfirmDialog = ({ idPrefix, actionsList, title, titleIcon, vm }) = ); - let body = ( - - - - ); + let body; + if (dialogLoading) { + body = ( + + + + ); + } else if (uptime) { + let uptimeStr = distanceToNow(new Date(uptime)); + + // https://libvirt.org/html/libvirt-libvirt-domain.html#virDomainRunningReason + switch (vm.stateReason) { + case Enum.VIR_DOMAIN_RUNNING_MIGRATED: { + uptimeStr = cockpit.format(_("$0 since migration"), uptimeStr); + break; + } + case Enum.VIR_DOMAIN_RUNNING_RESTORED: { + uptimeStr = cockpit.format(_("$0 since restoration from a state file"), uptimeStr); + break; + } + case Enum.VIR_DOMAIN_RUNNING_FROM_SNAPSHOT: { + uptimeStr = cockpit.format(_("$0 since reverting to snapshot"), uptimeStr); + break; + } + case Enum.VIR_DOMAIN_RUNNING_UNPAUSED: { + uptimeStr = cockpit.format(_("$0 since VM was resumed"), uptimeStr); + break; + } + case Enum.VIR_DOMAIN_RUNNING_MIGRATION_CANCELED: { + uptimeStr = cockpit.format(_("$0 since migration was cancelled"), uptimeStr); + break; + } + case Enum.VIR_DOMAIN_RUNNING_SAVE_CANCELED: { + uptimeStr = cockpit.format(_("$0 since failed save process"), uptimeStr); + break; + } + case Enum.VIR_DOMAIN_RUNNING_WAKEUP: { + uptimeStr = cockpit.format(_("$0 since wakeup event"), uptimeStr); + break; + } + case Enum.VIR_DOMAIN_RUNNING_CRASHED: { + uptimeStr = cockpit.format(_("$0 since resumed from crash"), uptimeStr); + break; + } + case Enum.VIR_DOMAIN_RUNNING_POSTCOPY: { + uptimeStr = cockpit.format(_("$0 since post-copy migration"), uptimeStr); + break; + } + case Enum.VIR_DOMAIN_RUNNING_POSTCOPY_FAILED: { + uptimeStr = cockpit.format(_("$0 since failed post-copy migration"), uptimeStr); + break; + } + } - if (!dialogLoading) { - body = (uptime && + body = ( {_("Uptime")} - {distanceToNow(new Date(uptime))} + {uptimeStr} ); diff --git a/test/check-machines-lifecycle b/test/check-machines-lifecycle index 6b4b3f147..03f271c45 100755 --- a/test/check-machines-lifecycle +++ b/test/check-machines-lifecycle @@ -244,6 +244,17 @@ class TestMachinesLifecycle(VirtualMachinesCase): b.click(".pf-c-modal-box__footer button:contains(Cancel)") b.wait_not_present("#vm-subVmTest2-system-confirm-action-modal") + # Check uptime with VM boot message + # Non-privileged user doesn't have access to system-connection VM's logs + if superuser: + m.execute("virsh managedsave --domain subVmTest2") + m.execute("virsh start --domain subVmTest2") + b.click("#vm-subVmTest2-system-shutdown-button") + b.wait_visible("#vm-subVmTest2-system-confirm-action-modal") + b.wait_in_text("#vm-subVmTest2-system-confirm-action-modal #uptime", "since restoration from a state file") + b.click(".pf-c-modal-box__footer button:contains(Cancel)") + b.wait_not_present("#vm-subVmTest2-system-confirm-action-modal") + b.set_input_text("#text-search", "subVmTest2") self.waitVmRow("subVmTest2") self.waitVmRow("subVmTest1", "system", False)