mirror of
https://github.com/retspen/webvirtcloud
synced 2026-11-08 11:16:47 +00:00
fix(instances): a snapshot file another VM uses is not called left behind
After a snapshot revert or delete, files libvirt could not remove are named in a warning that says nothing uses them and asks to remove them by hand. A file another VM on the same host uses (as a disk, a backing file or a snapshot file) is no longer named: removing it would break that VM. The warning now says no VM on this host uses the files.
This commit is contained in:
parent
c970f8e853
commit
097a91592c
3 changed files with 32 additions and 5 deletions
|
|
@ -1383,7 +1383,7 @@ def _warn_left_behind(request, files):
|
|||
messages.warning(
|
||||
request,
|
||||
_(
|
||||
"These snapshot files were not removed, although nothing uses them any more: %(files)s. "
|
||||
"These snapshot files were not removed, although no VM on this host uses them any more: %(files)s. "
|
||||
"On NFS libvirt removes them as the qemu user, who needs write access to their directory. "
|
||||
"Remove them by hand."
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1715,9 +1715,10 @@ class wvmInstance(wvmConnect):
|
|||
logs a warning then (on NFS it removes them as the qemu user, who
|
||||
needs write access to their directory). Only a snapshot's own file or
|
||||
an overlay on a snapshot point counts; a disk a revert detached is
|
||||
kept on purpose. A file outside every storage pool is not checked,
|
||||
nor is anything when the pools could not be refreshed: a stale pool
|
||||
still lists the removed files."""
|
||||
kept on purpose, and a file another VM on this host uses (or one
|
||||
below it) is not reported. A file outside every storage pool is not
|
||||
checked, nor is anything when the pools could not be refreshed: a
|
||||
stale pool still lists the removed files."""
|
||||
disks, own, points = before
|
||||
if not self._refresh_pools_after_snapshot():
|
||||
return []
|
||||
|
|
@ -1734,6 +1735,14 @@ class wvmInstance(wvmConnect):
|
|||
except libvirtError: # not in a pool, or removed meanwhile
|
||||
continue
|
||||
left.append(path)
|
||||
if left:
|
||||
# another VM on this host may use one; their own backing files
|
||||
# do not keep each other, but a file in use keeps the files below it
|
||||
in_use = self.paths_in_use(own=left)
|
||||
for path in [path for path in left if path in in_use]:
|
||||
while (path := self._backing_path(path)) and path not in in_use:
|
||||
in_use.add(path)
|
||||
left = [path for path in left if path not in in_use]
|
||||
return left
|
||||
|
||||
@staticmethod
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ cases are in instances/tests/test_live_snapshots.py."""
|
|||
|
||||
import unittest
|
||||
from datetime import datetime
|
||||
from unittest.mock import MagicMock
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
from django.conf import settings
|
||||
|
||||
|
|
@ -440,6 +440,24 @@ class LeftBehindTestCase(unittest.TestCase):
|
|||
["/pool/a.one", "/pool/vm.one.mem"],
|
||||
)
|
||||
|
||||
def test_a_file_another_vm_uses_is_not_reported(self):
|
||||
# on NFS libvirt could not remove it, but another VM uses it now
|
||||
with patch.object(wvmInstance, "paths_in_use", return_value={"/pool/a.one"}) as in_use, \
|
||||
patch.object(wvmInstance, "_backing_path", return_value=None):
|
||||
left = self.run_delete({"/pool/a.one", "/pool/vm.one.mem", "/pool/a.two", "/pool/a.qcow2"})
|
||||
self.assertEqual(left, ["/pool/vm.one.mem"])
|
||||
# their own backing files do not keep each other
|
||||
in_use.assert_called_once_with(own=["/pool/a.one", "/pool/vm.one.mem"])
|
||||
|
||||
def test_a_file_below_one_another_vm_uses_is_not_reported(self):
|
||||
# the other VM is shut off: its definition does not list the backing
|
||||
# file, and the in-use top's own backing reference does not count
|
||||
backing = {"/pool/a.one": "/pool/vm.one.mem"}
|
||||
with patch.object(wvmInstance, "paths_in_use", return_value={"/pool/a.one"}), \
|
||||
patch.object(wvmInstance, "_backing_path", side_effect=backing.get):
|
||||
left = self.run_delete({"/pool/a.one", "/pool/vm.one.mem", "/pool/a.two", "/pool/a.qcow2"})
|
||||
self.assertEqual(left, [])
|
||||
|
||||
def test_nothing_is_reported_when_libvirt_removed_them(self):
|
||||
# files still in use (base, the newer overlay) are never reported
|
||||
self.assertEqual(self.run_delete({"/pool/a.two", "/pool/a.qcow2"}), [])
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue