From 8bf52a94315a3fa219875a009a5d9661c46c47fe Mon Sep 17 00:00:00 2001 Message-Id: <8bf52a94315a3fa219875a009a5d9661c46c47fe@dist-git> From: Pavel Hrdina Date: Thu, 4 Oct 2018 12:22:22 -0400 Subject: [PATCH] guest: Add DomainCapabilities caching From: Cole Robinson (cherry picked from commit 76334bfabdfd32498d78f390182d9621036e02d3) Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1525337 Conflicts: - virtinst/guest.py: different code-base as upstream have a lot of cleanup patches that moved a lot of code around Reviewed-by: Cole Robinson Signed-off-by: Pavel Hrdina --- tests/capabilities.py | 5 +++++ virtinst/cpu.py | 26 ++++++++++++++------------ virtinst/domcapabilities.py | 7 +++++-- virtinst/guest.py | 21 ++++++++++++++++++++- 4 files changed, 44 insertions(+), 15 deletions(-) diff --git a/tests/capabilities.py b/tests/capabilities.py index ef1d961b..f1416925 100644 --- a/tests/capabilities.py +++ b/tests/capabilities.py @@ -135,6 +135,11 @@ class TestCapabilities(unittest.TestCase): xml = open("tests/capabilities-xml/kvm-x86_64-domcaps.xml").read() caps = DomainCapabilities(utils.open_testdriver(), xml) + self.assertEqual(caps.machine, "pc-i440fx-2.1") + self.assertEqual(caps.arch, "x86_64") + self.assertEqual(caps.domain, "kvm") + self.assertEqual(caps.path, "/bin/qemu-system-x86_64") + custom_mode = caps.cpu.get_mode("custom") self.assertTrue(bool(custom_mode)) cpu_model = custom_mode.get_model("Opteron_G4") diff --git a/virtinst/cpu.py b/virtinst/cpu.py index 1b8f4a96..1f1ad7ec 100644 --- a/virtinst/cpu.py +++ b/virtinst/cpu.py @@ -19,7 +19,6 @@ import logging -from .domcapabilities import DomainCapabilities from .xmlbuilder import XMLBuilder, XMLProperty, XMLChildProperty @@ -237,20 +236,14 @@ class CPU(XMLBuilder): # Default config # ################## - def _set_cpu_x86_kvm_default(self, guest): - if guest.os.arch != self.conn.caps.host.cpu.arch: - return - - self.set_special_mode(guest.x86_cpu_default) - if guest.x86_cpu_default != self.SPECIAL_MODE_HOST_MODEL_ONLY: - return - if not self.model: - return - + def _validate_default_host_model_only(self, guest): # It's possible that the value HOST_MODEL_ONLY gets from # is not actually supported by qemu/kvm # combo which will be reported in - domcaps = DomainCapabilities.build_from_guest(guest) + if not self.model: + return + + domcaps = guest.lookup_domcaps() domcaps_mode = domcaps.cpu.get_mode("custom") if not domcaps_mode: return @@ -264,6 +257,15 @@ class CPU(XMLBuilder): self.model) self.model = None + def _set_cpu_x86_kvm_default(self, guest): + if guest.os.arch != self.conn.caps.host.cpu.arch: + return + + mode = guest.x86_cpu_default + self.set_special_mode(mode) + if mode == self.SPECIAL_MODE_HOST_MODEL_ONLY: + self._validate_default_host_model_only(guest) + def set_defaults(self, guest): self.set_topology_defaults(guest.vcpus) diff --git a/virtinst/domcapabilities.py b/virtinst/domcapabilities.py index 78ac7a3e..1a84ab95 100644 --- a/virtinst/domcapabilities.py +++ b/virtinst/domcapabilities.py @@ -192,6 +192,9 @@ class DomainCapabilities(XMLBuilder): os = XMLChildProperty(_OS, is_single=True) cpu = XMLChildProperty(_CPU, is_single=True) devices = XMLChildProperty(_Devices, is_single=True) - - arch = XMLProperty("./arch") features = XMLChildProperty(_Features, is_single=True) + + arch = XMLProperty("./arch") + domain = XMLProperty("./domain") + machine = XMLProperty("./machine") + path = XMLProperty("./path") diff --git a/virtinst/guest.py b/virtinst/guest.py index 6bf1b59a..9c45b1b8 100644 --- a/virtinst/guest.py +++ b/virtinst/guest.py @@ -140,6 +140,7 @@ class Guest(XMLBuilder): # This is set via Capabilities.build_virtinst_guest self.capsinfo = None + self._domcaps = None self.installer = DistroInstaller(self.conn) @@ -534,6 +535,24 @@ class Guest(XMLBuilder): logging.error("Failed to remove disk '%s': %s", name, e) + def lookup_domcaps(self): + # We need to regenerate domcaps cache if any of these values change + def _compare(domcaps): + if self.os.machine and self.os.machine != domcaps.machine: + return False + if self.type and self.type != domcaps.domain: + return False + if self.os.arch and self.os.arch != domcaps.arch: + return False + if self.emulator and self.emulator != domcaps.path: + return False + return True + + if not self._domcaps or not _compare(self._domcaps): + self._domcaps = DomainCapabilities.build_from_guest(self) + return self._domcaps + + ########################### # XML convenience helpers # ########################### @@ -543,7 +562,7 @@ class Guest(XMLBuilder): Configure UEFI for the VM, but only if libvirt is advertising a known UEFI binary path. """ - domcaps = DomainCapabilities.build_from_guest(self) + domcaps = self.lookup_domcaps() if not domcaps.supports_uefi_xml(): raise RuntimeError(_("Libvirt version does not support UEFI.")) -- 2.20.1