details: Add os.firmware=efi in the firmware selector UI

Let users choose libvirt's os.firmware=efi setting in the UI, putting
it about the firmware path list, since it's the preferred default
these days.

Signed-off-by: Cole Robinson <crobinso@redhat.com>
This commit is contained in:
Cole Robinson 2022-01-26 13:08:55 -05:00
parent 3013889727
commit 5003f0432e
5 changed files with 48 additions and 33 deletions

View File

@ -114,7 +114,7 @@ def testDomainCapabilitiesAArch64():
xml = open(DATADIR + "/kvm-aarch64-domcaps.xml").read()
caps = DomainCapabilities(utils.URIs.open_testdriver_cached(), xml)
assert "None" in caps.label_for_firmware_path(None)
assert "Default" in caps.label_for_firmware_path(None)
assert not caps.supports_filesystem_virtiofs()
assert not caps.supports_memorybacking_memfd()

View File

@ -536,8 +536,10 @@ def testNewKVMQ35UEFI(app):
# Change to UEFI
details.combo_check_default("Chipset:", "Q35")
details.combo_check_default("Firmware:", "BIOS")
details.combo_select("Firmware:", ".*x86_64.*")
details.combo_select("Firmware:", "UEFI")
details.find("config-apply").click()
new_xml = lib.utils.get_xmleditor_xml(app, details)
assert "os firmware=\"efi\"" in new_xml
# Finish
details.find_fuzzy("Begin Installation", "button").click()

View File

@ -647,10 +647,11 @@ class vmmDetails(vmmGObjectUI):
self.widget("machine-type-label").set_visible(
not self.is_customize_dialog)
# Firmware
combo = self.widget("overview-firmware")
# [label, path, is_sensitive]
model = Gtk.ListStore(str, str, bool)
# [label, loader path, is_sensitive, ./os/@firmware value]
model = Gtk.ListStore(str, str, bool, str)
combo.set_model(model)
text = Gtk.CellRendererText()
combo.pack_start(text, True)
@ -660,37 +661,41 @@ class vmmDetails(vmmGObjectUI):
domcaps = self.vm.get_domain_capabilities()
uefipaths = [v.value for v in domcaps.os.loader.values]
warn_icon = self.widget("overview-firmware-warn")
hv_supports_uefi = domcaps.supports_uefi_loader()
uefirows = []
if domcaps.supports_firmware_efi():
uefirows.append([_("UEFI"), None, True, "efi"])
for path in uefipaths:
uefirows.append(
[domcaps.label_for_firmware_path(path), path, True, None])
hv_supports_uefi = (domcaps.supports_uefi_loader() or
domcaps.supports_firmware_efi())
firmware_warn = None
if not hv_supports_uefi:
warn_icon.set_tooltip_text(
_("Libvirt or hypervisor does not support UEFI."))
elif not uefipaths:
warn_icon.set_tooltip_text( # pragma: no cover
firmware_warn = _("Libvirt or hypervisor does not support UEFI.")
elif not uefirows:
firmware_warn = ( # pragma: no cover
_("Libvirt did not detect any UEFI/OVMF firmware image "
"installed on the host."))
model.append([domcaps.label_for_firmware_path(None), None, True])
if not uefipaths:
model.append([_("UEFI not found"), None, False])
else:
for path in uefipaths:
model.append([domcaps.label_for_firmware_path(path),
path, True])
# Put the default entry first in the list
model.append([domcaps.label_for_firmware_path(None), None, True, None])
for row in uefirows:
model.append(row)
combo.set_active(0)
self.widget("overview-firmware-warn").set_visible(
not (uefipaths and hv_supports_uefi) and self.is_customize_dialog)
self.is_customize_dialog and firmware_warn)
self.widget("overview-firmware-warn").set_tooltip_text(firmware_warn)
self.widget("overview-firmware").set_visible(self.is_customize_dialog)
self.widget("overview-firmware-label").set_visible(
not self.is_customize_dialog)
show_firmware = ((self.conn.is_qemu() or
self.conn.is_test() or
self.conn.is_xen()) and
domcaps.arch_can_uefi())
uiutil.set_grid_row_visible(
self.widget("overview-firmware-title"), show_firmware)
self.widget("overview-firmware-title"),
self.vm.xmlobj.os.is_hvm() and
(domcaps.supports_firmware_efi() or
domcaps.arch_can_uefi()))
# Chipset
combo = self.widget("overview-chipset")
@ -1394,6 +1399,8 @@ class vmmDetails(vmmGObjectUI):
if self._edited(EDIT_FIRMWARE):
kwargs["loader"] = uiutil.get_list_selection(
self.widget("overview-firmware"), column=1)
kwargs["firmware"] = uiutil.get_list_selection(
self.widget("overview-firmware"), column=3)
if self._edited(EDIT_MACHTYPE):
if self.widget("overview-chipset").is_visible():
@ -1773,7 +1780,7 @@ class vmmDetails(vmmGObjectUI):
# Firmware
domcaps = self.vm.get_domain_capabilities()
if self.vm.get_xmlobj().os.firmware == "efi":
firmware = 'UEFI'
firmware = _("UEFI")
else:
firmware = domcaps.label_for_firmware_path(
self.vm.get_xmlobj().os.loader)

View File

@ -702,7 +702,7 @@ class vmmDomain(vmmLibvirtObject):
def define_overview(self, machine=_SENTINEL, description=_SENTINEL,
title=_SENTINEL, loader=_SENTINEL,
nvram=_SENTINEL):
nvram=_SENTINEL, firmware=_SENTINEL):
guest = self._make_xmlobj_to_define()
if machine != _SENTINEL:
guest.os.machine = machine
@ -712,14 +712,20 @@ class vmmDomain(vmmLibvirtObject):
if title != _SENTINEL:
guest.title = title or None
if loader != _SENTINEL:
if loader != _SENTINEL and firmware != _SENTINEL:
guest.os.firmware = firmware
if loader is None:
# Implies seabios, aka the default, so clear everything
guest.os.loader = None
guest.os.loader_ro = None
guest.os.loader_type = None
guest.os.nvram = None
guest.os.nvram_template = None
# But if switching to firmware=efi we may need to
# preserve NVRAM paths, so skip clearing all the properties
# and let libvirt do it for us.
if firmware is None:
# Implies 'default', so clear everything
guest.os.loader_ro = None
guest.os.loader_type = None
guest.os.nvram = None
guest.os.nvram_template = None
else:
# Implies UEFI
guest.set_uefi_path(loader)

View File

@ -240,7 +240,7 @@ class DomainCapabilities(XMLBuilder):
if not path:
if self.arch in ["i686", "x86_64"]:
return _("BIOS")
return _("None")
return _("Default")
for arch, patterns in self._uefi_arch_patterns.items():
for pattern in patterns: