Skip to content
Merged
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
2 changes: 1 addition & 1 deletion .github/workflows/ruff-format.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
- uses: astral-sh/ruff-action@eaf0ecdd668ceea36159ff9d91882c9795d89b49 # v3.4.0
- uses: astral-sh/ruff-action@0c50076f12c38c3d0115b7b519b54a91cb9cf0ad # v3.5.0
- run: ruff format --diff
2 changes: 1 addition & 1 deletion .github/workflows/ruff-lint.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
- uses: astral-sh/ruff-action@eaf0ecdd668ceea36159ff9d91882c9795d89b49 # v3.4.0
- uses: astral-sh/ruff-action@0c50076f12c38c3d0115b7b519b54a91cb9cf0ad # v3.5.0
4 changes: 2 additions & 2 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
default_stages: ['pre-commit']
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.12.1
rev: v0.12.3
hooks:
# fix unused imports and sort them
- id: ruff
Expand Down Expand Up @@ -31,7 +31,7 @@ repos:
args: [--config=.flake8]
fail_fast: true
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.16.1
rev: v1.17.0
hooks:
- id: mypy
args: [
Expand Down
23 changes: 16 additions & 7 deletions archinstall/lib/args.py
Original file line number Diff line number Diff line change
@@ -1,28 +1,30 @@
import argparse
import json
import os
import urllib.error
import urllib.parse
from argparse import ArgumentParser, Namespace
from dataclasses import dataclass, field
from importlib.metadata import version
from pathlib import Path
from typing import Any
from urllib.request import Request, urlopen

from pydantic.dataclasses import dataclass as p_dataclass

from archinstall.lib.crypt import decrypt
from archinstall.lib.models.application import ApplicationConfiguration
from archinstall.lib.models.authentication import AuthenticationConfiguration
from archinstall.lib.models.bootloader import Bootloader
from archinstall.lib.models.device_model import DiskEncryption, DiskLayoutConfiguration
from archinstall.lib.models.device import DiskEncryption, DiskLayoutConfiguration
from archinstall.lib.models.locale import LocaleConfiguration
from archinstall.lib.models.mirrors import MirrorConfiguration
from archinstall.lib.models.network_configuration import NetworkConfiguration
from archinstall.lib.models.packages import Repository
from archinstall.lib.models.profile_model import ProfileConfiguration
from archinstall.lib.models.profile import ProfileConfiguration
from archinstall.lib.models.users import Password, User
from archinstall.lib.models.profile_model import ProfileConfiguration

Check failure on line 26 in archinstall/lib/args.py

View workflow job for this annotation

GitHub Actions / ruff_format_check

Ruff (F811)

archinstall/lib/args.py:26:50: F811 Redefinition of unused `ProfileConfiguration` from line 24

Check failure on line 26 in archinstall/lib/args.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (F811)

archinstall/lib/args.py:26:50: F811 Redefinition of unused `ProfileConfiguration` from line 24
from archinstall.lib.models.users import Password, User, UserSerialization

Check failure on line 27 in archinstall/lib/args.py

View workflow job for this annotation

GitHub Actions / ruff_format_check

Ruff (F811)

archinstall/lib/args.py:27:52: F811 Redefinition of unused `User` from line 25

Check failure on line 27 in archinstall/lib/args.py

View workflow job for this annotation

GitHub Actions / ruff_format_check

Ruff (F811)

archinstall/lib/args.py:27:42: F811 Redefinition of unused `Password` from line 25

Check failure on line 27 in archinstall/lib/args.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (F811)

archinstall/lib/args.py:27:52: F811 Redefinition of unused `User` from line 25

Check failure on line 27 in archinstall/lib/args.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (F811)

archinstall/lib/args.py:27:42: F811 Redefinition of unused `Password` from line 25
from archinstall.lib.output import debug, error, logger, warn
from archinstall.lib.plugins import load_plugin
from archinstall.lib.translationhandler import Language, tr, translation_handler
Expand Down Expand Up @@ -78,14 +80,15 @@

# Special fields that should be handle with care due to security implications
users: list[User] = field(default_factory=list)
root_enc_password: Password | None = None

def unsafe_json(self) -> dict[str, Any]:
config = {
config: dict[str, list[UserSerialization] | str | None] = {
'users': [user.json() for user in self.users],
'root_enc_password': self.root_enc_password.enc_password if self.root_enc_password else None,
}

if self.auth_config and self.auth_config.root_enc_password:
config['root_enc_password'] = self.auth_config.root_enc_password.enc_password

if self.disk_config:
disk_encryption = self.disk_config.disk_encryption
if disk_encryption and disk_encryption.encryption_password:
Expand Down Expand Up @@ -222,11 +225,17 @@
arch_config.services = services

# DEPRECATED: backwards compatibility
root_password = None
if root_password := args_config.get('!root-password', None):
arch_config.root_enc_password = Password(plaintext=root_password)
root_password = Password(plaintext=root_password)

if enc_password := args_config.get('root_enc_password', None):
arch_config.root_enc_password = Password(enc_password=enc_password)
root_password = Password(enc_password=enc_password)

if root_password is not None:
if arch_config.auth_config is None:
arch_config.auth_config = AuthenticationConfiguration()
arch_config.auth_config.root_enc_password = root_password

if custom_commands := args_config.get('custom_commands', []):
arch_config.custom_commands = custom_commands
Expand Down
33 changes: 30 additions & 3 deletions archinstall/lib/authentication/authentication_menu.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
from archinstall.lib.disk.fido import Fido2
from archinstall.lib.menu.abstract_menu import AbstractSubMenu
from archinstall.lib.models.authentication import AuthenticationConfiguration, U2FLoginConfiguration, U2FLoginMethod
from archinstall.lib.models.users import Password
from archinstall.lib.translationhandler import tr
from archinstall.lib.utils.util import get_password
from archinstall.tui.curses_menu import SelectMenu
from archinstall.tui.menu_item import MenuItem, MenuItemGroup
from archinstall.tui.result import ResultType
Expand Down Expand Up @@ -33,16 +35,27 @@ def run(self, additional_title: str | None = None) -> AuthenticationConfiguratio

def _define_menu_options(self) -> list[MenuItem]:
return [
MenuItem(
text=tr('Root password'),
action=select_root_password,
preview_action=self._prev_root_pwd,
key='root_enc_password',
),
MenuItem(
text=tr('U2F login setup'),
action=setup_u2f_login,
action=select_u2f_login,
value=self._auth_config.u2f_config,
preview_action=self._prev_u2f_login,
dependencies=[self._depends_on_u2f],
key='u2f_config',
),
]

def _prev_root_pwd(self, item: MenuItem) -> str | None:
if item.value is not None:
password: Password = item.value
return f'{tr("Root password")}: {password.hidden()}'
return None

def _depends_on_u2f(self) -> bool:
devices = Fido2.get_fido2_devices()
if not devices:
Expand All @@ -60,10 +73,24 @@ def _prev_u2f_login(self, item: MenuItem) -> str | None:
output += tr('Passwordless sudo: ') + (tr('Enabled') if u2f_config.passwordless_sudo else tr('Disabled'))

return output

devices = Fido2.get_fido2_devices()
if not devices:
return tr('No U2F devices found')

return None


def setup_u2f_login(preset: U2FLoginConfiguration) -> U2FLoginConfiguration | None:
def select_root_password(preset: str | None = None) -> Password | None:
password = get_password(text=tr('Root password'), allow_skip=True)
return password


def select_u2f_login(preset: U2FLoginConfiguration) -> U2FLoginConfiguration | None:
devices = Fido2.get_fido2_devices()
if not devices:
return None

items = []
for method in U2FLoginMethod:
items.append(MenuItem(method.display_value(), value=method))
Expand Down
2 changes: 1 addition & 1 deletion archinstall/lib/disk/device_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from ..exceptions import DiskError, SysCallError, UnknownFilesystemFormat
from ..general import SysCommand, SysCommandWorker
from ..luks import Luks2
from ..models.device_model import (
from ..models.device import (
DEFAULT_ITER_TIME,
BDevice,
BtrfsMountOption,
Expand Down
2 changes: 1 addition & 1 deletion archinstall/lib/disk/disk_menu.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from typing import override

from archinstall.lib.disk.encryption_menu import DiskEncryptionMenu
from archinstall.lib.models.device_model import (
from archinstall.lib.models.device import (
DEFAULT_ITER_TIME,
BtrfsOptions,
DiskEncryption,
Expand Down
4 changes: 2 additions & 2 deletions archinstall/lib/disk/encryption_menu.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from typing import override

from archinstall.lib.menu.menu_helper import MenuHelper
from archinstall.lib.models.device_model import (
from archinstall.lib.models.device import (
DeviceModification,
DiskEncryption,
EncryptionType,
Expand All @@ -17,7 +17,7 @@
from archinstall.tui.types import Alignment, FrameProperties

from ..menu.abstract_menu import AbstractSubMenu
from ..models.device_model import DEFAULT_ITER_TIME, Fido2Device
from ..models.device import DEFAULT_ITER_TIME, Fido2Device
from ..models.users import Password
from ..output import FormattedOutput
from ..utils.util import get_password
Expand Down
7 changes: 5 additions & 2 deletions archinstall/lib/disk/fido.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from pathlib import Path
from typing import ClassVar

from archinstall.lib.models.device_model import Fido2Device
from archinstall.lib.models.device import Fido2Device

from ..exceptions import SysCallError
from ..general import SysCommand, SysCommandWorker, clear_vt100_escape_codes_from_str
Expand Down Expand Up @@ -36,7 +36,10 @@ def get_fido2_devices(cls) -> list[Fido2Device]:

fido_devices = clear_vt100_escape_codes_from_str(ret)

for line in fido_devices.split('\r\n'):
if not fido_devices:
return []

for line in fido_devices.splitlines():
path, details = line.replace(',', '').split(':', maxsplit=1)
_, product, manufacturer = details.strip().split(' ', maxsplit=2)

Expand Down
2 changes: 1 addition & 1 deletion archinstall/lib/disk/filesystem.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

from ..interactions.general_conf import ask_abort
from ..luks import Luks2
from ..models.device_model import (
from ..models.device import (
DiskEncryption,
DiskLayoutConfiguration,
DiskLayoutType,
Expand Down
2 changes: 1 addition & 1 deletion archinstall/lib/disk/partitioning_menu.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from pathlib import Path
from typing import override

from archinstall.lib.models.device_model import (
from archinstall.lib.models.device import (
BtrfsMountOption,
DeviceModification,
FilesystemType,
Expand Down
2 changes: 1 addition & 1 deletion archinstall/lib/disk/subvolume_menu.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from pathlib import Path
from typing import assert_never, override

from archinstall.lib.models.device_model import SubvolumeModification
from archinstall.lib.models.device import SubvolumeModification
from archinstall.lib.translationhandler import tr
from archinstall.tui.curses_menu import EditMenu
from archinstall.tui.result import ResultType
Expand Down
2 changes: 1 addition & 1 deletion archinstall/lib/disk/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

from archinstall.lib.exceptions import DiskError, SysCallError
from archinstall.lib.general import SysCommand
from archinstall.lib.models.device_model import LsblkInfo
from archinstall.lib.models.device import LsblkInfo
from archinstall.lib.output import debug, warn


Expand Down
42 changes: 16 additions & 26 deletions archinstall/lib/global_menu.py
Original file line number Diff line number Diff line change
@@ -1,43 +1,44 @@
from __future__ import annotations

from typing import override

from archinstall.lib.disk.disk_menu import DiskLayoutConfigurationMenu
from archinstall.lib.models.application import ApplicationConfiguration
from archinstall.lib.models.authentication import AuthenticationConfiguration
from archinstall.lib.models.device_model import DiskLayoutConfiguration, DiskLayoutType, EncryptionType, FilesystemType, PartitionModification
from archinstall.lib.models.device import DiskLayoutConfiguration, DiskLayoutType, EncryptionType, FilesystemType, PartitionModification
from archinstall.lib.packages import list_available_packages
from archinstall.tui.menu_item import MenuItem, MenuItemGroup

from .applications.application_menu import ApplicationMenu
from .args import ArchConfig
from .authentication.authentication_menu import AuthenticationMenu
from .configuration import save_config
from .hardware import SysInfo
from .interactions.general_conf import (
add_number_of_parallel_downloads,
ask_additional_packages_to_install,
ask_for_a_timezone,
ask_hostname,
ask_ntp,
)
from .interactions.manage_users_conf import ask_for_additional_users
from .interactions.network_menu import ask_to_configure_network
from .interactions.system_conf import ask_for_bootloader, ask_for_swap, ask_for_uki, select_kernel
from .locale.locale_menu import LocaleMenu
from .menu.abstract_menu import CONFIG_KEY, AbstractMenu
from .mirrors import MirrorMenu
from .models.bootloader import Bootloader
from .models.locale import LocaleConfiguration
from .models.mirrors import MirrorConfiguration
from .models.network_configuration import NetworkConfiguration, NicType
from .models.packages import Repository
from .models.profile_model import ProfileConfiguration
from .models.profile import ProfileConfiguration
from .models.users import Password, User

Check failure on line 36 in archinstall/lib/global_menu.py

View workflow job for this annotation

GitHub Actions / ruff_format_check

Ruff (F401)

archinstall/lib/global_menu.py:36:27: F401 `.models.users.Password` imported but unused

Check failure on line 36 in archinstall/lib/global_menu.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (F401)

archinstall/lib/global_menu.py:36:27: F401 `.models.users.Password` imported but unused
from .models.profile_model import ProfileConfiguration

Check failure on line 37 in archinstall/lib/global_menu.py

View workflow job for this annotation

GitHub Actions / ruff_format_check

Ruff (F811)

archinstall/lib/global_menu.py:37:35: F811 Redefinition of unused `ProfileConfiguration` from line 35

Check failure on line 37 in archinstall/lib/global_menu.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (F811)

archinstall/lib/global_menu.py:37:35: F811 Redefinition of unused `ProfileConfiguration` from line 35
from .models.users import User

Check failure on line 38 in archinstall/lib/global_menu.py

View workflow job for this annotation

GitHub Actions / ruff_format_check

Ruff (F811)

archinstall/lib/global_menu.py:38:27: F811 Redefinition of unused `User` from line 36

Check failure on line 38 in archinstall/lib/global_menu.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (F811)

archinstall/lib/global_menu.py:38:27: F811 Redefinition of unused `User` from line 36
from .output import FormattedOutput
from .pacman.config import PacmanConfig
from .translationhandler import Language, tr, translation_handler

Check failure on line 41 in archinstall/lib/global_menu.py

View workflow job for this annotation

GitHub Actions / ruff_format_check

Ruff (I001)

archinstall/lib/global_menu.py:1:1: I001 Import block is un-sorted or un-formatted

Check failure on line 41 in archinstall/lib/global_menu.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (I001)

archinstall/lib/global_menu.py:1:1: I001 Import block is un-sorted or un-formatted
from .utils.util import get_password


class GlobalMenu(AbstractMenu[None]):
Expand Down Expand Up @@ -110,16 +111,9 @@
preview_action=self._prev_hostname,
key='hostname',
),
MenuItem(
text=tr('Root password'),
action=self._set_root_password,
preview_action=self._prev_root_pwd,
key='root_enc_password',
),
MenuItem(
text=tr('Authentication'),
action=self._select_authentication,
value=[],
preview_action=self._prev_authentication,
key='auth_config',
),
Expand Down Expand Up @@ -230,13 +224,16 @@

missing = set()

item: MenuItem = self._item_group.find_by_key('auth_config')
auth_config: AuthenticationConfiguration | None = item.value

if (auth_config is None or auth_config.root_enc_password is None) and not has_superuser():
missing.add(
tr('Either root-password or at least 1 user with sudo privileges must be specified'),
)

for item in self._item_group.items:
if item.key in ['root_enc_password', 'users']:
if not check('root_enc_password') and not has_superuser():
missing.add(
tr('Either root-password or at least 1 user with sudo privileges must be specified'),
)
elif item.mandatory:
if item.mandatory:
assert item.key is not None
if not check(item.key):
missing.add(item.text)
Expand Down Expand Up @@ -314,6 +311,9 @@
auth_config: AuthenticationConfiguration = item.value
output = ''

if auth_config.root_enc_password:
output += f'{tr("Root password")}: {auth_config.root_enc_password.hidden()}\n'

if auth_config.u2f_config:
u2f_config = auth_config.u2f_config
login_method = u2f_config.u2f_login_method.display_value()
Expand Down Expand Up @@ -400,12 +400,6 @@
return f'{tr("Hostname")}: {item.value}'
return None

def _prev_root_pwd(self, item: MenuItem) -> str | None:
if item.value is not None:
password: Password = item.value
return f'{tr("Root password")}: {password.hidden()}'
return None

def _prev_parallel_dw(self, item: MenuItem) -> str | None:
if item.value is not None:
return f'{tr("Parallel Downloads")}: {item.value}'
Expand Down Expand Up @@ -510,10 +504,6 @@

return None

def _set_root_password(self, preset: str | None = None) -> Password | None:
password = get_password(text=tr('Root password'), allow_skip=True)
return password

def _select_disk_config(
self,
preset: DiskLayoutConfiguration | None = None,
Expand Down
7 changes: 4 additions & 3 deletions archinstall/lib/installer.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
from archinstall.lib.disk.device_handler import device_handler
from archinstall.lib.disk.fido import Fido2
from archinstall.lib.disk.utils import get_lsblk_by_mountpoint, get_lsblk_info
from archinstall.lib.models.device_model import (
from archinstall.lib.models.device import (
DiskEncryption,
DiskLayoutConfiguration,
EncryptionType,
Expand Down Expand Up @@ -956,6 +956,7 @@ def setup_btrfs_snapshot(

if bootloader and bootloader == Bootloader.Grub:
self.pacman.strap('grub-btrfs')
self.pacman.strap('inotify-tools')
self.enable_service('grub-btrfsd.service')

def setup_swap(self, kind: str = 'zram') -> None:
Expand Down Expand Up @@ -1506,7 +1507,7 @@ def _add_efistub_bootloader(

parent_dev_path = device_handler.get_parent_device_path(boot_partition.safe_dev_path)

cmd_template = [
cmd_template = (
'efibootmgr',
'--create',
'--disk',
Expand All @@ -1520,7 +1521,7 @@ def _add_efistub_bootloader(
'--unicode',
*cmdline,
'--verbose',
]
)

for kernel in self.kernels:
# Setup the firmware entry
Expand Down
2 changes: 1 addition & 1 deletion archinstall/lib/interactions/disk_conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from archinstall.lib.disk.device_handler import device_handler
from archinstall.lib.disk.partitioning_menu import manual_partitioning
from archinstall.lib.menu.menu_helper import MenuHelper
from archinstall.lib.models.device_model import (
from archinstall.lib.models.device import (
BDevice,
BtrfsMountOption,
DeviceModification,
Expand Down
2 changes: 1 addition & 1 deletion archinstall/lib/luks.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from types import TracebackType

from archinstall.lib.disk.utils import get_lsblk_info, umount
from archinstall.lib.models.device_model import DEFAULT_ITER_TIME
from archinstall.lib.models.device import DEFAULT_ITER_TIME

from .exceptions import DiskError, SysCallError
from .general import SysCommand, SysCommandWorker, generate_password, run
Expand Down
Loading
Loading