guest: Rework set/get_uefi entry points

This replaces the pattern:

  Guest.set_uefi_path(Guest.get_uefi_path())

With a single entrypoint

  Guest.enable_uefi()

to immediately change the guest config to use UEFI, using our
default logic.

This will make it easier to change that logic in the future, like
using <os firmware='efi'> instead of hardcoded paths

Signed-off-by: Cole Robinson <crobinso@redhat.com>
This commit is contained in:
Cole Robinson 2022-01-26 11:17:41 -05:00
parent 6c3b5def81
commit 245e89ac38
4 changed files with 51 additions and 42 deletions

View File

@ -104,7 +104,7 @@ class _GuestData:
self.machine = None
self.os_variant = None
self.uefi_path = None
self.uefi_requested = None
self.name = None
self.vcpus = None
@ -140,8 +140,8 @@ class _GuestData:
guest.os.machine = self.machine
if self.os_variant:
guest.set_os_name(self.os_variant)
if self.uefi_path:
guest.set_uefi_path(self.uefi_path)
if self.uefi_requested:
guest.uefi_requested = self.uefi_requested
if self.filesystem:
guest.add_device(self.filesystem)
@ -480,9 +480,9 @@ class vmmCreateVM(vmmGObjectUI):
if guest.prefers_uefi():
try:
self._gdata.uefi_path = guest.get_uefi_path()
# Call for validation
guest.set_uefi_path(self._gdata.uefi_path)
# We call this for validation
guest.enable_uefi()
self._gdata.uefi_requested = True
installable_arch = True
log.debug("UEFI found, setting it as default.")
except Exception as e:

View File

@ -2740,7 +2740,7 @@ class ParserBoot(VirtCLIParser):
# dep on determining arch/machine info
self.guest.uefi_requested = True
else:
self.guest.set_uefi_path(self.guest.get_uefi_path())
self.guest.enable_uefi()
def set_initargs_cb(self, inst, val, virtarg):
inst.set_initargs_string(val)

View File

@ -260,6 +260,8 @@ class DomainCapabilities(XMLBuilder):
"""
Return True if libvirt advertises support for proper UEFI setup
"""
if "efi" in self.os.get_enum("firmware").get_values():
return True
return ("readonly" in self.os.loader.enum_names() and
"yes" in self.os.loader.get_enum("readonly").get_values())

View File

@ -518,27 +518,6 @@ class Guest(XMLBuilder):
"""
return self.os.is_arm_machvirt() or self.conn.is_bhyve()
def get_uefi_path(self):
"""
If UEFI firmware path is found, return it, otherwise raise an error
"""
domcaps = self.lookup_domcaps()
if not domcaps.supports_uefi_xml():
raise RuntimeError(_("Libvirt version does not support UEFI."))
if not domcaps.arch_can_uefi():
raise RuntimeError(
_("Don't know how to setup UEFI for arch '%s'") %
self.os.arch)
path = domcaps.find_uefi_path_for_arch()
if not path: # pragma: no cover
raise RuntimeError(_("Did not find any UEFI binary path for "
"arch '%s'") % self.os.arch)
return path
def is_uefi(self):
if self.os.loader and self.os.loader_type == "pflash":
return True
@ -546,8 +525,8 @@ class Guest(XMLBuilder):
def set_uefi_path(self, path):
"""
Configure UEFI for the VM, but only if libvirt is advertising
a known UEFI binary path.
Set old style UEFI XML via loader path.
Set up smm if needed for secureboot
"""
self.os.loader_ro = True
self.os.loader_type = "pflash"
@ -570,6 +549,14 @@ class Guest(XMLBuilder):
self.os.machine)
self.os.machine = "q35"
def enable_uefi(self):
"""
Enable UEFI using our default logic
"""
path = self._lookup_default_uefi_path()
log.debug("Setting default UEFI path=%s", path)
self.set_uefi_path(path)
def has_spice(self):
for gfx in self.devices.graphics:
if gfx.type == gfx.TYPE_SPICE:
@ -754,6 +741,27 @@ class Guest(XMLBuilder):
default = capsinfo.machines and capsinfo.machines[0] or None
self.os.machine = default
def _lookup_default_uefi_path(self):
"""
If a default UEFI firmware path is found, return it,
otherwise raise an error
"""
domcaps = self.lookup_domcaps()
if not domcaps.supports_uefi_xml():
raise RuntimeError(_("Libvirt version does not support UEFI."))
if not domcaps.arch_can_uefi():
raise RuntimeError(
_("Don't know how to setup UEFI for arch '%s'") %
self.os.arch)
path = domcaps.find_uefi_path_for_arch()
if not path: # pragma: no cover
raise RuntimeError(_("Did not find any UEFI binary path for "
"arch '%s'") % self.os.arch)
return path
def _set_default_uefi(self):
use_default_uefi = (self.prefers_uefi() and
@ -763,18 +771,17 @@ class Guest(XMLBuilder):
self.os.nvram is None and
self.os.firmware is None)
if use_default_uefi or self.uefi_requested:
try:
path = self.get_uefi_path()
log.debug("Setting UEFI path=%s", path)
self.set_uefi_path(path)
except RuntimeError as e:
if self.uefi_requested:
raise
log.debug("Error setting UEFI default",
exc_info=True)
log.warning("Couldn't configure UEFI: %s", e)
log.warning("Your VM may not boot successfully.")
if not use_default_uefi and not self.uefi_requested:
return
try:
self.enable_uefi()
except RuntimeError as e:
if self.uefi_requested:
raise
log.debug("Error setting UEFI default", exc_info=True)
log.warning("Couldn't configure UEFI: %s", e)
log.warning("Your VM may not boot successfully.")
def _usb_disabled(self):
controllers = [c for c in self.devices.controller if