116 lines
3.0 KiB
Python
116 lines
3.0 KiB
Python
import sys
|
|
from dataclasses import dataclass
|
|
from enum import Enum
|
|
from typing import Any, Self, override
|
|
|
|
from archinstall.lib.log import warn
|
|
from archinstall.lib.models.config import SubConfig
|
|
from archinstall.lib.translationhandler import tr
|
|
|
|
|
|
class Bootloader(Enum):
|
|
NO_BOOTLOADER = 'No bootloader'
|
|
Systemd = 'Systemd-boot'
|
|
Grub = 'Grub'
|
|
Efistub = 'Efistub'
|
|
Limine = 'Limine'
|
|
Refind = 'Refind'
|
|
|
|
def has_uki_support(self) -> bool:
|
|
return self != Bootloader.NO_BOOTLOADER
|
|
|
|
def has_removable_support(self) -> bool:
|
|
match self:
|
|
case Bootloader.Grub | Bootloader.Limine:
|
|
return True
|
|
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
|
|
|
|
@classmethod
|
|
def get_default(cls, uefi: bool, skip_boot: bool = False) -> Self:
|
|
if skip_boot:
|
|
return cls.NO_BOOTLOADER
|
|
elif uefi:
|
|
return cls.Systemd
|
|
else:
|
|
return cls.Grub
|
|
|
|
@classmethod
|
|
def from_arg(cls, bootloader: str, skip_boot: bool) -> Self:
|
|
# to support old configuration files
|
|
bootloader = bootloader.capitalize()
|
|
|
|
bootloader_options = [e.value for e in cls if e != cls.NO_BOOTLOADER or skip_boot is True]
|
|
|
|
if bootloader not in bootloader_options:
|
|
values = ', '.join(bootloader_options)
|
|
warn(f'Invalid bootloader value "{bootloader}". Allowed values: {values}')
|
|
sys.exit(1)
|
|
|
|
return cls(bootloader)
|
|
|
|
|
|
@dataclass
|
|
class BootloaderConfiguration(SubConfig):
|
|
bootloader: Bootloader
|
|
uki: bool = False
|
|
removable: bool = True
|
|
|
|
@override
|
|
def json(self) -> dict[str, Any]:
|
|
return {'bootloader': self.bootloader.json(), 'uki': self.uki, 'removable': self.removable}
|
|
|
|
@override
|
|
def summary(self) -> list[str]:
|
|
out = [tr('Bootloader "{}"').format(self.bootloader.value)]
|
|
|
|
if self.uki:
|
|
out.append(tr('UKI enabled'))
|
|
if self.removable:
|
|
out.append(tr('Removable'))
|
|
|
|
return out
|
|
|
|
@classmethod
|
|
def parse_arg(cls, config: dict[str, Any], skip_boot: bool) -> Self:
|
|
bootloader = Bootloader.from_arg(config.get('bootloader', ''), skip_boot)
|
|
uki = config.get('uki', False)
|
|
removable = config.get('removable', True)
|
|
return cls(bootloader=bootloader, uki=uki, removable=removable)
|
|
|
|
@classmethod
|
|
def get_default(cls, uefi: bool, skip_boot: bool = False) -> Self:
|
|
bootloader = Bootloader.get_default(uefi, skip_boot)
|
|
removable = uefi and bootloader.has_removable_support()
|
|
uki = uefi and bootloader.has_uki_support()
|
|
return cls(bootloader=bootloader, uki=uki, removable=removable)
|
|
|
|
def preview(self, uefi: bool) -> str:
|
|
text = f'{tr("Bootloader")}: {self.bootloader.value}'
|
|
text += '\n'
|
|
if uefi and self.bootloader.has_uki_support():
|
|
if self.uki:
|
|
uki_string = tr('Enabled')
|
|
else:
|
|
uki_string = tr('Disabled')
|
|
text += f'UKI: {uki_string}'
|
|
text += '\n'
|
|
if uefi and self.bootloader.has_removable_support():
|
|
if self.removable:
|
|
removable_string = tr('Enabled')
|
|
else:
|
|
removable_string = tr('Disabled')
|
|
text += f'{tr("Removable")}: {removable_string}'
|
|
text += '\n'
|
|
return text
|