mirror of
https://github.com/retspen/webvirtcloud
synced 2026-11-11 12:46:49 +00:00
feat(instances): external snapshots use libvirt's snapshot API
Create, revert and delete are one libvirt call each. The pflash-to-rom loader rewrite, the hand-written block commit and the s1./s2. names are gone, so UEFI VMs can take external snapshots, a revert keeps disks added later, and deleting an older snapshot keeps the newer one. Create refuses what libvirt could not revert or delete later: internal snapshots on the VM, a saved state, a running snapshot job, disks that are not files, CD-ROM media, a branch after a revert, and memory without a running VM or room in the first disk's pool. A disk-only revert keeps the VM running, paused or shut off; one with memory resumes it as saved. A revert in the same second as the previous one, which libvirt fails after stopping the VM, is retried once. A snapshot the old code took of a UEFI VM saved the loader as rom; its revert is refused (deleting it still works). The snapshots tab lists internal and external snapshots separately, can save memory too, shows running snapshot jobs, and the revert confirmation names the disks it detaches and that NVRAM is not restored.
This commit is contained in:
parent
c55f52f025
commit
ff1508b3c2
13 changed files with 994 additions and 311 deletions
|
|
@ -35,7 +35,6 @@ from libvirt import (VIR_DOMAIN_UNDEFINE_KEEP_NVRAM,
|
|||
VIR_DOMAIN_UNDEFINE_MANAGED_SAVE,
|
||||
VIR_DOMAIN_UNDEFINE_SNAPSHOTS_METADATA,
|
||||
VIR_DOMAIN_UNDEFINE_NVRAM,
|
||||
VIR_DOMAIN_START_PAUSED,
|
||||
libvirtError)
|
||||
from logs.views import addlogmsg
|
||||
from webvirtcloud.middleware import error_text
|
||||
|
|
@ -1342,7 +1341,11 @@ def delete_snapshot(request, pk):
|
|||
if not request.user.has_perm("instances.snapshot_instances"):
|
||||
raise PermissionDenied
|
||||
snap_name = request.POST.get("name", "")
|
||||
instance.proxy.snapshot_delete(snap_name)
|
||||
try:
|
||||
instance.proxy.snapshot_delete(snap_name)
|
||||
except libvirtError as err:
|
||||
messages.error(request, _("Snapshot was not deleted: %(err)s") % {"err": error_text(request, err)})
|
||||
return _back(request, pk, "managesnapshot")
|
||||
msg = _("Delete snapshot: %(snap)s") % {"snap": snap_name}
|
||||
addlogmsg(request.user.username, instance.compute.name, instance.name, msg)
|
||||
return _back(request, pk, "managesnapshot")
|
||||
|
|
@ -1376,9 +1379,14 @@ def create_external_snapshot(request, pk):
|
|||
raise PermissionDenied
|
||||
name = request.POST.get("name", "")
|
||||
desc = request.POST.get("description", "")
|
||||
instance.proxy.create_external_snapshot("s1." + name, instance, desc=desc)
|
||||
msg = _("Create external snapshot: %(snap)s") % {"snap": name}
|
||||
addlogmsg(request.user.username, instance.compute.name, instance.name, msg)
|
||||
memory = request.POST.get("memory") == "on"
|
||||
try:
|
||||
instance.proxy.create_external_snapshot(name, desc, memory)
|
||||
except libvirtError as err:
|
||||
messages.error(request, _("Snapshot was not created: %(err)s") % {"err": error_text(request, err)})
|
||||
else:
|
||||
msg = _("Create external snapshot: %(snap)s") % {"snap": name}
|
||||
addlogmsg(request.user.username, instance.compute.name, instance.name, msg)
|
||||
return _back(request, pk, "managesnapshot")
|
||||
|
||||
|
||||
|
|
@ -1388,15 +1396,15 @@ def revert_external_snapshot(request, pk):
|
|||
instance = get_instance(request.user, pk, perm_type="change")
|
||||
if not request.user.has_perm("instances.snapshot_instances"):
|
||||
raise PermissionDenied
|
||||
instance_state = True if instance.proxy.get_status() != 5 else False
|
||||
name = request.POST.get("name", "")
|
||||
date = request.POST.get("date", "")
|
||||
desc = request.POST.get("desc", "")
|
||||
instance.proxy.force_shutdown() if instance_state else None
|
||||
instance.proxy.revert_external_snapshot(name, date, desc)
|
||||
instance.proxy.start() if instance_state else None
|
||||
msg = _("Revert external snapshot: %(snap)s") % {"snap": name}
|
||||
addlogmsg(request.user.username, instance.compute.name, instance.name, msg)
|
||||
try:
|
||||
instance.proxy.revert_external_snapshot(name)
|
||||
except libvirtError as err:
|
||||
messages.error(request, _("Snapshot was not reverted: %(err)s") % {"err": error_text(request, err)})
|
||||
else:
|
||||
messages.success(request, _("Successful revert snapshot: ") + name)
|
||||
msg = _("Revert external snapshot: %(snap)s") % {"snap": name}
|
||||
addlogmsg(request.user.username, instance.compute.name, instance.name, msg)
|
||||
return _back(request, pk, "managesnapshot")
|
||||
|
||||
|
||||
|
|
@ -1406,18 +1414,14 @@ def delete_external_snapshot(request, pk):
|
|||
instance = get_instance(request.user, pk, perm_type="change")
|
||||
if not request.user.has_perm("instances.snapshot_instances"):
|
||||
raise PermissionDenied
|
||||
instance_state = True if instance.proxy.get_status() == 5 else False
|
||||
name = request.POST.get("name", "")
|
||||
|
||||
instance.proxy.start(VIR_DOMAIN_START_PAUSED) if instance_state else None
|
||||
|
||||
try:
|
||||
instance.proxy.delete_external_snapshot(name)
|
||||
except libvirtError as err:
|
||||
messages.error(request, _("Snapshot was not deleted: %(err)s") % {"err": error_text(request, err)})
|
||||
else:
|
||||
msg = _("Delete external snapshot: %(snap)s") % {"snap": name}
|
||||
addlogmsg(request.user.username, instance.compute.name, instance.name, msg)
|
||||
finally:
|
||||
instance.proxy.force_shutdown() if instance_state else None
|
||||
|
||||
return _back(request, pk, "managesnapshot")
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue