Skip to content
Open
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
38 changes: 37 additions & 1 deletion archinstall/lib/bootloader/bootloader_menu.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

from archinstall.lib.menu.abstract_menu import AbstractSubMenu
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.tui.menu_item import MenuItem, MenuItemGroup
from archinstall.tui.result import ResultType
Expand Down Expand Up @@ -66,6 +66,13 @@ def _define_menu_options(self) -> list[MenuItem]:
key='removable',
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:
Expand All @@ -85,6 +92,11 @@ def _prev_removable(self, item: MenuItem) -> str | None:
return tr('Will install to /EFI/BOOT/ (removable location, safe default)')
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
async def show(self) -> BootloaderConfiguration:
_ = await super().show()
Expand Down Expand Up @@ -117,6 +129,9 @@ async def _select_bootloader(self, preset: Bootloader | None) -> Bootloader | No

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:
prompt = tr('Would you like to use unified kernel images?') + '\n'

Expand Down Expand Up @@ -215,3 +230,24 @@ async def select_bootloader(
return result.get_value()
case ResultType.Reset:
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())
33 changes: 28 additions & 5 deletions archinstall/lib/installer.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
from archinstall.lib.log import debug, error, info, log, logger, warn
from archinstall.lib.mirror.mirror_handler import MirrorListHandler
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 (
DiskEncryption,
DiskLayoutConfiguration,
Expand Down Expand Up @@ -1755,6 +1755,28 @@ def _add_refind_bootloader(

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(
self,
root: PartitionModification | LvmVolume,
Expand Down Expand Up @@ -1807,10 +1829,7 @@ def _config_uki(
error('Error generating initramfs (continuing anyway)')

def add_bootloader(
self,
bootloader: Bootloader,
uki_enabled: bool = False,
bootloader_removable: bool = False,
self, bootloader: Bootloader, uki_enabled: bool = False, bootloader_removable: bool = False, plymouth: PlymouthTheme | None = None
) -> None:
"""
Adds a bootloader to the installation instance.
Expand All @@ -1824,6 +1843,7 @@ def add_bootloader(
:param bootloader: Type of bootloader to be added
: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 plymouth: Optional Plymouth theme to install and configure
"""

for plugin in plugins.values():
Expand Down Expand Up @@ -1859,6 +1879,9 @@ def add_bootloader(
warn(f'Bootloader {bootloader.value} lacks removable support; disabling.')
bootloader_removable = False

if plymouth is not None:
self._install_plymouth(plymouth)

if uki_enabled:
keep_initramfs = (
bootloader == Bootloader.Grub
Expand Down
46 changes: 43 additions & 3 deletions archinstall/lib/models/bootloader.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,15 +60,48 @@ def from_arg(cls, bootloader: str, skip_boot: bool) -> Self:
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
class BootloaderConfiguration(SubConfig):
bootloader: Bootloader
uki: bool = False
removable: bool = True
plymouth: PlymouthTheme | None = None

@override
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
def summary(self) -> list[str]:
Expand All @@ -78,6 +111,8 @@ def summary(self) -> list[str]:
out.append(tr('UKI enabled'))
if self.removable:
out.append(tr('Removable'))
if self.plymouth is not None:
out.append(tr('Plymouth "{}"').format(self.plymouth.value))

return out

Expand All @@ -86,14 +121,16 @@ 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)
plymouth = PlymouthTheme.from_arg(config.get('plymouth', None))
return cls(bootloader=bootloader, uki=uki, removable=removable, plymouth=plymouth)

@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)
plymouth = None
return cls(bootloader=bootloader, uki=uki, removable=removable, plymouth=plymouth)

def preview(self, uefi: bool) -> str:
text = f'{tr("Bootloader")}: {self.bootloader.value}'
Expand All @@ -112,4 +149,7 @@ def preview(self, uefi: bool) -> str:
removable_string = tr('Disabled')
text += f'{tr("Removable")}: {removable_string}'
text += '\n'
if self.plymouth is not None:
text += f'{tr("Plymouth")}: {self.plymouth.value}'
text += '\n'
return text
1 change: 1 addition & 0 deletions archinstall/scripts/guided.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ def perform_installation(
config.bootloader_config.bootloader,
config.bootloader_config.uki,
config.bootloader_config.removable,
config.bootloader_config.plymouth,
)

if config.network_config:
Expand Down
Loading