Add Plymouth configuration setup (#4555)
* feat: add plymouth config * refactor: move plymouth to bootleader menu
This commit is contained in:
parent
c6cb7b319d
commit
73d78b1aa9
|
|
@ -3,7 +3,7 @@ from typing import override
|
||||||
|
|
||||||
from archinstall.lib.menu.abstract_menu import AbstractSubMenu
|
from archinstall.lib.menu.abstract_menu import AbstractSubMenu
|
||||||
from archinstall.lib.menu.helpers import Confirmation, Selection
|
from archinstall.lib.menu.helpers import Confirmation, Selection
|
||||||
from archinstall.lib.models.bootloader import Bootloader, BootloaderConfiguration
|
from archinstall.lib.models.bootloader import Bootloader, BootloaderConfiguration, PlymouthTheme
|
||||||
from archinstall.lib.translationhandler import tr
|
from archinstall.lib.translationhandler import tr
|
||||||
from archinstall.tui.menu_item import MenuItem, MenuItemGroup
|
from archinstall.tui.menu_item import MenuItem, MenuItemGroup
|
||||||
from archinstall.tui.result import ResultType
|
from archinstall.tui.result import ResultType
|
||||||
|
|
@ -66,6 +66,13 @@ class BootloaderMenu(AbstractSubMenu[BootloaderConfiguration]):
|
||||||
key='removable',
|
key='removable',
|
||||||
enabled=removable_enabled,
|
enabled=removable_enabled,
|
||||||
),
|
),
|
||||||
|
MenuItem(
|
||||||
|
text=tr('Plymouth'),
|
||||||
|
action=self._select_plymouth,
|
||||||
|
value=self._bootloader_conf.plymouth,
|
||||||
|
preview_action=self._prev_plymouth,
|
||||||
|
key='plymouth',
|
||||||
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
def _prev_bootloader(self, item: MenuItem) -> str | None:
|
def _prev_bootloader(self, item: MenuItem) -> str | None:
|
||||||
|
|
@ -85,6 +92,11 @@ class BootloaderMenu(AbstractSubMenu[BootloaderConfiguration]):
|
||||||
return tr('Will install to /EFI/BOOT/ (removable location, safe default)')
|
return tr('Will install to /EFI/BOOT/ (removable location, safe default)')
|
||||||
return tr('Will install to custom location with NVRAM entry')
|
return tr('Will install to custom location with NVRAM entry')
|
||||||
|
|
||||||
|
def _prev_plymouth(self, item: MenuItem) -> str | None:
|
||||||
|
if item.value:
|
||||||
|
return f'{tr("Plymouth")}: {item.value.value}'
|
||||||
|
return None
|
||||||
|
|
||||||
@override
|
@override
|
||||||
async def show(self) -> BootloaderConfiguration:
|
async def show(self) -> BootloaderConfiguration:
|
||||||
_ = await super().show()
|
_ = await super().show()
|
||||||
|
|
@ -117,6 +129,9 @@ class BootloaderMenu(AbstractSubMenu[BootloaderConfiguration]):
|
||||||
|
|
||||||
return bootloader
|
return bootloader
|
||||||
|
|
||||||
|
async def _select_plymouth(self, preset: PlymouthTheme | None) -> PlymouthTheme | None:
|
||||||
|
return await select_plymouth_theme(preset)
|
||||||
|
|
||||||
async def _select_uki(self, preset: bool) -> bool:
|
async def _select_uki(self, preset: bool) -> bool:
|
||||||
prompt = tr('Would you like to use unified kernel images?') + '\n'
|
prompt = tr('Would you like to use unified kernel images?') + '\n'
|
||||||
|
|
||||||
|
|
@ -215,3 +230,24 @@ async def select_bootloader(
|
||||||
return result.get_value()
|
return result.get_value()
|
||||||
case ResultType.Reset:
|
case ResultType.Reset:
|
||||||
raise ValueError('Unhandled result type')
|
raise ValueError('Unhandled result type')
|
||||||
|
|
||||||
|
|
||||||
|
async def select_plymouth_theme(preset: PlymouthTheme | None = None) -> PlymouthTheme | None:
|
||||||
|
items = [MenuItem(t.value, value=t) for t in PlymouthTheme]
|
||||||
|
group = MenuItemGroup(items, sort_items=False)
|
||||||
|
group.set_selected_by_value(preset.value if preset else None)
|
||||||
|
|
||||||
|
result = await Selection[PlymouthTheme](
|
||||||
|
group,
|
||||||
|
header=tr('Select Plymouth theme'),
|
||||||
|
allow_reset=True,
|
||||||
|
allow_skip=True,
|
||||||
|
).show()
|
||||||
|
|
||||||
|
match result.type_:
|
||||||
|
case ResultType.Skip:
|
||||||
|
return preset
|
||||||
|
case ResultType.Reset:
|
||||||
|
return None
|
||||||
|
case ResultType.Selection:
|
||||||
|
return PlymouthTheme(result.get_value())
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ from archinstall.lib.locale.utils import verify_keyboard_layout, verify_x11_keyb
|
||||||
from archinstall.lib.log import debug, error, info, log, logger, warn
|
from archinstall.lib.log import debug, error, info, log, logger, warn
|
||||||
from archinstall.lib.mirror.mirror_handler import MirrorListHandler
|
from archinstall.lib.mirror.mirror_handler import MirrorListHandler
|
||||||
from archinstall.lib.models.application import ZramAlgorithm
|
from archinstall.lib.models.application import ZramAlgorithm
|
||||||
from archinstall.lib.models.bootloader import Bootloader, BootloaderConfiguration
|
from archinstall.lib.models.bootloader import Bootloader, BootloaderConfiguration, PlymouthTheme
|
||||||
from archinstall.lib.models.device import (
|
from archinstall.lib.models.device import (
|
||||||
DiskEncryption,
|
DiskEncryption,
|
||||||
DiskLayoutConfiguration,
|
DiskLayoutConfiguration,
|
||||||
|
|
@ -1755,6 +1755,28 @@ class Installer:
|
||||||
|
|
||||||
self._helper_flags['bootloader'] = 'refind'
|
self._helper_flags['bootloader'] = 'refind'
|
||||||
|
|
||||||
|
def _install_plymouth(self, plymouth: PlymouthTheme) -> None:
|
||||||
|
debug(f'Installing plymouth with theme: {plymouth.value}')
|
||||||
|
self.add_additional_packages(['plymouth'])
|
||||||
|
|
||||||
|
for param in ('quiet', 'splash'):
|
||||||
|
if param not in self._kernel_params:
|
||||||
|
self._kernel_params.append(param)
|
||||||
|
|
||||||
|
if 'plymouth' not in self._hooks:
|
||||||
|
for hook, insert_after in [('encrypt', False), ('sd-encrypt', False), ('systemd', True), ('filesystems', False), ('keyboard', True)]:
|
||||||
|
try:
|
||||||
|
idx = self._hooks.index(hook)
|
||||||
|
self._hooks.insert(idx + (1 if insert_after else 0), 'plymouth')
|
||||||
|
break
|
||||||
|
except ValueError:
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
self._hooks.append('plymouth')
|
||||||
|
|
||||||
|
self.arch_chroot(f'plymouth-set-default-theme {plymouth.value}')
|
||||||
|
self.mkinitcpio(['-P'])
|
||||||
|
|
||||||
def _config_uki(
|
def _config_uki(
|
||||||
self,
|
self,
|
||||||
root: PartitionModification | LvmVolume,
|
root: PartitionModification | LvmVolume,
|
||||||
|
|
@ -1807,10 +1829,7 @@ class Installer:
|
||||||
error('Error generating initramfs (continuing anyway)')
|
error('Error generating initramfs (continuing anyway)')
|
||||||
|
|
||||||
def add_bootloader(
|
def add_bootloader(
|
||||||
self,
|
self, bootloader: Bootloader, uki_enabled: bool = False, bootloader_removable: bool = False, plymouth: PlymouthTheme | None = None
|
||||||
bootloader: Bootloader,
|
|
||||||
uki_enabled: bool = False,
|
|
||||||
bootloader_removable: bool = False,
|
|
||||||
) -> None:
|
) -> None:
|
||||||
"""
|
"""
|
||||||
Adds a bootloader to the installation instance.
|
Adds a bootloader to the installation instance.
|
||||||
|
|
@ -1824,6 +1843,7 @@ class Installer:
|
||||||
:param bootloader: Type of bootloader to be added
|
:param bootloader: Type of bootloader to be added
|
||||||
:param uki_enabled: Whether to use unified kernel images
|
:param uki_enabled: Whether to use unified kernel images
|
||||||
:param bootloader_removable: Whether to install to removable media location (UEFI only, for GRUB and Limine)
|
:param bootloader_removable: Whether to install to removable media location (UEFI only, for GRUB and Limine)
|
||||||
|
:param plymouth: Optional Plymouth theme to install and configure
|
||||||
"""
|
"""
|
||||||
|
|
||||||
for plugin in plugins.values():
|
for plugin in plugins.values():
|
||||||
|
|
@ -1859,6 +1879,9 @@ class Installer:
|
||||||
warn(f'Bootloader {bootloader.value} lacks removable support; disabling.')
|
warn(f'Bootloader {bootloader.value} lacks removable support; disabling.')
|
||||||
bootloader_removable = False
|
bootloader_removable = False
|
||||||
|
|
||||||
|
if plymouth is not None:
|
||||||
|
self._install_plymouth(plymouth)
|
||||||
|
|
||||||
if uki_enabled:
|
if uki_enabled:
|
||||||
keep_initramfs = (
|
keep_initramfs = (
|
||||||
bootloader == Bootloader.Grub
|
bootloader == Bootloader.Grub
|
||||||
|
|
|
||||||
|
|
@ -60,15 +60,48 @@ class Bootloader(Enum):
|
||||||
return cls(bootloader)
|
return cls(bootloader)
|
||||||
|
|
||||||
|
|
||||||
|
class PlymouthTheme(Enum):
|
||||||
|
BGRT = 'bgrt'
|
||||||
|
FADE = 'fade-in'
|
||||||
|
GLOW = 'glow'
|
||||||
|
SCRIPT = 'script'
|
||||||
|
SOLAR = 'solar'
|
||||||
|
SPINNER = 'spinner'
|
||||||
|
SPINFINITY = 'spinfinity'
|
||||||
|
TRIBAR = 'tribar'
|
||||||
|
TEXT = 'text'
|
||||||
|
DETAILS = 'details'
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_arg(cls, plymouth: str | None) -> Self | None:
|
||||||
|
if plymouth is None:
|
||||||
|
return None
|
||||||
|
|
||||||
|
plymouth = plymouth.lower()
|
||||||
|
|
||||||
|
values = [e.value for e in cls]
|
||||||
|
|
||||||
|
if plymouth not in values:
|
||||||
|
warn(f'Invalid plymouth value "{plymouth}". Allowed values: {", ".join(values)}')
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
return cls(plymouth)
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class BootloaderConfiguration(SubConfig):
|
class BootloaderConfiguration(SubConfig):
|
||||||
bootloader: Bootloader
|
bootloader: Bootloader
|
||||||
uki: bool = False
|
uki: bool = False
|
||||||
removable: bool = True
|
removable: bool = True
|
||||||
|
plymouth: PlymouthTheme | None = None
|
||||||
|
|
||||||
@override
|
@override
|
||||||
def json(self) -> dict[str, Any]:
|
def json(self) -> dict[str, Any]:
|
||||||
return {'bootloader': self.bootloader.json(), 'uki': self.uki, 'removable': self.removable}
|
data = {'bootloader': self.bootloader.json(), 'uki': self.uki, 'removable': self.removable}
|
||||||
|
|
||||||
|
if self.plymouth is not None:
|
||||||
|
data['plymouth'] = self.plymouth.value
|
||||||
|
return data
|
||||||
|
|
||||||
@override
|
@override
|
||||||
def summary(self) -> list[str]:
|
def summary(self) -> list[str]:
|
||||||
|
|
@ -78,6 +111,8 @@ class BootloaderConfiguration(SubConfig):
|
||||||
out.append(tr('UKI enabled'))
|
out.append(tr('UKI enabled'))
|
||||||
if self.removable:
|
if self.removable:
|
||||||
out.append(tr('Removable'))
|
out.append(tr('Removable'))
|
||||||
|
if self.plymouth is not None:
|
||||||
|
out.append(tr('Plymouth "{}"').format(self.plymouth.value))
|
||||||
|
|
||||||
return out
|
return out
|
||||||
|
|
||||||
|
|
@ -86,14 +121,16 @@ class BootloaderConfiguration(SubConfig):
|
||||||
bootloader = Bootloader.from_arg(config.get('bootloader', ''), skip_boot)
|
bootloader = Bootloader.from_arg(config.get('bootloader', ''), skip_boot)
|
||||||
uki = config.get('uki', False)
|
uki = config.get('uki', False)
|
||||||
removable = config.get('removable', True)
|
removable = config.get('removable', True)
|
||||||
return cls(bootloader=bootloader, uki=uki, removable=removable)
|
plymouth = PlymouthTheme.from_arg(config.get('plymouth', None))
|
||||||
|
return cls(bootloader=bootloader, uki=uki, removable=removable, plymouth=plymouth)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_default(cls, uefi: bool, skip_boot: bool = False) -> Self:
|
def get_default(cls, uefi: bool, skip_boot: bool = False) -> Self:
|
||||||
bootloader = Bootloader.get_default(uefi, skip_boot)
|
bootloader = Bootloader.get_default(uefi, skip_boot)
|
||||||
removable = uefi and bootloader.has_removable_support()
|
removable = uefi and bootloader.has_removable_support()
|
||||||
uki = uefi and bootloader.has_uki_support()
|
uki = uefi and bootloader.has_uki_support()
|
||||||
return cls(bootloader=bootloader, uki=uki, removable=removable)
|
plymouth = None
|
||||||
|
return cls(bootloader=bootloader, uki=uki, removable=removable, plymouth=plymouth)
|
||||||
|
|
||||||
def preview(self, uefi: bool) -> str:
|
def preview(self, uefi: bool) -> str:
|
||||||
text = f'{tr("Bootloader")}: {self.bootloader.value}'
|
text = f'{tr("Bootloader")}: {self.bootloader.value}'
|
||||||
|
|
@ -112,4 +149,7 @@ class BootloaderConfiguration(SubConfig):
|
||||||
removable_string = tr('Disabled')
|
removable_string = tr('Disabled')
|
||||||
text += f'{tr("Removable")}: {removable_string}'
|
text += f'{tr("Removable")}: {removable_string}'
|
||||||
text += '\n'
|
text += '\n'
|
||||||
|
if self.plymouth is not None:
|
||||||
|
text += f'{tr("Plymouth")}: {self.plymouth.value}'
|
||||||
|
text += '\n'
|
||||||
return text
|
return text
|
||||||
|
|
|
||||||
|
|
@ -119,6 +119,7 @@ def perform_installation(
|
||||||
config.bootloader_config.bootloader,
|
config.bootloader_config.bootloader,
|
||||||
config.bootloader_config.uki,
|
config.bootloader_config.uki,
|
||||||
config.bootloader_config.removable,
|
config.bootloader_config.removable,
|
||||||
|
config.bootloader_config.plymouth,
|
||||||
)
|
)
|
||||||
|
|
||||||
if config.network_config:
|
if config.network_config:
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue