mirror of
https://github.com/retspen/webvirtcloud
synced 2026-11-10 20:26:48 +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
|
|
@ -2,7 +2,12 @@ from computes.models import Compute
|
|||
from django.db import models
|
||||
from django.utils.functional import cached_property
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from libvirt import VIR_DOMAIN_XML_SECURE, libvirtError
|
||||
from libvirt import (
|
||||
VIR_DOMAIN_SNAPSHOT_LIST_EXTERNAL,
|
||||
VIR_DOMAIN_SNAPSHOT_LIST_INTERNAL,
|
||||
VIR_DOMAIN_XML_SECURE,
|
||||
libvirtError,
|
||||
)
|
||||
from vrtManager.instance import wvmInstance
|
||||
from webvirtcloud.settings import QEMU_CONSOLE_LISTENER_ADDRESSES
|
||||
|
||||
|
|
@ -253,13 +258,24 @@ class Instance(models.Model):
|
|||
def video_models(self):
|
||||
return self.proxy.get_video_models(self.arch, self.machine)
|
||||
|
||||
@cached_property
|
||||
def snapshots(self) -> list[dict]:
|
||||
return sorted(self.proxy.get_snapshot(), reverse=True, key=lambda k: k["date"])
|
||||
def _snapshots(self, flag):
|
||||
return sorted(self.proxy.get_snapshot(flag), reverse=True, key=lambda k: k["date"])
|
||||
|
||||
@cached_property
|
||||
def external_snapshots(self):
|
||||
return sorted(self.proxy.get_external_snapshots(), reverse=True, key=lambda k: k["date"])
|
||||
def snapshots(self) -> list[dict]:
|
||||
return self._snapshots(VIR_DOMAIN_SNAPSHOT_LIST_INTERNAL | VIR_DOMAIN_SNAPSHOT_LIST_EXTERNAL)
|
||||
|
||||
@cached_property
|
||||
def internal_snapshots(self) -> list[dict]:
|
||||
return self._snapshots(VIR_DOMAIN_SNAPSHOT_LIST_INTERNAL)
|
||||
|
||||
@cached_property
|
||||
def external_snapshots(self) -> list[dict]:
|
||||
return self._snapshots(VIR_DOMAIN_SNAPSHOT_LIST_EXTERNAL)
|
||||
|
||||
@cached_property
|
||||
def snapshot_jobs(self) -> list[dict]:
|
||||
return self.proxy.get_snapshot_jobs()
|
||||
|
||||
@cached_property
|
||||
def inst_xml(self):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue