diff --git a/.github/workflows/ruff-format.yaml b/.github/workflows/ruff-format.yaml index 9897145b29..ad6650ab93 100644 --- a/.github/workflows/ruff-format.yaml +++ b/.github/workflows/ruff-format.yaml @@ -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 diff --git a/.github/workflows/ruff-lint.yaml b/.github/workflows/ruff-lint.yaml index 5d11a5982b..7f9c5df0dd 100644 --- a/.github/workflows/ruff-lint.yaml +++ b/.github/workflows/ruff-lint.yaml @@ -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 diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index a2df56069c..93dbd44bed 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -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 @@ -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: [ diff --git a/archinstall/lib/args.py b/archinstall/lib/args.py index 85d8914a3a..b255d1cceb 100644 --- a/archinstall/lib/args.py +++ b/archinstall/lib/args.py @@ -16,13 +16,15 @@ 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 +from archinstall.lib.models.users import Password, User, UserSerialization 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 @@ -78,14 +80,15 @@ class ArchConfig: # 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: @@ -222,11 +225,17 @@ def from_config(cls, args_config: dict[str, Any]) -> 'ArchConfig': 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 diff --git a/archinstall/lib/authentication/authentication_menu.py b/archinstall/lib/authentication/authentication_menu.py index e8852bbb74..9180e82fe9 100644 --- a/archinstall/lib/authentication/authentication_menu.py +++ b/archinstall/lib/authentication/authentication_menu.py @@ -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 @@ -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: @@ -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)) diff --git a/archinstall/lib/disk/device_handler.py b/archinstall/lib/disk/device_handler.py index 836c64a1f4..8492ed14ae 100644 --- a/archinstall/lib/disk/device_handler.py +++ b/archinstall/lib/disk/device_handler.py @@ -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, diff --git a/archinstall/lib/disk/disk_menu.py b/archinstall/lib/disk/disk_menu.py index ddbaf047e6..35ad1503fd 100644 --- a/archinstall/lib/disk/disk_menu.py +++ b/archinstall/lib/disk/disk_menu.py @@ -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, diff --git a/archinstall/lib/disk/encryption_menu.py b/archinstall/lib/disk/encryption_menu.py index 151f14236c..9375a06b1f 100644 --- a/archinstall/lib/disk/encryption_menu.py +++ b/archinstall/lib/disk/encryption_menu.py @@ -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, @@ -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 diff --git a/archinstall/lib/disk/fido.py b/archinstall/lib/disk/fido.py index b6676db41d..a46f1405e8 100644 --- a/archinstall/lib/disk/fido.py +++ b/archinstall/lib/disk/fido.py @@ -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 @@ -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) diff --git a/archinstall/lib/disk/filesystem.py b/archinstall/lib/disk/filesystem.py index e1f9504302..432b3ecfeb 100644 --- a/archinstall/lib/disk/filesystem.py +++ b/archinstall/lib/disk/filesystem.py @@ -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, diff --git a/archinstall/lib/disk/partitioning_menu.py b/archinstall/lib/disk/partitioning_menu.py index ff33ce1c43..baac9f7745 100644 --- a/archinstall/lib/disk/partitioning_menu.py +++ b/archinstall/lib/disk/partitioning_menu.py @@ -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, diff --git a/archinstall/lib/disk/subvolume_menu.py b/archinstall/lib/disk/subvolume_menu.py index af448a30e3..5b66334cc7 100644 --- a/archinstall/lib/disk/subvolume_menu.py +++ b/archinstall/lib/disk/subvolume_menu.py @@ -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 diff --git a/archinstall/lib/disk/utils.py b/archinstall/lib/disk/utils.py index fa9f3c3173..95a0871f54 100644 --- a/archinstall/lib/disk/utils.py +++ b/archinstall/lib/disk/utils.py @@ -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 diff --git a/archinstall/lib/global_menu.py b/archinstall/lib/global_menu.py index f0df3ef4c5..e86e537c01 100644 --- a/archinstall/lib/global_menu.py +++ b/archinstall/lib/global_menu.py @@ -5,7 +5,7 @@ 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 @@ -32,12 +32,13 @@ 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 +from .models.profile_model import ProfileConfiguration +from .models.users import User from .output import FormattedOutput from .pacman.config import PacmanConfig from .translationhandler import Language, tr, translation_handler -from .utils.util import get_password class GlobalMenu(AbstractMenu[None]): @@ -110,16 +111,9 @@ def _get_menu_options(self) -> list[MenuItem]: 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', ), @@ -230,13 +224,16 @@ def has_superuser() -> bool: 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) @@ -314,6 +311,9 @@ def _prev_authentication(self, item: MenuItem) -> str | None: 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() @@ -400,12 +400,6 @@ def _prev_hostname(self, item: MenuItem) -> str | None: 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}' @@ -510,10 +504,6 @@ def _prev_profile(self, item: MenuItem) -> str | None: 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, diff --git a/archinstall/lib/installer.py b/archinstall/lib/installer.py index 652482ed49..96d642fbbb 100644 --- a/archinstall/lib/installer.py +++ b/archinstall/lib/installer.py @@ -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, @@ -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: @@ -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', @@ -1520,7 +1521,7 @@ def _add_efistub_bootloader( '--unicode', *cmdline, '--verbose', - ] + ) for kernel in self.kernels: # Setup the firmware entry diff --git a/archinstall/lib/interactions/disk_conf.py b/archinstall/lib/interactions/disk_conf.py index 3a75624cbe..1f3497869a 100644 --- a/archinstall/lib/interactions/disk_conf.py +++ b/archinstall/lib/interactions/disk_conf.py @@ -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, diff --git a/archinstall/lib/luks.py b/archinstall/lib/luks.py index 5845f84330..075bef9e6f 100644 --- a/archinstall/lib/luks.py +++ b/archinstall/lib/luks.py @@ -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 diff --git a/archinstall/lib/models/__init__.py b/archinstall/lib/models/__init__.py index 74ca3b67cc..b938543001 100644 --- a/archinstall/lib/models/__init__.py +++ b/archinstall/lib/models/__init__.py @@ -5,7 +5,7 @@ BluetoothConfiguration, ) from .bootloader import Bootloader -from .device_model import ( +from .device import ( BDevice, DeviceGeometry, DeviceModification, @@ -36,7 +36,7 @@ from .mirrors import CustomRepository, MirrorConfiguration, MirrorRegion from .network_configuration import NetworkConfiguration, Nic, NicType from .packages import LocalPackage, PackageSearch, PackageSearchResult, Repository -from .profile_model import ProfileConfiguration +from .profile import ProfileConfiguration from .users import PasswordStrength, User __all__ = [ diff --git a/archinstall/lib/models/authentication.py b/archinstall/lib/models/authentication.py index 6683181323..74ead43ce1 100644 --- a/archinstall/lib/models/authentication.py +++ b/archinstall/lib/models/authentication.py @@ -2,6 +2,7 @@ from enum import Enum from typing import Any, NotRequired, TypedDict +from archinstall.lib.models.users import Password from archinstall.lib.translationhandler import tr @@ -58,6 +59,7 @@ def parse_arg(args: U2FLoginConfigSerialization) -> 'U2FLoginConfiguration | Non @dataclass class AuthenticationConfiguration: + root_enc_password: Password | None = None u2f_config: U2FLoginConfiguration | None = None @staticmethod @@ -67,6 +69,9 @@ def parse_arg(args: dict[str, Any]) -> 'AuthenticationConfiguration': if (u2f_config := args.get('u2f_config')) is not None: auth_config.u2f_config = U2FLoginConfiguration.parse_arg(u2f_config) + if enc_password := args.get('root_enc_password'): + auth_config.root_enc_password = Password(enc_password=enc_password) + return auth_config def json(self) -> AuthenticationSerialization: diff --git a/archinstall/lib/models/device_model.py b/archinstall/lib/models/device.py similarity index 100% rename from archinstall/lib/models/device_model.py rename to archinstall/lib/models/device.py diff --git a/archinstall/lib/models/network_configuration.py b/archinstall/lib/models/network_configuration.py index e470ec8341..993169d826 100644 --- a/archinstall/lib/models/network_configuration.py +++ b/archinstall/lib/models/network_configuration.py @@ -6,7 +6,7 @@ from archinstall.lib.translationhandler import tr -from ..models.profile_model import ProfileConfiguration +from ..models.profile import ProfileConfiguration if TYPE_CHECKING: from archinstall.lib.installer import Installer diff --git a/archinstall/lib/models/profile_model.py b/archinstall/lib/models/profile.py similarity index 100% rename from archinstall/lib/models/profile_model.py rename to archinstall/lib/models/profile.py diff --git a/archinstall/lib/models/users.py b/archinstall/lib/models/users.py index e6a338410a..3f18f52d09 100644 --- a/archinstall/lib/models/users.py +++ b/archinstall/lib/models/users.py @@ -100,8 +100,8 @@ def _check_password_strength( return PasswordStrength.VERY_WEAK -_UserSerialization = TypedDict( - '_UserSerialization', +UserSerialization = TypedDict( + 'UserSerialization', { 'username': str, '!password': NotRequired[str], @@ -173,7 +173,7 @@ def table_data(self) -> dict[str, str | bool | list[str]]: 'groups': self.groups, } - def json(self) -> _UserSerialization: + def json(self) -> UserSerialization: return { 'username': self.username, 'enc_password': self.password.enc_password, @@ -184,7 +184,7 @@ def json(self) -> _UserSerialization: @classmethod def parse_arguments( cls, - args: list[_UserSerialization], + args: list[UserSerialization], ) -> list['User']: users: list[User] = [] diff --git a/archinstall/lib/profile/profile_menu.py b/archinstall/lib/profile/profile_menu.py index 882b47e3c1..ca12246cc8 100644 --- a/archinstall/lib/profile/profile_menu.py +++ b/archinstall/lib/profile/profile_menu.py @@ -12,7 +12,7 @@ from ..hardware import GfxDriver from ..interactions.system_conf import select_driver from ..menu.abstract_menu import AbstractSubMenu -from ..models.profile_model import ProfileConfiguration +from ..models.profile import ProfileConfiguration class ProfileMenu(AbstractSubMenu[ProfileConfiguration]): diff --git a/archinstall/lib/profile/profiles_handler.py b/archinstall/lib/profile/profiles_handler.py index 25522240e2..0043e704e3 100644 --- a/archinstall/lib/profile/profiles_handler.py +++ b/archinstall/lib/profile/profiles_handler.py @@ -14,7 +14,7 @@ from ...default_profiles.profile import GreeterType, Profile from ..hardware import GfxDriver -from ..models.profile_model import ProfileConfiguration +from ..models.profile import ProfileConfiguration from ..networking import fetch_data_from_url, list_interfaces from ..output import debug, error, info @@ -164,7 +164,7 @@ def remove_custom_profiles(self, profiles: Profile | list[Profile]) -> None: self._profiles = [p for p in self.profiles if p.name not in remove_names] def get_profile_by_name(self, name: str) -> Profile | None: - return next(filter(lambda x: x.name == name, self.profiles), None) # type: ignore[arg-type, union-attr] + return next(filter(lambda x: x.name == name, self.profiles), None) def get_top_level_profiles(self) -> list[Profile]: return [p for p in self.profiles if p.is_top_level_profile()] diff --git a/archinstall/locales/base.pot b/archinstall/locales/base.pot index 2b5602aef8..f18f2f48e3 100644 --- a/archinstall/locales/base.pot +++ b/archinstall/locales/base.pot @@ -971,9 +971,6 @@ msgstr "" msgid "Default: 10000ms, Recommended range: 1000-60000" msgstr "" -msgid "Iteration time" -msgstr "" - msgid "Iteration time cannot be empty" msgstr "" diff --git a/archinstall/locales/it/LC_MESSAGES/base.mo b/archinstall/locales/it/LC_MESSAGES/base.mo index 85f95c1bed..b71071a9d0 100644 Binary files a/archinstall/locales/it/LC_MESSAGES/base.mo and b/archinstall/locales/it/LC_MESSAGES/base.mo differ diff --git a/archinstall/locales/it/LC_MESSAGES/base.po b/archinstall/locales/it/LC_MESSAGES/base.po index 36b533a8f9..398eadd0cb 100644 --- a/archinstall/locales/it/LC_MESSAGES/base.po +++ b/archinstall/locales/it/LC_MESSAGES/base.po @@ -2,7 +2,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2025-05-04 21:57+0200\n" +"PO-Revision-Date: 2025-07-02 21:31+0200\n" "Last-Translator: Van Matten\n" "Language-Team: \n" "Language: it\n" @@ -75,7 +75,7 @@ msgid "Select which mode to configure for \"{}\" or skip to use default mode \"{ msgstr "Seleziona la modalità da configurare per \"{}\" o salta per utilizzare la modalità predefinita \"{}\"" msgid "Enter the IP and subnet for {} (example: 192.168.0.5/24): " -msgstr "Immetti l'IP e la sottorete per {} (esempio: 192.168.0.5/24): " +msgstr "Inserisci l'IP e la sottorete per {} (esempio: 192.168.0.5/24): " msgid "Enter your gateway (router) IP address or leave blank for none: " msgstr "Inserisci l'indirizzo IP del tuo gateway (router) o lascia vuoto per nessuno: " @@ -97,7 +97,7 @@ msgstr "" "{}" msgid "Enter a desired filesystem type for the partition" -msgstr "Immetti un tipo di filesystem desiderato per la partizione" +msgstr "Inserisci un tipo di filesystem desiderato per la partizione" msgid "Enter the start location (in parted units: s, GB, %, etc. ; default: {}): " msgstr "Inserisci la posizione iniziale (in unità separate: s, GB, %, ecc.; impostazione predefinita: {}): " @@ -169,7 +169,7 @@ msgstr "" "Seleziona su quale partizione impostare un filesystem" msgid "Enter a desired filesystem type for the partition: " -msgstr "Immetti un tipo di filesystem desiderato per la partizione: " +msgstr "Inserisci un tipo di filesystem desiderato per la partizione: " msgid "Archinstall language" msgstr "Lingua di Archinstall" @@ -518,7 +518,7 @@ msgid "Choose which configuration to save" msgstr "Scegli quale configurazione salvare" msgid "Enter a directory for the configuration(s) to be saved: " -msgstr "Immetti una directory per le configurazioni da salvare: " +msgstr "Inserisci una directory per le configurazioni da salvare: " msgid "Not a valid directory: {}" msgstr "Directory non valida: {}" @@ -650,9 +650,8 @@ msgstr "Seleziona/Deseleziona una partizione come compressa (solo btrfs)" msgid "The password you are using seems to be weak, are you sure you want to use it?" msgstr "La password che stai utilizzando sembra essere debole, sei sicuro di volerla usare?" -#, fuzzy msgid "Provides a selection of desktop environments and tiling window managers, e.g. gnome, kde, sway" -msgstr "Fornisce una selezione di ambienti desktop e gestori di finestre tile, per esempio gnome, kde, sway" +msgstr "Fornisce una selezione di ambienti desktop e gestori di finestre, per esempio gnome, kde, sway" msgid "Select your desired desktop environment" msgstr "Seleziona l'ambiente desktop desiderato" @@ -865,7 +864,7 @@ msgid "Select a partitioning option" msgstr "Selezione opzione di partizionamento" msgid "Enter the root directory of the mounted devices: " -msgstr "Inserisci la directory principale del dispositivo montato: " +msgstr "Inserisci la directory principale dei dispositivi montati: " msgid "Minimum capacity for /home partition: {}GiB\n" msgstr "Capacità minima per la partizione /home: {}GiB\n" @@ -942,6 +941,30 @@ msgstr "Lunghezza totale: {}" msgid "Encryption type" msgstr "Tipo di crittografia" +msgid "Iteration time" +msgstr "Tempo di iterazione" + +msgid "Enter iteration time for LUKS encryption (in milliseconds)" +msgstr "Inserisci il tempo di iterazione per la crittografia LUKS (in millisecondi)" + +msgid "Higher values increase security but slow down boot time" +msgstr "Valori alti aumentano la sicurezza ma rallentano l'avvio" + +msgid "Default: 10000ms, Recommended range: 1000-60000" +msgstr "Predefinito: 10000 ms, Intervallo consigliato: 1000-60000" + +msgid "Iteration time cannot be empty" +msgstr "Il tempo di iterazione non può essere vuoto" + +msgid "Iteration time must be at least 100ms" +msgstr "Il tempo di iterazione deve essere almeno 100 ms" + +msgid "Iteration time must be at most 120000ms" +msgstr "Il tempo di iterazione deve essere al massimo 120000 ms" + +msgid "Please enter a valid number" +msgstr "Inserisci un numero valido" + msgid "Partitions" msgstr "Partizioni" @@ -1109,7 +1132,7 @@ msgid "" "Enter a directory for the configuration(s) to be saved (tab completion enabled)\n" "Save directory: " msgstr "" -"Immetti una directory per le configurazioni da salvare: (completamento col tasto tab abilitato)\n" +"Inserisci una directory per le configurazioni da salvare: (completamento col tasto tab abilitato)\n" "Directory di salvataggio: " msgid "" @@ -1248,9 +1271,8 @@ msgstr "Usa la compressione" msgid "Disable Copy-on-Write" msgstr "Disabilita Copy-on-Write" -#, fuzzy msgid "Provides a selection of desktop environments and tiling window managers, e.g. GNOME, KDE Plasma, Sway" -msgstr "Fornisce una selezione di ambienti desktop e gestori di finestre tile, per esempio GNOME, KDE Plasma, Sway" +msgstr "Fornisce una selezione di ambienti desktop e gestori di finestre, per esempio GNOME, KDE Plasma, Sway" msgid "Configuration type: {}" msgstr "Tipo configurazione: {}" @@ -1357,9 +1379,8 @@ msgstr "Nome del sottovolume" msgid "Disk configuration type" msgstr "Tipo configurazione disco" -#, fuzzy msgid "Root mount directory" -msgstr "Cartella montata di root" +msgstr "Cartella di montaggio di root" msgid "Select language" msgstr "Seleziona lingua" @@ -1367,11 +1388,9 @@ msgstr "Seleziona lingua" msgid "Write additional packages to install (space separated, leave blank to skip)" msgstr "Scrivi i pacchetti aggiuntivi da installare (separati da spazi, lascia vuoto per saltare)" -#, fuzzy msgid "Invalid download number" msgstr "Numero di download non valido" -#, fuzzy msgid "Number downloads" msgstr "Numero di download" @@ -1408,9 +1427,8 @@ msgstr "Inserisci i tuoi server DNS (separati da spazi, vuoto per nessuno)" msgid "DNS servers" msgstr "Server DNS" -#, fuzzy msgid "Configure interfaces" -msgstr "Configura interfacce" +msgstr "Configurazione interfacce" msgid "Kernel" msgstr "Kernel" @@ -1446,7 +1464,7 @@ msgid "Directory" msgstr "Cartella" msgid "Enter a directory for the configuration(s) to be saved (tab completion enabled)" -msgstr "Immetti una cartella dove salvare le configurazioni (completamento col tasto tab abilitato)" +msgstr "Inserisci una cartella dove salvare le configurazioni (completamento col tasto tab abilitato)" msgid "Do you want to save the configuration file(s) to {}?" msgstr "Vuoi salvare i file di configurazione in {}?" @@ -1493,9 +1511,8 @@ msgstr "Nome" msgid "Signature check" msgstr "Controllo della firma" -#, fuzzy msgid "Selected free space segment on device {}:" -msgstr "Spazio libero del segmento selezionato sul dispositivo {}:" +msgstr "Segmento di spazio libero selezionato sul dispositivo {}:" msgid "Size: {} / {}" msgstr "Dimensione: {} / {}" @@ -1602,9 +1619,8 @@ msgstr "Muovi a destra" msgid "Move left" msgstr "Muovi a sinistra" -#, fuzzy msgid "Jump to entry" -msgstr "Vai al successivo" +msgstr "Vai alla voce" msgid "Skip selection (if available)" msgstr "Salta selezione (se disponibile)" @@ -1645,9 +1661,8 @@ msgstr "Scegli un’opzione per concedere a niri l’accesso al tuo hardware" msgid "Mark/Unmark as ESP" msgstr "Contrassegna/Deseleziona come ESP" -#, fuzzy msgid "Package group:" -msgstr "Gruppo pacchetto:" +msgstr "Gruppo di pacchetti:" msgid "Exit archinstall" msgstr "Esci da archinstall" @@ -1682,6 +1697,5 @@ msgstr "Vuoi criptare il file di user_credentials.json?" msgid "Credentials file encryption password" msgstr "Password di crittazione del file delle credenziali" -#, fuzzy msgid "Repositories: {}" -msgstr "Nome repository" +msgstr "Repository: {}" diff --git a/archinstall/locales/ja/LC_MESSAGES/base.mo b/archinstall/locales/ja/LC_MESSAGES/base.mo index a489476278..714febb2ad 100644 Binary files a/archinstall/locales/ja/LC_MESSAGES/base.mo and b/archinstall/locales/ja/LC_MESSAGES/base.mo differ diff --git a/archinstall/locales/ja/LC_MESSAGES/base.po b/archinstall/locales/ja/LC_MESSAGES/base.po index d46c3d59d3..e031ea0020 100644 --- a/archinstall/locales/ja/LC_MESSAGES/base.po +++ b/archinstall/locales/ja/LC_MESSAGES/base.po @@ -938,6 +938,30 @@ msgstr "全体のサイズ: {}" msgid "Encryption type" msgstr "暗号化のタイプ" +msgid "Iteration time" +msgstr "反復時間" + +msgid "Enter iteration time for LUKS encryption (in milliseconds)" +msgstr "LUKS 暗号化のイテレーション時間(ミリ秒単位)を入力" + +msgid "Higher values increase security but slow down boot time" +msgstr "値を大きくするとセキュリティは向上しますが、起動時間が遅くなります" + +msgid "Default: 10000ms, Recommended range: 1000-60000" +msgstr "デフォルト: 10000ms, 推奨範囲: 1000-60000" + +msgid "Iteration time cannot be empty" +msgstr "イテレーション時間は空にできません" + +msgid "Iteration time must be at least 100ms" +msgstr "イテレーション時間は最低 100ms にしてください" + +msgid "Iteration time must be at most 120000ms" +msgstr "イテレーション時間は最大 120000ms にしてください" + +msgid "Please enter a valid number" +msgstr "有効な数字を入力してください" + msgid "Partitions" msgstr "パーティション" diff --git a/archinstall/scripts/guided.py b/archinstall/scripts/guided.py index 2c2173a760..6de7fe099f 100644 --- a/archinstall/scripts/guided.py +++ b/archinstall/scripts/guided.py @@ -12,7 +12,7 @@ from archinstall.lib.installer import Installer, accessibility_tools_in_use, run_custom_user_commands from archinstall.lib.interactions.general_conf import PostInstallationAction, ask_post_installation from archinstall.lib.models import Bootloader -from archinstall.lib.models.device_model import ( +from archinstall.lib.models.device import ( DiskLayoutType, EncryptionType, ) @@ -138,8 +138,8 @@ def perform_installation(mountpoint: Path) -> None: if accessibility_tools_in_use(): installation.enable_espeakup() - if root_pw := config.root_enc_password: - root_user = User('root', root_pw, False) + if config.auth_config and config.auth_config.root_enc_password: + root_user = User('root', config.auth_config.root_enc_password, False) installation.set_user_password(root_user) if (profile_config := config.profile_config) and profile_config.profile: diff --git a/archinstall/scripts/minimal.py b/archinstall/scripts/minimal.py index fe52334467..18bcaaa941 100644 --- a/archinstall/scripts/minimal.py +++ b/archinstall/scripts/minimal.py @@ -7,7 +7,7 @@ from archinstall.lib.disk.filesystem import FilesystemHandler from archinstall.lib.installer import Installer from archinstall.lib.models import Bootloader -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.output import debug, error, info from archinstall.lib.profile.profiles_handler import profile_handler diff --git a/docs/examples/python.rst b/docs/examples/python.rst index 59f27f00a2..9050b9bcb4 100644 --- a/docs/examples/python.rst +++ b/docs/examples/python.rst @@ -53,9 +53,9 @@ After running ``python -m archinstall test_installer`` it should print something total_size=Size(value=512110190592, unit=, sector_size=SectorSize(value=512, unit=)), free_space_regions=[ - , - , - ], + , + , + ], sector_size=SectorSize(value=512, unit=), read_only=False, dirty=False diff --git a/examples/auto_discovery_mounted.py b/examples/auto_discovery_mounted.py index df792bb2b0..51180504be 100644 --- a/examples/auto_discovery_mounted.py +++ b/examples/auto_discovery_mounted.py @@ -1,7 +1,7 @@ from pathlib import Path from archinstall.lib.disk.device_handler import device_handler -from archinstall.lib.models.device_model import DiskLayoutConfiguration, DiskLayoutType +from archinstall.lib.models.device import DiskLayoutConfiguration, DiskLayoutType root_mount_dir = Path('/mnt/archinstall') diff --git a/examples/full_automated_installation.py b/examples/full_automated_installation.py index d172978388..760d492689 100644 --- a/examples/full_automated_installation.py +++ b/examples/full_automated_installation.py @@ -4,7 +4,7 @@ from archinstall.lib.disk.device_handler import device_handler from archinstall.lib.disk.filesystem import FilesystemHandler from archinstall.lib.installer import Installer -from archinstall.lib.models.device_model import ( +from archinstall.lib.models.device import ( DeviceModification, DiskEncryption, DiskLayoutConfiguration, @@ -18,7 +18,7 @@ Size, Unit, ) -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.profile.profiles_handler import profile_handler diff --git a/pyproject.toml b/pyproject.toml index 847ca275e3..0aa16f3c97 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -31,10 +31,10 @@ Source = "https://github.com/archlinux/archinstall" [project.optional-dependencies] log = ["systemd_python==235"] dev = [ - "mypy==1.16.1", + "mypy==1.17.0", "flake8==7.3.0", "pre-commit==4.2.0", - "ruff==0.12.1", + "ruff==0.12.3", "pylint==3.3.7", "pylint-pydantic==0.3.5", "pytest==8.4.1", diff --git a/tests/test_args.py b/tests/test_args.py index 5a6d61f0bb..3feb0f9f50 100644 --- a/tests/test_args.py +++ b/tests/test_args.py @@ -9,12 +9,12 @@ from archinstall.lib.models.application import ApplicationConfiguration, Audio, AudioConfiguration, BluetoothConfiguration from archinstall.lib.models.authentication import AuthenticationConfiguration, U2FLoginConfiguration, U2FLoginMethod from archinstall.lib.models.bootloader import Bootloader -from archinstall.lib.models.device_model import DiskLayoutConfiguration, DiskLayoutType +from archinstall.lib.models.device import DiskLayoutConfiguration, DiskLayoutType from archinstall.lib.models.locale import LocaleConfiguration from archinstall.lib.models.mirrors import CustomRepository, CustomServer, MirrorConfiguration, MirrorRegion, SignCheck, SignOption from archinstall.lib.models.network_configuration import NetworkConfiguration, Nic, NicType 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.profile.profiles_handler import profile_handler from archinstall.lib.translationhandler import translation_handler @@ -134,6 +134,7 @@ def test_config_file_parsing( audio_config=AudioConfiguration(audio=Audio.PIPEWIRE), ), auth_config=AuthenticationConfiguration( + root_enc_password=Password(enc_password='password_hash'), u2f_config=U2FLoginConfiguration( u2f_login_method=U2FLoginMethod.Passwordless, passwordless_sudo=True, @@ -223,7 +224,6 @@ def test_config_file_parsing( ), ], services=['service_1', 'service_2'], - root_enc_password=Password(enc_password='password_hash'), custom_commands=["echo 'Hello, World!'"], ) @@ -280,7 +280,8 @@ def test_deprecated_creds_config_parsing( handler = ArchConfigHandler() arch_config = handler.config - assert arch_config.root_enc_password == Password(plaintext='rootPwd') + assert arch_config.auth_config is not None + assert arch_config.auth_config.root_enc_password == Password(plaintext='rootPwd') assert arch_config.users == [ User( @@ -331,7 +332,8 @@ def test_encrypted_creds_with_arg( handler = ArchConfigHandler() arch_config = handler.config - assert arch_config.root_enc_password == Password(enc_password='$y$j9T$FWCInXmSsS.8KV4i7O50H.$Hb6/g.Sw1ry888iXgkVgc93YNuVk/Rw94knDKdPVQw7') + assert arch_config.auth_config is not None + assert arch_config.auth_config.root_enc_password == Password(enc_password='$y$j9T$FWCInXmSsS.8KV4i7O50H.$Hb6/g.Sw1ry888iXgkVgc93YNuVk/Rw94knDKdPVQw7') assert arch_config.users == [ User( username='t', @@ -359,7 +361,8 @@ def test_encrypted_creds_with_env_var( handler = ArchConfigHandler() arch_config = handler.config - assert arch_config.root_enc_password == Password(enc_password='$y$j9T$FWCInXmSsS.8KV4i7O50H.$Hb6/g.Sw1ry888iXgkVgc93YNuVk/Rw94knDKdPVQw7') + assert arch_config.auth_config is not None + assert arch_config.auth_config.root_enc_password == Password(enc_password='$y$j9T$FWCInXmSsS.8KV4i7O50H.$Hb6/g.Sw1ry888iXgkVgc93YNuVk/Rw94knDKdPVQw7') assert arch_config.users == [ User( username='t',