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
44
vrtManager/test_console_setters.py
Normal file
44
vrtManager/test_console_setters.py
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
import unittest
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
from django.conf import settings
|
||||
|
||||
if not settings.configured:
|
||||
settings.configure(MAC_OUI="52:54:10")
|
||||
|
||||
from lxml import etree
|
||||
from vrtManager.instance import PERSISTENT_XML, wvmInstance
|
||||
|
||||
LIVE = "<domain><devices><graphics type='vnc' passwd='live'><listen type='address'/></graphics></devices></domain>"
|
||||
PERSISTENT = "<domain><devices><graphics type='spice' passwd='old'><listen type='address'/></graphics></devices></domain>"
|
||||
|
||||
|
||||
def running_vm_with_pending_graphics_type():
|
||||
vm = wvmInstance.__new__(wvmInstance)
|
||||
vm.wvm = MagicMock()
|
||||
vm._XMLDesc = MagicMock(side_effect=lambda flags: PERSISTENT if flags == PERSISTENT_XML else LIVE)
|
||||
return vm
|
||||
|
||||
|
||||
class ConsoleSettersTestCase(unittest.TestCase):
|
||||
"""The graphics device to edit comes from the persistent definition."""
|
||||
|
||||
def defined_graphics(self, vm):
|
||||
return etree.fromstring(vm.wvm.defineXML.call_args[0][0]).find("devices/graphics")
|
||||
|
||||
def test_setters_edit_the_persistent_graphics_device(self):
|
||||
edits = {
|
||||
"set_console_passwd": (lambda vm: vm.set_console_passwd("new"), "passwd", "new"),
|
||||
"set_console_keymap": (lambda vm: vm.set_console_keymap("de"), "keymap", "de"),
|
||||
"set_console_listener_addr": (lambda vm: vm.set_console_listener_addr("127.0.0.1"), "listen", "127.0.0.1"),
|
||||
"set_console_type": (lambda vm: vm.set_console_type("vnc"), "type", "vnc"),
|
||||
}
|
||||
for name, (edit, attr, value) in edits.items():
|
||||
with self.subTest(name):
|
||||
vm = running_vm_with_pending_graphics_type()
|
||||
edit(vm)
|
||||
self.assertEqual(self.defined_graphics(vm).get(attr), value)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Loading…
Add table
Add a link
Reference in a new issue