mirror of
https://github.com/retspen/webvirtcloud
synced 2026-11-10 04:06:47 +00:00
fix(quota): a disk whose size is unknown is not counted as 0 GiB
A disk of the user's VMs whose size could not be read (its volume not in a pool, the pool stopped) counted as 0 GiB, so a disk-limited user's increase could pass over the limit. A disk no pool holds now has the size libvirt reads from the file or device (blockInfo, also for a shut-off VM); one whose size is still unknown makes the usage unverified and the increase is refused, as when a host cannot be reached. Users without a disk limit are not affected.
This commit is contained in:
parent
d8a184eff7
commit
0b4a601ecb
9 changed files with 215 additions and 184 deletions
|
|
@ -926,6 +926,11 @@ class wvmInstance(wvmConnect):
|
|||
volume, disk_size, used_size, storage = details
|
||||
else:
|
||||
volume = src_file
|
||||
# a disk no pool holds: libvirt reads its size from the file or device,
|
||||
# named by its path: a target names the running VM's disk, which may
|
||||
# be another file than the one saved for its next start (that one: unknown)
|
||||
with contextlib.suppress(libvirtError):
|
||||
disk_size, used_size = self.instance.blockInfo(src_file)[:2]
|
||||
except Exception as e:
|
||||
logger.warning("Disk %s of %s not fully read: %s", dev, self.instance.name(), e)
|
||||
finally:
|
||||
|
|
|
|||
|
|
@ -48,6 +48,15 @@ class DeviceGettersTestCase(unittest.TestCase):
|
|||
self.assertEqual([(n["inbound"], n["outbound"]) for n in nics[1:]], [([], [])] * 2)
|
||||
self.assertEqual([(n["nic"], n["model"]) for n in nics], [("default", "virtio"), ("br0", ""), ("", "")])
|
||||
|
||||
def test_a_disk_no_pool_holds_has_the_size_libvirt_reads(self):
|
||||
p = proxy()
|
||||
p.instance = MagicMock()
|
||||
# vda: libvirt reads it, by its path; vdb: it cannot
|
||||
p.instance.blockInfo.side_effect = lambda path: [20 << 30, 5 << 30, 20 << 30] if path == "/pool/a.qcow2" else \
|
||||
(_ for _ in ()).throw(libvirtError("cannot read"))
|
||||
self.assertEqual([(d["dev"], d["size"], d["used"]) for d in p.get_disk_devices()],
|
||||
[("vda", 20 << 30, 5 << 30), ("vdb", None, None)])
|
||||
|
||||
def test_an_empty_cdrom_shows_no_pool(self):
|
||||
media = proxy().get_media_devices()
|
||||
self.assertEqual(
|
||||
|
|
|
|||
|
|
@ -25,6 +25,9 @@ class FakeDomain:
|
|||
self.reads.append(flags)
|
||||
return f"<domain flags='{flags}' read='{len(self.reads)}'/>"
|
||||
|
||||
def blockInfo(self, dev): # a disk no pool holds that libvirt cannot read either
|
||||
raise libvirtError("cannot read")
|
||||
|
||||
|
||||
class FakeConn:
|
||||
def __init__(self):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue