Skip to content

Commit d91fcc9

Browse files
committed
Merge branch 'master' into fix-issue-4368-mkinitcpio
# Conflicts: # archinstall/lib/installer.py
2 parents 2068ab8 + 08cba23 commit d91fcc9

18 files changed

Lines changed: 518 additions & 204 deletions

File tree

.github/workflows/translation-check.yaml

Lines changed: 0 additions & 28 deletions
This file was deleted.

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,10 @@ qemu-system-x86_64 -enable-kvm \
219219

220220
# FAQ
221221

222+
## AUR
223+
224+
`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/).
225+
222226
## Keyring out-of-date
223227
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.
224228

archinstall/lib/args.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
from archinstall.lib.models.locale import LocaleConfiguration
2222
from archinstall.lib.models.mirrors import MirrorConfiguration
2323
from archinstall.lib.models.network import NetworkConfiguration
24+
from archinstall.lib.models.package_types import DEFAULT_KERNEL
2425
from archinstall.lib.models.packages import Repository
2526
from archinstall.lib.models.pacman import PacmanConfiguration
2627
from archinstall.lib.models.profile import ProfileConfiguration
@@ -71,7 +72,7 @@ class ArchConfig:
7172
auth_config: AuthenticationConfiguration | None = None
7273
swap: ZramConfiguration | None = None
7374
hostname: str = 'archlinux'
74-
kernels: list[str] = field(default_factory=lambda: ['linux'])
75+
kernels: list[str] = field(default_factory=lambda: [DEFAULT_KERNEL.value])
7576
ntp: bool = True
7677
packages: list[str] = field(default_factory=list)
7778
pacman_config: PacmanConfiguration = field(default_factory=PacmanConfiguration.default)

archinstall/lib/configuration.py

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
from archinstall.lib.crypt import encrypt
1111
from archinstall.lib.menu.helpers import Confirmation, Selection
1212
from archinstall.lib.menu.util import get_password, prompt_dir
13+
from archinstall.lib.models.bootloader import Bootloader
14+
from archinstall.lib.models.network import NetworkConfiguration
1315
from archinstall.lib.output import debug, logger, warn
1416
from archinstall.lib.translationhandler import tr
1517
from archinstall.tui.ui.menu_item import MenuItem, MenuItemGroup
@@ -58,6 +60,70 @@ def write_debug(self) -> None:
5860
debug(' -- Chosen configuration --')
5961
debug(self.user_config_to_json())
6062

63+
def as_summary(self) -> str:
64+
"""
65+
Render a concise two-column summary of the current configuration.
66+
67+
The left column holds section labels, the right column holds values.
68+
Column width adapts to the longest translated label so translations
69+
do not break the alignment. Rows whose underlying config is not set
70+
are skipped.
71+
72+
Returns an empty string if nothing meaningful to show.
73+
"""
74+
rows: list[tuple[str, str]] = []
75+
76+
disk_config = self._config.disk_config
77+
if disk_config and disk_config.device_modifications:
78+
disk_parts: list[str] = []
79+
for mod in disk_config.device_modifications:
80+
path = str(mod.device_path)
81+
root_part = mod.get_root_partition()
82+
flags: list[str] = []
83+
if root_part and root_part.fs_type:
84+
flags.append(root_part.fs_type.value)
85+
if disk_config.disk_encryption:
86+
flags.append(tr('LUKS'))
87+
disk_parts.append(f'{path} ({" + ".join(flags)})' if flags else path)
88+
rows.append((tr('Disks'), ', '.join(disk_parts)))
89+
90+
bl_config = self._config.bootloader_config
91+
if bl_config and bl_config.bootloader != Bootloader.NO_BOOTLOADER:
92+
rows.append((tr('Bootloader'), bl_config.bootloader.value))
93+
94+
kernels = self._config.kernels
95+
if kernels:
96+
rows.append((tr('Kernel'), ', '.join(kernels)))
97+
98+
profile_config = self._config.profile_config
99+
if profile_config and profile_config.profile:
100+
names = profile_config.profile.current_selection_names()
101+
rows.append((tr('Profile'), ', '.join(names) if names else profile_config.profile.name))
102+
if profile_config.greeter:
103+
rows.append((tr('Greeter'), profile_config.greeter.value))
104+
105+
packages = self._config.packages
106+
if packages:
107+
rows.append((tr('Packages'), str(len(packages))))
108+
109+
net_config = self._config.network_config
110+
if isinstance(net_config, NetworkConfiguration):
111+
rows.append((tr('Network'), net_config.type.display_msg()))
112+
113+
locale_config = self._config.locale_config
114+
if locale_config:
115+
rows.append((tr('Locale'), locale_config.sys_lang))
116+
117+
tz = self._config.timezone
118+
if tz:
119+
rows.append((tr('Timezone'), tz))
120+
121+
if not rows:
122+
return ''
123+
124+
label_width = max(len(label) for label, _ in rows) + 2
125+
return '\n'.join(f'{label:<{label_width}}{value}' for label, value in rows)
126+
61127
async def confirm_config(self) -> bool:
62128
header = f'{tr("The specified configuration will be applied")}. '
63129
header += tr('Would you like to continue?') + '\n'

archinstall/lib/general/system_menu.py

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,29 +3,24 @@
33
from archinstall.lib.hardware import GfxDriver, SysInfo
44
from archinstall.lib.menu.helpers import Confirmation, Selection
55
from archinstall.lib.models.application import ZramAlgorithm, ZramConfiguration
6+
from archinstall.lib.models.package_types import DEFAULT_KERNEL, Kernel
67
from archinstall.lib.translationhandler import tr
78
from archinstall.tui.ui.menu_item import MenuItem, MenuItemGroup
89
from archinstall.tui.ui.result import ResultType
910

1011

11-
async def select_kernel(preset: list[str] = []) -> list[str]:
12+
async def select_kernel(preset: list[Kernel] = []) -> list[Kernel]:
1213
"""
1314
Asks the user to select a kernel for system.
1415
1516
:return: The string as a selected kernel
1617
:rtype: string
1718
"""
18-
kernels = ['linux', 'linux-lts', 'linux-zen', 'linux-hardened']
19-
default_kernel = 'linux'
19+
group = MenuItemGroup.from_enum(Kernel, sort_items=True, preset=preset)
20+
group.set_default_by_value(DEFAULT_KERNEL)
21+
group.set_focus_by_value(DEFAULT_KERNEL)
2022

21-
items = [MenuItem(k, value=k) for k in kernels]
22-
23-
group = MenuItemGroup(items, sort_items=True)
24-
group.set_default_by_value(default_kernel)
25-
group.set_focus_by_value(default_kernel)
26-
group.set_selected_by_value(preset)
27-
28-
result = await Selection[str](
23+
result = await Selection[Kernel](
2924
group,
3025
header=tr('Select which kernel(s) to install'),
3126
allow_skip=True,

archinstall/lib/global_menu.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from archinstall.lib.authentication.authentication_menu import AuthenticationMenu
77
from archinstall.lib.bootloader.bootloader_menu import BootloaderMenu
88
from archinstall.lib.bootloader.utils import validate_bootloader_layout
9-
from archinstall.lib.configuration import save_config
9+
from archinstall.lib.configuration import ConfigurationOutput, save_config
1010
from archinstall.lib.disk.disk_menu import DiskLayoutConfigurationMenu
1111
from archinstall.lib.general.general_menu import select_hostname, select_ntp, select_timezone
1212
from archinstall.lib.general.system_menu import select_kernel, select_swap
@@ -22,6 +22,7 @@
2222
from archinstall.lib.models.locale import LocaleConfiguration
2323
from archinstall.lib.models.mirrors import MirrorConfiguration
2424
from archinstall.lib.models.network import NetworkConfiguration, NicType
25+
from archinstall.lib.models.package_types import DEFAULT_KERNEL
2526
from archinstall.lib.models.packages import Repository
2627
from archinstall.lib.models.pacman import PacmanConfiguration
2728
from archinstall.lib.models.profile import ProfileConfiguration
@@ -103,7 +104,7 @@ def _get_menu_options(self) -> list[MenuItem]:
103104
),
104105
MenuItem(
105106
text=tr('Kernels'),
106-
value=['linux'],
107+
value=[DEFAULT_KERNEL],
107108
action=select_kernel,
108109
preview_action=self._prev_kernel,
109110
mandatory=True,
@@ -503,7 +504,11 @@ def _prev_install_invalid_config(self, item: MenuItem) -> str | None:
503504
if error := self._validate_bootloader():
504505
return tr(f'Invalid configuration: {error}')
505506

506-
return None
507+
self.sync_all_to_config()
508+
summary = ConfigurationOutput(self._arch_config).as_summary()
509+
if summary:
510+
return f'{tr("Ready to install")}\n\n{summary}'
511+
return tr('Ready to install')
507512

508513
def _prev_profile(self, item: MenuItem) -> str | None:
509514
profile_config: ProfileConfiguration | None = item.value

archinstall/lib/installer.py

Lines changed: 25 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
from archinstall.lib.models.locale import LocaleConfiguration
4949
from archinstall.lib.models.mirrors import MirrorConfiguration
5050
from archinstall.lib.models.network import Nic
51+
from archinstall.lib.models.package_types import DEFAULT_KERNEL, Kernel
5152
from archinstall.lib.models.packages import Repository
5253
from archinstall.lib.models.pacman import PacmanConfiguration
5354
from archinstall.lib.models.users import User
@@ -65,7 +66,7 @@
6566
# pacman picks the first initramfs provider from the host's pacman.conf, which on non-Arch
6667
# hosts (EndeavourOS prefers dracut, etc.) breaks the installer's mkinitcpio() and
6768
# _config_uki() methods that assume mkinitcpio is present in the chroot.
68-
__packages__ = ['base', 'sudo', 'linux-firmware', 'mkinitcpio', 'linux', 'linux-lts', 'linux-zen', 'linux-hardened']
69+
__packages__ = ['base', 'sudo', 'linux-firmware', 'mkinitcpio'] + [k.value for k in Kernel]
6970

7071
# Additional packages that are installed if the user is running the Live ISO with accessibility tools enabled
7172
__accessibility_packages__ = ['brltty', 'espeakup', 'alsa-utils']
@@ -85,7 +86,7 @@ def __init__(
8586
It also wraps :py:func:`~archinstall.Installer.pacstrap` among other things.
8687
"""
8788
self._base_packages = base_packages or __packages__[:4]
88-
self.kernels = kernels or ['linux']
89+
self.kernels = kernels or [DEFAULT_KERNEL.value]
8990
self._disk_config = disk_config
9091

9192
self._disk_encryption = disk_config.disk_encryption or DiskEncryption(EncryptionType.NO_ENCRYPTION)
@@ -744,6 +745,9 @@ def arch_chroot(self, cmd: str, run_as: str | None = None, peek_output: bool = F
744745

745746
return self.run_command(cmd, peek_output=peek_output)
746747

748+
def _chroot_argv(self, *args: str) -> list[str]:
749+
return ['arch-chroot', '-S', str(self.target), *args]
750+
747751
def drop_to_shell(self) -> None:
748752
subprocess.check_call(f'arch-chroot {self.target}', shell=True)
749753

@@ -992,17 +996,7 @@ def setup_btrfs_snapshot(
992996
}
993997

994998
for config_name, mountpoint in snapper.items():
995-
command = [
996-
'arch-chroot',
997-
'-S',
998-
str(self.target),
999-
'snapper',
1000-
'--no-dbus',
1001-
'-c',
1002-
config_name,
1003-
'create-config',
1004-
mountpoint,
1005-
]
999+
command = self._chroot_argv('snapper', '--no-dbus', '-c', config_name, 'create-config', mountpoint)
10061000

10071001
try:
10081002
SysCommand(command, peek_output=True)
@@ -1341,13 +1335,7 @@ def _add_grub_bootloader(
13411335

13421336
boot_dir = Path('/boot')
13431337

1344-
command = [
1345-
'arch-chroot',
1346-
'-S',
1347-
str(self.target),
1348-
'grub-install',
1349-
'--debug',
1350-
]
1338+
command = self._chroot_argv('grub-install', '--debug')
13511339

13521340
if SysInfo.has_uefi():
13531341
if not efi_partition:
@@ -1927,16 +1915,17 @@ def _create_user(self, user: User) -> None:
19271915
if not handled_by_plugin:
19281916
info(f'Creating user {user.username}')
19291917

1930-
cmd = 'useradd -m'
1918+
cmd = self._chroot_argv('useradd', '-m')
19311919

19321920
if user.sudo:
1933-
cmd += ' -G wheel'
1921+
cmd += ['-G', 'wheel']
19341922

1935-
cmd += f' {user.username}'
1923+
cmd += ['--', user.username]
19361924

19371925
try:
1938-
self.arch_chroot(cmd)
1939-
except SysCallError as err:
1926+
run(cmd)
1927+
except CalledProcessError as err:
1928+
debug(f'Error creating user {user.username}: {err}')
19401929
raise SystemError(f'Could not create user inside installation: {err}')
19411930

19421931
for plugin in plugins.values():
@@ -1947,7 +1936,11 @@ def _create_user(self, user: User) -> None:
19471936
self.set_user_password(user)
19481937

19491938
for group in user.groups:
1950-
self.arch_chroot(f'gpasswd -a {user.username} {group}')
1939+
cmd = self._chroot_argv('gpasswd', '-a', user.username, group)
1940+
try:
1941+
run(cmd)
1942+
except CalledProcessError as err:
1943+
warn(f'Failed to add {user.username} to group {group}: {err}')
19511944

19521945
if user.sudo:
19531946
self.enable_sudo(user)
@@ -1962,7 +1955,7 @@ def set_user_password(self, user: User) -> bool:
19621955
return False
19631956

19641957
input_data = f'{user.username}:{enc_password}'.encode()
1965-
cmd = ['arch-chroot', '-S', str(self.target), 'chpasswd', '--encrypted']
1958+
cmd = self._chroot_argv('chpasswd', '--encrypted')
19661959

19671960
try:
19681961
run(cmd, input_data=input_data)
@@ -1974,7 +1967,7 @@ def set_user_password(self, user: User) -> bool:
19741967
def user_set_shell(self, user: str, shell: str) -> bool:
19751968
info(f'Setting shell for {user} to {shell}')
19761969

1977-
cmd = ['arch-chroot', '-S', str(self.target), 'chsh', '-s', shell, user]
1970+
cmd = self._chroot_argv('chsh', '-s', shell, user)
19781971
try:
19791972
run(cmd)
19801973
return True
@@ -1984,7 +1977,7 @@ def user_set_shell(self, user: str, shell: str) -> bool:
19841977

19851978
def chown(self, owner: str, path: str, options: list[str] | None = None) -> bool:
19861979
options = options or []
1987-
cmd = ['arch-chroot', '-S', str(self.target), 'chown', *options, owner, path]
1980+
cmd = self._chroot_argv('chown', *options, '--', owner, path)
19881981
try:
19891982
run(cmd)
19901983
return True
@@ -1995,12 +1988,10 @@ def chown(self, owner: str, path: str, options: list[str] | None = None) -> bool
19951988
def set_vconsole(self, locale_config: LocaleConfiguration) -> None:
19961989
# use the already set kb layout
19971990
kb_vconsole: str = locale_config.kb_layout
1998-
# this is the default used in ISO other option for hdpi screens TER16x32
1999-
# can be checked using
2000-
# zgrep "CONFIG_FONT" /proc/config.gz
2001-
# https://wiki.archlinux.org/title/Linux_console#Fonts
1991+
font_vconsole = locale_config.console_font
20021992

2003-
font_vconsole = 'default8x16'
1993+
if font_vconsole.startswith('ter-'):
1994+
self.pacman.strap(['terminus-font'])
20041995

20051996
# Ensure /etc exists
20061997
vconsole_dir: Path = self.target / 'etc'

0 commit comments

Comments
 (0)