feat: add plymouth config
This commit is contained in:
parent
d92a98d3bf
commit
1f66848b22
|
|
@ -16,6 +16,7 @@ from pydantic.dataclasses import dataclass as p_dataclass
|
|||
from archinstall.lib.crypt import decrypt
|
||||
from archinstall.lib.log import debug, error, logger, warn
|
||||
from archinstall.lib.menu.util import get_password
|
||||
from archinstall.lib.models import PlymouthConfiguration
|
||||
from archinstall.lib.models.application import ApplicationConfiguration, ZramConfiguration
|
||||
from archinstall.lib.models.authentication import AuthenticationConfiguration
|
||||
from archinstall.lib.models.bootloader import Bootloader, BootloaderConfiguration
|
||||
|
|
@ -88,6 +89,7 @@ class ArchConfigType(StrEnum):
|
|||
SERVICES = 'services'
|
||||
PACKAGES = 'packages'
|
||||
PACMAN_CONFIG = 'pacman_config'
|
||||
PLYMOUTH_CONFIG = 'plymouth_config'
|
||||
CUSTOM_COMMANDS = 'custom_commands'
|
||||
|
||||
def text(self) -> str:
|
||||
|
|
@ -130,6 +132,8 @@ class ArchConfigType(StrEnum):
|
|||
return tr('Additional packages')
|
||||
case ArchConfigType.PACMAN_CONFIG:
|
||||
return tr('Pacman')
|
||||
case ArchConfigType.PLYMOUTH_CONFIG:
|
||||
return tr('Plymouth')
|
||||
case ArchConfigType.CUSTOM_COMMANDS:
|
||||
return tr('Custom commands')
|
||||
case ArchConfigType.USERS:
|
||||
|
|
@ -159,6 +163,7 @@ class ArchConfig:
|
|||
ntp: bool = True
|
||||
packages: list[str] = field(default_factory=list)
|
||||
pacman_config: PacmanConfiguration = field(default_factory=PacmanConfiguration.default)
|
||||
plymouth_config: PlymouthConfiguration | None = None
|
||||
timezone: str = 'UTC'
|
||||
services: list[str] = field(default_factory=list)
|
||||
custom_commands: list[str] = field(default_factory=list)
|
||||
|
|
@ -240,6 +245,9 @@ class ArchConfig:
|
|||
if self.app_config:
|
||||
cfg[ArchConfigType.APP_CONFIG] = self.app_config
|
||||
|
||||
if self.plymouth_config:
|
||||
cfg[ArchConfigType.PLYMOUTH_CONFIG] = self.plymouth_config
|
||||
|
||||
return cfg
|
||||
|
||||
@classmethod
|
||||
|
|
@ -336,6 +344,9 @@ class ArchConfig:
|
|||
if services := args_config.get('services', []):
|
||||
arch_config.services = services
|
||||
|
||||
if plymouth_config := args_config.get('plymouth_config', None):
|
||||
arch_config.plymouth_config = PlymouthConfiguration.parse_arg(plymouth_config)
|
||||
|
||||
# DEPRECATED: backwards compatibility
|
||||
root_password = None
|
||||
if root_password := args_config.get('!root-password', None):
|
||||
|
|
|
|||
|
|
@ -25,11 +25,13 @@ from archinstall.lib.models.network import NetworkConfiguration, NicType
|
|||
from archinstall.lib.models.package_types import DEFAULT_KERNEL
|
||||
from archinstall.lib.models.packages import Repository
|
||||
from archinstall.lib.models.pacman import PacmanConfiguration
|
||||
from archinstall.lib.models.plymouth import PlymouthConfiguration
|
||||
from archinstall.lib.models.profile import ProfileConfiguration
|
||||
from archinstall.lib.network.network_menu import select_network
|
||||
from archinstall.lib.packages.packages import list_available_packages, select_additional_packages
|
||||
from archinstall.lib.pacman.config import PacmanConfig
|
||||
from archinstall.lib.pacman.pacman_menu import PacmanMenu
|
||||
from archinstall.lib.plymouth.plymouth_menu import select_plymouth_theme
|
||||
from archinstall.lib.translationhandler import Language, tr, translation_handler
|
||||
from archinstall.lib.utils.format import as_table
|
||||
from archinstall.tui.components import tui
|
||||
|
|
@ -150,6 +152,13 @@ class GlobalMenu(AbstractMenu[None]):
|
|||
preview_action=self._prev_pacman_config,
|
||||
key='pacman_config',
|
||||
),
|
||||
MenuItem(
|
||||
text=tr('Plymouth'),
|
||||
action=self._plymouth_configuration,
|
||||
value=None,
|
||||
preview_action=self._prev_plymouth_config,
|
||||
key='plymouth_config',
|
||||
),
|
||||
MenuItem(
|
||||
text=tr('Additional packages'),
|
||||
action=self._select_additional_packages,
|
||||
|
|
@ -432,6 +441,15 @@ class GlobalMenu(AbstractMenu[None]):
|
|||
output += '{}: {}'.format(tr('Color'), config.color)
|
||||
return output
|
||||
|
||||
async def _plymouth_configuration(self, preset: PlymouthConfiguration | None) -> PlymouthConfiguration | None:
|
||||
return await select_plymouth_theme(preset)
|
||||
|
||||
def _prev_plymouth_config(self, item: MenuItem) -> str | None:
|
||||
if not item.value:
|
||||
return None
|
||||
config: PlymouthConfiguration = item.value
|
||||
return config.preview()
|
||||
|
||||
def _prev_kernel(self, item: MenuItem) -> str | None:
|
||||
if item.value:
|
||||
kernel = ', '.join(item.value)
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ from archinstall.lib.models.locale import LocaleConfiguration
|
|||
from archinstall.lib.models.mirrors import CustomRepository, MirrorConfiguration, MirrorRegion
|
||||
from archinstall.lib.models.network import NetworkConfiguration, Nic, NicType
|
||||
from archinstall.lib.models.packages import LocalPackage, PackageSearch, PackageSearchResult, Repository
|
||||
from archinstall.lib.models.plymouth import PlymouthConfiguration, PlymouthTheme
|
||||
from archinstall.lib.models.profile import ProfileConfiguration
|
||||
from archinstall.lib.models.users import PasswordStrength, User
|
||||
|
||||
|
|
@ -69,6 +70,8 @@ __all__ = [
|
|||
'PartitionTable',
|
||||
'PartitionType',
|
||||
'PasswordStrength',
|
||||
'PlymouthConfiguration',
|
||||
'PlymouthTheme',
|
||||
'PrintServiceConfiguration',
|
||||
'ProfileConfiguration',
|
||||
'Repository',
|
||||
|
|
|
|||
|
|
@ -0,0 +1,57 @@
|
|||
from dataclasses import dataclass
|
||||
from enum import Enum
|
||||
from typing import Self, TypedDict, override
|
||||
|
||||
from archinstall.lib.models.config import SubConfig
|
||||
from archinstall.lib.translationhandler import tr
|
||||
|
||||
|
||||
class PlymouthConfigSerialization(TypedDict):
|
||||
plymouth: str
|
||||
|
||||
|
||||
class PlymouthTheme(Enum):
|
||||
DISABLED = 'Disabled'
|
||||
BGRT = 'bgrt'
|
||||
FADE_IN = 'fade-in'
|
||||
GLOW = 'glow'
|
||||
SCRIPT = 'script'
|
||||
SOLAR = 'solar'
|
||||
SPINNER = 'spinner'
|
||||
SPINFINITY = 'spinfinity'
|
||||
TRIBAR = 'tribar'
|
||||
TEXT = 'text'
|
||||
DETAILS = 'details'
|
||||
|
||||
|
||||
@dataclass
|
||||
class PlymouthConfiguration(SubConfig):
|
||||
plymouth: PlymouthTheme = PlymouthTheme.DISABLED
|
||||
|
||||
@override
|
||||
def json(self) -> PlymouthConfigSerialization:
|
||||
return {
|
||||
'plymouth': self.plymouth.value,
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def default(cls) -> Self:
|
||||
return cls()
|
||||
|
||||
@classmethod
|
||||
def parse_arg(cls, arg: PlymouthConfigSerialization) -> Self:
|
||||
config = cls.default()
|
||||
|
||||
if 'plymouth' in arg:
|
||||
config.plymouth = PlymouthTheme(arg['plymouth'])
|
||||
|
||||
return config
|
||||
|
||||
@override
|
||||
def summary(self) -> str:
|
||||
if self.plymouth == PlymouthTheme.DISABLED:
|
||||
return tr('Disabled')
|
||||
return tr('{} Selected').format(self.plymouth.value)
|
||||
|
||||
def preview(self) -> str:
|
||||
return f'Plymouth: {tr(self.plymouth.value)}'
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
from typing import TYPE_CHECKING
|
||||
|
||||
from archinstall.lib.log import debug
|
||||
from archinstall.lib.models.plymouth import PlymouthConfiguration, PlymouthTheme
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from archinstall.lib.installer import Installer
|
||||
|
||||
|
||||
class PlymouthHandler:
|
||||
@property
|
||||
def plymouth_packages(self) -> list[str]:
|
||||
return [
|
||||
'plymouth',
|
||||
]
|
||||
|
||||
@property
|
||||
def kernel_params(self) -> list[str]:
|
||||
return [
|
||||
'quiet',
|
||||
'splash',
|
||||
]
|
||||
|
||||
@property
|
||||
def plymouth_hook(self) -> str:
|
||||
return 'plymouth'
|
||||
|
||||
@property
|
||||
def _hook_anchors(self) -> list[tuple[str, bool]]:
|
||||
return [
|
||||
# hook_name, insert_after
|
||||
('encrypt', False),
|
||||
('sd-encrypt', False),
|
||||
('systemd', True),
|
||||
('systemd', True),
|
||||
('filesystems', False),
|
||||
('keyboard', True),
|
||||
]
|
||||
|
||||
def install(self, install_session: Installer, plymouth_config: PlymouthConfiguration) -> None:
|
||||
debug(f'Installing plymouth with theme: {plymouth_config.plymouth.value}')
|
||||
|
||||
if plymouth_config.plymouth == PlymouthTheme.DISABLED:
|
||||
debug('No plymouth theme selected, skipping installation.')
|
||||
return
|
||||
|
||||
install_session.add_additional_packages(self.plymouth_packages)
|
||||
|
||||
self._add_kernel_params(install_session)
|
||||
self._add_hooks(install_session)
|
||||
self._set_theme(install_session, plymouth_config.plymouth.value)
|
||||
self._regenerate_mkinitcpio(install_session)
|
||||
|
||||
debug('Plymouth install completed')
|
||||
|
||||
def _add_kernel_params(self, install_session: Installer) -> None:
|
||||
debug(f'Adding kernel params for plymouth {self.kernel_params}')
|
||||
for param in self.kernel_params:
|
||||
if param not in install_session._kernel_params:
|
||||
install_session._kernel_params.append(param)
|
||||
|
||||
def _add_hooks(self, install_session: Installer) -> None:
|
||||
debug('Adding Plymouth hook')
|
||||
|
||||
if self.plymouth_hook in install_session._hooks:
|
||||
debug(f'{self.plymouth_hook} hook already present')
|
||||
return
|
||||
|
||||
for hook, insert_after in self._hook_anchors:
|
||||
try:
|
||||
index = install_session._hooks.index(hook)
|
||||
position = index + (1 if insert_after else 0)
|
||||
install_session._hooks.insert(position, self.plymouth_hook)
|
||||
debug(f'Plymouth hook inserted {["before", "after"][insert_after]} {hook!r}')
|
||||
return
|
||||
except ValueError:
|
||||
continue
|
||||
|
||||
install_session._hooks.append(self.plymouth_hook)
|
||||
debug('Plymouth hook appended at end (no anchor hook found)')
|
||||
|
||||
def _set_theme(self, install_session: Installer, theme: str) -> None:
|
||||
debug(f'Set plymouth theme to {theme}')
|
||||
install_session.arch_chroot(f'plymouth-set-default-theme {theme}')
|
||||
|
||||
def _regenerate_mkinitcpio(self, install_session: Installer) -> None:
|
||||
install_session.mkinitcpio(['-P'])
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
from archinstall.lib.menu.helpers import Selection
|
||||
from archinstall.lib.models.plymouth import PlymouthConfiguration, PlymouthTheme
|
||||
from archinstall.lib.translationhandler import tr
|
||||
from archinstall.tui.menu_item import MenuItem, MenuItemGroup
|
||||
from archinstall.tui.result import ResultType
|
||||
|
||||
|
||||
async def select_plymouth_theme(preset: PlymouthConfiguration | None = None) -> PlymouthConfiguration | None:
|
||||
items = [MenuItem(t.value, value=t) for t in PlymouthTheme]
|
||||
group = MenuItemGroup(items, sort_items=False)
|
||||
group.set_selected_by_value(preset.plymouth if preset else PlymouthTheme.DISABLED)
|
||||
|
||||
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 PlymouthConfiguration(result.get_value())
|
||||
|
|
@ -20,6 +20,7 @@ from archinstall.lib.models.device import DiskLayoutType, EncryptionType
|
|||
from archinstall.lib.models.users import User
|
||||
from archinstall.lib.network.network_handler import install_network_config
|
||||
from archinstall.lib.packages.util import check_version_upgrade
|
||||
from archinstall.lib.plymouth.plymouth_handler import PlymouthHandler
|
||||
from archinstall.lib.profile.profiles_handler import profile_handler
|
||||
from archinstall.lib.translationhandler import tr
|
||||
from archinstall.tui.components import tui
|
||||
|
|
@ -114,6 +115,9 @@ def perform_installation(
|
|||
if config.swap and config.swap.enabled:
|
||||
installation.setup_swap(algo=config.swap.algorithm)
|
||||
|
||||
if config.plymouth_config:
|
||||
PlymouthHandler().install(installation, config.plymouth_config)
|
||||
|
||||
if config.bootloader_config and config.bootloader_config.bootloader != Bootloader.NO_BOOTLOADER:
|
||||
installation.add_bootloader(
|
||||
config.bootloader_config.bootloader,
|
||||
|
|
|
|||
Loading…
Reference in New Issue