Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 27 additions & 4 deletions archinstall/lib/bootloader/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,16 @@
from enum import Enum, auto
from pathlib import Path

from archinstall.lib.hardware import SysInfo
from archinstall.lib.models.bootloader import Bootloader, BootloaderConfiguration
from archinstall.lib.models.device import DiskLayoutConfiguration


class BootloaderValidationFailureKind(Enum):
LimineNonFatBoot = auto()
LimineLayout = auto()
BootloaderRequiresUefi = auto()
EfistubNonFatBoot = auto()


@dataclass(frozen=True)
Expand All @@ -29,12 +32,32 @@ def validate_bootloader_layout(
if not (bootloader_config and disk_config):
return None

if bootloader_config.bootloader == Bootloader.Limine:
boot_part = next(
(p for m in disk_config.device_modifications if (p := m.get_boot_partition())),
None,
bootloader = bootloader_config.bootloader

if bootloader == Bootloader.NO_BOOTLOADER:
return None

if bootloader.is_uefi_only() and not SysInfo.has_uefi():
return BootloaderValidationFailure(
kind=BootloaderValidationFailureKind.BootloaderRequiresUefi,
description=f'{bootloader.value} requires a UEFI system.',
)

boot_part = next(
(p for m in disk_config.device_modifications if (p := m.get_boot_partition())),
None,
)

if bootloader == Bootloader.Efistub:
# The UEFI firmware reads the kernel directly from the boot partition,
# which must be FAT.
if boot_part and (boot_part.fs_type is None or not boot_part.fs_type.is_fat()):
return BootloaderValidationFailure(
kind=BootloaderValidationFailureKind.EfistubNonFatBoot,
description='Efistub does not support booting with a non-FAT boot partition.',
)

if bootloader == Bootloader.Limine:
# Limine reads its config and kernels from the boot partition, which
# must be FAT.
if boot_part and (boot_part.fs_type is None or not boot_part.fs_type.is_fat()):
Expand Down
5 changes: 0 additions & 5 deletions archinstall/lib/global_menu.py
Original file line number Diff line number Diff line change
Expand Up @@ -461,8 +461,6 @@ def _validate_bootloader(self) -> str | None:
if not bootloader_config or bootloader_config.bootloader == Bootloader.NO_BOOTLOADER:
return None

bootloader = bootloader_config.bootloader

if disk_config := self._item_group.find_by_key('disk_config').value:
for layout in disk_config.device_modifications:
if root_partition := layout.get_root_partition():
Expand Down Expand Up @@ -490,9 +488,6 @@ def _validate_bootloader(self) -> str | None:
if efi_partition.fs_type is None or not efi_partition.fs_type.is_fat():
return 'ESP must be formatted as a FAT filesystem'

if bootloader == Bootloader.Refind and not self._uefi:
return 'rEFInd can only be used on UEFI systems'

if failure := validate_bootloader_layout(bootloader_config, disk_config):
return failure.description

Expand Down
7 changes: 7 additions & 0 deletions archinstall/lib/models/bootloader.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,13 @@ def has_removable_support(self) -> bool:
case _:
return False

def is_uefi_only(self) -> bool:
match self:
case Bootloader.Systemd | Bootloader.Efistub | Bootloader.Refind:
return True
case _:
return False

def json(self) -> str:
return self.value

Expand Down