guest: Add DomainCapabilities caching

This commit is contained in:
Cole Robinson 2018-10-04 12:22:22 -04:00
parent 210cb858bc
commit 76334bfabd
4 changed files with 45 additions and 18 deletions

View File

@ -106,6 +106,11 @@ class TestCapabilities(unittest.TestCase):
xml = open("tests/capabilities-xml/kvm-x86_64-domcaps.xml").read()
caps = DomainCapabilities(utils.URIs.open_testdriver_cached(), 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")

View File

@ -7,7 +7,6 @@
import logging
from ..domcapabilities import DomainCapabilities
from ..xmlbuilder import XMLBuilder, XMLProperty, XMLChildProperty
@ -206,20 +205,14 @@ class DomainCpu(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
# <capabilities> is not actually supported by qemu/kvm
# combo which will be reported in <domainCapabilities>
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
@ -233,6 +226,15 @@ class DomainCpu(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)

View File

@ -217,6 +217,9 @@ class DomainCapabilities(XMLBuilder):
os = XMLChildProperty(_OS, is_single=True)
cpu = XMLChildProperty(_CPU, is_single=True)
devices = XMLChildProperty(_Devices, is_single=True)
features = XMLChildProperty(_Features, is_single=True)
arch = XMLProperty("./arch")
features = XMLChildProperty(_Features, is_single=True)
domain = XMLProperty("./domain")
machine = XMLProperty("./machine")
path = XMLProperty("./path")

View File

@ -165,6 +165,7 @@ class Guest(XMLBuilder):
self.__osinfo = None
self._capsinfo = None
self._domcaps = None
######################
@ -326,7 +327,7 @@ class Guest(XMLBuilder):
"""
if not self.os.arch:
self.set_capabilities_defaults()
domcaps = DomainCapabilities.build_from_guest(self)
domcaps = self.lookup_domcaps()
if not domcaps.supports_uefi_xml():
raise RuntimeError(_("Libvirt version does not support UEFI."))
@ -408,10 +409,26 @@ class Guest(XMLBuilder):
return False
return True
def lookup_capsinfo(self):
def _compare_to_capsinfo(capsinfo):
if not capsinfo:
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
def lookup_capsinfo(self):
# We need to regenerate capsinfo cache if any of these values change
def _compare(capsinfo):
if self.type and self.type != capsinfo.hypervisor_type:
return False
if self.os.os_type and self.os.os_type != capsinfo.os_type:
@ -422,7 +439,7 @@ class Guest(XMLBuilder):
return False
return True
if not _compare_to_capsinfo(self._capsinfo):
if not self._capsinfo or not _compare(self._capsinfo):
self._capsinfo = self.conn.caps.guest_lookup(
os_type=self.os.os_type,
arch=self.os.arch,