mirror of
https://github.com/retspen/webvirtcloud
synced 2026-11-09 03:36:48 +00:00
feat(jobs): deleting a VM is a job that recovery finishes
The delete ran in the request: undefine, then the VM's record, then its disk files. A request that died in between (a gunicorn worker past its timeout, OOM, a restart), or a database write that failed after the undefine, left a record that later showed as removed outside the panel, and the disk files the user asked to delete were never deleted. Deleting a VM is now an instance.delete job. It holds the compute exclusively, as the request did, so no other VM attaches a file it is about to delete. The job chooses the files before it stops the VM (a host that cannot be checked still stops nothing) and records them first. It then stops and undefines the VM, removes its record, and deletes the files, each with its own Logs row. Recovery decides from libvirt: a VM still on its host means the delete failed; a VM gone means libvirt did it, so recovery removes the record and deletes the recorded files that are still there. The page queues the job and returns to the VM page, where the job panel follows it and opens the VM list when it ends; disks that were kept are the result's warning. The API's delete answers 202 with the job and needs a submission_key. backing_path moves to wvmConnect, as recovery has no domain to ask.
This commit is contained in:
parent
ce066052d9
commit
02412b7ea5
19 changed files with 923 additions and 764 deletions
|
|
@ -1833,18 +1833,6 @@ class wvmInstance(wvmConnect):
|
|||
grew = True
|
||||
return files[len(tops):] + memory
|
||||
|
||||
def backing_path(self, path):
|
||||
"""The backing file of a volume; None if it has none or is in no pool.
|
||||
Any other error is raised: a chain cut short would let a file a kept
|
||||
one needs count as deletable."""
|
||||
try:
|
||||
vol = self.get_volume_by_path(path)
|
||||
except libvirtError as err:
|
||||
if err.get_error_code() != VIR_ERR_NO_STORAGE_VOL:
|
||||
raise
|
||||
return None
|
||||
return util.get_xml_path(vol.XMLDesc(0), "/volume/backingStore/path")
|
||||
|
||||
def _snapshotCreateXML(self, xml, flag):
|
||||
self.instance.snapshotCreateXML(xml, flag)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue