From 9e05260df55ed3a2ad3a3546521919317dda94c5 Mon Sep 17 00:00:00 2001 From: Softer Date: Mon, 27 Apr 2026 02:24:51 +0300 Subject: [PATCH 1/8] Fix argv injection in _create_user and gpasswd loop (#4473) * Fix argv injection in _create_user and gpasswd loop Use argv list with run() instead of f-string interpolation into SysCommand, add debug logging on failure. * Extract _chroot_argv helper and harden user/file ops Address svartkanin's review on #4473: factor the ['arch-chroot', '-S', str(self.target), ...] boilerplate into a private Installer._chroot_argv() helper, and migrate the seven existing argv-form call sites to it (useradd, gpasswd, chpasswd, chsh, chown, snapper-create-config, grub-install). Two related hardening tweaks while in the area: - Raise gpasswd failure log from debug() to warn(). The group-add loop has no return-False feedback channel for the caller, so a silent debug() means a half-configured user looks like a successful install. - Add `--` end-of-options separator for useradd and chown so a username or path starting with `-` cannot smuggle flags. The TUI validates usernames, but parse_arguments() in models/users.py does not, so config.json is the residual hole; this closes it for these two sites at zero cost. --- archinstall/lib/installer.py | 46 +++++++++++++++--------------------- 1 file changed, 19 insertions(+), 27 deletions(-) diff --git a/archinstall/lib/installer.py b/archinstall/lib/installer.py index 19560d75..e596f7fe 100644 --- a/archinstall/lib/installer.py +++ b/archinstall/lib/installer.py @@ -739,6 +739,9 @@ class Installer: return self.run_command(cmd, peek_output=peek_output) + def _chroot_argv(self, *args: str) -> list[str]: + return ['arch-chroot', '-S', str(self.target), *args] + def drop_to_shell(self) -> None: subprocess.check_call(f'arch-chroot {self.target}', shell=True) @@ -987,17 +990,7 @@ class Installer: } for config_name, mountpoint in snapper.items(): - command = [ - 'arch-chroot', - '-S', - str(self.target), - 'snapper', - '--no-dbus', - '-c', - config_name, - 'create-config', - mountpoint, - ] + command = self._chroot_argv('snapper', '--no-dbus', '-c', config_name, 'create-config', mountpoint) try: SysCommand(command, peek_output=True) @@ -1336,13 +1329,7 @@ class Installer: boot_dir = Path('/boot') - command = [ - 'arch-chroot', - '-S', - str(self.target), - 'grub-install', - '--debug', - ] + command = self._chroot_argv('grub-install', '--debug') if SysInfo.has_uefi(): if not efi_partition: @@ -1922,16 +1909,17 @@ class Installer: if not handled_by_plugin: info(f'Creating user {user.username}') - cmd = 'useradd -m' + cmd = self._chroot_argv('useradd', '-m') if user.sudo: - cmd += ' -G wheel' + cmd += ['-G', 'wheel'] - cmd += f' {user.username}' + cmd += ['--', user.username] try: - self.arch_chroot(cmd) - except SysCallError as err: + run(cmd) + except CalledProcessError as err: + debug(f'Error creating user {user.username}: {err}') raise SystemError(f'Could not create user inside installation: {err}') for plugin in plugins.values(): @@ -1942,7 +1930,11 @@ class Installer: self.set_user_password(user) for group in user.groups: - self.arch_chroot(f'gpasswd -a {user.username} {group}') + cmd = self._chroot_argv('gpasswd', '-a', user.username, group) + try: + run(cmd) + except CalledProcessError as err: + warn(f'Failed to add {user.username} to group {group}: {err}') if user.sudo: self.enable_sudo(user) @@ -1957,7 +1949,7 @@ class Installer: return False input_data = f'{user.username}:{enc_password}'.encode() - cmd = ['arch-chroot', '-S', str(self.target), 'chpasswd', '--encrypted'] + cmd = self._chroot_argv('chpasswd', '--encrypted') try: run(cmd, input_data=input_data) @@ -1969,7 +1961,7 @@ class Installer: def user_set_shell(self, user: str, shell: str) -> bool: info(f'Setting shell for {user} to {shell}') - cmd = ['arch-chroot', '-S', str(self.target), 'chsh', '-s', shell, user] + cmd = self._chroot_argv('chsh', '-s', shell, user) try: run(cmd) return True @@ -1979,7 +1971,7 @@ class Installer: def chown(self, owner: str, path: str, options: list[str] | None = None) -> bool: options = options or [] - cmd = ['arch-chroot', '-S', str(self.target), 'chown', *options, owner, path] + cmd = self._chroot_argv('chown', *options, '--', owner, path) try: run(cmd) return True From 210329ed808628cf11fa3a8543d8f5da33c5c4a5 Mon Sep 17 00:00:00 2001 From: Softer Date: Mon, 27 Apr 2026 02:30:20 +0300 Subject: [PATCH 2/8] Add console font selection to Locales menu (#4469) * Add console font selection to Locales menu Add a 4th menu item "Console font" to the Locales configuration, allowing users to select a console font for the target system. The selected font is written to /etc/vconsole.conf. If a terminus font (ter-*) is selected, the terminus-font package is automatically installed on the target system. * Switch list_console_fonts to pathlib and add @lru_cache Address svartkanin's review on #4469. Replace os.listdir + chained removesuffix with Path.glob('*.gz') + split('.')[0], and cache the result via lru_cache - the kbd consolefonts directory is static at runtime so re-scanning on every menu reopen was wasted I/O. --- archinstall/lib/installer.py | 8 +++--- archinstall/lib/locale/locale_menu.py | 31 +++++++++++++++++++++- archinstall/lib/locale/utils.py | 10 +++++++ archinstall/lib/models/locale.py | 11 +++++++- archinstall/locales/base.pot | 3 +++ archinstall/locales/uk/LC_MESSAGES/base.po | 3 +++ 6 files changed, 59 insertions(+), 7 deletions(-) diff --git a/archinstall/lib/installer.py b/archinstall/lib/installer.py index e596f7fe..ff530df0 100644 --- a/archinstall/lib/installer.py +++ b/archinstall/lib/installer.py @@ -1982,12 +1982,10 @@ class Installer: def set_vconsole(self, locale_config: LocaleConfiguration) -> None: # use the already set kb layout kb_vconsole: str = locale_config.kb_layout - # this is the default used in ISO other option for hdpi screens TER16x32 - # can be checked using - # zgrep "CONFIG_FONT" /proc/config.gz - # https://wiki.archlinux.org/title/Linux_console#Fonts + font_vconsole = locale_config.console_font - font_vconsole = 'default8x16' + if font_vconsole.startswith('ter-'): + self.pacman.strap(['terminus-font']) # Ensure /etc exists vconsole_dir: Path = self.target / 'etc' diff --git a/archinstall/lib/locale/locale_menu.py b/archinstall/lib/locale/locale_menu.py index c03824a1..dc743fd3 100644 --- a/archinstall/lib/locale/locale_menu.py +++ b/archinstall/lib/locale/locale_menu.py @@ -1,6 +1,6 @@ from typing import override -from archinstall.lib.locale.utils import list_keyboard_languages, list_locales, set_kb_layout +from archinstall.lib.locale.utils import list_console_fonts, list_keyboard_languages, list_locales, set_kb_layout from archinstall.lib.menu.abstract_menu import AbstractSubMenu from archinstall.lib.menu.helpers import Selection from archinstall.lib.models.locale import LocaleConfiguration @@ -47,6 +47,13 @@ class LocaleMenu(AbstractSubMenu[LocaleConfiguration]): preview_action=lambda item: item.get_value(), key='sys_enc', ), + MenuItem( + text=tr('Console font'), + action=select_console_font, + value=self._locale_conf.console_font, + preview_action=lambda item: item.get_value(), + key='console_font', + ), ] @override @@ -140,3 +147,25 @@ async def select_kb_layout(preset: str | None = None) -> str | None: return preset case _: raise ValueError('Unhandled return type') + + +async def select_console_font(preset: str | None = None) -> str | None: + fonts = list_console_fonts() + + items = [MenuItem(f, value=f) for f in fonts] + group = MenuItemGroup(items, sort_items=False) + group.set_focus_by_value(preset) + + result = await Selection[str]( + header=tr('Console font'), + group=group, + enable_filter=True, + ).show() + + match result.type_: + case ResultType.Selection: + return result.get_value() + case ResultType.Skip: + return preset + case _: + raise ValueError('Unhandled return type') diff --git a/archinstall/lib/locale/utils.py b/archinstall/lib/locale/utils.py index e7229160..497e1fcb 100644 --- a/archinstall/lib/locale/utils.py +++ b/archinstall/lib/locale/utils.py @@ -1,3 +1,6 @@ +from functools import lru_cache +from pathlib import Path + from archinstall.lib.command import SysCommand from archinstall.lib.exceptions import ServiceException, SysCallError from archinstall.lib.output import error @@ -26,6 +29,13 @@ def list_locales() -> list[str]: return locales +@lru_cache +def list_console_fonts() -> list[str]: + directory = Path('/usr/share/kbd/consolefonts') + fonts = {path.name.split('.')[0] for path in directory.glob('*.gz')} + return sorted(fonts) + + def list_x11_keyboard_languages() -> list[str]: return ( SysCommand( diff --git a/archinstall/lib/models/locale.py b/archinstall/lib/models/locale.py index 15dee2f6..8f580989 100644 --- a/archinstall/lib/models/locale.py +++ b/archinstall/lib/models/locale.py @@ -10,6 +10,11 @@ class LocaleConfiguration: kb_layout: str sys_lang: str sys_enc: str + # this is the default used in ISO other option for hdpi screens TER16x32 + # can be checked using + # zgrep "CONFIG_FONT" /proc/config.gz + # https://wiki.archlinux.org/title/Linux_console#Font + console_font: str = 'default8x16' @classmethod def default(cls) -> Self: @@ -23,12 +28,14 @@ class LocaleConfiguration: 'kb_layout': self.kb_layout, 'sys_lang': self.sys_lang, 'sys_enc': self.sys_enc, + 'console_font': self.console_font, } def preview(self) -> str: output = '{}: {}\n'.format(tr('Keyboard layout'), self.kb_layout) output += '{}: {}\n'.format(tr('Locale language'), self.sys_lang) - output += '{}: {}'.format(tr('Locale encoding'), self.sys_enc) + output += '{}: {}\n'.format(tr('Locale encoding'), self.sys_enc) + output += '{}: {}'.format(tr('Console font'), self.console_font) return output def _load_config(self, args: dict[str, str]) -> None: @@ -38,6 +45,8 @@ class LocaleConfiguration: self.sys_enc = args['sys_enc'] if 'kb_layout' in args: self.kb_layout = args['kb_layout'] + if 'console_font' in args: + self.console_font = args['console_font'] @classmethod def parse_arg(cls, args: dict[str, Any]) -> Self: diff --git a/archinstall/locales/base.pot b/archinstall/locales/base.pot index f707ec7a..a0c4c5b7 100644 --- a/archinstall/locales/base.pot +++ b/archinstall/locales/base.pot @@ -252,6 +252,9 @@ msgstr "" msgid "Locale encoding" msgstr "" +msgid "Console font" +msgstr "" + msgid "Drive(s)" msgstr "" diff --git a/archinstall/locales/uk/LC_MESSAGES/base.po b/archinstall/locales/uk/LC_MESSAGES/base.po index a178ac2d..ffab244f 100644 --- a/archinstall/locales/uk/LC_MESSAGES/base.po +++ b/archinstall/locales/uk/LC_MESSAGES/base.po @@ -256,6 +256,9 @@ msgstr "Мова локалізації" msgid "Locale encoding" msgstr "Кодування локалізації" +msgid "Console font" +msgstr "Шрифт консолі" + msgid "Drive(s)" msgstr "Диск(и)" From 3795bfc21a87224f9dd8e983a5a736b58cda06ad Mon Sep 17 00:00:00 2001 From: utuhiro78 <34818411+utuhiro78@users.noreply.github.com> Date: Mon, 27 Apr 2026 08:32:10 +0900 Subject: [PATCH 3/8] Update Japanese translation (#4482) --- archinstall/locales/ja/LC_MESSAGES/base.mo | Bin 68172 -> 72857 bytes archinstall/locales/ja/LC_MESSAGES/base.po | 230 ++++++++++++++++++++- 2 files changed, 219 insertions(+), 11 deletions(-) diff --git a/archinstall/locales/ja/LC_MESSAGES/base.mo b/archinstall/locales/ja/LC_MESSAGES/base.mo index 3ad3d1a276e7039db33fe23806d6b3fcdd109ba2..bfdce38d646ec876e4516067ceaba61ea4c87c39 100644 GIT binary patch delta 17972 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 delta 13924 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 wKg!_gll8y)=)_mI%?$HY3kpk5 Date: Mon, 27 Apr 2026 02:35:34 +0300 Subject: [PATCH 4/8] Remove disabled translation-check workflow (#4483) The workflow has been fully commented out since #2119 (2023-09-28) when translation handling was reworked. Because the file has no `on:` triggers, GitHub Actions creates a failed workflow run for every push, polluting the Actions tab without affecting PR check-runs. --- .github/workflows/translation-check.yaml | 28 ------------------------ 1 file changed, 28 deletions(-) delete mode 100644 .github/workflows/translation-check.yaml diff --git a/.github/workflows/translation-check.yaml b/.github/workflows/translation-check.yaml deleted file mode 100644 index 3cd4d14c..00000000 --- a/.github/workflows/translation-check.yaml +++ /dev/null @@ -1,28 +0,0 @@ -#on: -# push: -# paths: -# - 'archinstall/locales/**' -# pull_request: -# paths: -# - 'archinstall/locales/**' -#name: Verify local_generate script was run on translation changes -#jobs: -# translation-check: -# runs-on: ubuntu-latest -# container: -# image: archlinux/archlinux:latest -# steps: -# - uses: actions/checkout@v4 -# - run: pacman --noconfirm -Syu python git diffutils -# - name: Verify all translation scripts are up to date -# run: | -# cd .. -# cp -r archinstall archinstall_orig -# cd archinstall/archinstall/locales -# bash locales_generator.sh 1> /dev/null -# cd ../../.. -# git diff \ -# --quiet --no-index --name-only \ -# archinstall_orig/archinstall/locales \ -# archinstall/archinstall/locales \ -# || (echo "Translation files have not been updated after translation, please run ./locales_generator.sh once more and commit" && exit 1) From 074dfbb1784a374f6f2a548a2c027b1f942b153d Mon Sep 17 00:00:00 2001 From: Anton Hvornum Date: Mon, 27 Apr 2026 08:44:14 +0200 Subject: [PATCH 5/8] Adding a reference to why AUR is not bundled as an option in archinstall (#4468) --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 75631b6b..95d15702 100644 --- a/README.md +++ b/README.md @@ -219,6 +219,10 @@ qemu-system-x86_64 -enable-kvm \ # FAQ +## AUR + +`archinstall` will not offer or bundle AUR helpers or AUR packages due to a current consensus. This is not any individual developers decision. The reasons and discussions for this stance on the topic can be found on our mailing list thread: [(optional) AUR helper in archinstall](https://lists.archlinux.org/archives/list/arch-dev-public@lists.archlinux.org/thread/VYOULH2GOJLFM2BXOFLWH3D754YXFPSL/). + ## Keyring out-of-date For a description of the problem see https://archinstall.archlinux.page/help/known_issues.html#keyring-is-out-of-date-2213 and discussion in issue https://github.com/archlinux/archinstall/issues/2213. From 9010ccf9eb3369f713d60cefc0b17e619f23c143 Mon Sep 17 00:00:00 2001 From: codefiles <11915375+codefiles@users.noreply.github.com> Date: Tue, 28 Apr 2026 03:08:19 -0400 Subject: [PATCH 6/8] Add kernel enum (#4489) --- archinstall/lib/args.py | 3 ++- archinstall/lib/general/system_menu.py | 17 ++++++----------- archinstall/lib/global_menu.py | 3 ++- archinstall/lib/installer.py | 5 +++-- archinstall/lib/models/package_types.py | 12 ++++++++++++ archinstall/tui/ui/menu_item.py | 4 ++-- 6 files changed, 27 insertions(+), 17 deletions(-) create mode 100644 archinstall/lib/models/package_types.py diff --git a/archinstall/lib/args.py b/archinstall/lib/args.py index 79441a06..77545736 100644 --- a/archinstall/lib/args.py +++ b/archinstall/lib/args.py @@ -21,6 +21,7 @@ from archinstall.lib.models.device import DiskEncryption, DiskLayoutConfiguratio from archinstall.lib.models.locale import LocaleConfiguration from archinstall.lib.models.mirrors import MirrorConfiguration from archinstall.lib.models.network import NetworkConfiguration +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.profile import ProfileConfiguration @@ -71,7 +72,7 @@ class ArchConfig: auth_config: AuthenticationConfiguration | None = None swap: ZramConfiguration | None = None hostname: str = 'archlinux' - kernels: list[str] = field(default_factory=lambda: ['linux']) + kernels: list[str] = field(default_factory=lambda: [DEFAULT_KERNEL.value]) ntp: bool = True packages: list[str] = field(default_factory=list) pacman_config: PacmanConfiguration = field(default_factory=PacmanConfiguration.default) diff --git a/archinstall/lib/general/system_menu.py b/archinstall/lib/general/system_menu.py index 5c4d4634..7fa0d1f2 100644 --- a/archinstall/lib/general/system_menu.py +++ b/archinstall/lib/general/system_menu.py @@ -3,29 +3,24 @@ from typing import assert_never from archinstall.lib.hardware import GfxDriver, SysInfo from archinstall.lib.menu.helpers import Confirmation, Selection from archinstall.lib.models.application import ZramAlgorithm, ZramConfiguration +from archinstall.lib.models.package_types import DEFAULT_KERNEL, Kernel from archinstall.lib.translationhandler import tr from archinstall.tui.ui.menu_item import MenuItem, MenuItemGroup from archinstall.tui.ui.result import ResultType -async def select_kernel(preset: list[str] = []) -> list[str]: +async def select_kernel(preset: list[Kernel] = []) -> list[Kernel]: """ Asks the user to select a kernel for system. :return: The string as a selected kernel :rtype: string """ - kernels = ['linux', 'linux-lts', 'linux-zen', 'linux-hardened'] - default_kernel = 'linux' + group = MenuItemGroup.from_enum(Kernel, sort_items=True, preset=preset) + group.set_default_by_value(DEFAULT_KERNEL) + group.set_focus_by_value(DEFAULT_KERNEL) - items = [MenuItem(k, value=k) for k in kernels] - - group = MenuItemGroup(items, sort_items=True) - group.set_default_by_value(default_kernel) - group.set_focus_by_value(default_kernel) - group.set_selected_by_value(preset) - - result = await Selection[str]( + result = await Selection[Kernel]( group, header=tr('Select which kernel(s) to install'), allow_skip=True, diff --git a/archinstall/lib/global_menu.py b/archinstall/lib/global_menu.py index e327b388..3bfefce7 100644 --- a/archinstall/lib/global_menu.py +++ b/archinstall/lib/global_menu.py @@ -22,6 +22,7 @@ from archinstall.lib.models.device import DiskLayoutConfiguration, DiskLayoutTyp from archinstall.lib.models.locale import LocaleConfiguration from archinstall.lib.models.mirrors import MirrorConfiguration 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.profile import ProfileConfiguration @@ -103,7 +104,7 @@ class GlobalMenu(AbstractMenu[None]): ), MenuItem( text=tr('Kernels'), - value=['linux'], + value=[DEFAULT_KERNEL], action=select_kernel, preview_action=self._prev_kernel, mandatory=True, diff --git a/archinstall/lib/installer.py b/archinstall/lib/installer.py index ff530df0..ca98fdb9 100644 --- a/archinstall/lib/installer.py +++ b/archinstall/lib/installer.py @@ -48,6 +48,7 @@ from archinstall.lib.models.device import ( from archinstall.lib.models.locale import LocaleConfiguration from archinstall.lib.models.mirrors import MirrorConfiguration from archinstall.lib.models.network import Nic +from archinstall.lib.models.package_types import DEFAULT_KERNEL, Kernel from archinstall.lib.models.packages import Repository from archinstall.lib.models.pacman import PacmanConfiguration from archinstall.lib.models.users import User @@ -60,7 +61,7 @@ from archinstall.lib.plugins import plugins from archinstall.lib.translationhandler import tr # Any package that the Installer() is responsible for (optional and the default ones) -__packages__ = ['base', 'sudo', 'linux-firmware', 'linux', 'linux-lts', 'linux-zen', 'linux-hardened'] +__packages__ = ['base', 'sudo', 'linux-firmware'] + [k.value for k in Kernel] # Additional packages that are installed if the user is running the Live ISO with accessibility tools enabled __accessibility_packages__ = ['brltty', 'espeakup', 'alsa-utils'] @@ -80,7 +81,7 @@ class Installer: It also wraps :py:func:`~archinstall.Installer.pacstrap` among other things. """ self._base_packages = base_packages or __packages__[:3] - self.kernels = kernels or ['linux'] + self.kernels = kernels or [DEFAULT_KERNEL.value] self._disk_config = disk_config self._disk_encryption = disk_config.disk_encryption or DiskEncryption(EncryptionType.NO_ENCRYPTION) diff --git a/archinstall/lib/models/package_types.py b/archinstall/lib/models/package_types.py new file mode 100644 index 00000000..e314c30a --- /dev/null +++ b/archinstall/lib/models/package_types.py @@ -0,0 +1,12 @@ +from enum import StrEnum, auto +from typing import Final + + +class Kernel(StrEnum): + LINUX = auto() + LINUX_LTS = 'linux-lts' + LINUX_ZEN = 'linux-zen' + LINUX_HARDENED = 'linux-hardened' + + +DEFAULT_KERNEL: Final = Kernel.LINUX diff --git a/archinstall/tui/ui/menu_item.py b/archinstall/tui/ui/menu_item.py index ed5a16ec..4c10e275 100644 --- a/archinstall/tui/ui/menu_item.py +++ b/archinstall/tui/ui/menu_item.py @@ -1,4 +1,4 @@ -from collections.abc import Awaitable, Callable +from collections.abc import Awaitable, Callable, Iterable from dataclasses import dataclass, field from enum import Enum from functools import cached_property @@ -148,7 +148,7 @@ class MenuItemGroup: cls, enum_cls: type[Enum], sort_items: bool = False, - preset: Enum | None = None, + preset: Iterable[Enum] | Enum | None = None, ) -> Self: items = [MenuItem(elem.value, value=elem) for elem in enum_cls] group = cls(items, sort_items=sort_items) From 8cc35f41d8da44b1665e3f8b41a10bb22bb0b1c7 Mon Sep 17 00:00:00 2001 From: Franco Castillo Date: Tue, 28 Apr 2026 04:08:39 -0300 Subject: [PATCH 7/8] Update Spanish translation (#4490) Signed-off-by: Franco Castillo --- archinstall/locales/es/LC_MESSAGES/base.mo | Bin 65086 -> 67046 bytes archinstall/locales/es/LC_MESSAGES/base.po | 200 +++++++++------------ 2 files changed, 88 insertions(+), 112 deletions(-) diff --git a/archinstall/locales/es/LC_MESSAGES/base.mo b/archinstall/locales/es/LC_MESSAGES/base.mo index 14e916ef66dffeec86c2631fab615c138248130d..5701d45472451d2476f3d5d88f44cf536839ce2b 100644 GIT binary patch delta 16896 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 roibA Date: Tue, 28 Apr 2026 12:22:01 +0300 Subject: [PATCH 8/8] Show install summary when configuration is valid (#4475) * Show install summary when configuration is valid Previously the Install menu preview was empty when everything was valid, leaving the user with no "ready" signal. Now show "Ready to install" plus a two-column summary of the current configuration. - New _install_summary() composes an aligned key/value table with rows for disks+FS+LUKS, bootloader, kernel, profile, greeter, package count, network, locale and timezone. Column width adapts to the longest translated label so translations keep the alignment. - Rows whose underlying config is not set are skipped rather than rendered as empty. - base.pot / uk base.po: add new msgids for summary labels. * Move install summary into ConfigurationOutput The summary helper that renders the install preview's two-column configuration overview lived in GlobalMenu. Move it to ConfigurationOutput.as_summary() so it sits alongside the JSON output methods that share the same role. The preview now syncs menu state to ArchConfig and delegates rendering. --- archinstall/lib/configuration.py | 66 ++++++++++++++++++++++ archinstall/lib/global_menu.py | 8 ++- archinstall/locales/base.pot | 15 +++++ archinstall/locales/uk/LC_MESSAGES/base.po | 15 +++++ 4 files changed, 102 insertions(+), 2 deletions(-) diff --git a/archinstall/lib/configuration.py b/archinstall/lib/configuration.py index 39d39511..0f22190e 100644 --- a/archinstall/lib/configuration.py +++ b/archinstall/lib/configuration.py @@ -10,6 +10,8 @@ from archinstall.lib.args import ArchConfig from archinstall.lib.crypt import encrypt from archinstall.lib.menu.helpers import Confirmation, Selection from archinstall.lib.menu.util import get_password, prompt_dir +from archinstall.lib.models.bootloader import Bootloader +from archinstall.lib.models.network import NetworkConfiguration from archinstall.lib.output import debug, logger, warn from archinstall.lib.translationhandler import tr from archinstall.tui.ui.menu_item import MenuItem, MenuItemGroup @@ -58,6 +60,70 @@ class ConfigurationOutput: debug(' -- Chosen configuration --') debug(self.user_config_to_json()) + def as_summary(self) -> str: + """ + Render a concise two-column summary of the current configuration. + + The left column holds section labels, the right column holds values. + Column width adapts to the longest translated label so translations + do not break the alignment. Rows whose underlying config is not set + are skipped. + + Returns an empty string if nothing meaningful to show. + """ + rows: list[tuple[str, str]] = [] + + disk_config = self._config.disk_config + if disk_config and disk_config.device_modifications: + disk_parts: list[str] = [] + for mod in disk_config.device_modifications: + path = str(mod.device_path) + root_part = mod.get_root_partition() + flags: list[str] = [] + if root_part and root_part.fs_type: + flags.append(root_part.fs_type.value) + if disk_config.disk_encryption: + flags.append(tr('LUKS')) + disk_parts.append(f'{path} ({" + ".join(flags)})' if flags else path) + rows.append((tr('Disks'), ', '.join(disk_parts))) + + bl_config = self._config.bootloader_config + if bl_config and bl_config.bootloader != Bootloader.NO_BOOTLOADER: + rows.append((tr('Bootloader'), bl_config.bootloader.value)) + + kernels = self._config.kernels + if kernels: + rows.append((tr('Kernel'), ', '.join(kernels))) + + profile_config = self._config.profile_config + if profile_config and profile_config.profile: + names = profile_config.profile.current_selection_names() + rows.append((tr('Profile'), ', '.join(names) if names else profile_config.profile.name)) + if profile_config.greeter: + rows.append((tr('Greeter'), profile_config.greeter.value)) + + packages = self._config.packages + if packages: + rows.append((tr('Packages'), str(len(packages)))) + + net_config = self._config.network_config + if isinstance(net_config, NetworkConfiguration): + rows.append((tr('Network'), net_config.type.display_msg())) + + locale_config = self._config.locale_config + if locale_config: + rows.append((tr('Locale'), locale_config.sys_lang)) + + tz = self._config.timezone + if tz: + rows.append((tr('Timezone'), tz)) + + if not rows: + return '' + + label_width = max(len(label) for label, _ in rows) + 2 + return '\n'.join(f'{label:<{label_width}}{value}' for label, value in rows) + async def confirm_config(self) -> bool: header = f'{tr("The specified configuration will be applied")}. ' header += tr('Would you like to continue?') + '\n' diff --git a/archinstall/lib/global_menu.py b/archinstall/lib/global_menu.py index 3bfefce7..cdd820a9 100644 --- a/archinstall/lib/global_menu.py +++ b/archinstall/lib/global_menu.py @@ -6,7 +6,7 @@ from archinstall.lib.args import ArchConfig from archinstall.lib.authentication.authentication_menu import AuthenticationMenu from archinstall.lib.bootloader.bootloader_menu import BootloaderMenu from archinstall.lib.bootloader.utils import validate_bootloader_layout -from archinstall.lib.configuration import save_config +from archinstall.lib.configuration import ConfigurationOutput, save_config from archinstall.lib.disk.disk_menu import DiskLayoutConfigurationMenu from archinstall.lib.general.general_menu import select_hostname, select_ntp, select_timezone from archinstall.lib.general.system_menu import select_kernel, select_swap @@ -504,7 +504,11 @@ class GlobalMenu(AbstractMenu[None]): if error := self._validate_bootloader(): return tr(f'Invalid configuration: {error}') - return None + self.sync_all_to_config() + summary = ConfigurationOutput(self._arch_config).as_summary() + if summary: + return f'{tr("Ready to install")}\n\n{summary}' + return tr('Ready to install') def _prev_profile(self, item: MenuItem) -> str | None: profile_config: ProfileConfiguration | None = item.value diff --git a/archinstall/locales/base.pot b/archinstall/locales/base.pot index a0c4c5b7..b7e1184b 100644 --- a/archinstall/locales/base.pot +++ b/archinstall/locales/base.pot @@ -1248,6 +1248,21 @@ msgstr "" msgid "Invalid configuration: {error}" msgstr "" +msgid "Ready to install" +msgstr "" + +msgid "Disks" +msgstr "" + +msgid "Packages" +msgstr "" + +msgid "Network" +msgstr "" + +msgid "Locale" +msgstr "" + msgid "Type" msgstr "" diff --git a/archinstall/locales/uk/LC_MESSAGES/base.po b/archinstall/locales/uk/LC_MESSAGES/base.po index ffab244f..88bf9ede 100644 --- a/archinstall/locales/uk/LC_MESSAGES/base.po +++ b/archinstall/locales/uk/LC_MESSAGES/base.po @@ -1222,6 +1222,21 @@ msgstr "Модель" msgid "Invalid configuration: {error}" msgstr "Неправильна конфігурація: {error}" +msgid "Ready to install" +msgstr "Готово до встановлення" + +msgid "Disks" +msgstr "Диски" + +msgid "Packages" +msgstr "Пакети" + +msgid "Network" +msgstr "Мережа" + +msgid "Locale" +msgstr "Локаль" + msgid "Type" msgstr "Тип"