Refactor SysInfo.has_uefi() to DI for bootloader (#4230)

This commit is contained in:
codefiles 2026-02-14 20:34:40 -05:00 committed by GitHub
parent ec9ee80062
commit 9bd2131792
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 29 additions and 33 deletions

View File

@ -6,7 +6,6 @@ from archinstall.lib.translationhandler import tr
from archinstall.tui.ui.menu_item import MenuItem, MenuItemGroup from archinstall.tui.ui.menu_item import MenuItem, MenuItemGroup
from archinstall.tui.ui.result import ResultType from archinstall.tui.ui.result import ResultType
from ..hardware import SysInfo
from ..menu.abstract_menu import AbstractSubMenu from ..menu.abstract_menu import AbstractSubMenu
from ..models.bootloader import Bootloader, BootloaderConfiguration from ..models.bootloader import Bootloader, BootloaderConfiguration
@ -15,10 +14,12 @@ class BootloaderMenu(AbstractSubMenu[BootloaderConfiguration]):
def __init__( def __init__(
self, self,
bootloader_conf: BootloaderConfiguration, bootloader_conf: BootloaderConfiguration,
uefi: bool,
skip_boot: bool = False, skip_boot: bool = False,
): ):
self._bootloader_conf = bootloader_conf self._bootloader_conf = bootloader_conf
self._skip_boot = skip_boot self._skip_boot = skip_boot
self._uefi = uefi
menu_options = self._define_menu_options() menu_options = self._define_menu_options()
self._item_group = MenuItemGroup(menu_options, sort_items=False, checkmarks=True) self._item_group = MenuItemGroup(menu_options, sort_items=False, checkmarks=True)
@ -30,15 +31,14 @@ class BootloaderMenu(AbstractSubMenu[BootloaderConfiguration]):
def _define_menu_options(self) -> list[MenuItem]: def _define_menu_options(self) -> list[MenuItem]:
bootloader = self._bootloader_conf.bootloader bootloader = self._bootloader_conf.bootloader
has_uefi = SysInfo.has_uefi()
# UKI availability # UKI availability
uki_enabled = has_uefi and bootloader.has_uki_support() uki_enabled = self._uefi and bootloader.has_uki_support()
if not uki_enabled: if not uki_enabled:
self._bootloader_conf.uki = False self._bootloader_conf.uki = False
# Removable availability # Removable availability
removable_enabled = has_uefi and bootloader.has_removable_support() removable_enabled = self._uefi and bootloader.has_removable_support()
if not removable_enabled: if not removable_enabled:
self._bootloader_conf.removable = False self._bootloader_conf.removable = False
@ -92,12 +92,12 @@ class BootloaderMenu(AbstractSubMenu[BootloaderConfiguration]):
return self._bootloader_conf return self._bootloader_conf
def _select_bootloader(self, preset: Bootloader | None) -> Bootloader | None: def _select_bootloader(self, preset: Bootloader | None) -> Bootloader | None:
bootloader = select_bootloader(preset, self._skip_boot) bootloader = select_bootloader(preset, self._uefi, self._skip_boot)
if bootloader: if bootloader:
# Update UKI option based on bootloader # Update UKI option based on bootloader
uki_item = self._menu_item_group.find_by_key('uki') uki_item = self._menu_item_group.find_by_key('uki')
if not SysInfo.has_uefi() or not bootloader.has_uki_support(): if not self._uefi or not bootloader.has_uki_support():
uki_item.enabled = False uki_item.enabled = False
uki_item.value = False uki_item.value = False
self._bootloader_conf.uki = False self._bootloader_conf.uki = False
@ -106,7 +106,7 @@ class BootloaderMenu(AbstractSubMenu[BootloaderConfiguration]):
# Update removable option based on bootloader # Update removable option based on bootloader
removable_item = self._menu_item_group.find_by_key('removable') removable_item = self._menu_item_group.find_by_key('removable')
if not SysInfo.has_uefi() or not bootloader.has_removable_support(): if not self._uefi or not bootloader.has_removable_support():
removable_item.enabled = False removable_item.enabled = False
removable_item.value = False removable_item.value = False
self._bootloader_conf.removable = False self._bootloader_conf.removable = False
@ -180,27 +180,23 @@ class BootloaderMenu(AbstractSubMenu[BootloaderConfiguration]):
def select_bootloader( def select_bootloader(
preset: Bootloader | None, preset: Bootloader | None,
uefi: bool,
skip_boot: bool = False, skip_boot: bool = False,
) -> Bootloader | None: ) -> Bootloader | None:
options = [] options = []
hidden_options = [] hidden_options = []
default = None
header = tr('Select bootloader to install') header = tr('Select bootloader to install')
if skip_boot: default = Bootloader.get_default(uefi, skip_boot)
default = Bootloader.NO_BOOTLOADER
else: if not skip_boot:
hidden_options += [Bootloader.NO_BOOTLOADER] hidden_options += [Bootloader.NO_BOOTLOADER]
if not SysInfo.has_uefi(): if not uefi:
options += [Bootloader.Grub, Bootloader.Limine] options += [Bootloader.Grub, Bootloader.Limine]
if not default:
default = Bootloader.Grub
header += '\n' + tr('UEFI is not detected and some options are disabled') header += '\n' + tr('UEFI is not detected and some options are disabled')
else: else:
options += [b for b in Bootloader if b not in hidden_options] options += [b for b in Bootloader if b not in hidden_options]
if not default:
default = Bootloader.Systemd
items = [MenuItem(o.value, value=o) for o in options] items = [MenuItem(o.value, value=o) for o in options]
group = MenuItemGroup(items) group = MenuItemGroup(items)

View File

@ -47,6 +47,7 @@ class GlobalMenu(AbstractMenu[None]):
self._arch_config = arch_config self._arch_config = arch_config
self._mirror_list_handler = mirror_list_handler self._mirror_list_handler = mirror_list_handler
self._skip_boot = skip_boot self._skip_boot = skip_boot
self._uefi = SysInfo.has_uefi()
menu_options = self._get_menu_options() menu_options = self._get_menu_options()
self._item_group = MenuItemGroup( self._item_group = MenuItemGroup(
@ -94,7 +95,7 @@ class GlobalMenu(AbstractMenu[None]):
), ),
MenuItem( MenuItem(
text=tr('Bootloader'), text=tr('Bootloader'),
value=BootloaderConfiguration.get_default(self._skip_boot), value=BootloaderConfiguration.get_default(self._uefi, self._skip_boot),
action=self._select_bootloader_config, action=self._select_bootloader_config,
preview_action=self._prev_bootloader_config, preview_action=self._prev_bootloader_config,
key='bootloader_config', key='bootloader_config',
@ -422,7 +423,7 @@ class GlobalMenu(AbstractMenu[None]):
def _prev_bootloader_config(self, item: MenuItem) -> str | None: def _prev_bootloader_config(self, item: MenuItem) -> str | None:
bootloader_config: BootloaderConfiguration | None = item.value bootloader_config: BootloaderConfiguration | None = item.value
if bootloader_config: if bootloader_config:
return bootloader_config.preview() return bootloader_config.preview(self._uefi)
return None return None
def _validate_bootloader(self) -> str | None: def _validate_bootloader(self) -> str | None:
@ -455,7 +456,7 @@ class GlobalMenu(AbstractMenu[None]):
for layout in disk_config.device_modifications: for layout in disk_config.device_modifications:
if boot_partition := layout.get_boot_partition(): if boot_partition := layout.get_boot_partition():
break break
if SysInfo.has_uefi(): if self._uefi:
for layout in disk_config.device_modifications: for layout in disk_config.device_modifications:
if efi_partition := layout.get_efi_partition(): if efi_partition := layout.get_efi_partition():
break break
@ -468,7 +469,7 @@ class GlobalMenu(AbstractMenu[None]):
if boot_partition is None: if boot_partition is None:
return 'Boot partition not found' return 'Boot partition not found'
if SysInfo.has_uefi(): if self._uefi:
if efi_partition is None: if efi_partition is None:
return 'EFI system partition (ESP) not found' return 'EFI system partition (ESP) not found'
@ -480,7 +481,7 @@ class GlobalMenu(AbstractMenu[None]):
return 'Limine does not support booting with a non-FAT boot partition' return 'Limine does not support booting with a non-FAT boot partition'
elif bootloader == Bootloader.Refind: elif bootloader == Bootloader.Refind:
if not SysInfo.has_uefi(): if not self._uefi:
return 'rEFInd can only be used on UEFI systems' return 'rEFInd can only be used on UEFI systems'
return None return None
@ -530,9 +531,9 @@ class GlobalMenu(AbstractMenu[None]):
preset: BootloaderConfiguration | None = None, preset: BootloaderConfiguration | None = None,
) -> BootloaderConfiguration | None: ) -> BootloaderConfiguration | None:
if preset is None: if preset is None:
preset = BootloaderConfiguration.get_default(self._skip_boot) preset = BootloaderConfiguration.get_default(self._uefi, self._skip_boot)
bootloader_config = BootloaderMenu(preset, self._skip_boot).run() bootloader_config = BootloaderMenu(preset, self._uefi, self._skip_boot).run()
return bootloader_config return bootloader_config

View File

@ -5,7 +5,6 @@ from typing import Any, Self
from archinstall.lib.translationhandler import tr from archinstall.lib.translationhandler import tr
from ..hardware import SysInfo
from ..output import warn from ..output import warn
@ -31,10 +30,10 @@ class Bootloader(Enum):
return self.value return self.value
@classmethod @classmethod
def get_default(cls, skip_boot: bool = False) -> Self: def get_default(cls, uefi: bool, skip_boot: bool = False) -> Self:
if skip_boot: if skip_boot:
return cls.NO_BOOTLOADER return cls.NO_BOOTLOADER
elif SysInfo.has_uefi(): elif uefi:
return cls.Systemd return cls.Systemd
else: else:
return cls.Grub return cls.Grub
@ -71,23 +70,23 @@ class BootloaderConfiguration:
return cls(bootloader=bootloader, uki=uki, removable=removable) return cls(bootloader=bootloader, uki=uki, removable=removable)
@classmethod @classmethod
def get_default(cls, skip_boot: bool = False) -> Self: def get_default(cls, uefi: bool, skip_boot: bool = False) -> Self:
bootloader = Bootloader.get_default(skip_boot) bootloader = Bootloader.get_default(uefi, skip_boot)
removable = SysInfo.has_uefi() and bootloader.has_removable_support() removable = uefi and bootloader.has_removable_support()
uki = SysInfo.has_uefi() and bootloader.has_uki_support() uki = uefi and bootloader.has_uki_support()
return cls(bootloader=bootloader, uki=uki, removable=removable) return cls(bootloader=bootloader, uki=uki, removable=removable)
def preview(self) -> str: def preview(self, uefi: bool) -> str:
text = f'{tr("Bootloader")}: {self.bootloader.value}' text = f'{tr("Bootloader")}: {self.bootloader.value}'
text += '\n' text += '\n'
if SysInfo.has_uefi() and self.bootloader.has_uki_support(): if uefi and self.bootloader.has_uki_support():
if self.uki: if self.uki:
uki_string = tr('Enabled') uki_string = tr('Enabled')
else: else:
uki_string = tr('Disabled') uki_string = tr('Disabled')
text += f'UKI: {uki_string}' text += f'UKI: {uki_string}'
text += '\n' text += '\n'
if SysInfo.has_uefi() and self.bootloader.has_removable_support(): if uefi and self.bootloader.has_removable_support():
if self.removable: if self.removable:
removable_string = tr('Enabled') removable_string = tr('Enabled')
else: else: