mirror of
https://github.com/retspen/webvirtcloud
synced 2026-11-09 03:36:48 +00:00
fix(instances): domain edits start from the persistent definition
Edits that redefine a domain read the wrong XML: - boot menu/order, vCPU hotplug and QoS read XMLDesc(0), which has no secrets, so every such edit, even on a stopped VM, removed the VNC password from the definition; - console, video, CPU, memory and title/description edits read the live XML, so on a running VM pending changes (e.g. a new memory size) were reverted and runtime state was written into the definition. All of them now read VIR_DOMAIN_XML_INACTIVE | SECURE (PERSISTENT_XML). The console setters take the first graphics device of that definition instead of looking it up by the live type. Disk resize no longer redefines the domain. A running VM's image files grow through blockResize, since qemu-img cannot take the lock QEMU holds; block volumes (e.g. LVM) are grown by the storage pool first and QEMU is then told the new size. Live tests reproduce the losses on a RHEL qemu-kvm host; unit tests check the XML flags, the console setters and the resize paths in CI.
This commit is contained in:
parent
47c480f059
commit
08bf39ef61
6 changed files with 293 additions and 59 deletions
45
vrtManager/test_resize_disk.py
Normal file
45
vrtManager/test_resize_disk.py
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
import unittest
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
from django.conf import settings
|
||||
|
||||
if not settings.configured:
|
||||
settings.configure(MAC_OUI="52:54:10")
|
||||
|
||||
from libvirt import VIR_DOMAIN_BLOCK_RESIZE_BYTES, VIR_STORAGE_VOL_BLOCK, VIR_STORAGE_VOL_FILE
|
||||
from vrtManager.instance import wvmInstance
|
||||
|
||||
SIZE = 10 << 30
|
||||
|
||||
|
||||
def vm(active, vol_type):
|
||||
inst = wvmInstance.__new__(wvmInstance)
|
||||
inst.instance = MagicMock()
|
||||
inst.instance.isActive.return_value = active
|
||||
vol = MagicMock()
|
||||
vol.info.return_value = [vol_type, 0, 0]
|
||||
inst.get_volume_by_path = MagicMock(return_value=vol)
|
||||
inst.resize_disk([{"path": "/dev/vg/disk", "size_new": SIZE}])
|
||||
return inst, vol
|
||||
|
||||
|
||||
class ResizeDiskTestCase(unittest.TestCase):
|
||||
def test_running_block_volume_grows_in_the_pool_then_in_qemu(self):
|
||||
inst, vol = vm(active=True, vol_type=VIR_STORAGE_VOL_BLOCK)
|
||||
vol.resize.assert_called_once_with(SIZE)
|
||||
inst.instance.blockResize.assert_called_once_with("/dev/vg/disk", SIZE, VIR_DOMAIN_BLOCK_RESIZE_BYTES)
|
||||
|
||||
def test_running_image_file_grows_through_qemu_only(self):
|
||||
# qemu-img cannot take the image lock QEMU holds
|
||||
inst, vol = vm(active=True, vol_type=VIR_STORAGE_VOL_FILE)
|
||||
vol.resize.assert_not_called()
|
||||
inst.instance.blockResize.assert_called_once()
|
||||
|
||||
def test_stopped_vm_grows_the_volume(self):
|
||||
inst, vol = vm(active=False, vol_type=VIR_STORAGE_VOL_FILE)
|
||||
vol.resize.assert_called_once_with(SIZE)
|
||||
inst.instance.blockResize.assert_not_called()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Loading…
Add table
Add a link
Reference in a new issue