From 73d78b1aa908c49f4d57cd218057f8d51caa9ae5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rio=20Victor=20Ribeiro=20Silva?= Date: Wed, 10 Jun 2026 03:44:03 -0300 Subject: [PATCH 01/35] Add Plymouth configuration setup (#4555) * feat: add plymouth config * refactor: move plymouth to bootleader menu --- archinstall/lib/bootloader/bootloader_menu.py | 38 ++++++++++++++- archinstall/lib/installer.py | 33 +++++++++++-- archinstall/lib/models/bootloader.py | 46 +++++++++++++++++-- archinstall/scripts/guided.py | 1 + 4 files changed, 109 insertions(+), 9 deletions(-) diff --git a/archinstall/lib/bootloader/bootloader_menu.py b/archinstall/lib/bootloader/bootloader_menu.py index d32a5a21..64ad4c8d 100644 --- a/archinstall/lib/bootloader/bootloader_menu.py +++ b/archinstall/lib/bootloader/bootloader_menu.py @@ -3,7 +3,7 @@ from typing import override from archinstall.lib.menu.abstract_menu import AbstractSubMenu from archinstall.lib.menu.helpers import Confirmation, Selection -from archinstall.lib.models.bootloader import Bootloader, BootloaderConfiguration +from archinstall.lib.models.bootloader import Bootloader, BootloaderConfiguration, PlymouthTheme from archinstall.lib.translationhandler import tr from archinstall.tui.menu_item import MenuItem, MenuItemGroup from archinstall.tui.result import ResultType @@ -66,6 +66,13 @@ class BootloaderMenu(AbstractSubMenu[BootloaderConfiguration]): key='removable', enabled=removable_enabled, ), + MenuItem( + text=tr('Plymouth'), + action=self._select_plymouth, + value=self._bootloader_conf.plymouth, + preview_action=self._prev_plymouth, + key='plymouth', + ), ] def _prev_bootloader(self, item: MenuItem) -> str | None: @@ -85,6 +92,11 @@ class BootloaderMenu(AbstractSubMenu[BootloaderConfiguration]): return tr('Will install to /EFI/BOOT/ (removable location, safe default)') return tr('Will install to custom location with NVRAM entry') + def _prev_plymouth(self, item: MenuItem) -> str | None: + if item.value: + return f'{tr("Plymouth")}: {item.value.value}' + return None + @override async def show(self) -> BootloaderConfiguration: _ = await super().show() @@ -117,6 +129,9 @@ class BootloaderMenu(AbstractSubMenu[BootloaderConfiguration]): return bootloader + async def _select_plymouth(self, preset: PlymouthTheme | None) -> PlymouthTheme | None: + return await select_plymouth_theme(preset) + async def _select_uki(self, preset: bool) -> bool: prompt = tr('Would you like to use unified kernel images?') + '\n' @@ -215,3 +230,24 @@ async def select_bootloader( return result.get_value() case ResultType.Reset: raise ValueError('Unhandled result type') + + +async def select_plymouth_theme(preset: PlymouthTheme | None = None) -> PlymouthTheme | None: + items = [MenuItem(t.value, value=t) for t in PlymouthTheme] + group = MenuItemGroup(items, sort_items=False) + group.set_selected_by_value(preset.value if preset else None) + + result = await Selection[PlymouthTheme]( + group, + header=tr('Select Plymouth theme'), + allow_reset=True, + allow_skip=True, + ).show() + + match result.type_: + case ResultType.Skip: + return preset + case ResultType.Reset: + return None + case ResultType.Selection: + return PlymouthTheme(result.get_value()) diff --git a/archinstall/lib/installer.py b/archinstall/lib/installer.py index bf7d91ba..f53dcda4 100644 --- a/archinstall/lib/installer.py +++ b/archinstall/lib/installer.py @@ -32,7 +32,7 @@ from archinstall.lib.locale.utils import verify_keyboard_layout, verify_x11_keyb from archinstall.lib.log import debug, error, info, log, logger, warn from archinstall.lib.mirror.mirror_handler import MirrorListHandler from archinstall.lib.models.application import ZramAlgorithm -from archinstall.lib.models.bootloader import Bootloader, BootloaderConfiguration +from archinstall.lib.models.bootloader import Bootloader, BootloaderConfiguration, PlymouthTheme from archinstall.lib.models.device import ( DiskEncryption, DiskLayoutConfiguration, @@ -1755,6 +1755,28 @@ class Installer: self._helper_flags['bootloader'] = 'refind' + def _install_plymouth(self, plymouth: PlymouthTheme) -> None: + debug(f'Installing plymouth with theme: {plymouth.value}') + self.add_additional_packages(['plymouth']) + + for param in ('quiet', 'splash'): + if param not in self._kernel_params: + self._kernel_params.append(param) + + if 'plymouth' not in self._hooks: + for hook, insert_after in [('encrypt', False), ('sd-encrypt', False), ('systemd', True), ('filesystems', False), ('keyboard', True)]: + try: + idx = self._hooks.index(hook) + self._hooks.insert(idx + (1 if insert_after else 0), 'plymouth') + break + except ValueError: + continue + else: + self._hooks.append('plymouth') + + self.arch_chroot(f'plymouth-set-default-theme {plymouth.value}') + self.mkinitcpio(['-P']) + def _config_uki( self, root: PartitionModification | LvmVolume, @@ -1807,10 +1829,7 @@ class Installer: error('Error generating initramfs (continuing anyway)') def add_bootloader( - self, - bootloader: Bootloader, - uki_enabled: bool = False, - bootloader_removable: bool = False, + self, bootloader: Bootloader, uki_enabled: bool = False, bootloader_removable: bool = False, plymouth: PlymouthTheme | None = None ) -> None: """ Adds a bootloader to the installation instance. @@ -1824,6 +1843,7 @@ class Installer: :param bootloader: Type of bootloader to be added :param uki_enabled: Whether to use unified kernel images :param bootloader_removable: Whether to install to removable media location (UEFI only, for GRUB and Limine) + :param plymouth: Optional Plymouth theme to install and configure """ for plugin in plugins.values(): @@ -1859,6 +1879,9 @@ class Installer: warn(f'Bootloader {bootloader.value} lacks removable support; disabling.') bootloader_removable = False + if plymouth is not None: + self._install_plymouth(plymouth) + if uki_enabled: keep_initramfs = ( bootloader == Bootloader.Grub diff --git a/archinstall/lib/models/bootloader.py b/archinstall/lib/models/bootloader.py index bd6bce7e..040b6746 100644 --- a/archinstall/lib/models/bootloader.py +++ b/archinstall/lib/models/bootloader.py @@ -60,15 +60,48 @@ class Bootloader(Enum): return cls(bootloader) +class PlymouthTheme(Enum): + BGRT = 'bgrt' + FADE = 'fade-in' + GLOW = 'glow' + SCRIPT = 'script' + SOLAR = 'solar' + SPINNER = 'spinner' + SPINFINITY = 'spinfinity' + TRIBAR = 'tribar' + TEXT = 'text' + DETAILS = 'details' + + @classmethod + def from_arg(cls, plymouth: str | None) -> Self | None: + if plymouth is None: + return None + + plymouth = plymouth.lower() + + values = [e.value for e in cls] + + if plymouth not in values: + warn(f'Invalid plymouth value "{plymouth}". Allowed values: {", ".join(values)}') + sys.exit(1) + + return cls(plymouth) + + @dataclass class BootloaderConfiguration(SubConfig): bootloader: Bootloader uki: bool = False removable: bool = True + plymouth: PlymouthTheme | None = None @override def json(self) -> dict[str, Any]: - return {'bootloader': self.bootloader.json(), 'uki': self.uki, 'removable': self.removable} + data = {'bootloader': self.bootloader.json(), 'uki': self.uki, 'removable': self.removable} + + if self.plymouth is not None: + data['plymouth'] = self.plymouth.value + return data @override def summary(self) -> list[str]: @@ -78,6 +111,8 @@ class BootloaderConfiguration(SubConfig): out.append(tr('UKI enabled')) if self.removable: out.append(tr('Removable')) + if self.plymouth is not None: + out.append(tr('Plymouth "{}"').format(self.plymouth.value)) return out @@ -86,14 +121,16 @@ class BootloaderConfiguration(SubConfig): bootloader = Bootloader.from_arg(config.get('bootloader', ''), skip_boot) uki = config.get('uki', False) removable = config.get('removable', True) - return cls(bootloader=bootloader, uki=uki, removable=removable) + plymouth = PlymouthTheme.from_arg(config.get('plymouth', None)) + return cls(bootloader=bootloader, uki=uki, removable=removable, plymouth=plymouth) @classmethod def get_default(cls, uefi: bool, skip_boot: bool = False) -> Self: bootloader = Bootloader.get_default(uefi, skip_boot) removable = uefi and bootloader.has_removable_support() uki = uefi and bootloader.has_uki_support() - return cls(bootloader=bootloader, uki=uki, removable=removable) + plymouth = None + return cls(bootloader=bootloader, uki=uki, removable=removable, plymouth=plymouth) def preview(self, uefi: bool) -> str: text = f'{tr("Bootloader")}: {self.bootloader.value}' @@ -112,4 +149,7 @@ class BootloaderConfiguration(SubConfig): removable_string = tr('Disabled') text += f'{tr("Removable")}: {removable_string}' text += '\n' + if self.plymouth is not None: + text += f'{tr("Plymouth")}: {self.plymouth.value}' + text += '\n' return text diff --git a/archinstall/scripts/guided.py b/archinstall/scripts/guided.py index 29573a5f..775ed1fd 100644 --- a/archinstall/scripts/guided.py +++ b/archinstall/scripts/guided.py @@ -119,6 +119,7 @@ def perform_installation( config.bootloader_config.bootloader, config.bootloader_config.uki, config.bootloader_config.removable, + config.bootloader_config.plymouth, ) if config.network_config: From 091665a975eb3275c365ea375216e217d4169dfb Mon Sep 17 00:00:00 2001 From: Softer Date: Wed, 10 Jun 2026 09:56:17 +0300 Subject: [PATCH 02/35] Add users to seat group when seatd is selected (#4578) * Add users to seat group when seatd is selected When a desktop profile uses seatd for seat access, the user must be in the seat group for the compositor to access input devices. Without this, sway/hyprland/niri/labwc fail to start after installation. * Move seat access provisioning into DesktopProfile.provision() The four Wayland profiles (Hyprland, Sway, niri, labwc) each duplicated a provision() override calling provision_seat_access(). Move that into the base DesktopProfile.provision() loop, which already iterates the selected profiles, and read CustomSetting.SeatAccess from each. The None check now lives at the call site (walrus), so provision_seat_access() takes a plain str. This removes the per-profile overrides and their TYPE_CHECKING imports. * Use top-level imports in seat access utils The Installer and User imports were under a TYPE_CHECKING guard, but they cause no circular import (bspwm.py already imports both at top level). Move them to module scope per review feedback. --- archinstall/default_profiles/desktop.py | 6 +++++- archinstall/default_profiles/desktops/utils.py | 12 ++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/archinstall/default_profiles/desktop.py b/archinstall/default_profiles/desktop.py index b70f9f11..f9195357 100644 --- a/archinstall/default_profiles/desktop.py +++ b/archinstall/default_profiles/desktop.py @@ -1,6 +1,7 @@ from typing import TYPE_CHECKING, Self, override -from archinstall.default_profiles.profile import DisplayServerType, GreeterType, Profile, ProfileType, SelectResult +from archinstall.default_profiles.desktops.utils import provision_seat_access +from archinstall.default_profiles.profile import CustomSetting, DisplayServerType, GreeterType, Profile, ProfileType, SelectResult from archinstall.lib.log import info from archinstall.lib.menu.helpers import Selection from archinstall.lib.profile.profiles_handler import profile_handler @@ -94,6 +95,9 @@ class DesktopProfile(Profile): for profile in self.current_selection: profile.provision(install_session, users) + if seat_access := profile.custom_settings.get(CustomSetting.SeatAccess): + provision_seat_access(install_session, users, seat_access) + @override def install(self, install_session: Installer) -> None: # Install common packages for all desktop environments diff --git a/archinstall/default_profiles/desktops/utils.py b/archinstall/default_profiles/desktops/utils.py index 03e85aa5..b179ad50 100644 --- a/archinstall/default_profiles/desktops/utils.py +++ b/archinstall/default_profiles/desktops/utils.py @@ -1,6 +1,8 @@ from enum import Enum +from archinstall.lib.installer import Installer from archinstall.lib.menu.helpers import Selection +from archinstall.lib.models.users import User from archinstall.lib.translationhandler import tr from archinstall.tui.menu_item import MenuItem, MenuItemGroup from archinstall.tui.result import ResultType @@ -11,6 +13,16 @@ class SeatAccess(Enum): polkit = 'polkit' +def provision_seat_access( + install_session: Installer, + users: list[User], + seat_access: str, +) -> None: + if seat_access == SeatAccess.seatd.value: + for user in users: + install_session.arch_chroot(f'usermod -a -G seat {user.username}') + + async def select_seat_access(profile_name: str, default: str | None) -> SeatAccess: header = tr('{} needs access to your seat').format(profile_name) header += f' ({tr("collection of hardware devices i.e. keyboard, mouse")})' + '\n' From 919a435a6bb7f878ed78807b9c1cb77a36383f85 Mon Sep 17 00:00:00 2001 From: Softer Date: Wed, 10 Jun 2026 10:10:29 +0300 Subject: [PATCH 03/35] Skip custom mirror config when keyring sync fails (#4577) * Skip custom mirror config when keyring sync fails Check the exit state of archlinux-keyring-wkd-sync.service after waiting for it to finish. If it failed, skip set_mirrors() and continue installation with default mirrors instead of crashing with "GPGME error: No data" during pacman -Syy. * Reinit keyring automatically when pacman sync fails with GPGME error Instead of skipping mirror configuration when wkd-sync fails, catch the GPGME error at the point where it actually occurs - during pacman -Syy. If the sync fails with a keyring-related error, reinit the keyring with pacman-key --init/--populate and retry the sync. * Simplify pacman sync() and guard gpg-agent kill on running state Collapse the duplicated self.ask() blocks in sync() into a single call via a msg variable, and drop the redundant default_cmd='pacman' (it is already the default). In _reinit_keyring(), check that gpg-agent is actually running (pgrep -x) before killing it, instead of catching the killall error and assuming it was not running. --- archinstall/lib/installer.py | 3 ++ archinstall/lib/pacman/pacman.py | 48 ++++++++++++++++++++++++++------ 2 files changed, 42 insertions(+), 9 deletions(-) diff --git a/archinstall/lib/installer.py b/archinstall/lib/installer.py index f53dcda4..985e16cd 100644 --- a/archinstall/lib/installer.py +++ b/archinstall/lib/installer.py @@ -228,6 +228,9 @@ class Installer: while self._service_state('archlinux-keyring-wkd-sync.service') not in ('dead', 'failed', 'exited'): time.sleep(1) + if self._service_state('archlinux-keyring-wkd-sync.service') == 'failed': + warn('archlinux-keyring-wkd-sync failed, keyring may need reinit during pacman sync') + def _verify_boot_part(self) -> None: """ Check that mounted /boot device has at minimum size for installation diff --git a/archinstall/lib/pacman/pacman.py b/archinstall/lib/pacman/pacman.py index c78f6145..83b965e2 100644 --- a/archinstall/lib/pacman/pacman.py +++ b/archinstall/lib/pacman/pacman.py @@ -4,8 +4,8 @@ from collections.abc import Callable from pathlib import Path from archinstall.lib.command import SysCommand -from archinstall.lib.exceptions import RequirementError -from archinstall.lib.log import error, info, warn +from archinstall.lib.exceptions import RequirementError, SysCallError +from archinstall.lib.log import debug, error, info, warn from archinstall.lib.pathnames import PACMAN_CONF from archinstall.lib.plugins import plugins from archinstall.lib.translationhandler import tr @@ -53,15 +53,45 @@ class Pacman: def sync(self) -> None: if self.synced: return - self.ask( - 'Could not sync a new package database', - 'Could not sync mirrors', - self.run, - '-Syy', - default_cmd='pacman', - ) + + try: + self.run('-Syy') + except SysCallError as err: + if b'GPGME' in err.worker_log or b'keyring' in err.worker_log.lower(): + warn('Pacman sync failed with keyring error, attempting keyring reinit') + self._reinit_keyring() + msg = 'Could not sync a new package database after keyring reinit' + else: + msg = 'Could not sync a new package database' + + self.ask(msg, 'Could not sync mirrors', self.run, '-Syy') + self.synced = True + @staticmethod + def _is_running(process: str) -> bool: + try: + SysCommand(f'pgrep -x {process}') + return True + except SysCallError: + debug(f'{process} is not running') + return False + + @staticmethod + def _reinit_keyring() -> None: + if Pacman._is_running('gpg-agent'): + try: + SysCommand('killall gpg-agent') + except SysCallError as err: + debug(f'Failed to kill gpg-agent: {err}') + + try: + SysCommand('pacman-key --init') + SysCommand('pacman-key --populate archlinux') + debug('Keyring reinitialized successfully') + except SysCallError as err: + debug(f'Keyring reinit failed: {err}') + def strap(self, packages: str | list[str]) -> None: self.sync() if isinstance(packages, str): From f6a031f5846732db4e0e527644130b71efe3d2fc Mon Sep 17 00:00:00 2001 From: Softer Date: Fri, 12 Jun 2026 21:57:32 +0300 Subject: [PATCH 04/35] Fix Plymouth theme preset focus and add missing strings to base.pot (#4586) select_plymouth_theme() compared enum item values against a raw string, so the previously selected theme was never highlighted when reopening the menu. Use set_focus_by_value() like other single-select menus. Regenerate base.pot to pick up the three Plymouth strings introduced in #4555. --- archinstall/lib/bootloader/bootloader_menu.py | 2 +- archinstall/locales/base.pot | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/archinstall/lib/bootloader/bootloader_menu.py b/archinstall/lib/bootloader/bootloader_menu.py index 64ad4c8d..a985eb90 100644 --- a/archinstall/lib/bootloader/bootloader_menu.py +++ b/archinstall/lib/bootloader/bootloader_menu.py @@ -235,7 +235,7 @@ async def select_bootloader( async def select_plymouth_theme(preset: PlymouthTheme | None = None) -> PlymouthTheme | None: items = [MenuItem(t.value, value=t) for t in PlymouthTheme] group = MenuItemGroup(items, sort_items=False) - group.set_selected_by_value(preset.value if preset else None) + group.set_focus_by_value(preset) result = await Selection[PlymouthTheme]( group, diff --git a/archinstall/locales/base.pot b/archinstall/locales/base.pot index 23df29fb..9bfe074d 100644 --- a/archinstall/locales/base.pot +++ b/archinstall/locales/base.pot @@ -209,6 +209,9 @@ msgstr "" msgid "Install to removable location" msgstr "" +msgid "Plymouth" +msgstr "" + msgid "Will install to /EFI/BOOT/ (removable location, safe default)" msgstr "" @@ -248,6 +251,9 @@ msgstr "" msgid "UEFI is not detected and some options are disabled" msgstr "" +msgid "Select Plymouth theme" +msgstr "" + msgid "The specified configuration will be applied" msgstr "" @@ -882,6 +888,10 @@ msgstr "" msgid "Removable" msgstr "" +#, python-brace-format +msgid "Plymouth \"{}\"" +msgstr "" + msgid "Use a best-effort default partition layout" msgstr "" From 5397ae712490919969ba32b9e8001956612a30ac Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 13 Jun 2026 16:24:31 +1000 Subject: [PATCH 05/35] Update dependency arch/python-cryptography to v48.0.1 (#4591) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 8a128717..7711aef8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -20,7 +20,7 @@ classifiers = [ dependencies = [ "pyparted==3.13.0", "pydantic==2.13.4", - "cryptography==48.0.0", + "cryptography==48.0.1", "textual==8.2.7", "markdown-it-py==4.0.0", "linkify-it-py==2.1.0", From f67b7c2aa07b48f115cecaf59eaf37463eb50763 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 13 Jun 2026 16:24:48 +1000 Subject: [PATCH 06/35] Update dependency ruff to v0.15.17 (#4592) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 7711aef8..419cd680 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -37,7 +37,7 @@ dev = [ "mypy==2.1.0", "flake8==7.3.0", "pre-commit==4.6.0", - "ruff==0.15.16", + "ruff==0.15.17", "pylint==4.0.5", "pytest==9.0.3", "hypothesis>=6.152.4", From c777ee03f6165d1d10979ca0bc7a5cfedff8a98a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 13 Jun 2026 16:29:37 +1000 Subject: [PATCH 07/35] Update pre-commit hook astral-sh/ruff-pre-commit to v0.15.17 (#4593) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 33f112cf..3b7c18df 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.15.16 + rev: v0.15.17 hooks: # fix unused imports and sort them - id: ruff From c6a5a130a8195e2c6bb01fbe23a4057eed1bb311 Mon Sep 17 00:00:00 2001 From: Daniel Girtler Date: Mon, 29 Jun 2026 05:04:20 +1000 Subject: [PATCH 08/35] Refactor configuration file (#4583) --- archinstall/lib/args.py | 99 +++++++++++++++- archinstall/lib/configuration.py | 174 +++++------------------------ archinstall/lib/global_menu.py | 5 +- archinstall/lib/utils/util.py | 5 + archinstall/scripts/guided.py | 9 +- archinstall/scripts/minimal.py | 9 +- archinstall/scripts/only_hd.py | 9 +- tests/test_configuration_output.py | 15 +-- 8 files changed, 150 insertions(+), 175 deletions(-) diff --git a/archinstall/lib/args.py b/archinstall/lib/args.py index e3729504..4bc9f317 100644 --- a/archinstall/lib/args.py +++ b/archinstall/lib/args.py @@ -1,6 +1,7 @@ import argparse import json import os +import stat import sys import urllib.error import urllib.parse @@ -11,9 +12,10 @@ from pathlib import Path from typing import Any, Self from urllib.request import Request, urlopen +from pydantic import TypeAdapter from pydantic.dataclasses import dataclass as p_dataclass -from archinstall.lib.crypt import decrypt +from archinstall.lib.crypt import decrypt, encrypt from archinstall.lib.log import debug, error, logger, warn from archinstall.lib.menu.util import get_password from archinstall.lib.models.application import ApplicationConfiguration, ZramConfiguration @@ -31,6 +33,8 @@ from archinstall.lib.models.profile import ProfileConfiguration from archinstall.lib.models.users import Password, User, UserSerialization from archinstall.lib.plugins import load_plugin from archinstall.lib.translationhandler import Language, tr, translation_handler +from archinstall.lib.utils.format import as_key_value_pair +from archinstall.lib.utils.util import is_valid_path from archinstall.lib.version import get_version from archinstall.tui.components import tui @@ -140,6 +144,11 @@ class ArchConfigType(StrEnum): return tr('Disk encryption password') +USER_CONFIG_FILE: Path = Path('user_configuration.json') +USER_CREDS_FILE: Path = Path('user_credentials.json') +DEFAULT_SAVE_PATH = logger.directory + + @dataclass class ArchConfig: version: str | None = None @@ -367,6 +376,94 @@ class ArchConfig: return arch_config + def user_config_to_json(self) -> str: + config = self.safe_config() + + adapter = TypeAdapter(dict[ArchConfigType, Any]) + python_dict = adapter.dump_python(config) + return json.dumps(python_dict, indent=4, sort_keys=True) + + def user_credentials_to_json(self) -> str: + cfg = self.unsafe_config() + + adapter = TypeAdapter(dict[ArchConfigType, Any]) + python_dict = adapter.dump_python(cfg) + return json.dumps(python_dict, indent=4, sort_keys=True) + + def write_debug(self) -> None: + debug(' -- Chosen configuration --') + debug(self.user_config_to_json()) + + def save( + self, + dest_path: Path | None = None, + creds: bool = False, + password: str | None = None, + ) -> None: + save_path = dest_path or DEFAULT_SAVE_PATH + + if not is_valid_path(save_path): + warn( + f'Destination directory {save_path} does not exist or is not a directory\n.', + 'Configuration files can not be saved', + ) + return + + self.save_user_config(save_path) + if creds: + self.save_user_creds(save_path, password=password) + + def save_user_config(self, dest_path: Path) -> None: + if not is_valid_path(dest_path): + error(f'Invalid path {dest_path}. User configuration could not be saved.') + return + + target = dest_path / USER_CONFIG_FILE + data = self.user_config_to_json() + target.write_text(data) + target.chmod(stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP) + + def save_user_creds( + self, + dest_path: Path, + password: str | None = None, + ) -> None: + if not is_valid_path(dest_path): + error(f'Invalid path {dest_path}. User credentials could not be saved.') + return + + data = self.user_credentials_to_json() + + if password: + data = encrypt(password, data) + + target = dest_path / USER_CREDS_FILE + target.write_text(data) + target.chmod(stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP) + + def as_summary(self) -> str: + """ + Render a concise two-column summary of the current configuration. + + Returns an empty string if nothing meaningful to show. + """ + cfg: dict[str, str | list[str] | bool] = {} + + for key, value in self.plain_cfg().items(): + cfg[key.text()] = value + + for config_type, obj in self.sub_cfg().items(): + if not hasattr(obj, 'summary'): + continue + + summary = obj.summary() + if summary: + cfg[config_type.text()] = summary + + simple_summary = as_key_value_pair(cfg, ignore_empty=True) + + return simple_summary + class ArchConfigHandler: def __init__(self) -> None: diff --git a/archinstall/lib/configuration.py b/archinstall/lib/configuration.py index 5754dfcf..cb6844c3 100644 --- a/archinstall/lib/configuration.py +++ b/archinstall/lib/configuration.py @@ -1,171 +1,53 @@ -import json import readline -import stat -from pathlib import Path -from typing import Any -from pydantic import TypeAdapter - -from archinstall.lib.args import ArchConfig, ArchConfigType -from archinstall.lib.crypt import encrypt -from archinstall.lib.log import debug, logger, warn +from archinstall.lib.args import USER_CONFIG_FILE, USER_CREDS_FILE, ArchConfig +from archinstall.lib.log import debug from archinstall.lib.menu.helpers import Confirmation, Selection from archinstall.lib.menu.util import get_password, prompt_dir from archinstall.lib.translationhandler import tr -from archinstall.lib.utils.format import as_key_value_pair from archinstall.tui.menu_item import MenuItem, MenuItemGroup from archinstall.tui.result import ResultType -class ConfigurationOutput: - def __init__(self, config: ArchConfig): - """ - Configuration output handler to parse the existing - configuration data structure and prepare for output on the - console and for saving it to configuration files +async def confirm_config(config: ArchConfig) -> bool: + header = f'{tr("The specified configuration will be applied")}. ' + header += tr('Would you like to continue?') + '\n' - :param config: Archinstall configuration object - :type config: ArchConfig - """ + group = MenuItemGroup.yes_no() + group.set_preview_for_all(lambda x: config.user_config_to_json()) - self._config = config - self._default_save_path = logger.directory - self._user_config_file = Path('user_configuration.json') - self._user_creds_file = Path('user_credentials.json') + result = await Confirmation( + group=group, + header=header, + allow_skip=False, + preset=True, + preview_location='bottom', + preview_header=tr('Configuration preview'), + ).show() - @property - def user_configuration_file(self) -> Path: - return self._user_config_file + if not result.get_value(): + return False - @property - def user_credentials_file(self) -> Path: - return self._user_creds_file - - def user_config_to_json(self) -> str: - config = self._config.safe_config() - - adapter = TypeAdapter(dict[ArchConfigType, Any]) - python_dict = adapter.dump_python(config) - return json.dumps(python_dict, indent=4, sort_keys=True) - - def user_credentials_to_json(self) -> str: - cfg = self._config.unsafe_config() - - adapter = TypeAdapter(dict[ArchConfigType, Any]) - python_dict = adapter.dump_python(cfg) - return json.dumps(python_dict, indent=4, sort_keys=True) - - def write_debug(self) -> None: - debug(' -- Chosen configuration --') - debug(self.user_config_to_json()) - - def as_summary(self) -> str: - """ - Render a concise two-column summary of the current configuration. - - Returns an empty string if nothing meaningful to show. - """ - cfg: dict[str, str | list[str] | bool] = {} - - for key, value in self._config.plain_cfg().items(): - cfg[key.text()] = value - - for config_type, obj in self._config.sub_cfg().items(): - if not hasattr(obj, 'summary'): - continue - - summary = obj.summary() - if summary: - cfg[config_type.text()] = summary - - simple_summary = as_key_value_pair(cfg, ignore_empty=True) - - return simple_summary - - async def confirm_config(self) -> bool: - header = f'{tr("The specified configuration will be applied")}. ' - header += tr('Would you like to continue?') + '\n' - - group = MenuItemGroup.yes_no() - group.set_preview_for_all(lambda x: self.user_config_to_json()) - - result = await Confirmation( - group=group, - header=header, - allow_skip=False, - preset=True, - preview_location='bottom', - preview_header=tr('Configuration preview'), - ).show() - - if not result.get_value(): - return False - - return True - - def _is_valid_path(self, dest_path: Path) -> bool: - dest_path_ok = dest_path.exists() and dest_path.is_dir() - if not dest_path_ok: - warn( - f'Destination directory {dest_path.resolve()} does not exist or is not a directory\n.', - 'Configuration files can not be saved', - ) - return dest_path_ok - - def save_user_config(self, dest_path: Path) -> None: - if self._is_valid_path(dest_path): - target = dest_path / self._user_config_file - target.write_text(self.user_config_to_json()) - target.chmod(stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP) - - def save_user_creds( - self, - dest_path: Path, - password: str | None = None, - ) -> None: - data = self.user_credentials_to_json() - - if password: - data = encrypt(password, data) - - if self._is_valid_path(dest_path): - target = dest_path / self._user_creds_file - target.write_text(data) - target.chmod(stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP) - - def save( - self, - dest_path: Path | None = None, - creds: bool = False, - password: str | None = None, - ) -> None: - save_path = dest_path or self._default_save_path - - if self._is_valid_path(save_path): - self.save_user_config(save_path) - if creds: - self.save_user_creds(save_path, password=password) + return True async def save_config(config: ArchConfig) -> None: def preview(item: MenuItem) -> str | None: match item.value: case 'user_config': - serialized = config_output.user_config_to_json() - return f'{config_output.user_configuration_file}\n{serialized}' + serialized = config.user_config_to_json() + return f'{USER_CONFIG_FILE}\n{serialized}' case 'user_creds': - if maybe_serial := config_output.user_credentials_to_json(): - return f'{config_output.user_credentials_file}\n{maybe_serial}' + if maybe_serial := config.user_credentials_to_json(): + return f'{USER_CREDS_FILE}\n{maybe_serial}' return tr('No configuration') case 'all': - output = [str(config_output.user_configuration_file)] - config_output.user_credentials_to_json() - output.append(str(config_output.user_credentials_file)) + output = [str(USER_CONFIG_FILE)] + config.user_credentials_to_json() + output.append(str(USER_CREDS_FILE)) return '\n'.join(output) return None - config_output = ConfigurationOutput(config) - items = [ MenuItem( tr('Save user configuration (including disk layout)'), @@ -248,8 +130,8 @@ async def save_config(config: ArchConfig) -> None: match save_option: case 'user_config': - config_output.save_user_config(dest_path) + config.save_user_config(dest_path) case 'user_creds': - config_output.save_user_creds(dest_path, password=enc_password) + config.save_user_creds(dest_path, password=enc_password) case 'all': - config_output.save(dest_path, creds=True, password=enc_password) + config.save(dest_path, creds=True, password=enc_password) diff --git a/archinstall/lib/global_menu.py b/archinstall/lib/global_menu.py index 548ed522..72c31033 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 ConfigurationOutput, save_config +from archinstall.lib.configuration import 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,6 @@ class GlobalMenu(AbstractMenu[None]): def _prev_install_invalid_config(self, item: MenuItem) -> PreviewResult | None: self.sync_all_to_config() - config_output = ConfigurationOutput(self._arch_config) warnings = self._get_install_warnings() messages: list[tuple[str, MsgLevelType]] = [] @@ -531,7 +530,7 @@ class GlobalMenu(AbstractMenu[None]): messages.append((text, MsgLevelType.MsgWarning)) if not errors: - summary = config_output.as_summary() + summary = self._arch_config.as_summary() if summary: messages.append((summary, MsgLevelType.MsgNone)) diff --git a/archinstall/lib/utils/util.py b/archinstall/lib/utils/util.py index f94ca18c..a0c34f5f 100644 --- a/archinstall/lib/utils/util.py +++ b/archinstall/lib/utils/util.py @@ -1,6 +1,7 @@ import secrets import string from datetime import UTC, datetime +from pathlib import Path from archinstall.lib.pathnames import ARCHISO_MOUNTPOINT from archinstall.lib.utils.format import as_columns @@ -46,3 +47,7 @@ def format_cols(items: list[str], header: str | None = None) -> str: # remove whitespaces on each row text = '\n'.join(t.strip() for t in text.split('\n')) return text + + +def is_valid_path(path: Path) -> bool: + return path.exists() and path.is_dir() diff --git a/archinstall/scripts/guided.py b/archinstall/scripts/guided.py index 775ed1fd..627a3b75 100644 --- a/archinstall/scripts/guided.py +++ b/archinstall/scripts/guided.py @@ -6,7 +6,7 @@ from archinstall.lib.applications.application_handler import ApplicationHandler from archinstall.lib.args import ArchConfig, ArchConfigHandler from archinstall.lib.authentication.authentication_handler import AuthenticationHandler from archinstall.lib.bootloader.utils import validate_bootloader_layout -from archinstall.lib.configuration import ConfigurationOutput +from archinstall.lib.configuration import confirm_config from archinstall.lib.disk.filesystem import FilesystemHandler from archinstall.lib.disk.utils import disk_layouts from archinstall.lib.general.general_menu import PostInstallationAction, select_post_installation @@ -213,9 +213,8 @@ def main(arch_config_handler: ArchConfigHandler | None = None) -> None: if not arch_config_handler.args.silent: show_menu(arch_config_handler, mirror_list_handler) - config = ConfigurationOutput(arch_config_handler.config) - config.write_debug() - config.save() + arch_config_handler.config.write_debug() + arch_config_handler.config.save() # Safety net for silent/config-file flow. The TUI menu blocks Install via # GlobalMenu._validate_bootloader() before reaching this point. @@ -231,7 +230,7 @@ def main(arch_config_handler: ArchConfigHandler | None = None) -> None: if not arch_config_handler.args.silent: aborted = False - res: bool = tui.run(config.confirm_config) + res: bool = tui.run(lambda: confirm_config(arch_config_handler.config)) if not res: debug('Installation aborted') diff --git a/archinstall/scripts/minimal.py b/archinstall/scripts/minimal.py index a58963f2..0ab6da83 100644 --- a/archinstall/scripts/minimal.py +++ b/archinstall/scripts/minimal.py @@ -1,6 +1,6 @@ from archinstall.default_profiles.minimal import MinimalProfile from archinstall.lib.args import ArchConfigHandler -from archinstall.lib.configuration import ConfigurationOutput +from archinstall.lib.configuration import confirm_config from archinstall.lib.disk.disk_menu import DiskLayoutConfigurationMenu from archinstall.lib.disk.filesystem import FilesystemHandler from archinstall.lib.installer import Installer @@ -68,16 +68,15 @@ async def main(arch_config_handler: ArchConfigHandler | None = None) -> None: disk_config = await DiskLayoutConfigurationMenu(disk_layout_config=None).show() arch_config_handler.config.disk_config = disk_config - config = ConfigurationOutput(arch_config_handler.config) - config.write_debug() - config.save() + arch_config_handler.config.write_debug() + arch_config_handler.config.save() if arch_config_handler.args.dry_run: return if not arch_config_handler.args.silent: aborted = False - res: bool = tui.run(config.confirm_config) + res: bool = tui.run(lambda: confirm_config(arch_config_handler.config)) if not res: debug('Installation aborted') diff --git a/archinstall/scripts/only_hd.py b/archinstall/scripts/only_hd.py index c7349c51..6a2374df 100644 --- a/archinstall/scripts/only_hd.py +++ b/archinstall/scripts/only_hd.py @@ -2,7 +2,7 @@ import sys from pathlib import Path from archinstall.lib.args import ArchConfig, ArchConfigHandler -from archinstall.lib.configuration import ConfigurationOutput +from archinstall.lib.configuration import confirm_config from archinstall.lib.disk.filesystem import FilesystemHandler from archinstall.lib.disk.utils import disk_layouts from archinstall.lib.global_menu import GlobalMenu @@ -69,16 +69,15 @@ def main(arch_config_handler: ArchConfigHandler | None = None) -> None: if not arch_config_handler.args.silent: show_menu(arch_config_handler) - config = ConfigurationOutput(arch_config_handler.config) - config.write_debug() - config.save() + arch_config_handler.config.write_debug() + arch_config_handler.config.save() if arch_config_handler.args.dry_run: return if not arch_config_handler.args.silent: aborted = False - res: bool = tui.run(config.confirm_config) + res: bool = tui.run(lambda: confirm_config(arch_config_handler.config)) if not res: debug('Installation aborted') diff --git a/tests/test_configuration_output.py b/tests/test_configuration_output.py index 7d9f1f97..cbedc026 100644 --- a/tests/test_configuration_output.py +++ b/tests/test_configuration_output.py @@ -3,8 +3,7 @@ from pathlib import Path from pytest import MonkeyPatch -from archinstall.lib.args import ArchConfigHandler -from archinstall.lib.configuration import ConfigurationOutput +from archinstall.lib.args import USER_CONFIG_FILE, USER_CREDS_FILE, ArchConfigHandler def test_user_config_roundtrip( @@ -20,12 +19,10 @@ def test_user_config_roundtrip( # as there is no version present in the test environment we'll set it manually arch_config.version = '3.0.2' - config_output = ConfigurationOutput(arch_config) - test_out_dir = Path('/tmp/') - test_out_file = test_out_dir / config_output.user_configuration_file + test_out_file = test_out_dir / USER_CONFIG_FILE - config_output.save(test_out_dir) + arch_config.save(test_out_dir) result = json.loads(test_out_file.read_text()) expected = json.loads(config_fixture.read_text()) @@ -55,12 +52,10 @@ def test_creds_roundtrip( handler = ArchConfigHandler() arch_config = handler.config - config_output = ConfigurationOutput(arch_config) - test_out_dir = Path('/tmp/') - test_out_file = test_out_dir / config_output.user_credentials_file + test_out_file = test_out_dir / USER_CREDS_FILE - config_output.save(test_out_dir, creds=True) + arch_config.save(test_out_dir, creds=True) result = json.loads(test_out_file.read_text()) expected = json.loads(creds_fixture.read_text()) From cce0c47e1177daad27aa731048b861a540aaea0d Mon Sep 17 00:00:00 2001 From: emanu <117443145+ScarletEmanu@users.noreply.github.com> Date: Sun, 28 Jun 2026 21:09:20 +0200 Subject: [PATCH 09/35] Fix plugin (#4594) * change behaviour to load plugin * add checks in _write_plugin_to_temp_file * modify test * fixed test --- archinstall/lib/args.py | 40 +++++++++++++++++++++++++++++++++++--- archinstall/lib/plugins.py | 33 +++---------------------------- tests/test_args.py | 4 +++- 3 files changed, 43 insertions(+), 34 deletions(-) diff --git a/archinstall/lib/args.py b/archinstall/lib/args.py index 4bc9f317..95869c2f 100644 --- a/archinstall/lib/args.py +++ b/archinstall/lib/args.py @@ -3,6 +3,7 @@ import json import os import stat import sys +import tempfile import urllib.error import urllib.parse from argparse import ArgumentParser, Namespace @@ -60,7 +61,8 @@ class Arguments: debug: bool = False offline: bool = False no_pkg_lookups: bool = False - plugin: str | None = None + plugin: Path | None = None + plugin_url: str | None = None skip_version_check: bool = False skip_wifi_check: bool = False advanced: bool = False @@ -614,10 +616,17 @@ class ArchConfigHandler: parser.add_argument( '--plugin', nargs='?', - type=str, + type=Path, default=None, help='File path to a plugin to load', ) + parser.add_argument( + '--plugin-url', + type=str, + nargs='?', + default=None, + help='Url to a plugin file to load', + ) parser.add_argument( '--skip-version-check', action='store_true', @@ -657,7 +666,11 @@ class ArchConfigHandler: warn(f'Warning: --debug mode will write certain credentials to {logger.path}!') if args.plugin: - plugin_path = Path(args.plugin) + load_plugin(args.plugin) + + if args.plugin_url: + plugin_data = self._fetch_from_url(args.plugin_url) + plugin_path = self._write_plugin_to_temp_file(plugin_data) load_plugin(plugin_path) if args.creds_decryption_key is None: @@ -749,6 +762,27 @@ class ArchConfigHandler: sys.exit(1) + def _write_plugin_to_temp_file(self, plugin_data: str) -> Path: + if not plugin_data.strip(): + error('The downloaded plugin is empty') + sys.exit(1) + + tmp_file = tempfile.NamedTemporaryFile( + mode='w', + suffix='.py', + prefix='archinstall_plugin_', + delete=False, + ) + + try: + with tmp_file as f: + f.write(plugin_data) + except OSError as err: + error(f'Could not write the downloaded plugin to a temporary file: {err}') + sys.exit(1) + + return Path(tmp_file.name) + def _read_file(self, path: Path) -> str: if not path.exists(): error(f'Could not find file {path}') diff --git a/archinstall/lib/plugins.py b/archinstall/lib/plugins.py index ac8383b1..6019f114 100644 --- a/archinstall/lib/plugins.py +++ b/archinstall/lib/plugins.py @@ -1,9 +1,6 @@ -import hashlib import importlib.util import os import sys -import urllib.parse -import urllib.request from importlib import metadata from pathlib import Path @@ -34,23 +31,6 @@ def plugin(f, *args, **kwargs) -> None: # type: ignore[no-untyped-def] plugins[f.__name__] = f -def _localize_path(path: Path) -> Path: - """ - Support structures for load_plugin() - """ - url = urllib.parse.urlparse(str(path)) - - if url.scheme and url.scheme in ('https', 'http'): - converted_path = Path(f'/tmp/{path.stem}_{hashlib.md5(os.urandom(12)).hexdigest()}.py') - - with open(converted_path, 'w') as temp_file: - temp_file.write(urllib.request.urlopen(url.geturl()).read().decode('utf-8')) - - return converted_path - else: - return path - - def _import_via_path(path: Path, namespace: str | None = None) -> str: if not namespace: namespace = os.path.basename(path) @@ -82,17 +62,10 @@ def _import_via_path(path: Path, namespace: str | None = None) -> str: def load_plugin(path: Path) -> None: namespace: str | None = None - parsed_url = urllib.parse.urlparse(str(path)) - info(f'Loading plugin from url {parsed_url}') + info(f'Loading plugin from {path}') - # The Profile was not a direct match on a remote URL - if not parsed_url.scheme: - # Path was not found in any known examples, check if it's an absolute path - if os.path.isfile(path): - namespace = _import_via_path(path) - elif parsed_url.scheme in ('https', 'http'): - localized = _localize_path(path) - namespace = _import_via_path(localized) + if os.path.isfile(path): + namespace = _import_via_path(path) if namespace and namespace in sys.modules: # Version dependency via __archinstall__version__ variable (if present) in the plugin diff --git a/tests/test_args.py b/tests/test_args.py index 4cbad41b..324f5a11 100644 --- a/tests/test_args.py +++ b/tests/test_args.py @@ -50,6 +50,7 @@ def test_default_args(monkeypatch: MonkeyPatch) -> None: offline=False, no_pkg_lookups=False, plugin=None, + plugin_url=None, skip_version_check=False, advanced=False, ) @@ -106,7 +107,8 @@ def test_correct_parsing_args( debug=True, offline=True, no_pkg_lookups=True, - plugin='pytest_plugin.py', + plugin=Path('pytest_plugin.py'), + plugin_url=None, skip_version_check=True, advanced=True, ) From 4b14b795f587572745ca3adb3bcae1ec5890169c Mon Sep 17 00:00:00 2001 From: utuhiro78 <34818411+utuhiro78@users.noreply.github.com> Date: Mon, 29 Jun 2026 04:11:32 +0900 Subject: [PATCH 10/35] Update Japanese translation (#4600) --- archinstall/locales/ja/LC_MESSAGES/base.mo | Bin 35463 -> 35644 bytes archinstall/locales/ja/LC_MESSAGES/base.po | 69 ++++++++++++--------- 2 files changed, 39 insertions(+), 30 deletions(-) diff --git a/archinstall/locales/ja/LC_MESSAGES/base.mo b/archinstall/locales/ja/LC_MESSAGES/base.mo index 0331225b8081e621bee9901c10316e2c4108c5d1..cf6e5372d82a6e8177ae971de7548b0661bf7f13 100644 GIT binary patch delta 8586 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�OB71h!5U7Wvss-kA5 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 ug?oKPyL^QQeMMWDbmPBOoYcRH_s;Vlx Date: Sun, 28 Jun 2026 22:13:10 +0300 Subject: [PATCH 11/35] Warn before enabling Plymouth in the bootloader menu (#4604) Plymouth is purely cosmetic and a frequent source of boot breakage, most notably a black screen with the NVIDIA driver and a hidden LUKS password prompt. Show a yellow confirmation warning listing these risks when enabling it; when Plymouth is already enabled the user is only changing the theme, so the warning is skipped. Regenerate base.pot for the new strings. --- archinstall/lib/bootloader/bootloader_menu.py | 28 +++++++++++++++++++ archinstall/locales/base.pot | 14 ++++++++++ 2 files changed, 42 insertions(+) diff --git a/archinstall/lib/bootloader/bootloader_menu.py b/archinstall/lib/bootloader/bootloader_menu.py index a985eb90..88fe8f73 100644 --- a/archinstall/lib/bootloader/bootloader_menu.py +++ b/archinstall/lib/bootloader/bootloader_menu.py @@ -130,6 +130,34 @@ class BootloaderMenu(AbstractSubMenu[BootloaderConfiguration]): return bootloader async def _select_plymouth(self, preset: PlymouthTheme | None) -> PlymouthTheme | None: + # Plymouth is purely cosmetic and a frequent source of boot breakage + # (notably with the NVIDIA driver and disk encryption), so confirm before + # enabling it. When it is already enabled the user is only changing the + # theme, so the warning is skipped. + if preset is None: + prompt = ( + '[ansi_bright_yellow]' + + tr('Plymouth adds a cosmetic boot splash but can cause boot problems on some setups:') + + '\n\n • ' + + tr('black screen with the NVIDIA driver') + + '\n • ' + + tr('hidden password prompt with disk encryption (LUKS)') + + '\n\n' + + tr('Would you like to enable it?') + + '[/]\n' + ) + + result = await Confirmation(header=prompt, allow_skip=True, preset=False).show() + + match result.type_: + case ResultType.Skip: + return preset + case ResultType.Selection: + if not result.get_value(): + return preset + case ResultType.Reset: + raise ValueError('Unhandled result type') + return await select_plymouth_theme(preset) async def _select_uki(self, preset: bool) -> bool: diff --git a/archinstall/locales/base.pot b/archinstall/locales/base.pot index 9bfe074d..a5ffcc7d 100644 --- a/archinstall/locales/base.pot +++ b/archinstall/locales/base.pot @@ -218,6 +218,20 @@ msgstr "" msgid "Will install to custom location with NVRAM entry" msgstr "" +msgid "" +"Plymouth adds a cosmetic boot splash but can cause boot problems on some " +"setups:" +msgstr "" + +msgid "black screen with the NVIDIA driver" +msgstr "" + +msgid "hidden password prompt with disk encryption (LUKS)" +msgstr "" + +msgid "Would you like to enable it?" +msgstr "" + msgid "Would you like to use unified kernel images?" msgstr "" From e4b2894db5e8391aee958a347bbc984edb63c0ab Mon Sep 17 00:00:00 2001 From: brurmonemt Date: Sun, 28 Jun 2026 14:19:42 -0500 Subject: [PATCH 12/35] fix ValueError exception when no disks are detected in the disk menu (#4598) * Fix ValueError exception when no disks are detected in the disk menu in lib/disk/disk_menu.py, the menu items are created using info from a list called "devices" (device_handler.devices). when no block devices are detected, the list is empty, creating zero MenuItems, and causing the following ValueError: ValueError: Menu must have at least one item this change checks if the length of the list is shorter than 1 (empty list) before constructing the menu. if the list is empty, the user will be notified that no disks were detected. otherwise, the menu is created and behaves as normal * Fixed ruff formatting issue * Fixed ruff formatting issue --------- Co-authored-by: Anton Hvornum --- archinstall/lib/disk/disk_menu.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/archinstall/lib/disk/disk_menu.py b/archinstall/lib/disk/disk_menu.py index f8e8e2e3..f89635af 100644 --- a/archinstall/lib/disk/disk_menu.py +++ b/archinstall/lib/disk/disk_menu.py @@ -311,6 +311,10 @@ async def select_devices(preset: list[BDevice] | None = []) -> list[BDevice] | N devices = device_handler.devices + if len(devices) < 1: + await Notify(tr('No disks were detected. A disk is required to be able to install Arch Linux')).show() + return None + items = [ MenuItem( str(d.device_info.path), From 3ece182d31dda7b14abd56d13abf3ff79a5717ae Mon Sep 17 00:00:00 2001 From: Anton Hvornum Date: Sun, 28 Jun 2026 22:06:04 +0200 Subject: [PATCH 13/35] Bumping version to: 4.4 (#4608) --- PKGBUILD | 2 +- pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/PKGBUILD b/PKGBUILD index e9ee1173..af7cd5a0 100644 --- a/PKGBUILD +++ b/PKGBUILD @@ -5,7 +5,7 @@ # Contributor: demostanis worlds pkgname=archinstall -pkgver=4.3 +pkgver=4.4 pkgrel=1 pkgdesc="Just another guided/automated Arch Linux installer with a twist" arch=(any) diff --git a/pyproject.toml b/pyproject.toml index 419cd680..d86f7f8e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "archinstall" -version = "4.3" +version = "4.4" description = "Arch Linux installer - guided, templates etc." authors = [ {name = "Anton Hvornum", email = "anton@hvornum.se"}, From 214e55248cce35468193ad63a27dd0417ffe8b74 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 29 Jun 2026 21:44:58 +1000 Subject: [PATCH 14/35] Update actions/setup-python digest to ece7cb0 (#4605) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/github-pages.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/github-pages.yml b/.github/workflows/github-pages.yml index 4465aa41..d58c7f60 100644 --- a/.github/workflows/github-pages.yml +++ b/.github/workflows/github-pages.yml @@ -22,7 +22,7 @@ jobs: options: --privileged steps: - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 - - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6 + - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6 - name: Install pre-dependencies run: | pacman -Sy --noconfirm tree git python-pyparted python-setuptools python-sphinx python-sphinx_rtd_theme python-build python-installer python-wheel From e2b869786483866964b3a0b5341edd8d2f5e3bb4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 29 Jun 2026 21:45:20 +1000 Subject: [PATCH 15/35] Update dependency pylint to v4.0.6 (#4606) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index d86f7f8e..31560033 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -38,7 +38,7 @@ dev = [ "flake8==7.3.0", "pre-commit==4.6.0", "ruff==0.15.17", - "pylint==4.0.5", + "pylint==4.0.6", "pytest==9.0.3", "hypothesis>=6.152.4", ] From faf6fe5ce20c73a7b954916c79dfda2586031514 Mon Sep 17 00:00:00 2001 From: Softer Date: Mon, 29 Jun 2026 14:46:30 +0300 Subject: [PATCH 16/35] Improve Ukrainian translation (#4611) Translate the new Plymouth bootloader strings (enable warning prompt, theme selection) and add the graphics driver label. --- archinstall/locales/uk/LC_MESSAGES/base.mo | Bin 91540 -> 92437 bytes archinstall/locales/uk/LC_MESSAGES/base.po | 30 +++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/archinstall/locales/uk/LC_MESSAGES/base.mo b/archinstall/locales/uk/LC_MESSAGES/base.mo index 26cd6bdba7f822a7f585e142046228e9f08ff755..d42b443a2ced1382a354ede77348cb3857a29351 100644 GIT binary patch delta 16776 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 Txi;+@+ue1_Yw@r?u2ugBvS^6g diff --git a/archinstall/locales/uk/LC_MESSAGES/base.po b/archinstall/locales/uk/LC_MESSAGES/base.po index 06bfe3ff..c398b37c 100644 --- a/archinstall/locales/uk/LC_MESSAGES/base.po +++ b/archinstall/locales/uk/LC_MESSAGES/base.po @@ -2389,3 +2389,33 @@ msgstr "набір апаратних пристроїв, напр. клавіа msgid "No network configuration selected. Network will need to be set up manually on the installed system." msgstr "Конфігурацію мережі не обрано. Мережу доведеться налаштувати вручну на встановленій системі." + +msgid "Plymouth" +msgstr "Plymouth" + +msgid "" +"Plymouth adds a cosmetic boot splash but can cause boot problems on some " +"setups:" +msgstr "" +"Plymouth додає косметичну заставку завантаження, але на деяких конфігураціях " +"може спричинити проблеми із завантаженням:" + +msgid "black screen with the NVIDIA driver" +msgstr "чорний екран із драйвером NVIDIA" + +msgid "hidden password prompt with disk encryption (LUKS)" +msgstr "прихований запит пароля при шифруванні диска (LUKS)" + +msgid "Would you like to enable it?" +msgstr "Увімкнути Plymouth?" + +msgid "Select Plymouth theme" +msgstr "Оберіть тему Plymouth" + +#, python-brace-format +msgid "Plymouth \"{}\"" +msgstr "Plymouth \"{}\"" + +#, python-brace-format +msgid "{} graphics driver" +msgstr "Графічний драйвер {}" From fc3a22683e140a3575c808809564a2e3b44e47ee Mon Sep 17 00:00:00 2001 From: Arvind <120897974+arvindfroi@users.noreply.github.com> Date: Mon, 29 Jun 2026 13:52:02 +0200 Subject: [PATCH 17/35] =?UTF-8?q?Add=20Norwegian=20Bokm=C3=A5l=20(nb)=20tr?= =?UTF-8?q?anslation=20(#4599)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add Norwegian Bokmål (nb) translation * Register Norwegian Bokmål in languages.json --- archinstall/locales/languages.json | 2 +- archinstall/locales/nb/LC_MESSAGES/base.mo | Bin 0 -> 29132 bytes archinstall/locales/nb/LC_MESSAGES/base.po | 1192 ++++++++++++++++++++ 3 files changed, 1193 insertions(+), 1 deletion(-) create mode 100644 archinstall/locales/nb/LC_MESSAGES/base.mo create mode 100644 archinstall/locales/nb/LC_MESSAGES/base.po diff --git a/archinstall/locales/languages.json b/archinstall/locales/languages.json index 22c9c9ec..11fb97c7 100644 --- a/archinstall/locales/languages.json +++ b/archinstall/locales/languages.json @@ -116,7 +116,7 @@ {"abbr": "ne", "lang": "Nepali", "translated_lang": "नेपाली"}, {"abbr": "nl", "lang": "Dutch", "translated_lang": "Nederlands"}, {"abbr": "nn", "lang": "Norwegian Nynorsk"}, - {"abbr": "nb", "lang": "Norwegian Bokmål"}, + {"abbr": "nb", "lang": "Norwegian Bokmål", "translated_lang": "Norsk bokmål"}, {"abbr": "no", "lang": "Norwegian"}, {"abbr": "ny", "lang": "Nyanja"}, {"abbr": "oc", "lang": "Occitan (post 1500)"}, diff --git a/archinstall/locales/nb/LC_MESSAGES/base.mo b/archinstall/locales/nb/LC_MESSAGES/base.mo new file mode 100644 index 0000000000000000000000000000000000000000..5acd8170f27161ce0e1f2cf330e89074ccd77bac GIT binary patch literal 29132 zcmb`P3v?t`dFKo817sVpjg2wb6n<(LwKOx>#t6SOBaJQ3Xhw`iGXofKNnL97ba!>r z)h$^#hF}N_Nk{?)7QAGET}<$Sg#^Q50!hGgmc)?9@_xk030@Y=D}m!>*@Up{@BiIf zkCrsXXLo%(`d8h$b?e^me((E9e}BdaZw>hGmd6CaGr$K<(OvQ1JD(Z^L)`v8cp~_I za0mDykpF{k@#9SJpF#CI?VKPu3p@ur0~`fU11CK02cOLSOF+GsfEwp^a2mW5)D*rA zo(ldLdsRCAbsRyzT+@{$GH4@0;L7;P=7jf=_z7qwDpc z=2ZnnkE5XIbc?_L9e@8$@NC*Y0&4vGef!^oqTB!Qcp{r6`kW2w`xkK3 zH-MVgM?kITK9H#eUj;>%pMaW2a9$9c44e(B{d`dLt$^B(7lB&$5~z8-3e@0<&Q zU?(^NUJbTEz4xC$&Fel;<9-w5mEZ^d{2h;0fS^p!n~*pvHd~yb&BiDAYa=YF&}PZ-R(ca0~c&@GYSD==VX*_v4_x^LbF; z`CEVgV}BoPaq~F~WJ`kcK+W?yQ14$4>b)0(T6YK3e!j-zzXSEXdqDBSUx5rAdeS?!D8&Q@DL5D0$lo zYWx}~J@9f+{qF#^p7(o)L-+`kx9|D&MR^J?%(;5$IQe>bRc?*|d>;0ONx%*&npT@E5T!4XjJ-wvJ$-U*5h z9|HBAkAsre&w}Ek?}3`nW3O=Ey95*+uK*k1BzQXbhoHWHAEx&vkrw zI(QcM=Y!XRmw|{t&;$8Dcn?4Jf!_dM1P))x-h!_IHIEO2hrus_2f?k+bN1`k!8Ptb z4r)Ey$KC#qgZlm+@C0xtnS18Q9lffs>KWzeUC zSAmc;I07C4-vnLAT(ie(-GW z-wKMp9|ZNCKLoYj&w$#8zX3J=!=Tptb5P@-2=T>#=YSe#7!)0@180cu^Z z2A>AL8`OJ$4C*_d11|=@4x&O6N@y)s55O@jrRB*e$p9b~* zK~VHq0?!5epyvB~{`uXY@FA`rQv| zo)3VM^B;ox{&_QQUSpu>cs;0f-UNzYZUy!JyFkg^M?ih=JD}u$Y@gf5Wl-yTmB0VD zpuYDZP~-e5sC7LEqT+*}gCpRM{f@t028thU17XSFE#L(Bx8M`O^Jd+AM?kIr8t?+} z0I2u+p!VgrLGkVTK&}56_$2Tz!Iy#$fUgCg{{nmm@YCP|xch+Hx4S{{$;Uy-(U-s{ zfL{Y&4}J^020S|F+V2KMmwUib@Vnrt;MoV=K3oXu{cAw+_YL5g;8E}l@RgwE|0aL` zeh`rfJ_()%K5pLW;nTqi_g8|F!zJ)!umx&;eNf~426zJaPEhlBk8l4FD82DteETVf z-1Bq5Q)s^!)V^;AHU2E9{W=VaPdea}!P`OY^Bw;F1OEO~pvL(!sB!)Q)ck%4o(-Oi z5k3n%9~6IH21;-42eprFQ1p2-7=j-Kw}W2+)$imZj&CmoFXR3Q_!RJspvM0XpvL_K zD0+Mu)c$=N6g?gS#ScFM)&GBjPX$kVq3d@ssP%0D&jH6l?b95%2-d(5{Jd}fAt=2l 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 literal 0 HcmV?d00001 diff --git a/archinstall/locales/nb/LC_MESSAGES/base.po b/archinstall/locales/nb/LC_MESSAGES/base.po new file mode 100644 index 00000000..3821d1b0 --- /dev/null +++ b/archinstall/locales/nb/LC_MESSAGES/base.po @@ -0,0 +1,1192 @@ +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: \n" +"PO-Revision-Date: \n" +"Last-Translator: \n" +"Language-Team: Norwegian Bokmål\n" +"Language: nb\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +msgid "Recommended" +msgstr "Anbefalt" + +msgid "Package" +msgstr "Pakke" + +msgid "Curated selection of KDE Plasma packages" +msgstr "Kuratert utvalg av KDE Plasma-pakker" + +msgid "Dependencies" +msgstr "Avhengigheter" + +msgid "Package group" +msgstr "Pakkegruppe" + +msgid "Extensive KDE Plasma installation" +msgstr "Omfattende KDE Plasma-installasjon" + +msgid "Packages in group" +msgstr "Pakker i gruppen" + +msgid "Minimal KDE Plasma installation" +msgstr "Minimal KDE Plasma-installasjon" + +msgid "Type" +msgstr "Type" + +msgid "Description" +msgstr "Beskrivelse" + +msgid "Select a flavor of KDE Plasma to install" +msgstr "Velg en variant av KDE Plasma å installere" + +#, python-brace-format +msgid "{} needs access to your seat" +msgstr "{} trenger tilgang til seat-en din" + +msgid "collection of hardware devices i.e. keyboard, mouse" +msgstr "samling av maskinvareenheter, f.eks. tastatur, mus" + +#, python-brace-format +msgid "Choose an option how to give {} access to your hardware" +msgstr "Velg hvordan {} skal få tilgang til maskinvaren din" + +#, python-brace-format +msgid "Environment type: {} {}" +msgstr "Miljøtype: {} {}" + +#, python-brace-format +msgid "Environment type: {}" +msgstr "Miljøtype: {}" + +msgid "Installed packages" +msgstr "Installerte pakker" + +msgid "Bluetooth" +msgstr "Bluetooth" + +msgid "Audio" +msgstr "Lyd" + +msgid "Print service" +msgstr "Utskriftstjeneste" + +msgid "Power management" +msgstr "Strømstyring" + +msgid "Firewall" +msgstr "Brannmur" + +msgid "Additional fonts" +msgstr "Tilleggsskrifter" + +msgid "Enabled" +msgstr "Aktivert" + +msgid "Disabled" +msgstr "Deaktivert" + +msgid "Would you like to configure Bluetooth?" +msgstr "Vil du konfigurere Bluetooth?" + +msgid "Would you like to configure the print service?" +msgstr "Vil du konfigurere utskriftstjenesten?" + +msgid "Select audio configuration" +msgstr "Velg lydkonfigurasjon" + +msgid "Select font packages to install" +msgstr "Velg skriftpakker å installere" + +msgid "ArchInstall Language" +msgstr "ArchInstall-språk" + +msgid "Version" +msgstr "Versjon" + +msgid "Installation Script" +msgstr "Installasjonsskript" + +msgid "Locales" +msgstr "Lokaliteter" + +msgid "Disk configuration" +msgstr "Diskkonfigurasjon" + +msgid "Profile" +msgstr "Profil" + +msgid "Mirrors and repositories" +msgstr "Speil og pakkebrønner" + +msgid "Network" +msgstr "Nettverk" + +msgid "Bootloader" +msgstr "Oppstartslaster" + +msgid "Application" +msgstr "Program" + +msgid "Authentication" +msgstr "Autentisering" + +msgid "Swap" +msgstr "Veksleminne" + +msgid "Hostname" +msgstr "Vertsnavn" + +msgid "Kernels" +msgstr "Kjerner" + +msgid "Automatic time sync (NTP)" +msgstr "Automatisk tidssynkronisering (NTP)" + +msgid "Timezone" +msgstr "Tidssone" + +msgid "Services" +msgstr "Tjenester" + +msgid "Additional packages" +msgstr "Tilleggspakker" + +msgid "Pacman" +msgstr "Pacman" + +msgid "Custom commands" +msgstr "Egendefinerte kommandoer" + +msgid "Users" +msgstr "Brukere" + +msgid "Root encrypted password" +msgstr "Kryptert root-passord" + +msgid "Disk encryption password" +msgstr "Passord for diskkryptering" + +msgid "Incorrect credentials file decryption password" +msgstr "Feil dekrypteringspassord for legitimasjonsfil" + +msgid "Enter credentials file decryption password" +msgstr "Skriv inn dekrypteringspassord for legitimasjonsfil" + +msgid "Incorrect password" +msgstr "Feil passord" + +#, python-brace-format +msgid "Setting up U2F login: {}" +msgstr "Setter opp U2F-innlogging: {}" + +#, python-brace-format +msgid "Setting up U2F device for user: {}" +msgstr "Setter opp U2F-enhet for bruker: {}" + +msgid "You may need to enter the PIN and then touch your U2F device to register it" +msgstr "Du må kanskje skrive inn PIN-koden og deretter berøre U2F-enheten for å registrere den" + +msgid "Root password" +msgstr "Root-passord" + +msgid "User account" +msgstr "Brukerkonto" + +msgid "U2F login setup" +msgstr "Oppsett av U2F-innlogging" + +msgid "U2F login method: " +msgstr "U2F-innloggingsmetode: " + +msgid "Passwordless sudo: " +msgstr "Passordløs sudo: " + +msgid "No U2F devices found" +msgstr "Ingen U2F-enheter funnet" + +msgid "Enter root password" +msgstr "Skriv inn root-passord" + +msgid "Enable passwordless sudo?" +msgstr "Aktivere passordløs sudo?" + +msgid "Unified kernel images" +msgstr "Samlede kjernebilder (UKI)" + +msgid "Install to removable location" +msgstr "Installer til flyttbar plassering" + +msgid "Plymouth" +msgstr "Plymouth" + +msgid "Will install to /EFI/BOOT/ (removable location, safe default)" +msgstr "Installeres til /EFI/BOOT/ (flyttbar plassering, trygt standardvalg)" + +msgid "Will install to custom location with NVRAM entry" +msgstr "Installeres til egendefinert plassering med NVRAM-oppføring" + +msgid "Would you like to use unified kernel images?" +msgstr "Vil du bruke samlede kjernebilder (UKI)?" + +msgid "Would you like to install the bootloader to the default removable media search location?" +msgstr "Vil du installere oppstartslasteren til standard søkeplassering for flyttbare medier?" + +msgid "This installs the bootloader to /EFI/BOOT/BOOTX64.EFI (or similar) which is useful for:" +msgstr "Dette installerer oppstartslasteren til /EFI/BOOT/BOOTX64.EFI (eller lignende), noe som er nyttig for:" + +msgid "Firmware that does not properly support NVRAM boot entries like most MSI motherboards," +msgstr "Fastvare som ikke støtter NVRAM-oppstartsoppføringer ordentlig, som de fleste MSI-hovedkort," + +msgid "most Apple Macs, many laptops..." +msgstr "de fleste Apple Mac-er, mange bærbare ..." + +msgid "USB drives or other portable external media." +msgstr "USB-stasjoner eller andre bærbare eksterne medier." + +msgid "Systems where you want the disk to be bootable on any computer." +msgstr "Systemer der du vil at disken skal kunne starte opp på enhver datamaskin." + +msgid "Select bootloader to install" +msgstr "Velg oppstartslaster å installere" + +msgid "UEFI is not detected and some options are disabled" +msgstr "UEFI er ikke oppdaget, og enkelte valg er deaktivert" + +msgid "Select Plymouth theme" +msgstr "Velg Plymouth-tema" + +msgid "The specified configuration will be applied" +msgstr "Den angitte konfigurasjonen vil bli tatt i bruk" + +msgid "Would you like to continue?" +msgstr "Vil du fortsette?" + +msgid "Configuration preview" +msgstr "Forhåndsvisning av konfigurasjon" + +msgid "No configuration" +msgstr "Ingen konfigurasjon" + +msgid "Save user configuration (including disk layout)" +msgstr "Lagre brukerkonfigurasjon (inkludert diskoppsett)" + +msgid "Save user credentials" +msgstr "Lagre brukerlegitimasjon" + +msgid "Save all" +msgstr "Lagre alt" + +msgid "Enter a directory for the configuration(s) to be saved" +msgstr "Angi en mappe der konfigurasjonen(e) skal lagres" + +#, python-brace-format +msgid "Do you want to save the configuration file(s) to {}?" +msgstr "Vil du lagre konfigurasjonsfilen(e) til {}?" + +msgid "Do you want to encrypt the user_credentials.json file?" +msgstr "Vil du kryptere filen user_credentials.json?" + +msgid "Credentials file encryption password" +msgstr "Krypteringspassord for legitimasjonsfil" + +msgid "Partitioning" +msgstr "Partisjonering" + +msgid "Disk encryption" +msgstr "Diskkryptering" + +#, python-brace-format +msgid "Configuration type: {}" +msgstr "Konfigurasjonstype: {}" + +msgid "Mountpoint" +msgstr "Monteringspunkt" + +msgid "Configuration" +msgstr "Konfigurasjon" + +msgid "Wipe" +msgstr "Slett" + +msgid "Physical volumes" +msgstr "Fysiske volumer" + +msgid "Volumes" +msgstr "Volumer" + +#, python-brace-format +msgid "Snapshot type: {}" +msgstr "Øyeblikksbildetype: {}" + +msgid "LVM disk encryption with more than 2 partitions is currently not supported" +msgstr "LVM-diskkryptering med mer enn 2 partisjoner støttes foreløpig ikke" + +msgid "Encryption type" +msgstr "Krypteringstype" + +msgid "Password" +msgstr "Passord" + +msgid "Iteration time" +msgstr "Iterasjonstid" + +msgid "Select disks for the installation" +msgstr "Velg disker for installasjonen" + +msgid "Partitions" +msgstr "Partisjoner" + +msgid "Select a disk configuration" +msgstr "Velg en diskkonfigurasjon" + +msgid "Enter root mount directory" +msgstr "Angi rotmonteringsmappe" + +msgid "You will use whatever drive-setup is mounted at the specified directory" +msgstr "Du vil bruke det diskoppsettet som er montert på den angitte mappen" + +msgid "WARNING: Archinstall won't check the suitability of this setup" +msgstr "ADVARSEL: Archinstall vil ikke kontrollere om dette oppsettet egner seg" + +msgid "Select main filesystem" +msgstr "Velg hovedfilsystem" + +msgid "Would you like to use compression or disable CoW?" +msgstr "Vil du bruke komprimering eller deaktivere CoW?" + +msgid "Use compression" +msgstr "Bruk komprimering" + +msgid "Disable Copy-on-Write" +msgstr "Deaktiver Copy-on-Write" + +msgid "Would you like to use BTRFS subvolumes with a default structure?" +msgstr "Vil du bruke BTRFS-undervolumer med en standardstruktur?" + +msgid "Would you like to create a separate partition for /home?" +msgstr "Vil du opprette en egen partisjon for /home?" + +msgid "The selected drives do not have the minimum capacity required for an automatic suggestion\n" +msgstr "De valgte stasjonene har ikke den minimumskapasiteten som kreves for et automatisk forslag\n" + +#, python-brace-format +msgid "Minimum capacity for /home partition: {}GiB\n" +msgstr "Minimumskapasitet for /home-partisjonen: {} GiB\n" + +#, python-brace-format +msgid "Minimum capacity for Arch Linux partition: {}GiB" +msgstr "Minimumskapasitet for Arch Linux-partisjonen: {} GiB" + +msgid "Encryption password" +msgstr "Krypteringspassord" + +msgid "LVM volumes" +msgstr "LVM-volumer" + +msgid "HSM" +msgstr "HSM" + +msgid "Partitions to be encrypted" +msgstr "Partisjoner som skal krypteres" + +msgid "LVM volumes to be encrypted" +msgstr "LVM-volumer som skal krypteres" + +msgid "HSM device" +msgstr "HSM-enhet" + +msgid "Select encryption type" +msgstr "Velg krypteringstype" + +msgid "Enter disk encryption password (leave blank for no encryption)" +msgstr "Skriv inn passord for diskkryptering (la stå tomt for ingen kryptering)" + +msgid "Select a FIDO2 device to use for HSM" +msgstr "Velg en FIDO2-enhet å bruke for HSM" + +msgid "Enter iteration time for LUKS encryption (in milliseconds)" +msgstr "Angi iterasjonstid for LUKS-kryptering (i millisekunder)" + +msgid "Higher values increase security but slow down boot time" +msgstr "Høyere verdier øker sikkerheten, men gir lengre oppstartstid" + +#, python-brace-format +msgid "Default: {}ms, Recommended range: 1000-60000" +msgstr "Standard: {} ms, anbefalt område: 1000–60000" + +msgid "Iteration time must be at least 100ms" +msgstr "Iterasjonstiden må være minst 100 ms" + +msgid "Iteration time must be at most 120000ms" +msgstr "Iterasjonstiden kan være maksimalt 120000 ms" + +msgid "Please enter a valid number" +msgstr "Skriv inn et gyldig tall" + +msgid "Suggest partition layout" +msgstr "Foreslå partisjonsoppsett" + +msgid "Remove all newly added partitions" +msgstr "Fjern alle nylig lagt til partisjoner" + +msgid "Assign mountpoint" +msgstr "Tildel monteringspunkt" + +msgid "Mark/Unmark to be formatted (wipes data)" +msgstr "Merk/fjern merking for formatering (sletter data)" + +msgid "Mark/Unmark as bootable" +msgstr "Merk/fjern merking som oppstartbar" + +msgid "Mark/Unmark as ESP" +msgstr "Merk/fjern merking som ESP" + +msgid "Mark/Unmark as XBOOTLDR" +msgstr "Merk/fjern merking som XBOOTLDR" + +msgid "Change filesystem" +msgstr "Endre filsystem" + +msgid "Mark/Unmark as compressed" +msgstr "Merk/fjern merking som komprimert" + +msgid "Mark/Unmark as nodatacow" +msgstr "Merk/fjern merking som nodatacow" + +msgid "Set subvolumes" +msgstr "Angi undervolumer" + +msgid "Delete partition" +msgstr "Slett partisjon" + +#, python-brace-format +msgid "Partition management: {}" +msgstr "Partisjonsbehandling: {}" + +#, python-brace-format +msgid "Total length: {}" +msgstr "Total lengde: {}" + +msgid "Partition - New" +msgstr "Partisjon – Ny" + +msgid "Partition" +msgstr "Partisjon" + +msgid "This partition is currently encrypted, to format it a filesystem has to be specified" +msgstr "Denne partisjonen er for øyeblikket kryptert. For å formatere den må et filsystem angis" + +msgid "Partition mount-points are relative to inside the installation, the boot would be /boot as an example." +msgstr "Monteringspunkter for partisjoner er relative til innsiden av installasjonen; oppstart vil for eksempel være /boot." + +msgid "Enter a mountpoint" +msgstr "Angi et monteringspunkt" + +msgid "Invalid size" +msgstr "Ugyldig størrelse" + +#, python-brace-format +msgid "Selected free space segment on device {}:" +msgstr "Valgt ledig diskområde på enhet {}:" + +#, python-brace-format +msgid "Size: {} / {}" +msgstr "Størrelse: {} / {}" + +msgid "All entered values can be suffixed with a unit: %, B, KB, KiB, MB, MiB..." +msgstr "Alle angitte verdier kan ha en enhet som suffiks: %, B, KB, KiB, MB, MiB ..." + +msgid "If no unit is provided, the value is interpreted as sectors" +msgstr "Hvis ingen enhet angis, tolkes verdien som sektorer" + +#, python-brace-format +msgid "Enter a size (default: {}): " +msgstr "Angi en størrelse (standard: {}): " + +msgid "This will remove all newly added partitions, continue?" +msgstr "Dette vil fjerne alle nylig lagt til partisjoner. Fortsette?" + +msgid "Add subvolume" +msgstr "Legg til undervolum" + +msgid "Edit subvolume" +msgstr "Rediger undervolum" + +msgid "Delete subvolume" +msgstr "Slett undervolum" + +msgid "Value cannot be empty" +msgstr "Verdien kan ikke være tom" + +msgid "Enter subvolume name" +msgstr "Angi navn på undervolum" + +msgid "Subvolume name" +msgstr "Navn på undervolum" + +msgid "Enter subvolume mountpoint" +msgstr "Angi monteringspunkt for undervolum" + +msgid "Exit archinstall" +msgstr "Avslutt archinstall" + +msgid "Reboot system" +msgstr "Start systemet på nytt" + +msgid "chroot into installation for post-installation configurations" +msgstr "chroot inn i installasjonen for konfigurasjon etter installasjon" + +msgid "Would you like to use automatic time synchronization (NTP) with the default time servers?\n" +msgstr "Vil du bruke automatisk tidssynkronisering (NTP) med standard tidsservere?\n" + +msgid "" +"Hardware time and other post-configuration steps might be required in order for NTP to work.\n" +"For more information, please check the Arch wiki" +msgstr "" +"Maskinvaretid og andre konfigurasjonssteg i etterkant kan være nødvendige for at NTP skal fungere.\n" +"For mer informasjon, se Arch-wikien" + +msgid "Enter a hostname" +msgstr "Angi et vertsnavn" + +msgid "Select timezone" +msgstr "Velg tidssone" + +msgid "What would you like to do next?" +msgstr "Hva vil du gjøre nå?" + +msgid "Select which kernel(s) to install" +msgstr "Velg hvilke(n) kjerne(r) som skal installeres" + +msgid "For the best compatibility with your AMD hardware, you may want to use either the all open-source or AMD / ATI options." +msgstr "For best kompatibilitet med AMD-maskinvaren din kan du bruke enten det helt åpne kildekode-alternativet eller AMD/ATI-alternativet." + +msgid "For the best compatibility with your Intel hardware, you may want to use either the all open-source or Intel options.\n" +msgstr "For best kompatibilitet med Intel-maskinvaren din kan du bruke enten det helt åpne kildekode-alternativet eller Intel-alternativet.\n" + +msgid "For the best compatibility with your Nvidia hardware, you may want to use the Nvidia proprietary driver.\n" +msgstr "For best kompatibilitet med Nvidia-maskinvaren din kan du bruke den proprietære Nvidia-driveren.\n" + +msgid "Would you like to use swap on zram?" +msgstr "Vil du bruke veksleminne på zram?" + +msgid "Select zram compression algorithm:" +msgstr "Velg komprimeringsalgoritme for zram:" + +msgid "Archinstall language" +msgstr "Archinstall-språk" + +msgid "Applications" +msgstr "Programmer" + +msgid "Network configuration" +msgstr "Nettverkskonfigurasjon" + +msgid "Save configuration" +msgstr "Lagre konfigurasjon" + +msgid "Install" +msgstr "Installer" + +msgid "Abort" +msgstr "Avbryt" + +msgid "Either root-password or at least 1 user with sudo privileges must be specified" +msgstr "Enten root-passord eller minst én bruker med sudo-rettigheter må angis" + +msgid "The selected desktop profile requires a regular user to log in via the greeter" +msgstr "Den valgte skrivebordsprofilen krever en vanlig bruker for å logge inn via innloggingsskjermen" + +msgid "Language" +msgstr "Språk" + +msgid "NTP" +msgstr "NTP" + +msgid "LVM configuration type" +msgstr "LVM-konfigurasjonstype" + +#, python-brace-format +msgid "Btrfs snapshot type: {}" +msgstr "Btrfs-øyeblikksbildetype: {}" + +msgid "Swap on zram" +msgstr "Veksleminne på zram" + +msgid "Compression algorithm" +msgstr "Komprimeringsalgoritme" + +msgid "Parallel Downloads" +msgstr "Parallelle nedlastinger" + +msgid "Color" +msgstr "Farge" + +msgid "Kernel" +msgstr "Kjerne" + +msgid "No network configuration selected. Network will need to be set up manually on the installed system." +msgstr "Ingen nettverkskonfigurasjon valgt. Nettverket må settes opp manuelt på det installerte systemet." + +msgid "Missing configurations:" +msgstr "Manglende konfigurasjoner:" + +msgid "Invalid configuration:" +msgstr "Ugyldig konfigurasjon:" + +msgid "Ready to install" +msgstr "Klar til å installere" + +msgid "Warnings:" +msgstr "Advarsler:" + +msgid "Profiles" +msgstr "Profiler" + +msgid "Graphics driver" +msgstr "Grafikkdriver" + +msgid "Greeter" +msgstr "Innloggingsskjerm (greeter)" + +msgid "Selected mirror regions" +msgstr "Valgte speilregioner" + +msgid "Custom servers" +msgstr "Egendefinerte servere" + +msgid "Optional repositories" +msgstr "Valgfrie pakkebrønner" + +msgid "Custom repositories" +msgstr "Egendefinerte pakkebrønner" + +#, python-brace-format +msgid "[!] A log file has been created here: {}" +msgstr "[!] En loggfil er opprettet her: {}" + +msgid "Please submit this issue (and file) to https://github.com/archlinux/archinstall/issues" +msgstr "Send inn dette problemet (og filen) til https://github.com/archlinux/archinstall/issues" + +msgid "Syncing the system..." +msgstr "Synkroniserer systemet ..." + +msgid "Waiting for time sync (timedatectl show) to complete." +msgstr "Venter på at tidssynkronisering (timedatectl show) skal fullføres." + +msgid "Time synchronization not completing, while you wait - check the docs for workarounds: https://archinstall.readthedocs.io/" +msgstr "Tidssynkroniseringen fullføres ikke. Mens du venter – sjekk dokumentasjonen for løsninger: https://archinstall.readthedocs.io/" + +msgid "Skipping waiting for automatic time sync (this can cause issues if time is out of sync during installation)" +msgstr "Hopper over venting på automatisk tidssynkronisering (dette kan føre til problemer hvis tiden ikke er synkronisert under installasjonen)" + +msgid "Waiting for Arch Linux keyring sync (archlinux-keyring-wkd-sync) to complete." +msgstr "Venter på at synkronisering av Arch Linux-nøkkelring (archlinux-keyring-wkd-sync) skal fullføres." + +msgid "Keyboard layout" +msgstr "Tastaturoppsett" + +msgid "Locale language" +msgstr "Lokalitetsspråk" + +msgid "Locale encoding" +msgstr "Lokalitetskoding" + +msgid "Console font" +msgstr "Konsollskrift" + +msgid "Back" +msgstr "Tilbake" + +msgid "Are you sure you want to reset this setting?" +msgstr "Er du sikker på at du vil tilbakestille denne innstillingen?" + +msgid "Confirm and exit" +msgstr "Bekreft og avslutt" + +msgid "Cancel" +msgstr "Avbryt" + +msgid "Password strength: Weak" +msgstr "Passordstyrke: Svakt" + +msgid "Password strength: Moderate" +msgstr "Passordstyrke: Middels" + +msgid "Password strength: Strong" +msgstr "Passordstyrke: Sterkt" + +msgid "Confirm password" +msgstr "Bekreft passord" + +msgid "The password did not match, please try again" +msgstr "Passordene var ikke like, prøv igjen" + +msgid "Not a valid directory" +msgstr "Ikke en gyldig mappe" + +msgid "Do you really want to abort?" +msgstr "Vil du virkelig avbryte?" + +msgid "Add a custom repository" +msgstr "Legg til en egendefinert pakkebrønn" + +msgid "Change custom repository" +msgstr "Endre egendefinert pakkebrønn" + +msgid "Delete custom repository" +msgstr "Slett egendefinert pakkebrønn" + +msgid "Enter a repository name" +msgstr "Angi et navn på pakkebrønnen" + +msgid "Name" +msgstr "Navn" + +msgid "Enter the repository url" +msgstr "Angi URL-en til pakkebrønnen" + +msgid "Url" +msgstr "URL" + +msgid "Select signature check" +msgstr "Velg signatursjekk" + +msgid "Signature check" +msgstr "Signatursjekk" + +msgid "Select signature option" +msgstr "Velg signaturvalg" + +msgid "Add a custom server" +msgstr "Legg til en egendefinert server" + +msgid "Change custom server" +msgstr "Endre egendefinert server" + +msgid "Delete custom server" +msgstr "Slett egendefinert server" + +msgid "Enter server url" +msgstr "Angi server-URL" + +msgid "Select regions" +msgstr "Velg regioner" + +msgid "Add custom servers" +msgstr "Legg til egendefinerte servere" + +msgid "Add custom repository" +msgstr "Legg til egendefinert pakkebrønn" + +msgid "Additional repositories" +msgstr "Flere pakkebrønner" + +msgid "Loading mirror regions..." +msgstr "Laster speilregioner ..." + +msgid "Select mirror regions to be enabled" +msgstr "Velg speilregioner som skal aktiveres" + +msgid "Select optional repositories to be enabled" +msgstr "Velg valgfrie pakkebrønner som skal aktiveres" + +msgid "Unicode font coverage for most languages" +msgstr "Unicode-skriftdekning for de fleste språk" + +msgid "color emoji for browsers and apps" +msgstr "fargeemoji for nettlesere og apper" + +msgid "Chinese, Japanese, Korean characters" +msgstr "kinesiske, japanske og koreanske tegn" + +msgid "Arial/Times/Courier replacement, Cyrillic support for Steam/games" +msgstr "erstatning for Arial/Times/Courier, kyrillisk støtte for Steam/spill" + +msgid "wide Unicode coverage, good fallback font" +msgstr "bred Unicode-dekning, god reserveskrift" + +msgid "Zram enabled" +msgstr "Zram aktivert" + +#, python-brace-format +msgid "Zram algorithm {}" +msgstr "Zram-algoritme {}" + +msgid "Bluetooth enabled" +msgstr "Bluetooth aktivert" + +#, python-brace-format +msgid "Audio server \"{}\"" +msgstr "Lydserver «{}»" + +#, python-brace-format +msgid "Power management \"{}\"" +msgstr "Strømstyring «{}»" + +msgid "Print service enabled" +msgstr "Utskriftstjeneste aktivert" + +#, python-brace-format +msgid "Firewall \"{}\"" +msgstr "Brannmur «{}»" + +#, python-brace-format +msgid "Extra fonts \"{}\"" +msgstr "Ekstra skrifter «{}»" + +msgid "Passwordless login" +msgstr "Passordløs innlogging" + +msgid "Second factor login" +msgstr "Tofaktorinnlogging" + +msgid "Root password set" +msgstr "Root-passord angitt" + +#, python-brace-format +msgid "Configured {} user(s)" +msgstr "Konfigurerte {} bruker(e)" + +msgid "U2F set up" +msgstr "U2F satt opp" + +#, python-brace-format +msgid "Bootloader \"{}\"" +msgstr "Oppstartslaster «{}»" + +msgid "UKI enabled" +msgstr "UKI aktivert" + +msgid "Removable" +msgstr "Flyttbar" + +#, python-brace-format +msgid "Plymouth \"{}\"" +msgstr "Plymouth «{}»" + +msgid "Use a best-effort default partition layout" +msgstr "Bruk et anbefalt standard partisjonsoppsett" + +msgid "Manual Partitioning" +msgstr "Manuell partisjonering" + +msgid "Pre-mounted configuration" +msgstr "Forhåndsmontert konfigurasjon" + +msgid "Default" +msgstr "Standard" + +msgid "Manual" +msgstr "Manuell" + +msgid "Pre-mount" +msgstr "Forhåndsmontering" + +#, python-brace-format +msgid "{} layout" +msgstr "{}-oppsett" + +#, python-brace-format +msgid "Devices {}" +msgstr "Enheter {}" + +msgid "LVM set up" +msgstr "LVM satt opp" + +#, python-brace-format +msgid "{} encryption" +msgstr "{}-kryptering" + +#, python-brace-format +msgid "Btrfs snapshot \"{}\"" +msgstr "Btrfs-øyeblikksbilde «{}»" + +msgid "Unknown" +msgstr "Ukjent" + +msgid "Default layout" +msgstr "Standardoppsett" + +msgid "No Encryption" +msgstr "Ingen kryptering" + +msgid "LUKS" +msgstr "LUKS" + +msgid "LVM on LUKS" +msgstr "LVM på LUKS" + +msgid "LUKS on LVM" +msgstr "LUKS på LVM" + +#, python-brace-format +msgid "Keyboard layout \"{}\"" +msgstr "Tastaturoppsett «{}»" + +#, python-brace-format +msgid "Locale language \"{}\"" +msgstr "Lokalitetsspråk «{}»" + +#, python-brace-format +msgid "Locale encoding \"{}\"" +msgstr "Lokalitetskoding «{}»" + +#, python-brace-format +msgid "Console font \"{}\"" +msgstr "Konsollskrift «{}»" + +#, python-brace-format +msgid "Mirror regions \"{}\"" +msgstr "Speilregioner «{}»" + +#, python-brace-format +msgid "Optional repositories \"{}\"" +msgstr "Valgfrie pakkebrønner «{}»" + +msgid "Custom servers set up" +msgstr "Egendefinerte servere satt opp" + +msgid "Custom repositories set up" +msgstr "Egendefinerte pakkebrønner satt opp" + +msgid "Copy ISO network configuration to installation" +msgstr "Kopier ISO-nettverkskonfigurasjon til installasjonen" + +msgid "Use Network Manager (default backend)" +msgstr "Bruk Network Manager (standard bakgrunnssystem)" + +msgid "Use Network Manager (iwd backend)" +msgstr "Bruk Network Manager (iwd-bakgrunnssystem)" + +msgid "Use standalone iwd" +msgstr "Bruk frittstående iwd" + +msgid "Manual configuration" +msgstr "Manuell konfigurasjon" + +msgid "Package group:" +msgstr "Pakkegruppe:" + +msgid "Color enabled" +msgstr "Farge aktivert" + +#, python-brace-format +msgid "{} graphics driver" +msgstr "{}-grafikkdriver" + +#, python-brace-format +msgid "{} greeter" +msgstr "{}-innloggingsskjerm" + +msgid "very weak" +msgstr "svært svakt" + +msgid "weak" +msgstr "svakt" + +msgid "moderate" +msgstr "middels" + +msgid "strong" +msgstr "sterkt" + +msgid "Add interface" +msgstr "Legg til grensesnitt" + +msgid "Edit interface" +msgstr "Rediger grensesnitt" + +msgid "Delete interface" +msgstr "Slett grensesnitt" + +msgid "Select an interface" +msgstr "Velg et grensesnitt" + +msgid "You need to enter a valid IP in IP-config mode" +msgstr "Du må angi en gyldig IP i IP-konfigurasjonsmodus" + +#, python-brace-format +msgid "Select which mode to configure for \"{}\"" +msgstr "Velg hvilken modus som skal konfigureres for «{}»" + +#, python-brace-format +msgid "Enter the IP and subnet for {} (example: 192.168.0.5/24): " +msgstr "Angi IP og subnett for {} (eksempel: 192.168.0.5/24): " + +msgid "Enter your gateway (router) IP address (leave blank for none)" +msgstr "Angi IP-adressen til gatewayen (ruteren) (la stå tomt for ingen)" + +msgid "Enter your DNS servers with space separated (leave blank for none)" +msgstr "Angi DNS-serverne dine, atskilt med mellomrom (la stå tomt for ingen)" + +msgid "Choose network configuration" +msgstr "Velg nettverkskonfigurasjon" + +msgid "Recommended: Network Manager for desktop, Manual for server" +msgstr "Anbefalt: Network Manager for skrivebord, Manuell for server" + +msgid "Configure interfaces" +msgstr "Konfigurer grensesnitt" + +msgid "No network connection found" +msgstr "Ingen nettverkstilkobling funnet" + +msgid "Would you like to connect to a Wifi?" +msgstr "Vil du koble til et wifi?" + +msgid "No wifi interface found" +msgstr "Ingen wifi-grensesnitt funnet" + +msgid "No wifi networks found" +msgstr "Ingen wifi-nettverk funnet" + +msgid "Select wifi network to connect to" +msgstr "Velg wifi-nettverk å koble til" + +msgid "Scanning wifi networks..." +msgstr "Søker etter wifi-nettverk ..." + +msgid "Failed setting up wifi" +msgstr "Kunne ikke sette opp wifi" + +msgid "Enter wifi password" +msgstr "Skriv inn wifi-passord" + +#, python-brace-format +msgid "Repositories: {}" +msgstr "Pakkebrønner: {}" + +msgid "Loading packages..." +msgstr "Laster pakker ..." + +msgid "No packages found" +msgstr "Ingen pakker funnet" + +msgid "Only packages such as base, sudo, linux, linux-firmware, efibootmgr and optional profile packages are installed." +msgstr "Bare pakker som base, sudo, linux, linux-firmware, efibootmgr og valgfrie profilpakker installeres." + +msgid "Note: base-devel is no longer installed by default. Add it here if you need build tools." +msgstr "Merk: base-devel installeres ikke lenger som standard. Legg den til her hvis du trenger byggeverktøy." + +msgid "Select any packages from the below list that should be installed additionally" +msgstr "Velg eventuelle pakker fra listen nedenfor som skal installeres i tillegg" + +#, python-brace-format +msgid "Enter the number of parallel downloads (1-{})" +msgstr "Angi antall parallelle nedlastinger (1–{})" + +#, python-brace-format +msgid "Value must be between 1 and {}" +msgstr "Verdien må være mellom 1 og {}" + +msgid "Enable colored output for pacman" +msgstr "Aktiver farget utdata for pacman" + +msgid "Pacman is already running, waiting maximum 10 minutes for it to terminate." +msgstr "Pacman kjører allerede. Venter maksimalt 10 minutter på at den skal avsluttes." + +msgid "Pre-existing pacman lock never exited. Please clean up any existing pacman sessions before using archinstall." +msgstr "En eksisterende pacman-lås ble aldri frigjort. Rydd opp i eventuelle eksisterende pacman-økter før du bruker archinstall." + +msgid "The proprietary Nvidia driver is not supported by Sway." +msgstr "Den proprietære Nvidia-driveren støttes ikke av Sway." + +msgid "It is likely that you will run into issues, are you okay with that?" +msgstr "Det er sannsynlig at du vil støte på problemer. Er det greit for deg?" + +msgid "Selected profiles: " +msgstr "Valgte profiler: " + +msgid "Select which greeter to install" +msgstr "Velg hvilken innloggingsskjerm som skal installeres" + +msgid "Select a profile type" +msgstr "Velg en profiltype" + +#, python-brace-format +msgid "Unable to fetch profile from specified url: {}" +msgstr "Kunne ikke hente profil fra angitt URL: {}" + +#, python-brace-format +msgid "Profiles must have unique name, but profile definitions with duplicate name found: {}" +msgstr "Profiler må ha unike navn, men profildefinisjoner med duplikatnavn ble funnet: {}" + +msgid "Add a user" +msgstr "Legg til en bruker" + +msgid "Change password" +msgstr "Endre passord" + +msgid "Promote/Demote user" +msgstr "Forfrem/degrader bruker" + +msgid "Delete User" +msgstr "Slett bruker" + +msgid "User" +msgstr "Bruker" + +msgid "Enter new password" +msgstr "Skriv inn nytt passord" + +msgid "The username you entered is invalid" +msgstr "Brukernavnet du oppga er ugyldig" + +msgid "Enter a username" +msgstr "Angi et brukernavn" + +msgid "Username" +msgstr "Brukernavn" + +msgid "Enter a password" +msgstr "Skriv inn et passord" + +#, python-brace-format +msgid "Should \"{}\" be a superuser (sudo)?\n" +msgstr "Skal «{}» være superbruker (sudo)?\n" + +#, python-brace-format +msgid "About to upload \"{}\" to the publicly accessible {}" +msgstr "Er i ferd med å laste opp «{}» til det offentlig tilgjengelige {}" + +msgid "Do you want to continue?" +msgstr "Vil du fortsette?" + +#, python-brace-format +msgid "Log uploaded successfully. URL: {}" +msgstr "Loggen ble lastet opp. URL: {}" + +msgid "Failed to upload log." +msgstr "Kunne ikke laste opp loggen." + +msgid "Archinstall requires root privileges to run. See --help for more." +msgstr "Archinstall krever root-rettigheter for å kjøre. Se --help for mer." + +msgid "New version available" +msgstr "Ny versjon tilgjengelig" + +msgid "Starting device modifications in " +msgstr "Starter endringer på enheten om " + +msgid "Ok" +msgstr "OK" + +msgid "Input cannot be empty" +msgstr "Inndata kan ikke være tom" + +msgid "Yes" +msgstr "Ja" + +msgid "No" +msgstr "Nei" + +msgid " (default)" +msgstr " (standard)" + From ebdf625e5c17517069bdfeb7bc553193d234863c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 30 Jun 2026 07:56:42 +1000 Subject: [PATCH 18/35] Update actions/checkout action to v7 (#4613) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/bandit.yaml | 2 +- .github/workflows/flake8.yaml | 2 +- .github/workflows/github-pages.yml | 2 +- .github/workflows/iso-build.yaml | 2 +- .github/workflows/mypy.yaml | 2 +- .github/workflows/pylint.yaml | 2 +- .github/workflows/pytest.yaml | 2 +- .github/workflows/python-build.yml | 2 +- .github/workflows/python-publish.yml | 2 +- .github/workflows/ruff-format.yaml | 2 +- .github/workflows/ruff-lint.yaml | 2 +- .github/workflows/translation-check.yaml | 2 +- .github/workflows/uki-build.yaml | 2 +- 13 files changed, 13 insertions(+), 13 deletions(-) diff --git a/.github/workflows/bandit.yaml b/.github/workflows/bandit.yaml index 551e1fad..68072742 100644 --- a/.github/workflows/bandit.yaml +++ b/.github/workflows/bandit.yaml @@ -6,7 +6,7 @@ jobs: container: image: archlinux/archlinux:latest steps: - - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 - run: pacman --noconfirm -Syu bandit - name: Security checkup with Bandit run: bandit -r archinstall || exit 0 diff --git a/.github/workflows/flake8.yaml b/.github/workflows/flake8.yaml index 3d4a4d42..278a9840 100644 --- a/.github/workflows/flake8.yaml +++ b/.github/workflows/flake8.yaml @@ -6,7 +6,7 @@ jobs: container: image: archlinux/archlinux:latest steps: - - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 - name: Prepare arch run: | pacman-key --init diff --git a/.github/workflows/github-pages.yml b/.github/workflows/github-pages.yml index d58c7f60..5f129d82 100644 --- a/.github/workflows/github-pages.yml +++ b/.github/workflows/github-pages.yml @@ -21,7 +21,7 @@ jobs: image: archlinux/archlinux:latest options: --privileged steps: - - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6 - name: Install pre-dependencies run: | diff --git a/.github/workflows/iso-build.yaml b/.github/workflows/iso-build.yaml index aa7f49b6..0e6eaabc 100644 --- a/.github/workflows/iso-build.yaml +++ b/.github/workflows/iso-build.yaml @@ -26,7 +26,7 @@ jobs: image: archlinux/archlinux:latest options: --privileged steps: - - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 - run: pwd - run: find . - run: cat /etc/os-release diff --git a/.github/workflows/mypy.yaml b/.github/workflows/mypy.yaml index 0fac32ba..35909767 100644 --- a/.github/workflows/mypy.yaml +++ b/.github/workflows/mypy.yaml @@ -6,7 +6,7 @@ jobs: container: image: archlinux/archlinux:latest steps: - - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 - name: Prepare arch run: | pacman-key --init diff --git a/.github/workflows/pylint.yaml b/.github/workflows/pylint.yaml index 30d251a8..0c6975c9 100644 --- a/.github/workflows/pylint.yaml +++ b/.github/workflows/pylint.yaml @@ -6,7 +6,7 @@ jobs: container: image: archlinux/archlinux:latest steps: - - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 - name: Prepare arch run: | pacman-key --init diff --git a/.github/workflows/pytest.yaml b/.github/workflows/pytest.yaml index b427d3e8..0378544b 100644 --- a/.github/workflows/pytest.yaml +++ b/.github/workflows/pytest.yaml @@ -7,7 +7,7 @@ jobs: image: archlinux/archlinux:latest options: --privileged steps: - - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 - name: Prepare arch run: | pacman-key --init diff --git a/.github/workflows/python-build.yml b/.github/workflows/python-build.yml index 67ca0165..313e63fb 100644 --- a/.github/workflows/python-build.yml +++ b/.github/workflows/python-build.yml @@ -11,7 +11,7 @@ jobs: image: archlinux/archlinux:latest options: --privileged steps: - - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 - name: Prepare arch run: | pacman-key --init diff --git a/.github/workflows/python-publish.yml b/.github/workflows/python-publish.yml index 539a606e..8868cd38 100644 --- a/.github/workflows/python-publish.yml +++ b/.github/workflows/python-publish.yml @@ -18,7 +18,7 @@ jobs: image: archlinux/archlinux:latest options: --privileged steps: - - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 - name: Prepare arch run: | pacman-key --init diff --git a/.github/workflows/ruff-format.yaml b/.github/workflows/ruff-format.yaml index 9f520be0..3dd4644d 100644 --- a/.github/workflows/ruff-format.yaml +++ b/.github/workflows/ruff-format.yaml @@ -4,6 +4,6 @@ jobs: ruff_format_check: runs-on: ubuntu-latest steps: - - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 - uses: astral-sh/ruff-action@0ce1b0bf8b818ef400413f810f8a11cdbda0034b # v4.0.0 - run: ruff format --diff diff --git a/.github/workflows/ruff-lint.yaml b/.github/workflows/ruff-lint.yaml index ff37a6a8..d329c42c 100644 --- a/.github/workflows/ruff-lint.yaml +++ b/.github/workflows/ruff-lint.yaml @@ -4,5 +4,5 @@ jobs: ruff: runs-on: ubuntu-latest steps: - - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 - uses: astral-sh/ruff-action@0ce1b0bf8b818ef400413f810f8a11cdbda0034b # v4.0.0 diff --git a/.github/workflows/translation-check.yaml b/.github/workflows/translation-check.yaml index ebc521cb..927e8858 100644 --- a/.github/workflows/translation-check.yaml +++ b/.github/workflows/translation-check.yaml @@ -15,7 +15,7 @@ jobs: name: Validate translations runs-on: ubuntu-latest steps: - - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 - name: Install gettext run: sudo apt-get update && sudo apt-get install -y gettext - name: Run translation checks diff --git a/.github/workflows/uki-build.yaml b/.github/workflows/uki-build.yaml index ff75250d..87e2feb0 100644 --- a/.github/workflows/uki-build.yaml +++ b/.github/workflows/uki-build.yaml @@ -26,7 +26,7 @@ jobs: image: archlinux/archlinux:latest options: --privileged steps: - - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 - run: pwd - run: find . - run: cat /etc/os-release From 8aec36aa0a6d2181b81d69322637c71f40fc0457 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 30 Jun 2026 07:57:04 +1000 Subject: [PATCH 19/35] Update dependency arch/python-cryptography to v49 (#4614) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 31560033..927a994c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -20,7 +20,7 @@ classifiers = [ dependencies = [ "pyparted==3.13.0", "pydantic==2.13.4", - "cryptography==48.0.1", + "cryptography==49.0.0", "textual==8.2.7", "markdown-it-py==4.0.0", "linkify-it-py==2.1.0", From caa88872045bd8e6e877e64253a19836d13c882e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 30 Jun 2026 07:57:22 +1000 Subject: [PATCH 20/35] Update dependency arch/python-systemd to v236 (#4615) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 927a994c..ed3d0ed5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -32,7 +32,7 @@ Documentation = "https://archinstall.readthedocs.io/" Source = "https://github.com/archlinux/archinstall" [project.optional-dependencies] -log = ["systemd_python==235"] +log = ["systemd_python==236"] dev = [ "mypy==2.1.0", "flake8==7.3.0", From f94c27430c6798f6a911b6f82dac4208787d1ea6 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 30 Jun 2026 07:58:02 +1000 Subject: [PATCH 21/35] Update dependency pytest to v9.1.1 (#4612) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index ed3d0ed5..3af92e69 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -39,7 +39,7 @@ dev = [ "pre-commit==4.6.0", "ruff==0.15.17", "pylint==4.0.6", - "pytest==9.0.3", + "pytest==9.1.1", "hypothesis>=6.152.4", ] doc = ["sphinx"] From ec9295634be06a225137746c8a47f16fa705edc4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 30 Jun 2026 07:58:17 +1000 Subject: [PATCH 22/35] Update pre-commit hook astral-sh/ruff-pre-commit to v0.15.20 (#4610) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 3b7c18df..b3bb8f3b 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.15.17 + rev: v0.15.20 hooks: # fix unused imports and sort them - id: ruff From 338e3cf4b8494da2aeca4ffca9218cd3a18ca989 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 30 Jun 2026 07:58:34 +1000 Subject: [PATCH 23/35] Update dependency ruff to v0.15.20 (#4609) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 3af92e69..4c916863 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -37,7 +37,7 @@ dev = [ "mypy==2.1.0", "flake8==7.3.0", "pre-commit==4.6.0", - "ruff==0.15.17", + "ruff==0.15.20", "pylint==4.0.6", "pytest==9.1.1", "hypothesis>=6.152.4", From aca482b69123682fd6a241d4216c31f5aebfa6e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?BlackCatOfficial=20=F0=9F=92=80=20=28Python=2C=20C++=2C=20?= =?UTF-8?q?Lua=29?= Date: Sun, 12 Jul 2026 18:18:50 +0700 Subject: [PATCH 24/35] Add Vietnamese to Archinstall (#4582) * add vn lang, trans lang, translating ~28% * done 80/735 (10% not ~28% sorry) and 735/735 done (counted fuzzy or google translate helper). See https://gist.github.com/BlackCatOfficialytb/e85bad1758d9e29c349f2d75b91363f1 for program to help me translate * doing plenty of things * up to 40% by removing fuzzy tag in correct translate words/paragraph * fix the extension * more words/paragraphs are unfuzzied * trans up to 57% * translate up to 61% --- archinstall/locales/languages.json | 2 +- archinstall/locales/vi/LC_MESSAGES/base.mo | Bin 0 -> 45219 bytes archinstall/locales/vi/LC_MESSAGES/base.po | 2753 ++++++++++++++++++++ 3 files changed, 2754 insertions(+), 1 deletion(-) create mode 100644 archinstall/locales/vi/LC_MESSAGES/base.mo create mode 100644 archinstall/locales/vi/LC_MESSAGES/base.po diff --git a/archinstall/locales/languages.json b/archinstall/locales/languages.json index 11fb97c7..a3b8138f 100644 --- a/archinstall/locales/languages.json +++ b/archinstall/locales/languages.json @@ -173,7 +173,7 @@ {"abbr": "ur", "lang": "Urdu", "translated_lang": "اردو"}, {"abbr": "uz", "lang": "Uzbek", "translated_lang": "O'zbek"}, {"abbr": "ve", "lang": "Venda"}, - {"abbr": "vi", "lang": "Vietnamese"}, + {"abbr": "vi", "lang": "Vietnamese", "translated_lang": "Tiếng Việt"}, {"abbr": "vo", "lang": "Volapük"}, {"abbr": "wa", "lang": "Walloon"}, {"abbr": "wo", "lang": "Wolof"}, diff --git a/archinstall/locales/vi/LC_MESSAGES/base.mo b/archinstall/locales/vi/LC_MESSAGES/base.mo new file mode 100644 index 0000000000000000000000000000000000000000..164367e27e0a4c7b8773d339603f240f54b5a2ff GIT binary patch literal 45219 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 literal 0 HcmV?d00001 diff --git a/archinstall/locales/vi/LC_MESSAGES/base.po b/archinstall/locales/vi/LC_MESSAGES/base.po new file mode 100644 index 00000000..6b62bb62 --- /dev/null +++ b/archinstall/locales/vi/LC_MESSAGES/base.po @@ -0,0 +1,2753 @@ +# +msgid "" +msgstr "" +"Project-Id-Version: \n" +"POT-Creation-Date: \n" +"PO-Revision-Date: \n" +"Last-Translator: BlackCat \n" +"Language-Team: \n" +"Language: vi\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 3.9\n" + +msgid "[!] A log file has been created here: {} {}" +msgstr "[!] Một tệp nhật ký (log) đã được tạo ở đây: {} {}" + +msgid " Please submit this issue (and file) to https://github.com/archlinux/archinstall/issues" +msgstr "" +" Vui lòng gửi vấn đề này (và tệp tin) đến địa chỉ https://github.com/archlinux/archinstall/issues" + +msgid "Do you really want to abort?" +msgstr "Bạn thật sự có muốn hủy bỏ không?" + +msgid "And one more time for verification: " +msgstr "Xin hãy xác nhận một lần nữa: " + +msgid "Would you like to use swap on zram?" +msgstr "Bạn có muốn sử dụng swap trên zram không?" + +msgid "Desired hostname for the installation: " +msgstr "Tên của máy mà bạn mong muốn trong quá trình cài đặt: " + +msgid "Username for required superuser with sudo privileges: " +msgstr "Tên người dùng cho tài khoản quản trị có quyền sudo: " + +msgid "Any additional users to install (leave blank for no users): " +msgstr "Thêm người dùng khác (để trống nếu không cần): " + +msgid "Should this user be a superuser (sudoer)?" +msgstr "Bạn có muốn người dùng này là quản trị viên (superuser/sudoer) không ?" + +msgid "Select a timezone" +msgstr "Vui lòng chọn múi giờ" + +msgid "Would you like to use GRUB as a bootloader instead of systemd-boot?" +msgstr "Bạn có muốn GRUB là trình khởi động (bootloader) mặc định thay vì systemd-boot không?" + +msgid "Choose a bootloader" +msgstr "Chọn một trình khởi động (bootloader)" + +msgid "Choose an audio server" +msgstr "Chọn hệ thống âm thanh" + +msgid "" +"Only packages such as base, base-devel, linux, linux-firmware, efibootmgr and optional profile " +"packages are installed." +msgstr "" +"Chỉ có base, base-devel, linux, linux-firmware, efibootmgr và các gói cấu hình (profile) tùy chọn " +"sẽ được cài đặt." + +msgid "Note: base-devel is no longer installed by default. Add it here if you need build tools." +msgstr "" +"Lưu ý: base-devel không còn được cài đặt mặc định nữa. Thêm nó ở đây nếu bạn cần công cụ biên dịch." + +msgid "" +"If you desire a web browser, such as firefox or chromium, you may specify it in the following " +"prompt." +msgstr "" +"Nếu bạn cần trình duyệt như Firefox hay Chromium, bạn có thể chỉ định chúng ở dòng nhắc dưới đây." + +msgid "Write additional packages to install (space separated, leave blank to skip): " +msgstr "Ghi tất cả gói mà bạn muốn cài đặt (cách nhau bằng dấu cách, bỏ trống để bỏ qua): " + +msgid "Copy ISO network configuration to installation" +msgstr "Sao chép cấu hình mạng của ISO sang thư mục cài đặt" + +msgid "Use NetworkManager (necessary for configuring internet graphically in GNOME and KDE)" +msgstr "Dùng NetworkManager (cần thiết cho cấu hình mạng bằng giao diện đồ họa trên GNOME và KDE)" + +msgid "Select one network interface to configure" +msgstr "Chọn một giao diện mạng để cấu hình" + +msgid "Select which mode to configure for \"{}\" or skip to use default mode \"{}\"" +msgstr "Chọn chế độ nào để cấu hình cho \"{}\" hoặc bỏ qua để dùng cái mặc định \"{}\"" + +#, python-brace-format +msgid "Enter the IP and subnet for {} (example: 192.168.0.5/24): " +msgstr "Nhập địa chỉ IP và subnet cho {} (ví dụ: 192.168.0.5/24): " + +msgid "Enter your gateway (router) IP address or leave blank for none: " +msgstr "Nhập địa chỉ IP gateway (router) của bạn hoặc bỏ trống nếu không có: " + +msgid "Enter your DNS servers (space separated, blank for none): " +msgstr "Nhập máy chủ DNS mà bạn muốn (cách nhau bởi dấu cách, bỏ trống nếu muốn dùng mặc định): " + +msgid "Select which filesystem your main partition should use" +msgstr "Chọn hệ thống tệp nào mà phân vùng chính của bạn nên dùng" + +msgid "Current partition layout" +msgstr "Bố cục phân vùng hiện tại" + +msgid "" +"Select what to do with\n" +"{}" +msgstr "" +"Chọn hành động cho\n" +"{}" + +msgid "Enter a desired filesystem type for the partition" +msgstr "Vui lòng nhập loại hệ thống tập tin mà bạn muốn cho phân vùng" + +msgid "Enter the start location (in parted units: s, GB, %, etc. ; default: {}): " +msgstr "Nhập vị trí bắt đầu của phân vùng (theo đơn vị phân vùng: s, GB, %, v.v.; mặc định: {}): " + +msgid "Enter the end location (in parted units: s, GB, %, etc. ; ex: {}): " +msgstr "Nhập vị trí kết thúc của phân vùng (theo đơn vị phân vùng: s, GB, %, v.v.; mặc định: {}): " + +msgid "{} contains queued partitions, this will remove those, are you sure?" +msgstr "{} chứa các phân vùng trong hàng đợi, hành động này sẽ loại bỏ chúng, bạn có chắc chắn không?" + +msgid "" +"{}\n" +"\n" +"Select by index which partitions to delete" +msgstr "" +"{}\n" +"\n" +"Chọn số thứ tự của phân vùng cần xóa" + +msgid "" +"{}\n" +"\n" +"Select by index which partition to mount where" +msgstr "" +"{}\n" +"\n" +"Chọn số thứ tự phân vùng nàu cần gắn (mount)" + +msgid "" +" * Partition mount-points are relative to inside the installation, the boot would be /boot as an " +"example." +msgstr "" +" * Các điểm gắn phân vùng được tính tương đối với bên trong hệ thống mới, ví dụ phân vùng khởi động " +"sẽ là /boot." + +msgid "Select where to mount partition (leave blank to remove mountpoint): " +msgstr "Chọn điểm gắn cho phân vùng (để trống để xóa điểm gắn): " + +msgid "" +"{}\n" +"\n" +"Select which partition to mask for formatting" +msgstr "" +"{}\n" +"\n" +"Chọn phân vùng muốn đánh dấu để định dạng" + +msgid "" +"{}\n" +"\n" +"Select which partition to mark as encrypted" +msgstr "" +"{}\n" +"\n" +"Chọn phân vùng để mã hóa" + +msgid "" +"{}\n" +"\n" +"Select which partition to mark as bootable" +msgstr "" +"{}\n" +"\n" +"Chọn phân vùng làm phân vùng khởi động" + +msgid "" +"{}\n" +"\n" +"Select which partition to set a filesystem on" +msgstr "" +"{}\n" +"\n" +"Chọn phân vùng để đặt tệp hệ thống" + +msgid "Enter a desired filesystem type for the partition: " +msgstr "Chọn loại hệ thống tập tin mà bạn muốn cho phân vùng: " + +msgid "Archinstall language" +msgstr "Ngôn ngữ (Archinstall)" + +msgid "Wipe all selected drives and use a best-effort default partition layout" +msgstr "Xóa sạch các ổ đĩa đã chọn và dùng bố cục phân vùng mặc định tốt nhất" + +msgid "Select what to do with each individual drive (followed by partition usage)" +msgstr "Chọn việc với mỗi ổ đĩa (theo sau là cách sử dụng phân vùng)" + +msgid "Select what you wish to do with the selected block devices" +msgstr "Chọn những gì bạn muốn làm với các thiết bị đã chọn" + +msgid "" +"This is a list of pre-programmed profiles, they might make it easier to install things like desktop " +"environments" +msgstr "" +"Đây là danh sách các cấu hình được lập trình sẵn, chúng có thể giúp cài đặt những thứ như môi " +"trường máy tính dễ dàng hơn" + +msgid "Select keyboard layout" +msgstr "Bố cục bàn phím hiện tại" + +msgid "Select one of the regions to download packages from" +msgstr "Chọn một trong các khu vực để tải xuống các gói" + +msgid "Select one or more hard drives to use and configure" +msgstr "Chọn một hoặc nhiều ổ cứng để sử dụng và cấu hình" + +msgid "" +"For the best compatibility with your AMD hardware, you may want to use either the all open-source " +"or AMD / ATI options." +msgstr "" +"Để có khả năng tương thích tốt nhất với phần cứng AMD của bạn, bạn có thể muốn sử dụng tùy chọn tất " +"cả nguồn mở hoặc AMD / ATI." + +msgid "" +"For the best compatibility with your Intel hardware, you may want to use either the all open-source " +"or Intel options.\n" +msgstr "" +"Để có khả năng tương thích tốt nhất với phần cứng Intel của bạn, bạn có thể muốn sử dụng tùy chọn " +"tất cả nguồn mở hoặc Intel.\n" + +msgid "" +"For the best compatibility with your Nvidia hardware, you may want to use the Nvidia proprietary " +"driver.\n" +msgstr "" +"Để có khả năng tương thích tốt nhất với phần cứng Nvidia của bạn, bạn có thể muốn sử dụng trình " +"điều khiển độc quyền của Nvidia.\n" + +msgid "" +"\n" +"\n" +"Select a graphics driver or leave blank to install all open-source drivers" +msgstr "" +"\n" +"\n" +"Chọn trình điều khiển đồ họa hoặc để trống để cài đặt tất cả trình điều khiển nguồn mở" + +msgid "All open-source (default)" +msgstr "Tất cả nguồn mở (mặc định)" + +msgid "Choose which kernels to use or leave blank for default \"{}\"" +msgstr "Chọn nhân nào sẽ sử dụng hoặc để trống mặc định \"{}\"" + +msgid "Choose which locale language to use" +msgstr "Chọn ngôn ngữ hệ thống muốn sử dụng" + +msgid "Choose which locale encoding to use" +msgstr "Chọn mã hóa ngôn ngữ nào sẽ sử dụng" + +msgid "Select one of the values shown below: " +msgstr "Chọn một trong các giá trị hiển thị bên dưới: " + +msgid "Select one or more of the options below: " +msgstr "Chọn một hoặc nhiều tùy chọn bên dưới: " + +msgid "Adding partition...." +msgstr "Đang thêm phân vùng...." + +msgid "You need to enter a valid fs-type in order to continue. See `man parted` for valid fs-type's." +msgstr "" +"Vui lòng nhập loại hệ thống tập tin (fs) hợp lệ để tiếp tục. Xem `man parted` để biết loại fs hợp " +"lệ." + +msgid "Error: Listing profiles on URL \"{}\" resulted in:" +msgstr "Lỗi: Liệt kê cấu hình trên URL \"{}\" dẫn đến:" + +msgid "Error: Could not decode \"{}\" result as JSON:" +msgstr "Lỗi: Không thể giải mã kết quả \"{}\" dưới dạng JSON:" + +msgid "Keyboard layout" +msgstr "Bố cục bàn phím" + +msgid "Mirror region" +msgstr "Máy chủ bản sao" + +msgid "Locale language" +msgstr "Ngôn ngữ hệ thống (Locale)" + +msgid "Locale encoding" +msgstr "Mã hóa ngôn ngữ hệ thống" + +msgid "Console font" +msgstr "Phông chữ console" + +msgid "Drive(s)" +msgstr "(Các) ổ đĩa" + +msgid "Disk layout" +msgstr "Bố trí đĩa" + +msgid "Encryption password" +msgstr "Mật khẩu mã hóa" + +msgid "Swap" +msgstr "Bộ nhớ đệm (Swap)" + +msgid "Bootloader" +msgstr "Trình khởi động" + +msgid "Root password" +msgstr "Mật khẩu root" + +msgid "Superuser account" +msgstr "Tài khoản siêu người dùng" + +msgid "User account" +msgstr "Tài khoản người dùng" + +msgid "Profile" +msgstr "Cấu hình (Profile)" + +msgid "Audio" +msgstr "Âm thanh" + +msgid "Kernels" +msgstr "Nhân" + +msgid "Additional packages" +msgstr "Gói bổ sung" + +msgid "Network configuration" +msgstr "Cấu hình mạng" + +msgid "Automatic time sync (NTP)" +msgstr "Đồng bộ hóa thời gian tự động (NTP)" + +#, fuzzy +msgid "Install ({} config(s) missing)" +msgstr "Cài đặt (thiếu (các) cấu hình {})" + +msgid "" +"You decided to skip harddrive selection\n" +"and will use whatever drive-setup is mounted at {} (experimental)\n" +"WARNING: Archinstall won't check the suitability of this setup\n" +"Do you wish to continue?" +msgstr "" +"Bạn quyết định bỏ qua việc lựa chọn ổ cứng\n" +"và sẽ sử dụng bất kỳ thiết lập ổ đĩa nào được gắn ở {} (thử nghiệm)\n" +"CẢNH BÁO: Archinstall sẽ không kiểm tra tính phù hợp của thiết lập này\n" +"Bạn có muốn tiếp tục không?" + +msgid "Re-using partition instance: {}" +msgstr "Sử dụng lại phiên bản phân vùng: {}" + +msgid "Create a new partition" +msgstr "Tạo một phân vùng mới" + +msgid "Delete a partition" +msgstr "Xóa một phân vùng" + +msgid "Clear/Delete all partitions" +msgstr "Xóa tất cả các phân vùng" + +msgid "Assign mount-point for a partition" +msgstr "Gán điểm gắn cho một phân vùng" + +msgid "Mark/Unmark a partition to be formatted (wipes data)" +msgstr "Đánh dấu/Bỏ đánh dấu phân vùng cần định dạng (xóa dữ liệu)" + +msgid "Mark/Unmark a partition as encrypted" +msgstr "Đánh dấu/Bỏ đánh dấu phân vùng là đã mã hóa" + +msgid "Mark/Unmark a partition as bootable (automatic for /boot)" +msgstr "Đánh dấu/Bỏ đánh dấu phân vùng là có khả năng khởi động (tự động cho/boot)" + +msgid "Set desired filesystem for a partition" +msgstr "Đặt hệ thống tập tin mong muốn cho một phân vùng" + +msgid "Abort" +msgstr "Hủy bỏ" + +msgid "Hostname" +msgstr "Tên máy" + +msgid "Not configured, unavailable unless setup manually" +msgstr "Chưa được định cấu hình, không khả dụng trừ khi được thiết lập thủ công" + +msgid "Timezone" +msgstr "Múi giờ" + +msgid "Set/Modify the below options" +msgstr "Đặt/Sửa đổi các tùy chọn bên dưới" + +msgid "Install" +msgstr "Cài đặt" + +msgid "" +"Use ESC to skip\n" +"\n" +msgstr "" +"Sử dụng ESC để bỏ qua\n" +"\n" + +msgid "Suggest partition layout" +msgstr "Đề xuất bố trí phân vùng" + +msgid "Enter a password: " +msgstr "Nhập mật khẩu: " + +msgid "Enter a encryption password for {}" +msgstr "Nhập mật khẩu mã hóa cho {}" + +msgid "Enter disk encryption password (leave blank for no encryption): " +msgstr "Nhập mật khẩu mã hóa ổ đĩa (để trống nếu không mã hóa): " + +msgid "Create a required super-user with sudo privileges: " +msgstr "Tạo một siêu người dùng bắt buộc với các đặc quyền sudo: " + +msgid "Enter root password (leave blank to disable root): " +msgstr "Nhập mật khẩu root (để trống để tắt root): " + +msgid "Password for user \"{}\": " +msgstr "Mật khẩu cho người dùng \"{}\": " + +msgid "Verifying that additional packages exist (this might take a few seconds)" +msgstr "Xác minh rằng các gói bổ sung tồn tại (việc này có thể mất vài giây)" + +msgid "Would you like to use automatic time synchronization (NTP) with the default time servers?\n" +msgstr "" +"Bạn có muốn sử dụng đồng bộ hóa thời gian tự động (NTP) với máy chủ thời gian mặc định không?\n" + +#, fuzzy +msgid "" +"Hardware time and other post-configuration steps might be required in order for NTP to work.\n" +"For more information, please check the Arch wiki" +msgstr "" +"Thời gian phần cứng và các bước sau cấu hình khác có thể được yêu cầu để NTP hoạt động.\n" +"Để biết thêm thông tin, vui lòng kiểm tra Arch wiki" + +msgid "Enter a username to create an additional user (leave blank to skip): " +msgstr "Nhập tên người dùng để tạo thêm người dùng (để trống để bỏ qua): " + +msgid "Use ESC to skip\n" +msgstr "Sử dụng ESC để bỏ qua\n" + +msgid "" +"\n" +" Choose an object from the list, and select one of the available actions for it to execute" +msgstr "" +"\n" +" Chọn một đối tượng từ danh sách và chọn một trong các hành động có sẵn để nó thực thi" + +msgid "Cancel" +msgstr "Hủy bỏ" + +msgid "Confirm and exit" +msgstr "Xác nhận và thoát" + +msgid "Add" +msgstr "Thêm" + +msgid "Copy" +msgstr "Sao chép" + +msgid "Edit" +msgstr "Chỉnh sửa" + +msgid "Delete" +msgstr "Xóa" + +msgid "Select an action for '{}'" +msgstr "Chọn hành động cho '{}'" + +msgid "Copy to new key:" +msgstr "Sao chép sang khóa mới:" + +#, fuzzy +msgid "Unknown nic type: {}. Possible values are {}" +msgstr "Loại nic không xác định: {} . Giá trị có thể là {}" + +msgid "" +"\n" +"This is your chosen configuration:" +msgstr "" +"\n" +"Đây là cấu hình bạn đã chọn:" + +msgid "Pacman is already running, waiting maximum 10 minutes for it to terminate." +msgstr "Pacman đang chạy, đợi tối đa 10 phút để nó kết thúc." + +msgid "" +"Pre-existing pacman lock never exited. Please clean up any existing pacman sessions before using " +"archinstall." +msgstr "" +"Khóa pacman có sẵn không bao giờ thoát. Vui lòng dọn sạch mọi phiên pacman hiện có trước khi sử " +"dụng Archinstall." + +#, fuzzy +msgid "Choose which optional additional repositories to enable" +msgstr "Chọn kho bổ sung tùy chọn nào để kích hoạt" + +msgid "Add a user" +msgstr "Thêm người dùng" + +msgid "Change password" +msgstr "Thay đổi mật khẩu" + +msgid "Promote/Demote user" +msgstr "Cấp/Tước quyền quản trị cho người dùng" + +msgid "Delete User" +msgstr "Xóa người dùng" + +msgid "" +"\n" +"Define a new user\n" +msgstr "" +"\n" +"Xác định người dùng mới\n" + +msgid "User Name : " +msgstr "Tên người dùng: " + +#, fuzzy +msgid "Should {} be a superuser (sudoer)?" +msgstr "{} có nên là siêu người dùng (sudoer) không?" + +msgid "Define users with sudo privilege: " +msgstr "Xác định người dùng có đặc quyền sudo: " + +msgid "No network configuration" +msgstr "Không có cấu hình mạng" + +msgid "Set desired subvolumes on a btrfs partition" +msgstr "Đặt các phân vùng con (subvolume) mong muốn trên phân vùng btrfs" + +#, fuzzy +msgid "" +"{}\n" +"\n" +"Select which partition to set subvolumes on" +msgstr "" +"{} \n" +"\n" +"Chọn phân vùng để đặt subvolume trên" + +msgid "Manage btrfs subvolumes for current partition" +msgstr "Quản lý subvolume btrfs cho phân vùng hiện tại" + +msgid "No configuration" +msgstr "Không có cấu hình" + +msgid "Save user configuration" +msgstr "Lưu cấu hình người dùng" + +msgid "Save user credentials" +msgstr "Lưu thông tin đăng nhập của người dùng" + +msgid "Save disk layout" +msgstr "Lưu bố cục đĩa" + +msgid "Save all" +msgstr "Lưu tất cả" + +msgid "Choose which configuration to save" +msgstr "Chọn cấu hình nào để lưu" + +msgid "Enter a directory for the configuration(s) to be saved: " +msgstr "Nhập thư mục để lưu (các) cấu hình: " + +msgid "Not a valid directory: {}" +msgstr "Thư mục không hợp lệ: {}" + +msgid "The password you are using seems to be weak," +msgstr "Mật khẩu bạn đang sử dụng có vẻ yếu," + +msgid "are you sure you want to use it?" +msgstr "bạn có chắc chắn muốn sử dụng nó không?" + +msgid "Optional repositories" +msgstr "Kho phần mềm tùy chọn" + +msgid "Save configuration" +msgstr "Lưu cấu hình" + +msgid "Missing configurations:\n" +msgstr "Thiếu cấu hình:\n" + +msgid "Either root-password or at least 1 superuser must be specified" +msgstr "Phải chỉ định mật khẩu gốc hoặc ít nhất 1 siêu người dùng" + +msgid "Manage superuser accounts: " +msgstr "Quản lý tài khoản siêu người dùng: " + +#, fuzzy +msgid "Manage ordinary user accounts: " +msgstr "Quản lý tài khoản người dùng thông thường:" + +msgid " Subvolume :{:16}" +msgstr " Phân vùng con (subvolume): {:16}" + +msgid " mounted at {:16}" +msgstr " gắn ở {:16}" + +msgid " with option {}" +msgstr " với tùy chọn {}" + +msgid "" +"\n" +" Fill the desired values for a new subvolume \n" +msgstr "" +"\n" +"Điền các giá trị mong muốn cho một subvolume mới\n" + +msgid "Subvolume name " +msgstr "Tên phân vùng con (subvolume) " + +msgid "Subvolume mountpoint" +msgstr "Điểm gắn phân vùng con (subvolume)" + +msgid "Subvolume options" +msgstr "Tùy chọn phân vùng con (subvolume) phụ" + +msgid "Save" +msgstr "Lưu" + +msgid "Subvolume name :" +msgstr "Tên tập con:" + +msgid "Select a mount point :" +msgstr "Chọn điểm gắn:" + +msgid "Select the desired subvolume options " +msgstr "Chọn các tùy chọn tập con mong muốn " + +msgid "Define users with sudo privilege, by username: " +msgstr "Xác định người dùng có đặc quyền sudo, theo tên người dùng: " + +#, python-brace-format +msgid "[!] A log file has been created here: {}" +msgstr "[!] Một tệp nhật ký đã được tạo ở đây: {}" + +#, fuzzy +msgid "Would you like to use BTRFS subvolumes with a default structure?" +msgstr "Bạn có muốn sử dụng các tập con BTRFS có cấu trúc mặc định không?" + +msgid "Would you like to use BTRFS compression?" +msgstr "Bạn có muốn sử dụng tính năng nén BTRFS không?" + +msgid "Would you like to create a separate partition for /home?" +msgstr "Bạn có muốn tạo một phân vùng riêng cho /home không?" + +msgid "The selected drives do not have the minimum capacity required for an automatic suggestion\n" +msgstr "Các ổ đĩa đã chọn không có dung lượng tối thiểu cần thiết để tự động đề xuất\n" + +msgid "Minimum capacity for /home partition: {}GB\n" +msgstr "Dung lượng tối thiểu cho phân vùng /home: {} GB\n" + +msgid "Minimum capacity for Arch Linux partition: {}GB" +msgstr "Dung lượng tối thiểu cho phân vùng Arch Linux: {}GB" + +msgid "Continue" +msgstr "Tiếp tục" + +msgid "yes" +msgstr "có" + +msgid "no" +msgstr "không" + +msgid "set: {}" +msgstr "thiết lập: {}" + +msgid "Manual configuration setting must be a list" +msgstr "Cài đặt cấu hình thủ công phải là một danh sách" + +msgid "No iface specified for manual configuration" +msgstr "Không có iface được chỉ định cho cấu hình thủ công" + +msgid "Manual nic configuration with no auto DHCP requires an IP address" +msgstr "Cấu hình nic thủ công không có DHCP tự động yêu cầu địa chỉ IP" + +msgid "Add interface" +msgstr "Thêm giao diện" + +msgid "Edit interface" +msgstr "Chỉnh sửa giao diện" + +msgid "Delete interface" +msgstr "Xóa giao diện" + +msgid "Select interface to add" +msgstr "Chọn giao diện để thêm" + +msgid "Manual configuration" +msgstr "Cấu hình thủ công" + +msgid "Mark/Unmark a partition as compressed (btrfs only)" +msgstr "Đánh dấu/Bỏ đánh dấu phân vùng là đã nén (chỉ btrfs)" + +msgid "The password you are using seems to be weak, are you sure you want to use it?" +msgstr "Mật khẩu bạn đang sử dụng có vẻ yếu, bạn có chắc chắn muốn sử dụng nó không?" + +msgid "Provides a selection of desktop environments and tiling window managers, e.g. gnome, kde, sway" +msgstr "" +"Cung cấp lựa chọn môi trường máy tính để bàn và trình quản lý cửa sổ xếp lớp, ví dụ: gnome, kde, " +"sway" + +msgid "Select your desired desktop environment" +msgstr "Chọn môi trường máy tính mong muốn của bạn" + +msgid "A very basic installation that allows you to customize Arch Linux as you see fit." +msgstr "Một bản cài đặt rất cơ bản cho phép bạn tùy chỉnh Arch Linux khi bạn thấy phù hợp." + +msgid "" +"Provides a selection of various server packages to install and enable, e.g. httpd, nginx, mariadb" +msgstr "" +"Cung cấp nhiều lựa chọn gói máy chủ khác nhau để cài đặt và kích hoạt, ví dụ: httpd, nginx, mariadb" + +msgid "Choose which servers to install, if none then a minimal installation will be done" +msgstr "Chọn máy chủ nào sẽ cài đặt, nếu không có thì cài đặt tối thiểu sẽ được thực hiện" + +#, fuzzy +msgid "Installs a minimal system as well as xorg and graphics drivers." +msgstr "Cài đặt một hệ thống tối thiểu cũng như trình điều khiển xorg và đồ họa." + +msgid "Press Enter to continue." +msgstr "Nhấn Enter để tiếp tục." + +msgid "" +"Would you like to chroot into the newly created installation and perform post-installation " +"configuration?" +msgstr "Bạn có muốn chroot vào bản cài đặt mới tạo và thực hiện cấu hình sau khi cài đặt không?" + +msgid "Are you sure you want to reset this setting?" +msgstr "Bạn có chắc chắn muốn đặt lại cài đặt này không?" + +msgid "Select one or more hard drives to use and configure\n" +msgstr "Chọn một hoặc nhiều ổ cứng để sử dụng và cấu hình\n" + +msgid "Any modifications to the existing setting will reset the disk layout!" +msgstr "Mọi sửa đổi đối với cài đặt hiện có sẽ đặt lại bố cục đĩa!" + +msgid "" +"If you reset the harddrive selection this will also reset the current disk layout. Are you sure?" +msgstr "" +"Nếu bạn đặt lại lựa chọn ổ cứng, thao tác này cũng sẽ đặt lại bố cục đĩa hiện tại. Bạn có chắc " +"không?" + +msgid "Save and exit" +msgstr "Lưu và thoát" + +msgid "" +"{}\n" +"contains queued partitions, this will remove those, are you sure?" +msgstr "" +"{}\n" +"chứa các phân vùng được xếp hàng đợi, thao tác này sẽ xóa những phân vùng đó, bạn có chắc không?" + +msgid "No audio server" +msgstr "Không có hệ thống âm thanh" + +msgid "(default)" +msgstr "(mặc định)" + +msgid "Use ESC to skip" +msgstr "Sử dụng ESC để bỏ qua" + +msgid "" +"Use CTRL+C to reset current selection\n" +"\n" +msgstr "Sử dụng CTRL+C để đặt lại lựa chọn hiện tại\n" + +msgid "Copy to: " +msgstr "Sao chép vào: " + +msgid "Edit: " +msgstr "Chỉnh sửa: " + +msgid "Key: " +msgstr "Khóa: " + +msgid "Edit {}: " +msgstr "Chỉnh sửa {}: " + +msgid "Add: " +msgstr "Thêm: " + +msgid "Value: " +msgstr "Giá trị: " + +msgid "" +"You can skip selecting a drive and partitioning and use whatever drive-setup is mounted at /mnt " +"(experimental)" +msgstr "" +"Bạn có thể bỏ qua việc chọn ổ đĩa và phân vùng và sử dụng bất kỳ thiết lập ổ đĩa nào được gắn tại /" +"mnt (thử nghiệm)" + +#, fuzzy +msgid "Select one of the disks or skip and use /mnt as default" +msgstr "Chọn một trong các đĩa hoặc bỏ qua và sử dụng /mnt làm mặc định" + +#, fuzzy +msgid "Select which partitions to mark for formatting:" +msgstr "Chọn phân vùng cần đánh dấu để định dạng:" + +msgid "Use HSM to unlock encrypted drive" +msgstr "Sử dụng HSM để mở khóa ổ đĩa được mã hóa" + +msgid "Device" +msgstr "Thiết bị" + +msgid "Size" +msgstr "Kích cỡ" + +msgid "Free space" +msgstr "Không gian trống" + +msgid "Bus-type" +msgstr "Loại đường truyền" + +msgid "Either root-password or at least 1 user with sudo privileges must be specified" +msgstr "Phải chỉ định mật khẩu gốc hoặc ít nhất 1 người dùng có đặc quyền sudo" + +msgid "Enter username (leave blank to skip): " +msgstr "Nhập tên người dùng (để trống để bỏ qua): " + +msgid "The username you entered is invalid. Try again" +msgstr "Tên người dùng bạn đã nhập không hợp lệ. Thử lại" + +msgid "Should \"{}\" be a superuser (sudo)?" +msgstr "\"{}\" có nên là siêu người dùng (sudo) không?" + +msgid "Select which partitions to encrypt" +msgstr "Chọn phân vùng để mã hóa" + +msgid "very weak" +msgstr "rất yếu" + +msgid "weak" +msgstr "yếu" + +msgid "moderate" +msgstr "vừa phải" + +msgid "strong" +msgstr "mạnh" + +msgid "Add subvolume" +msgstr "Thêm tập con" + +msgid "Edit subvolume" +msgstr "Chỉnh sửa tập con" + +msgid "Delete subvolume" +msgstr "Xóa tập con" + +msgid "Configured {} interfaces" +msgstr "Giao diện {} được định cấu hình" + +msgid "This option enables the number of parallel downloads that can occur during installation" +msgstr "Tùy chọn này cho phép số lượng tải xuống song song có thể xảy ra trong quá trình cài đặt" + +#, fuzzy +msgid "" +"Enter the number of parallel downloads to be enabled.\n" +" (Enter a value between 1 to {})\n" +"Note:" +msgstr "" +"Nhập số lượng tải xuống song song sẽ được kích hoạt.\n" +" (Nhập giá trị từ 1 đến {} )\n" +"Lưu ý:" + +#, fuzzy +msgid " - Maximum value : {} ( Allows {} parallel downloads, allows {} downloads at a time )" +msgstr "- Giá trị tối đa: {} (Cho phép tải song song {}, cho phép tải {} cùng một lúc)" + +#, fuzzy +msgid " - Minimum value : 1 ( Allows 1 parallel download, allows 2 downloads at a time )" +msgstr "- Giá trị tối thiểu: 1 (Cho phép tải 1 song song, cho phép tải 2 lần cùng lúc)" + +#, fuzzy +msgid " - Disable/Default : 0 ( Disables parallel downloading, allows only 1 download at a time )" +msgstr "- Tắt/Mặc định: 0 ( Vô hiệu hóa tải xuống song song, chỉ cho phép tải xuống 1 lần mỗi lần )" + +#, python-brace-format +msgid "Invalid input! Try again with a valid input [1 to {max_downloads}, or 0 to disable]" +msgstr "" +"Đầu vào không hợp lệ! Hãy thử lại với giá trị đầu vào hợp lệ [1 đến {max_downloads} hoặc 0 để tắt]" + +msgid "Parallel Downloads" +msgstr "Tải xuống song song" + +msgid "Pacman" +msgstr "Pacman" + +msgid "Color" +msgstr "Màu sắc" + +#, fuzzy, python-brace-format +msgid "Enter the number of parallel downloads (1-{})" +msgstr "Nhập số lượt tải song song (1- {} )" + +msgid "Enable colored output for pacman" +msgstr "Kích hoạt đầu ra màu cho pacman" + +msgid "ESC to skip" +msgstr "ESC để bỏ qua" + +msgid "CTRL+C to reset" +msgstr "CTRL+C để đặt lại" + +msgid "TAB to select" +msgstr "TAB để chọn" + +msgid "[Default value: 0] > " +msgstr "[Giá trị mặc định: 0] > " + +msgid "To be able to use this translation, please install a font manually that supports the language." +msgstr "" +"Để có thể sử dụng bản dịch này, vui lòng cài đặt phông chữ hỗ trợ ngôn ngữ theo cách thủ công." + +msgid "The font should be stored as {}" +msgstr "Phông chữ phải được lưu dưới dạng {}" + +msgid "Archinstall requires root privileges to run. See --help for more." +msgstr "Archinstall yêu cầu quyền root để chạy. Xem --help để biết thêm." + +#, fuzzy +msgid "Select an execution mode" +msgstr "Chọn chế độ thực hiện" + +#, python-brace-format +msgid "Unable to fetch profile from specified url: {}" +msgstr "Không thể tìm nạp cấu hình từ url được chỉ định: {}" + +#, fuzzy, python-brace-format +msgid "Profiles must have unique name, but profile definitions with duplicate name found: {}" +msgstr "" +"Cấu hình (Profile) phải có tên duy nhất, nhưng tìm thấy định nghĩa cấu hình có tên trùng lặp: {}" + +msgid "Select one or more devices to use and configure" +msgstr "Chọn một hoặc nhiều thiết bị để sử dụng và định cấu hình" + +#, fuzzy +msgid "If you reset the device selection this will also reset the current disk layout. Are you sure?" +msgstr "" +"Nếu bạn đặt lại lựa chọn thiết bị, thao tác này cũng sẽ đặt lại bố cục đĩa hiện tại. Bạn có chắc " +"không?" + +msgid "Existing Partitions" +msgstr "Phân vùng hiện có" + +msgid "Select a partitioning option" +msgstr "Chọn một tùy chọn phân vùng" + +#, fuzzy +msgid "Enter the root directory of the mounted devices: " +msgstr "Nhập thư mục gốc của thiết bị được gắn:" + +#, fuzzy, python-brace-format +msgid "Minimum capacity for /home partition: {}GiB\n" +msgstr "Dung lượng tối thiểu cho phân vùng /home: {} GiB" + +#, fuzzy, python-brace-format +msgid "Minimum capacity for Arch Linux partition: {}GiB" +msgstr "Dung lượng tối thiểu cho phân vùng Arch Linux: {} GiB" + +#, fuzzy +msgid "" +"This is a list of pre-programmed profiles_bck, they might make it easier to install things like " +"desktop environments" +msgstr "" +"Đây là danh sách các profile_bck được lập trình sẵn, chúng có thể giúp cài đặt những thứ như môi " +"trường máy tính để bàn dễ dàng hơn" + +msgid "Current profile selection" +msgstr "Lựa chọn cấu hình hiện tại" + +msgid "Remove all newly added partitions" +msgstr "Xóa tất cả các phân vùng mới được thêm vào" + +#, fuzzy +msgid "Assign mountpoint" +msgstr "Chỉ định điểm gắn kết" + +msgid "Mark/Unmark to be formatted (wipes data)" +msgstr "Đánh dấu/Bỏ đánh dấu để định dạng (xóa dữ liệu)" + +msgid "Mark/Unmark as bootable" +msgstr "Đánh dấu/Bỏ đánh dấu là có khả năng khởi động" + +msgid "Change filesystem" +msgstr "Thay đổi hệ thống tập tin" + +msgid "Mark/Unmark as compressed" +msgstr "Đánh dấu/Bỏ đánh dấu là đã nén" + +#, fuzzy +msgid "Set subvolumes" +msgstr "Đặt tập con" + +msgid "Delete partition" +msgstr "Xóa phân vùng" + +msgid "Partition" +msgstr "Phân vùng" + +#, fuzzy +msgid "This partition is currently encrypted, to format it a filesystem has to be specified" +msgstr "Phân vùng này hiện đã được mã hóa, để định dạng nó, phải chỉ định hệ thống tập tin" + +#, fuzzy +msgid "" +"Partition mount-points are relative to inside the installation, the boot would be /boot as an " +"example." +msgstr "" +"Các điểm gắn kết phân vùng có liên quan đến bên trong quá trình cài đặt, khởi động sẽ là /boot làm " +"ví dụ." + +#, fuzzy +msgid "If mountpoint /boot is set, then the partition will also be marked as bootable." +msgstr "" +"Nếu điểm gắn kết/khởi động được đặt thì phân vùng cũng sẽ được đánh dấu là có khả năng khởi động." + +msgid "Mountpoint: " +msgstr "Điểm gắn: " + +msgid "Current free sectors on device {}:" +msgstr "Các phân khu trống hiện có trên thiết bị {}:" + +msgid "Total sectors: {}" +msgstr "Tổng số phân khu: {}" + +msgid "Enter the start sector (default: {}): " +msgstr "Nhập phân khu bắt đầu (mặc định: {} ): " + +#, fuzzy +msgid "Enter the end sector of the partition (percentage or block number, default: {}): " +msgstr "Nhập khu vực cuối của phân vùng (phần trăm hoặc số khối, mặc định: {} ):" + +#, fuzzy +msgid "This will remove all newly added partitions, continue?" +msgstr "Điều này sẽ loại bỏ tất cả các phân vùng mới được thêm vào, tiếp tục?" + +#, python-brace-format +msgid "Partition management: {}" +msgstr "Quản lý phân vùng: {}" + +#, python-brace-format +msgid "Total length: {}" +msgstr "Tổng chiều dài: {}" + +#, fuzzy +msgid "Encryption type" +msgstr "Kiểu mã hóa" + +#, fuzzy +msgid "Iteration time" +msgstr "Thời gian lặp lại" + +#, fuzzy +msgid "Enter iteration time for LUKS encryption (in milliseconds)" +msgstr "Nhập thời gian lặp lại để mã hóa LUKS (tính bằng mili giây)" + +#, fuzzy +msgid "Higher values increase security but slow down boot time" +msgstr "Giá trị cao hơn tăng cường bảo mật nhưng làm chậm thời gian khởi động" + +#, fuzzy +msgid "Default: 10000ms, Recommended range: 1000-60000" +msgstr "Mặc định: 10000ms, Phạm vi khuyến nghị: 1000-60000" + +#, fuzzy +msgid "Iteration time cannot be empty" +msgstr "Thời gian lặp lại không được để trống" + +#, fuzzy +msgid "Iteration time must be at least 100ms" +msgstr "Thời gian lặp phải ít nhất là 100ms" + +#, fuzzy +msgid "Iteration time must be at most 120000ms" +msgstr "Thời gian lặp lại tối đa là 120000ms" + +msgid "Please enter a valid number" +msgstr "Vui lòng nhập một số hợp lệ" + +msgid "Partitions" +msgstr "Phân vùng" + +#, fuzzy +msgid "No HSM devices available" +msgstr "Không có thiết bị HSM nào" + +#, fuzzy +msgid "Partitions to be encrypted" +msgstr "Các phân vùng được mã hóa" + +msgid "Select disk encryption option" +msgstr "Chọn tùy chọn mã hóa ổ đĩa" + +msgid "Select a FIDO2 device to use for HSM" +msgstr "Chọn thiết bị FIDO2 để sử dụng cho HSM" + +#, fuzzy +msgid "Use a best-effort default partition layout" +msgstr "Sử dụng bố cục phân vùng mặc định với nỗ lực tốt nhất" + +#, fuzzy +msgid "Manual Partitioning" +msgstr "Phân vùng thủ công" + +#, fuzzy +msgid "Pre-mounted configuration" +msgstr "Cấu hình được gắn sẵn" + +#, fuzzy +msgid "Unknown" +msgstr "Không xác định" + +#, fuzzy +msgid "Partition encryption" +msgstr "Mã hóa phân vùng" + +#, fuzzy, python-brace-format +msgid " ! Formatting {} in " +msgstr "! Định dạng {} trong" + +msgid "← Back" +msgstr "← Quay lại" + +msgid "Disk encryption" +msgstr "Mã hóa ổ đĩa" + +#, fuzzy +msgid "Configuration" +msgstr "Cấu hình" + +#, fuzzy +msgid "Password" +msgstr "Mật khẩu" + +#, fuzzy +msgid "All settings will be reset, are you sure?" +msgstr "Tất cả cài đặt sẽ được đặt lại, bạn có chắc chắn không?" + +msgid "Back" +msgstr "Quay lại" + +msgid "Please chose which greeter to install for the chosen profiles: {}" +msgstr "Vui lòng chọn màn hình đăng nhập cho các cấu hình đã chọn: {}" + +#, fuzzy, python-brace-format +msgid "Environment type: {}" +msgstr "Loại môi trường: {}" + +#, fuzzy +msgid "" +"The proprietary Nvidia driver is not supported by Sway. It is likely that you will run into issues, " +"are you okay with that?" +msgstr "" +"Trình điều khiển Nvidia độc quyền không được Sway hỗ trợ. Có khả năng là bạn sẽ gặp phải vấn đề, " +"bạn có ổn với điều đó không?" + +msgid "Installed packages" +msgstr "Gói đã cài đặt" + +msgid "Add profile" +msgstr "Thêm cấu hình" + +msgid "Edit profile" +msgstr "Chỉnh sửa cấu hình" + +msgid "Delete profile" +msgstr "Xóa cấu hình" + +msgid "Profile name: " +msgstr "Tên cấu hình: " + +msgid "The profile name you entered is already in use. Try again" +msgstr "Tên cấu hình bạn nhập đã được sử dụng. Thử lại" + +msgid "Packages to be install with this profile (space separated, leave blank to skip): " +msgstr "Các gói sẽ được cài đặt với cấu hình này (cách nhau bằng dấu cách, để trống để bỏ qua): " + +msgid "Services to be enabled with this profile (space separated, leave blank to skip): " +msgstr "Các dịch vụ được kích hoạt với cấu hình này (cách nhau bằng dấu cách, để trống để bỏ qua): " + +#, fuzzy +msgid "Should this profile be enabled for installation?" +msgstr "Cấu hình này có nên được kích hoạt để cài đặt không?" + +#, fuzzy +msgid "Create your own" +msgstr "Tạo của riêng bạn" + +#, fuzzy +msgid "" +"\n" +"Select a graphics driver or leave blank to install all open-source drivers" +msgstr "Chọn trình điều khiển đồ họa hoặc để trống để cài đặt tất cả trình điều khiển nguồn mở" + +msgid "Sway needs access to your seat (collection of hardware devices i.e. keyboard, mouse, etc)" +msgstr "" +"Sway cần quyền truy cập vào seat của bạn (bộ sưu tập các thiết bị phần cứng, ví dụ như bàn phím, " +"chuột, v.v.)" + +#, fuzzy +msgid "" +"\n" +"\n" +"Choose an option to give Sway access to your hardware" +msgstr "Chọn một tùy chọn để cấp cho Sway quyền truy cập vào phần cứng của bạn" + +#, fuzzy +msgid "Graphics driver" +msgstr "Trình điều khiển đồ họa" + +msgid "Greeter" +msgstr "Màn hình đăng nhập" + +msgid "Please chose which greeter to install" +msgstr "Vui lòng chọn màn hình đăng nhập nào để cài đặt" + +msgid "This is a list of pre-programmed default_profiles" +msgstr "Đây là danh sách cấu hình mặc định được lập trình sẵn" + +msgid "Disk configuration" +msgstr "Cấu hình đĩa" + +msgid "Profiles" +msgstr "Cấu hình (Profile)" + +#, fuzzy +msgid "Finding possible directories to save configuration files ..." +msgstr "Tìm các thư mục có thể lưu file cấu hình..." + +#, fuzzy +msgid "Select directory (or directories) for saving configuration files" +msgstr "Chọn thư mục (hoặc các thư mục) để lưu file cấu hình" + +msgid "Add a custom mirror" +msgstr "Thêm máy chủ bản sao (mirror) tùy chỉnh" + +msgid "Change custom mirror" +msgstr "Thay đổi máy chủ bản sao tùy chỉnh" + +msgid "Delete custom mirror" +msgstr "Xóa máy chủ bản sao tùy chỉnh" + +#, fuzzy +msgid "Enter name (leave blank to skip): " +msgstr "Nhập tên (để trống để bỏ qua):" + +#, fuzzy +msgid "Enter url (leave blank to skip): " +msgstr "Nhập url (để trống để bỏ qua):" + +#, fuzzy +msgid "Select signature check option" +msgstr "Chọn tùy chọn kiểm tra chữ ký" + +#, fuzzy +msgid "Select signature option" +msgstr "Chọn tùy chọn chữ ký" + +#, fuzzy +msgid "Custom mirrors" +msgstr "Máy chủ bản sao (Mirror) tùy chỉnh" + +#, fuzzy +msgid "Defined" +msgstr "Đã xác định" + +msgid "Save user configuration (including disk layout)" +msgstr "Lưu cấu hình người dùng (bao gồm cả bố cục đĩa)" + +#, fuzzy +msgid "" +"Enter a directory for the configuration(s) to be saved (tab completion enabled)\n" +"Save directory: " +msgstr "" +"Nhập thư mục để lưu (các) cấu hình (bật tính năng hoàn thành tab)\n" +"Lưu thư mục:" + +#, fuzzy +msgid "" +"Do you want to save {} configuration file(s) in the following location?\n" +"\n" +"{}" +msgstr "" +"Bạn có muốn lưu (các) tệp cấu hình {} ở vị trí sau không?\n" +"\n" +" {}" + +#, fuzzy +msgid "Saving {} configuration files to {}" +msgstr "Lưu tệp cấu hình {} vào {}" + +#, fuzzy +msgid "Mirrors" +msgstr "Máy chủ bản sao (Mirror)" + +msgid "Mirror regions" +msgstr "Máy chủ bản sao" + +#, fuzzy +msgid "" +" - Maximum value : {} ( Allows {} parallel downloads, allows {max_downloads+1} downloads at a " +"time )" +msgstr "- Giá trị tối đa: {} (Cho phép tải song song {}, cho phép tải {max_downloads+1} cùng lúc)" + +#, fuzzy +msgid "Invalid input! Try again with a valid input [1 to {}, or 0 to disable]" +msgstr "Đầu vào không hợp lệ! Hãy thử lại với giá trị đầu vào hợp lệ [1 đến {} hoặc 0 để tắt]" + +#, fuzzy +msgid "Locales" +msgstr "Ngôn ngữ" + +#, fuzzy +msgid "Use NetworkManager (necessary to configure internet graphically in GNOME and KDE)" +msgstr "Sử dụng Trình quản lý mạng (cần thiết để định cấu hình đồ họa internet trong Gnome và KDE)" + +#, fuzzy +msgid "Total: {} / {}" +msgstr "Tổng cộng: {}/{}" + +#, fuzzy +msgid "All entered values can be suffixed with a unit: B, KB, KiB, MB, MiB..." +msgstr "Tất cả các giá trị đã nhập có thể được thêm vào một đơn vị: B, KB, KiB, MB, MiB..." + +msgid "If no unit is provided, the value is interpreted as sectors" +msgstr "Nếu không có đơn vị nào được cung cấp, giá trị sẽ được hiểu theo đơn vị sector" + +#, fuzzy +msgid "Enter start (default: sector {}): " +msgstr "Nhập bắt đầu (mặc định: khu vực {} ):" + +#, fuzzy +msgid "Enter end (default: {}): " +msgstr "Nhập cuối (mặc định: {} ):" + +#, fuzzy +msgid "Unable to determine fido2 devices. Is libfido2 installed?" +msgstr "Không thể xác định thiết bị fido2. libfido2 đã được cài đặt chưa?" + +#, fuzzy +msgid "Path" +msgstr "Con đường" + +msgid "Manufacturer" +msgstr "Nhà sản xuất" + +#, fuzzy +msgid "Product" +msgstr "Sản phẩm" + +#, fuzzy, python-brace-format +msgid "Invalid configuration: {}" +msgstr "Cấu hình không hợp lệ: {}" + +msgid "Ready to install" +msgstr "Sẵn sàng để cài đặt" + +msgid "Disks" +msgstr "Đĩa" + +msgid "Packages" +msgstr "Gói" + +msgid "Network" +msgstr "Mạng" + +msgid "Locale" +msgstr "Ngôn ngữ" + +msgid "Type" +msgstr "Kiểu" + +#, fuzzy +msgid "This option enables the number of parallel downloads that can occur during package downloads" +msgstr "" +"Tùy chọn này cho phép số lượng tải xuống song song có thể xảy ra trong quá trình tải xuống gói" + +#, fuzzy +msgid "" +"Enter the number of parallel downloads to be enabled.\n" +"\n" +"Note:\n" +msgstr "" +"Nhập số lượng tải xuống song song sẽ được kích hoạt.\n" +"\n" +"Ghi chú:" + +#, fuzzy, python-brace-format +msgid " - Maximum recommended value : {} ( Allows {} parallel downloads at a time )" +msgstr "- Giá trị khuyến nghị tối đa: {} (Cho phép tải xuống song song {} cùng một lúc)" + +#, fuzzy +msgid " - Disable/Default : 0 ( Disables parallel downloading, allows only 1 download at a time )\n" +msgstr "- Tắt/Mặc định: 0 ( Vô hiệu hóa tải xuống song song, chỉ cho phép tải xuống 1 lần mỗi lần )" + +#, fuzzy +msgid "Invalid input! Try again with a valid input [or 0 to disable]" +msgstr "Đầu vào không hợp lệ! Hãy thử lại với thông tin đầu vào hợp lệ [hoặc 0 để tắt]" + +msgid "Hyprland needs access to your seat (collection of hardware devices i.e. keyboard, mouse, etc)" +msgstr "" +"Hyprland cần quyền truy cập vào seat của bạn (bộ sưu tập các thiết bị phần cứng như bàn phím, " +"chuột, v.v.)" + +#, fuzzy +msgid "" +"\n" +"\n" +"Choose an option to give Hyprland access to your hardware" +msgstr "Chọn một tùy chọn để cấp cho Hyprland quyền truy cập vào phần cứng của bạn" + +#, fuzzy +msgid "All entered values can be suffixed with a unit: %, B, KB, KiB, MB, MiB..." +msgstr "Tất cả các giá trị đã nhập có thể được gắn với một đơn vị: %, B, KB, KiB, MB, MiB..." + +msgid "Would you like to use unified kernel images?" +msgstr "Bạn có muốn sử dụng hình ảnh nhân hợp nhất không?" + +msgid "Unified kernel images" +msgstr "Hình ảnh nhân hợp nhất" + +msgid "Waiting for time sync (timedatectl show) to complete." +msgstr "" + +#, fuzzy +msgid "" +"Time syncronization not completing, while you wait - check the docs for workarounds: https://" +"archinstall.readthedocs.io/" +msgstr "" +"Quá trình đồng bộ hóa thời gian không hoàn tất trong khi bạn chờ đợi - hãy kiểm tra tài liệu để " +"biết cách giải quyết: https://archinstall.readthedocs.io/" + +#, fuzzy +msgid "" +"Skipping waiting for automatic time sync (this can cause issues if time is out of sync during " +"installation)" +msgstr "" +"Bỏ qua việc chờ đồng bộ hóa thời gian tự động (điều này có thể gây ra sự cố nếu thời gian không " +"đồng bộ trong khi cài đặt)" + +#, fuzzy +msgid "Waiting for Arch Linux keyring sync (archlinux-keyring-wkd-sync) to complete." +msgstr "Đang chờ đồng bộ hóa khóa Arch Linux (archlinux-keyring-wkd-sync) hoàn tất." + +#, fuzzy +msgid "Selected profiles: " +msgstr "Cấu hình (Profile) đã chọn:" + +#, fuzzy +msgid "" +"Time synchronization not completing, while you wait - check the docs for workarounds: https://" +"archinstall.readthedocs.io/" +msgstr "" +"Đồng bộ hóa thời gian không hoàn tất, trong khi bạn chờ đợi - hãy kiểm tra tài liệu để biết cách " +"giải quyết: https://archinstall.readthedocs.io/" + +msgid "Mark/Unmark as nodatacow" +msgstr "Đánh dấu/Bỏ đánh dấu là nodatacow" + +msgid "Would you like to use compression or disable CoW?" +msgstr "Bạn muốn sử dụng tính năng nén hay tắt CoW?" + +msgid "Use compression" +msgstr "Sử dụng tính năng nén" + +msgid "Disable Copy-on-Write" +msgstr "Tắt tính năng Sao chép khi ghi" + +#, fuzzy +msgid "" +"Provides a selection of desktop environments and tiling window managers, e.g. GNOME, KDE Plasma, " +"Sway" +msgstr "" +"Cung cấp lựa chọn môi trường máy tính để bàn và trình quản lý cửa sổ xếp lớp, ví dụ: Gnome, KDE " +"Plasma, Sway" + +#, fuzzy, python-brace-format +msgid "Configuration type: {}" +msgstr "Loại cấu hình: {}" + +#, fuzzy +msgid "LVM configuration type" +msgstr "Loại cấu hình LVM" + +#, fuzzy +msgid "LVM disk encryption with more than 2 partitions is currently not supported" +msgstr "Mã hóa đĩa LVM với hơn 2 phân vùng hiện không được hỗ trợ" + +#, fuzzy +msgid "Use NetworkManager (necessary to configure internet graphically in GNOME and KDE Plasma)" +msgstr "" +"Sử dụng Trình quản lý mạng (cần thiết để định cấu hình đồ họa internet trong Gnome và KDE Plasma)" + +#, fuzzy +msgid "Select a LVM option" +msgstr "Chọn tùy chọn LVM" + +#, fuzzy +msgid "Partitioning" +msgstr "Phân vùng" + +#, fuzzy +msgid "Logical Volume Management (LVM)" +msgstr "Quản lý khối hợp lý (LVM)" + +msgid "Physical volumes" +msgstr "Các phân vùng vật lý (PV)" + +#, fuzzy +msgid "Volumes" +msgstr "Tập" + +#, fuzzy +msgid "LVM volumes" +msgstr "Khối lượng LVM" + +#, fuzzy +msgid "LVM volumes to be encrypted" +msgstr "Khối lượng LVM được mã hóa" + +#, fuzzy +msgid "Select which LVM volumes to encrypt" +msgstr "Chọn khối LVM nào sẽ mã hóa" + +#, fuzzy +msgid "Default layout" +msgstr "Bố cục mặc định" + +#, fuzzy +msgid "No Encryption" +msgstr "Không mã hóa" + +#, fuzzy +msgid "LUKS" +msgstr "LUKS" + +#, fuzzy +msgid "LVM on LUKS" +msgstr "LVM trên LUKS" + +#, fuzzy +msgid "LUKS on LVM" +msgstr "LUKS trên LVM" + +msgid "Yes" +msgstr "Có" + +msgid "No" +msgstr "Không" + +#, fuzzy +msgid "Archinstall help" +msgstr "Trợ giúp cài đặt Arch" + +msgid " (default)" +msgstr " (mặc định)" + +#, fuzzy +msgid "Press Ctrl+h for help" +msgstr "Nhấn Ctrl+h để được trợ giúp" + +#, fuzzy +msgid "Choose an option to give Sway access to your hardware" +msgstr "Chọn một tùy chọn để cấp cho Sway quyền truy cập vào phần cứng của bạn" + +msgid "Seat access" +msgstr "Quyền truy cập seat" + +msgid "Mountpoint" +msgstr "Điểm gắn" + +#, fuzzy +msgid "HSM" +msgstr "HSM" + +msgid "Enter disk encryption password (leave blank for no encryption)" +msgstr "Nhập mật khẩu mã hóa ổ đĩa (để trống nếu không mã hóa)" + +msgid "Disk encryption password" +msgstr "Mật khẩu mã hóa ổ đĩa" + +#, fuzzy +msgid "Partition - New" +msgstr "Phân vùng - Mới" + +#, fuzzy +msgid "Filesystem" +msgstr "Hệ thống tập tin" + +#, fuzzy +msgid "Invalid size" +msgstr "Kích thước không hợp lệ" + +#, fuzzy +msgid "Start (default: sector {}): " +msgstr "Bắt đầu (mặc định: khu vực {} ):" + +#, fuzzy +msgid "End (default: {}): " +msgstr "Kết thúc (mặc định: {} ):" + +msgid "Subvolume name" +msgstr "Tên tập con" + +#, fuzzy +msgid "Disk configuration type" +msgstr "Kiểu cấu hình đĩa" + +#, fuzzy +msgid "Root mount directory" +msgstr "Thư mục gắn kết gốc" + +msgid "Select language" +msgstr "Chọn ngôn ngữ" + +#, fuzzy +msgid "Write additional packages to install (space separated, leave blank to skip)" +msgstr "Ghi thêm các gói cần cài đặt (cách nhau dấu cách, để trống để bỏ qua)" + +#, fuzzy +msgid "Invalid download number" +msgstr "Số tải xuống không hợp lệ" + +#, fuzzy +msgid "Number downloads" +msgstr "Số lượt tải xuống" + +#, fuzzy +msgid "The username you entered is invalid" +msgstr "Tên người dùng bạn đã nhập không hợp lệ" + +#, fuzzy +msgid "Username" +msgstr "Tên người dùng" + +#, python-brace-format +msgid "Should \"{}\" be a superuser (sudo)?\n" +msgstr "\"{}\" có nên là siêu người dùng (sudo) không?\n" + +#, fuzzy +msgid "Interfaces" +msgstr "Giao diện" + +#, fuzzy +msgid "You need to enter a valid IP in IP-config mode" +msgstr "Bạn cần nhập IP hợp lệ ở chế độ IP-config" + +#, fuzzy +msgid "Modes" +msgstr "Chế độ" + +#, fuzzy +msgid "IP address" +msgstr "địa chỉ IP" + +msgid "Enter your gateway (router) IP address (leave blank for none)" +msgstr "Nhập địa chỉ IP gateway (bộ định tuyến) của bạn (để trống nếu không có)" + +#, fuzzy +msgid "Gateway address" +msgstr "Địa chỉ cổng" + +msgid "Enter your DNS servers with space separated (leave blank for none)" +msgstr "Nhập các máy chủ DNS của bạn, cách nhau bằng dấu cách (để trống nếu không có)" + +#, fuzzy +msgid "DNS servers" +msgstr "máy chủ DNS" + +#, fuzzy +msgid "Configure interfaces" +msgstr "Cấu hình giao diện" + +#, fuzzy +msgid "Kernel" +msgstr "hạt nhân" + +msgid "UEFI is not detected and some options are disabled" +msgstr "UEFI không được phát hiện và một số tùy chọn bị tắt" + +msgid "Info" +msgstr "Thông tin" + +msgid "The proprietary Nvidia driver is not supported by Sway." +msgstr "Trình điều khiển Nvidia độc quyền không được Sway hỗ trợ." + +msgid "It is likely that you will run into issues, are you okay with that?" +msgstr "Có khả năng là bạn sẽ gặp phải vấn đề, bạn có ổn với điều đó không?" + +msgid "Main profile" +msgstr "Cấu hình (Profile) chính" + +msgid "Confirm password" +msgstr "Xác nhận mật khẩu" + +msgid "The confirmation password did not match, please try again" +msgstr "Mật khẩu xác nhận không khớp, vui lòng thử lại" + +#, fuzzy +msgid "Not a valid directory" +msgstr "Không phải là một thư mục hợp lệ" + +msgid "Would you like to continue?" +msgstr "Bạn có muốn tiếp tục không?" + +msgid "Directory" +msgstr "Thư mục" + +#, fuzzy +msgid "Enter a directory for the configuration(s) to be saved (tab completion enabled)" +msgstr "Nhập thư mục để lưu (các) cấu hình (bật tính năng hoàn thành tab)" + +#, fuzzy, python-brace-format +msgid "Do you want to save the configuration file(s) to {}?" +msgstr "Bạn có muốn lưu (các) tệp cấu hình vào {} không?" + +msgid "Enabled" +msgstr "Đã bật" + +msgid "Disabled" +msgstr "Vô hiệu hóa" + +msgid "Please submit this issue (and file) to https://github.com/archlinux/archinstall/issues" +msgstr "Vui lòng gửi vấn đề này (và tệp) tới https://github.com/archlinux/archinstall/issues" + +msgid "Mirror name" +msgstr "Tên máy chủ bản sao" + +#, fuzzy +msgid "Url" +msgstr "Url" + +#, fuzzy +msgid "Select signature check" +msgstr "Chọn kiểm tra chữ ký" + +#, fuzzy +msgid "Select execution mode" +msgstr "Chọn chế độ thực hiện" + +#, fuzzy +msgid "Press ? for help" +msgstr "Nhấn ? để được giúp đỡ" + +#, fuzzy +msgid "Choose an option to give Hyprland access to your hardware" +msgstr "Chọn một tùy chọn để cấp cho Hyprland quyền truy cập vào phần cứng của bạn" + +#, fuzzy +msgid "Additional repositories" +msgstr "Kho bổ sung" + +msgid "NTP" +msgstr "NTP" + +#, fuzzy +msgid "Swap on zram" +msgstr "Trao đổi trên zram" + +msgid "Name" +msgstr "Tên" + +#, fuzzy +msgid "Signature check" +msgstr "Kiểm tra chữ ký" + +#, python-brace-format +msgid "Selected free space segment on device {}:" +msgstr "Phân đoạn không gian trống đã chọn trên thiết bị {} :" + +#, fuzzy, python-brace-format +msgid "Size: {} / {}" +msgstr "Kích thước: {}/{}" + +#, fuzzy, python-brace-format +msgid "Size (default: {}): " +msgstr "Kích thước (mặc định: {} ):" + +#, fuzzy +msgid "HSM device" +msgstr "thiết bị HSM" + +msgid "Some packages could not be found in the repository" +msgstr "Không thể tìm thấy một số gói trong kho phần mềm" + +#, fuzzy +msgid "User" +msgstr "người dùng" + +#, fuzzy +msgid "The specified configuration will be applied" +msgstr "Cấu hình được chỉ định sẽ được áp dụng" + +msgid "Wipe" +msgstr "Ghi đè dữ liệu" + +#, fuzzy +msgid "Mark/Unmark as XBOOTLDR" +msgstr "Đánh dấu/Bỏ đánh dấu là XBOOTLDR" + +msgid "Loading packages..." +msgstr "Đang tải gói..." + +#, fuzzy +msgid "Select any packages from the below list that should be installed additionally" +msgstr "Chọn bất kỳ gói nào từ danh sách bên dưới cần được cài đặt bổ sung" + +msgid "Add a custom repository" +msgstr "Thêm kho phần mềm tùy chỉnh" + +msgid "Change custom repository" +msgstr "Thay đổi kho phần mềm tùy chỉnh" + +msgid "Delete custom repository" +msgstr "Xóa kho phần mềm tùy chỉnh" + +msgid "Repository name" +msgstr "Tên kho phần mềm" + +#, fuzzy +msgid "Add a custom server" +msgstr "Thêm một máy chủ tùy chỉnh" + +#, fuzzy +msgid "Change custom server" +msgstr "Thay đổi máy chủ tùy chỉnh" + +#, fuzzy +msgid "Delete custom server" +msgstr "Xóa máy chủ tùy chỉnh" + +#, fuzzy +msgid "Server url" +msgstr "Url máy chủ" + +#, fuzzy +msgid "Select regions" +msgstr "Chọn vùng" + +#, fuzzy +msgid "Add custom servers" +msgstr "Thêm máy chủ tùy chỉnh" + +msgid "Add custom repository" +msgstr "Thêm kho phần mềm tùy chỉnh" + +msgid "Loading mirror regions..." +msgstr "Đang tải các máy chủ bản sao..." + +msgid "Mirrors and repositories" +msgstr "Máy chủ bản sao (Mirror) và kho phần mềm" + +msgid "Selected mirror regions" +msgstr "Máy chủ bản sao được chọn" + +#, fuzzy +msgid "Custom servers" +msgstr "Máy chủ tùy chỉnh" + +#, fuzzy +msgid "Custom repositories" +msgstr "Kho tùy chỉnh" + +#, fuzzy +msgid "Only ASCII characters are supported" +msgstr "Chỉ hỗ trợ các ký tự ASCII" + +msgid "Show help" +msgstr "Hiển thị trợ giúp" + +msgid "Exit help" +msgstr "Thoát trợ giúp" + +#, fuzzy +msgid "Preview scroll up" +msgstr "Xem trước cuộn lên" + +#, fuzzy +msgid "Preview scroll down" +msgstr "Xem trước cuộn xuống" + +msgid "Move up" +msgstr "Di chuyển lên" + +msgid "Move down" +msgstr "Di chuyển xuống" + +msgid "Move right" +msgstr "Di chuyển sang phải" + +msgid "Move left" +msgstr "Di chuyển sang trái" + +#, fuzzy +msgid "Jump to entry" +msgstr "Chuyển đến mục nhập" + +#, fuzzy +msgid "Skip selection (if available)" +msgstr "Bỏ qua lựa chọn (nếu có)" + +#, fuzzy +msgid "Reset selection (if available)" +msgstr "Đặt lại lựa chọn (nếu có)" + +#, fuzzy +msgid "Select on single select" +msgstr "Chọn trên một lần chọn" + +#, fuzzy +msgid "Select on multi select" +msgstr "Chọn trên nhiều lựa chọn" + +#, fuzzy +msgid "Reset" +msgstr "Cài lại" + +#, fuzzy +msgid "Skip selection menu" +msgstr "Bỏ qua menu lựa chọn" + +#, fuzzy +msgid "Start search mode" +msgstr "Bắt đầu chế độ tìm kiếm" + +#, fuzzy +msgid "Exit search mode" +msgstr "Thoát chế độ tìm kiếm" + +msgid "General" +msgstr "Tổng quan" + +msgid "Navigation" +msgstr "Điều hướng" + +msgid "Selection" +msgstr "Lựa chọn" + +msgid "Search" +msgstr "Tìm kiếm" + +msgid "Down" +msgstr "Xuống" + +#, fuzzy +msgid "Up" +msgstr "Hướng lên" + +msgid "Confirm" +msgstr "Xác nhận" + +#, fuzzy +msgid "Focus right" +msgstr "Lấy nét phải" + +#, fuzzy +msgid "Focus left" +msgstr "Tập trung vào bên trái" + +#, fuzzy +msgid "Toggle" +msgstr "Chuyển đổi" + +#, fuzzy +msgid "Show/Hide help" +msgstr "Hiển thị/Ẩn trợ giúp" + +#, fuzzy +msgid "Quit" +msgstr "Từ bỏ" + +#, fuzzy +msgid "First" +msgstr "Đầu tiên" + +#, fuzzy +msgid "Last" +msgstr "Cuối cùng" + +msgid "Select" +msgstr "Lựa chọn" + +msgid "Page Up" +msgstr "Trang Lên" + +msgid "Page Down" +msgstr "Trang Xuống" + +msgid "Page up" +msgstr "Trang lên" + +msgid "Page down" +msgstr "Trang xuống" + +msgid "Page Left" +msgstr "Trang sang trái" + +msgid "Page Right" +msgstr "Trang sang phải" + +msgid "Cursor up" +msgstr "Con trỏ lên" + +msgid "Cursor down" +msgstr "Con trỏ xuống" + +msgid "Cursor right" +msgstr "Con trỏ sang phải" + +msgid "Cursor left" +msgstr "Con trỏ sang trái" + +msgid "Top" +msgstr "Đầu trang" + +msgid "Bottom" +msgstr "Cuối trang" + +msgid "Home" +msgstr "Home" + +msgid "End" +msgstr "Kết thúc" + +#, fuzzy +msgid "Toggle option" +msgstr "Tùy chọn chuyển đổi" + +msgid "Scroll Up" +msgstr "Cuộn lên" + +msgid "Scroll Down" +msgstr "Cuộn xuống" + +#, fuzzy +msgid "Scroll Left" +msgstr "Cuộn sang trái" + +#, fuzzy +msgid "Scroll Right" +msgstr "Cuộn sang phải" + +#, fuzzy +msgid "Scroll Home" +msgstr "Cuộn về nhà" + +#, fuzzy +msgid "Scroll End" +msgstr "Cuối cuộn" + +#, fuzzy +msgid "Focus Next" +msgstr "Tập trung tiếp theo" + +#, fuzzy +msgid "Focus Previous" +msgstr "Tập trung trước đó" + +#, fuzzy +msgid "Copy selected text" +msgstr "Sao chép văn bản đã chọn" + +msgid "labwc needs access to your seat (collection of hardware devices i.e. keyboard, mouse, etc)" +msgstr "" +"labwc cần quyền truy cập vào seat của bạn (bộ sưu tập các thiết bị phần cứng như bàn phím, chuột, " +"v.v.)" + +#, fuzzy +msgid "Choose an option to give labwc access to your hardware" +msgstr "Chọn một tùy chọn để cấp quyền truy cập labwc vào phần cứng của bạn" + +msgid "niri needs access to your seat (collection of hardware devices i.e. keyboard, mouse, etc)" +msgstr "" +"niri cần quyền truy cập vào seat của bạn (bộ sưu tập các thiết bị phần cứng như bàn phím, chuột, " +"v.v.)" + +#, fuzzy +msgid "Choose an option to give niri access to your hardware" +msgstr "Chọn một tùy chọn để cấp cho niri quyền truy cập vào phần cứng của bạn" + +#, fuzzy +msgid "Mark/Unmark as ESP" +msgstr "Đánh dấu/Bỏ đánh dấu là ESP" + +#, fuzzy +msgid "Package group:" +msgstr "Nhóm gói:" + +#, fuzzy +msgid "Exit archinstall" +msgstr "Thoát khỏi cài đặt Arch" + +#, fuzzy +msgid "Reboot system" +msgstr "Khởi động lại hệ thống" + +#, fuzzy +msgid "chroot into installation for post-installation configurations" +msgstr "chroot vào cài đặt để cấu hình sau khi cài đặt" + +msgid "Installation completed" +msgstr "Cài đặt hoàn tất" + +msgid "What would you like to do next?" +msgstr "Bạn muốn làm gì tiếp theo?" + +#, fuzzy, python-brace-format +msgid "Select which mode to configure for \"{}\"" +msgstr "Chọn chế độ cấu hình cho \"{}\"" + +#, fuzzy +msgid "Incorrect credentials file decryption password" +msgstr "Mật khẩu giải mã tập tin thông tin xác thực không chính xác" + +msgid "Incorrect password" +msgstr "Mật khẩu không chính xác" + +#, fuzzy +msgid "Credentials file decryption password" +msgstr "Mật khẩu giải mã tập tin thông tin xác thực" + +#, fuzzy +msgid "Do you want to encrypt the user_credentials.json file?" +msgstr "Bạn có muốn mã hóa tệp user_credentials.json không?" + +msgid "Credentials file encryption password" +msgstr "Mật khẩu mã hóa tập tin thông tin xác thực" + +#, python-brace-format +msgid "Repositories: {}" +msgstr "Kho phần mềm: {}" + +#, fuzzy +msgid "New version available" +msgstr "Đã có phiên bản mới" + +#, fuzzy +msgid "Passwordless login" +msgstr "Đăng nhập không cần mật khẩu" + +#, fuzzy +msgid "Second factor login" +msgstr "Đăng nhập yếu tố thứ hai" + +msgid "Bluetooth" +msgstr "Bluetooth" + +msgid "Would you like to configure Bluetooth?" +msgstr "Bạn có muốn định cấu hình Bluetooth không?" + +msgid "Print service" +msgstr "Dịch vụ in ấn" + +msgid "Would you like to configure the print service?" +msgstr "Bạn có muốn định cấu hình dịch vụ in không?" + +msgid "Power management" +msgstr "Quản lý nguồn điện" + +msgid "Authentication" +msgstr "Xác thực" + +msgid "Applications" +msgstr "Ứng dụng" + +#, fuzzy +msgid "U2F login method: " +msgstr "Phương thức đăng nhập U2F:" + +#, fuzzy +msgid "Passwordless sudo: " +msgstr "Sudo không cần mật khẩu:" + +#, python-brace-format +msgid "Btrfs snapshot type: {}" +msgstr "Loại bản sao lưu tức thời Btrfs \"{}\"" + +#, fuzzy +msgid "Syncing the system..." +msgstr "Đang đồng bộ hóa hệ thống..." + +#, fuzzy +msgid "Value cannot be empty" +msgstr "Giá trị không thể trống" + +msgid "Snapshot type" +msgstr "Kiểu của bản sao lưu" + +#, fuzzy, python-brace-format +msgid "Snapshot type: {}" +msgstr "Kiểu chụp nhanh: {}" + +#, fuzzy +msgid "U2F login setup" +msgstr "Thiết lập đăng nhập U2F" + +#, fuzzy +msgid "No U2F devices found" +msgstr "Không tìm thấy thiết bị U2F nào" + +#, fuzzy +msgid "U2F Login Method" +msgstr "Phương thức đăng nhập U2F" + +#, fuzzy +msgid "Enable passwordless sudo?" +msgstr "Kích hoạt sudo không mật khẩu?" + +#, fuzzy, python-brace-format +msgid "Setting up U2F device for user: {}" +msgstr "Thiết lập thiết bị U2F cho người dùng: {}" + +#, fuzzy +msgid "You may need to enter the PIN and then touch your U2F device to register it" +msgstr "Bạn có thể cần nhập mã PIN rồi chạm vào thiết bị U2F của mình để đăng ký" + +#, fuzzy +msgid "Starting device modifications in " +msgstr "Bắt đầu sửa đổi thiết bị trong" + +msgid "No network connection found" +msgstr "Không tìm thấy kết nối mạng" + +msgid "Would you like to connect to a Wifi?" +msgstr "Bạn có muốn kết nối với Wifi không?" + +msgid "No wifi interface found" +msgstr "Không tìm thấy giao diện wifi" + +msgid "Select wifi network to connect to" +msgstr "Chọn mạng wifi để kết nối" + +msgid "Scanning wifi networks..." +msgstr "Đang quét mạng wifi..." + +msgid "No wifi networks found" +msgstr "Không tìm thấy mạng wifi" + +msgid "Failed setting up wifi" +msgstr "Cài đặt wifi không thành công" + +msgid "Enter wifi password" +msgstr "Nhập mật khẩu wifi" + +#, fuzzy +msgid "Ok" +msgstr "Được rồi" + +#, fuzzy +msgid "Removable" +msgstr "Có thể tháo rời" + +#, fuzzy +msgid "Install to removable location" +msgstr "Cài đặt vào vị trí có thể tháo rời" + +#, fuzzy +msgid "Will install to /EFI/BOOT/ (removable location)" +msgstr "Sẽ cài đặt vào /EFI/BOOT/ (vị trí có thể tháo rời)" + +#, fuzzy +msgid "Will install to standard location with NVRAM entry" +msgstr "Sẽ cài đặt vào vị trí tiêu chuẩn với mục nhập NVRAM" + +#, fuzzy +msgid "Would you like to install the bootloader to the default removable media search location?" +msgstr "Bạn có muốn cài đặt bộ nạp khởi động vào vị trí tìm kiếm phương tiện di động mặc định không?" + +#, fuzzy +msgid "This installs the bootloader to /EFI/BOOT/BOOTX64.EFI (or similar) which is useful for:" +msgstr "" +"Việc này sẽ cài đặt bộ tải khởi động vào /EFI/BOOT/BOOTX64.EFI (hoặc tương tự), rất hữu ích cho:" + +#, fuzzy +msgid "USB drives or other portable external media." +msgstr "Ổ USB hoặc phương tiện di động bên ngoài khác." + +#, fuzzy +msgid "Systems where you want the disk to be bootable on any computer." +msgstr "Các hệ thống mà bạn muốn đĩa có khả năng khởi động trên bất kỳ máy tính nào." + +#, fuzzy +msgid "Firmware that does not properly support NVRAM boot entries." +msgstr "Phần sụn không hỗ trợ đúng cách các mục khởi động NVRAM." + +#, fuzzy +msgid "Will install to /EFI/BOOT/ (removable location, safe default)" +msgstr "Sẽ cài đặt vào /EFI/BOOT/ (vị trí có thể tháo rời, mặc định an toàn)" + +#, fuzzy +msgid "Will install to custom location with NVRAM entry" +msgstr "Sẽ cài đặt vào vị trí tùy chỉnh với mục nhập NVRAM" + +#, fuzzy +msgid "Firmware that does not properly support NVRAM boot entries like most MSI motherboards," +msgstr "Phần sụn không hỗ trợ đúng cách các mục khởi động NVRAM như hầu hết các bo mạch chủ MSI," + +#, fuzzy +msgid "most Apple Macs, many laptops..." +msgstr "hầu hết các máy Mac của Apple, nhiều máy tính xách tay..." + +msgid "Language" +msgstr "Ngôn ngữ" + +#, fuzzy +msgid "Compression algorithm" +msgstr "Thuật toán nén" + +msgid "" +"Only packages such as base, sudo, linux, linux-firmware, efibootmgr and optional profile packages " +"are installed." +msgstr "" +"Chỉ các gói như base, sudo, linux, linux-firmware, efibootmgr và các gói cấu hình tùy chọn mới được " +"cài đặt." + +#, fuzzy +msgid "Select zram compression algorithm:" +msgstr "Chọn thuật toán nén zram:" + +msgid "Use Network Manager (default backend)" +msgstr "Sử dụng NetworkManager (phụ trợ mặc định)" + +#, fuzzy +msgid "Use Network Manager (iwd backend)" +msgstr "Sử dụng Trình quản lý mạng (phụ trợ iwd)" + +msgid "Firewall" +msgstr "Tường lửa" + +msgid "Additional fonts" +msgstr "Phông chữ bổ sung" + +msgid "Select font packages to install" +msgstr "Chọn gói phông để cài đặt" + +#, fuzzy +msgid "Unicode font coverage for most languages" +msgstr "Phạm vi phông chữ Unicode cho hầu hết các ngôn ngữ" + +#, fuzzy +msgid "color emoji for browsers and apps" +msgstr "biểu tượng cảm xúc màu cho trình duyệt và ứng dụng" + +#, fuzzy +msgid "Chinese, Japanese, Korean characters" +msgstr "Ký tự Trung Quốc, Nhật Bản, Hàn Quốc" + +msgid "Select audio configuration" +msgstr "Chọn cấu hình âm thanh" + +#, fuzzy +msgid "Enter credentials file decryption password" +msgstr "Nhập mật khẩu giải mã tập tin thông tin xác thực" + +msgid "Enter root password" +msgstr "Nhập mật khẩu root" + +msgid "Select bootloader to install" +msgstr "Chọn bootloader để cài đặt" + +msgid "Configuration preview" +msgstr "Xem trước cấu hình" + +msgid "Enter a directory for the configuration(s) to be saved" +msgstr "Nhập thư mục để lưu (các) cấu hình" + +msgid "Select encryption type" +msgstr "Chọn loại mã hóa" + +msgid "Select disks for the installation" +msgstr "Chọn đĩa để cài đặt" + +msgid "Enter a mountpoint" +msgstr "Nhập điểm gắn" + +#, fuzzy, python-brace-format +msgid "Enter a size (default: {}): " +msgstr "Nhập kích thước (mặc định: {} ):" + +msgid "Enter subvolume name" +msgstr "Nhập tên phân vùng con (subvolume)" + +msgid "Enter subvolume mountpoint" +msgstr "Nhập điểm gắn subvolume" + +msgid "Select a disk configuration" +msgstr "Chọn cấu hình đĩa" + +msgid "Enter root mount directory" +msgstr "Nhập thư mục gắn gốc" + +#, fuzzy +msgid "You will use whatever drive-setup is mounted at the specified directory" +msgstr "Bạn sẽ sử dụng bất kỳ thiết lập ổ đĩa nào được gắn vào thư mục đã chỉ định" + +#, fuzzy +msgid "WARNING: Archinstall won't check the suitability of this setup" +msgstr "CẢNH BÁO: Archinstall sẽ không kiểm tra tính phù hợp của thiết lập này" + +msgid "Select main filesystem" +msgstr "Chọn hệ thống tập tin chính" + +msgid "Enter a hostname" +msgstr "Nhập tên máy" + +msgid "Select timezone" +msgstr "Chọn múi giờ" + +#, fuzzy +msgid "Enter the number of parallel downloads to be enabled" +msgstr "Nhập số lượng tải song song sẽ được kích hoạt" + +#, fuzzy, python-brace-format +msgid "Value must be between 1 and {}" +msgstr "Giá trị phải nằm trong khoảng từ 1 đến {}" + +msgid "Select which kernel(s) to install" +msgstr "Chọn (các) nhân để cài đặt" + +msgid "Enter a respository name" +msgstr "Nhập tên kho phần mềm" + +msgid "Enter the repository url" +msgstr "Nhập url kho phần mềm" + +#, fuzzy +msgid "Enter server url" +msgstr "Nhập url máy chủ" + +msgid "Select mirror regions to be enabled" +msgstr "Chọn các máy chủ bản sao sẽ được kích hoạt" + +msgid "Select optional repositories to be enabled" +msgstr "Chọn kho phần mềm bổ sung sẽ được kích hoạt" + +msgid "Select an interface" +msgstr "Chọn một giao diện" + +msgid "Choose network configuration" +msgstr "Chọn cấu hình mạng" + +msgid "Recommended: Network Manager for desktop, Manual for server" +msgstr "Khuyến nghị: Network Manager cho máy tính để bàn, Cấu hình thủ công cho máy chủ" + +#, fuzzy +msgid "" +"Warning: no network configuration selected. Network will need to be set up manually on the " +"installed system." +msgstr "" +"Cảnh báo: chưa chọn cấu hình mạng. Mạng sẽ cần được thiết lập thủ công trên hệ thống đã cài đặt." + +msgid "No packages found" +msgstr "Không tìm thấy gói nào" + +msgid "Select which greeter to install" +msgstr "Chọn màn hình đăng nhập để cài đặt" + +msgid "Select a profile type" +msgstr "Chọn loại cấu hình" + +msgid "Enter new password" +msgstr "Nhập mật khẩu mới" + +msgid "Enter a username" +msgstr "Nhập tên người dùng" + +msgid "Enter a password" +msgstr "Nhập mật khẩu" + +msgid "The password did not match, please try again" +msgstr "Mật khẩu không khớp, vui lòng thử lại" + +msgid "Password strength: Weak" +msgstr "Độ mạnh của mật khẩu: Yếu" + +msgid "Password strength: Moderate" +msgstr "Độ mạnh mật khẩu: Trung bình" + +msgid "Password strength: Strong" +msgstr "Độ mạnh mật khẩu: Mạnh" + +msgid "The selected desktop profile requires a regular user to log in via the greeter" +msgstr "" +"Cấu hình máy tính để bàn đã chọn yêu cầu người dùng thông thường đăng nhập thông qua màn hình đăng " +"nhập" + +#, fuzzy, python-brace-format +msgid "Environment type: {} {}" +msgstr "Loại môi trường: {} {}" + +msgid "Input cannot be empty" +msgstr "Đầu vào không thể trống" + +msgid "Recommended" +msgstr "Khuyến khích" + +msgid "Package" +msgstr "Gói" + +#, fuzzy +msgid "Curated selection of KDE Plasma packages" +msgstr "Lựa chọn các gói KDE Plasma được tuyển chọn" + +#, fuzzy +msgid "Dependencies" +msgstr "phụ thuộc" + +#, fuzzy +msgid "Package group" +msgstr "Nhóm gói" + +#, fuzzy +msgid "Extensive KDE Plasma installation" +msgstr "Cài đặt KDE Plasma mở rộng" + +#, fuzzy +msgid "Packages in group" +msgstr "Gói trong nhóm" + +#, fuzzy +msgid "Minimal KDE Plasma installation" +msgstr "Cài đặt KDE Plasma tối thiểu" + +#, fuzzy +msgid "Description" +msgstr "Sự miêu tả" + +#, fuzzy +msgid "Select a flavor of KDE Plasma to install" +msgstr "Chọn phiên bản KDE Plasma để cài đặt" + +#, fuzzy +msgid "Arial/Times/Courier replacement, Cyrillic support for Steam/games" +msgstr "Thay thế Arial/Time/Courier, hỗ trợ Cyrillic cho Steam/game" + +#, fuzzy +msgid "wide Unicode coverage, good fallback font" +msgstr "vùng phủ sóng Unicode rộng, phông chữ dự phòng tốt" + +#, fuzzy, python-brace-format +msgid "Setting up U2F login: {u2f_config.u2f_login_method.value}" +msgstr "Thiết lập đăng nhập U2F: {u2f_config.u2f_login_method.value}" + +#, fuzzy, python-brace-format +msgid "Default: {DEFAULT_ITER_TIME}ms, Recommended range: 1000-60000" +msgstr "Mặc định: {DEFAULT_ITER_TIME} ms, Phạm vi khuyến nghị: 1000-60000" + +#, fuzzy, python-brace-format +msgid "Setting up U2F login: {}" +msgstr "Thiết lập đăng nhập U2F: {}" + +#, fuzzy, python-brace-format +msgid "Default: {}ms, Recommended range: 1000-60000" +msgstr "Mặc định: {} ms, Phạm vi khuyến nghị: 1000-60000" + +#, python-brace-format +msgid "{} needs access to your seat" +msgstr "{} cần quyền truy cập vào seat của bạn" + +#, fuzzy +msgid "collection of hardware devices i.e. keyboard, mouse" +msgstr "tập hợp các thiết bị phần cứng như bàn phím, chuột" + +#, fuzzy, python-brace-format +msgid "Choose an option how to give {} access to your hardware" +msgstr "Chọn một tùy chọn về cách cấp quyền truy cập {} vào phần cứng của bạn" + +#, python-brace-format +msgid "About to upload \"{}\" to the publicly accessible {}" +msgstr "Sắp tải \"{}\" lên {} có thể truy cập công khai" + +#, fuzzy +msgid "Do you want to continue?" +msgstr "Bạn có muốn tiếp tục không?" + +#, fuzzy, python-brace-format +msgid "Log uploaded successfully. URL: {}" +msgstr "Nhật ký được tải lên thành công. URL: {}" + +#, fuzzy +msgid "Failed to upload log." +msgstr "Không thể tải lên nhật ký." + +#, fuzzy +msgid "ArchInstall Language" +msgstr "Ngôn ngữ cài đặt Arch" + +#, fuzzy +msgid "Version" +msgstr "Phiên bản" + +#, fuzzy +msgid "Installation Script" +msgstr "Tập lệnh cài đặt" + +msgid "Application" +msgstr "Ứng dụng" + +#, fuzzy +msgid "Services" +msgstr "Dịch vụ" + +#, fuzzy +msgid "Custom commands" +msgstr "Lệnh tùy chỉnh" + +#, fuzzy +msgid "Users" +msgstr "Người dùng" + +#, fuzzy +msgid "Root encrypted password" +msgstr "Mật khẩu được mã hóa gốc" + +#, fuzzy +msgid "Zram enabled" +msgstr "Đã bật Zram" + +#, fuzzy, python-brace-format +msgid "Zram algorithm {}" +msgstr "Thuật toán Zram {}" + +#, fuzzy +msgid "Bluetooth enabled" +msgstr "Đã bật Bluetooth" + +#, python-brace-format +msgid "Audio server \"{}\"" +msgstr "Hệ thống âm thanh \"{}\"" + +#, fuzzy, python-brace-format +msgid "Power management \"{}\"" +msgstr "Quản lý nguồn điện \"{}\"" + +#, fuzzy +msgid "Print service enabled" +msgstr "Đã bật dịch vụ in" + +#, fuzzy, python-brace-format +msgid "Firewall \"{}\"" +msgstr "Tường lửa \"{}\"" + +#, python-brace-format +msgid "Extra fonts \"{}\"" +msgstr "Phông chữ bổ sung \"{}\"" + +#, fuzzy +msgid "Root password set" +msgstr "Đã đặt mật khẩu gốc" + +#, fuzzy, python-brace-format +msgid "Configured {} user(s)" +msgstr "(Những) người dùng {} đã định cấu hình" + +#, fuzzy +msgid "U2F set up" +msgstr "thiết lập U2F" + +#, fuzzy, python-brace-format +msgid "Bootloader \"{}\"" +msgstr "Bộ nạp khởi động \"{}\"" + +#, fuzzy +msgid "UKI enabled" +msgstr "Đã bật UKI" + +#, fuzzy +msgid "Default" +msgstr "Mặc định" + +#, fuzzy +msgid "Manual" +msgstr "Thủ công" + +#, fuzzy +msgid "Pre-mount" +msgstr "Gắn trước" + +#, python-brace-format +msgid "{} layout" +msgstr "Bố cục {}" + +#, python-brace-format +msgid "Devices {}" +msgstr "Thiết bị {}" + +msgid "LVM set up" +msgstr "Cấu hình LVM" + +#, python-brace-format +msgid "{} encryption" +msgstr "Mã hóa {}" + +#, python-brace-format +msgid "Btrfs snapshot \"{}\"" +msgstr "Bản sao lưu tức thời Btrfs \"{}\"" + +#, python-brace-format +msgid "Keyboard layout \"{}\"" +msgstr "Bố cục bàn phím \"{}\"" + +#, python-brace-format +msgid "Locale language \"{}\"" +msgstr "Ngôn ngữ hệ thống (Locale) \"{}\"" + +#, python-brace-format +msgid "Locale encoding \"{}\"" +msgstr "Mã hóa ngôn ngữ hệ thống \"{}\"" + +#, python-brace-format +msgid "Console font \"{}\"" +msgstr "Phông chữ Console \"{}\"" + +#, python-brace-format +msgid "Mirror regions \"{}\"" +msgstr "Máy chủ bản sao \"{}\"" + +#, python-brace-format +msgid "Optional repositories \"{}\"" +msgstr "Kho phần mềm bổ sung \"{}\"" + +msgid "Custom servers set up" +msgstr "Cấu hình máy chủ tùy chỉnh" + +msgid "Custom repositories set up" +msgstr "Kho phần mềm tùy chỉnh được thiết lập" + +#, fuzzy +msgid "Use standalone iwd" +msgstr "Sử dụng iwd độc lập" + +#, fuzzy +msgid "Color enabled" +msgstr "Đã bật màu" + +#, fuzzy, python-brace-format +msgid "{} grphics driver" +msgstr "Trình điều khiển đồ họa {}" + +#, python-brace-format +msgid "{} greeter" +msgstr "Màn hình đăng nhập {}" + +msgid "Enter a repository name" +msgstr "Nhập tên kho phần mềm" From 8902d2e310c23193e75e0c2d3a6847a530e0a213 Mon Sep 17 00:00:00 2001 From: correctmost <134317971+correctmost@users.noreply.github.com> Date: Sun, 12 Jul 2026 07:20:44 -0400 Subject: [PATCH 25/35] Use a match statement for PasswordStrength enum values (#4619) This unblocks the upgrade to mypy 2.2.0, which now flags the unreachable "return None" statement. --- archinstall/lib/menu/util.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/archinstall/lib/menu/util.py b/archinstall/lib/menu/util.py index 5efef09d..6e227a7f 100644 --- a/archinstall/lib/menu/util.py +++ b/archinstall/lib/menu/util.py @@ -19,14 +19,15 @@ async def get_password( def password_hint(value: str) -> InputInfo | None: if not value: return None + strength = PasswordStrength.strength(value) - if strength in (PasswordStrength.VERY_WEAK, PasswordStrength.WEAK): - return InputInfo(message=tr('Password strength: Weak'), msg_level=MsgLevelType.MsgError) - elif strength == PasswordStrength.MODERATE: - return InputInfo(message=tr('Password strength: Moderate'), msg_level=MsgLevelType.MsgWarning) - elif strength == PasswordStrength.STRONG: - return InputInfo(message=tr('Password strength: Strong'), msg_level=MsgLevelType.MsgInfo) - return None + match strength: + case PasswordStrength.VERY_WEAK | PasswordStrength.WEAK: + return InputInfo(message=tr('Password strength: Weak'), msg_level=MsgLevelType.MsgError) + case PasswordStrength.MODERATE: + return InputInfo(message=tr('Password strength: Moderate'), msg_level=MsgLevelType.MsgWarning) + case PasswordStrength.STRONG: + return InputInfo(message=tr('Password strength: Strong'), msg_level=MsgLevelType.MsgInfo) while True: result = await Input( From c110081a424e291fe3f59c233e8cf778143a5144 Mon Sep 17 00:00:00 2001 From: correctmost <134317971+correctmost@users.noreply.github.com> Date: Sun, 12 Jul 2026 07:21:18 -0400 Subject: [PATCH 26/35] Enable more mypy and Pylint checks for test_tooling/ (#4620) --- pyproject.toml | 1 - test_tooling/qemu/qemu.py | 163 ++++++++++++++++++++------------------ 2 files changed, 87 insertions(+), 77 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 4c916863..e7217bdf 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -72,7 +72,6 @@ python_version = "3.14" files = "." exclude = [ "^build/", - "^test_tooling/", ] disallow_any_explicit = false disallow_any_expr = false diff --git a/test_tooling/qemu/qemu.py b/test_tooling/qemu/qemu.py index c8307771..69e766da 100644 --- a/test_tooling/qemu/qemu.py +++ b/test_tooling/qemu/qemu.py @@ -11,6 +11,8 @@ import sys import time from argparse import ArgumentParser from collections.abc import Iterator +from functools import cache +from pathlib import Path from select import EPOLLHUP, EPOLLIN, epoll from shutil import which from types import TracebackType @@ -25,25 +27,32 @@ class ArgumentError(Exception): pass -def get_master(interface): +def cpu_count() -> int: + count = os.cpu_count() + if not count: + return 1 + + return count - 1 + + +def get_master(interface: str) -> str | None: master_path = pathlib.Path(f'/sys/class/net/{interface}/master') return master_path.readlink().name if master_path.exists() else None -def gray(text): +def gray(text: str) -> str: return f'\033[38;5;246m{text}\033[0m' -def orange(text): +def orange(text: str) -> str: return f'\033[38;5;208m{text}\033[0m' -def red(text): +def red(text: str) -> str: return f'\033[31m{text}\033[0m' -sudo_password = None # Gets populated later -harddrives = {} +harddrives: dict[Path, str] = {} username = getpass.getuser() groupname = grp.getgrgid(os.getgid()).gr_name @@ -71,37 +80,37 @@ hardware = parser.add_argument_group('Hardware', 'General hardware specs for the hardware.add_argument('--bios', action='store_true', help='Disables EFI (edk2/ovmf) and uses BIOS support instead', default=False) hardware.add_argument('--memory', nargs='?', help='Ammount of memory to supply the machine', default=8192) hardware.add_argument('--harddrive', action='append', help='Sets up one or more virtio-scsi-pci, size is defined by --harddrive test.qcow2:15G', type=str) -hardware.add_argument('--cpu', help='Sets the number of cores to allocate (default nproc -1)', type=str, default=os.cpu_count() - 1 if os.cpu_count() else 1) +hardware.add_argument('--cpu', help='Sets the number of cores to allocate (default nproc -1)', type=str, default=cpu_count()) hardware.add_argument('--resolution', help="Sets Qemu's VGA resolution", type=str, default='1920x1107') kernel = parser.add_argument_group('Kernel', '--kernel specific arguments') kernel.add_argument('--initrd', nargs='?', help='Defines which ISO to run (skips build all together)', default=None, type=pathlib.Path) -args, unknowns = parser.parse_known_args() # pylint: disable=redefined-outer-name +cli_args, _ = parser.parse_known_args() -if args.bios and args.uki: +if cli_args.bios and cli_args.uki: raise ArgumentError('Cannot boot a --uki image with --bios mode (at least not that I know of).') -if args.uki is None and args.kernel is None and args.iso is None and args.harddrive is None: +if cli_args.uki is None and cli_args.kernel is None and cli_args.iso is None and cli_args.harddrive is None: raise ArgumentError('Cannot boot this machine, define at least one of: --uki, --kernel, --iso, --harddrive') -if args.bridge is None and args.bridge_master: +if cli_args.bridge is None and cli_args.bridge_master: raise ArgumentError('Cannot use --bridge-master without defining --bridge') -if args.bridge is None and args.bridge_mac: +if cli_args.bridge is None and cli_args.bridge_mac: raise ArgumentError('Cannot use --bridge-mac without defining --bridge') -elif args.bridge and args.bridge_mac is None: - args.bridge_mac = '52:54:00:00:00:1' +elif cli_args.bridge and cli_args.bridge_mac is None: + cli_args.bridge_mac = '52:54:00:00:00:1' -if args.tap and not args.bridge and get_master(args.tap) is None: +if cli_args.tap and not cli_args.bridge and get_master(cli_args.tap) is None: # We'll allow it, because maybe we're tesing what happens without networking, but the NIC exists. # Or the user has some creative iptables/nftables forwarding. print(orange('--tap does not have a master, consider adding --bridge or manual set a master using ip-link(8).')) -if args.tap is None and args.bridge: +if cli_args.tap is None and cli_args.bridge: print(orange("--bridge* arguments will be ignored since there's no --tap defined")) -elif args.tap and args.tap_mac is None: - args.tap_mac = '52:54:00:00:00:2' +elif cli_args.tap and cli_args.tap_mac is None: + cli_args.tap_mac = '52:54:00:00:00:2' class SysCallError(Exception): @@ -176,7 +185,7 @@ class SysCommandWorker: return False - def __iter__(self, *args: str, **kwargs: dict[str, Any]) -> Iterator[bytes]: # pylint: disable=redefined-outer-name + def __iter__(self, *args: str, **kwargs: dict[str, Any]) -> Iterator[bytes]: last_line = self._trace_log.rfind(b'\n') lines = filter(None, self._trace_log[self._trace_log_pos : last_line].splitlines()) for line in lines: @@ -334,81 +343,82 @@ class SysCommandWorker: return self._trace_log.decode(encoding) -def ensure_sudo(): - global sudo_password # pylint: disable=global-statement +@cache +def get_sudo_password() -> str: + sudo_password = getpass.getpass(f'[sudo] password for {username}: ') + if sudo_password == '': + raise ValueError('Certain commands need sudo to work and no sudo password was given.') - if sudo_password is None: - if (sudo_password := getpass.getpass(f'[sudo] password for {username}: ')) == '': - raise ValueError('Certain commands need sudo to work and no sudo password was given.') + return sudo_password -def setup_networking(): - if args.tap: - if pathlib.Path(f'/sys/class/net/{args.tap}').exists() is False: - print(gray(f'Creating {args.tap} for user {username} and group {groupname}')) - handle, pw_prompted = SysCommandWorker(f'sudo ip tuntap add dev {args.tap} mode tap user {username} group {groupname}'), False +def setup_networking() -> None: + if cli_args.tap: + if pathlib.Path(f'/sys/class/net/{cli_args.tap}').exists() is False: + print(gray(f'Creating {cli_args.tap} for user {username} and group {groupname}')) + handle, pw_prompted = SysCommandWorker(f'sudo ip tuntap add dev {cli_args.tap} mode tap user {username} group {groupname}'), False while handle.is_alive(): if b'password for' in handle and pw_prompted is False: - ensure_sudo() - handle.write(bytes(sudo_password, 'UTF-8')) + sudo_pw = get_sudo_password() + handle.write(bytes(sudo_pw, 'UTF-8')) pw_prompted = True - if args.bridge: - if pathlib.Path(f'/sys/class/net/{args.bridge}').exists() is False: - print(gray(f'Creating {args.bridge}')) - handle, pw_prompted = SysCommandWorker(f'sudo ip link add name {args.bridge} type bridge'), False + if cli_args.bridge: + if pathlib.Path(f'/sys/class/net/{cli_args.bridge}').exists() is False: + print(gray(f'Creating {cli_args.bridge}')) + handle, pw_prompted = SysCommandWorker(f'sudo ip link add name {cli_args.bridge} type bridge'), False while handle.is_alive(): if b'password for' in handle and pw_prompted is False: - ensure_sudo() - handle.write(bytes(sudo_password, 'UTF-8')) + sudo_pw = get_sudo_password() + handle.write(bytes(sudo_pw, 'UTF-8')) pw_prompted = True - if args.bridge_mac: - handle, pw_prompted = SysCommandWorker(f'sudo ip link set dev {args.bridge} address {args.bridge_mac}'), False - print(gray(f'Setting bridge {args.bridge} MAC address to {args.bridge_mac}')) + if cli_args.bridge_mac: + handle, pw_prompted = SysCommandWorker(f'sudo ip link set dev {cli_args.bridge} address {cli_args.bridge_mac}'), False + print(gray(f'Setting bridge {cli_args.bridge} MAC address to {cli_args.bridge_mac}')) while handle.is_alive(): if b'password for' in handle and pw_prompted is False: - ensure_sudo() - handle.write(bytes(sudo_password, 'UTF-8')) + sudo_pw = get_sudo_password() + handle.write(bytes(sudo_pw, 'UTF-8')) pw_prompted = True - if args.bridge_master and get_master(args.bridge) != args.bridge_master: - handle, pw_prompted = SysCommandWorker(f'sudo ip link set dev {args.bridge_master} master {args.bridge}'), False - print(gray(f'Setting interface {args.bridge_master} master to {args.bridge}')) + if cli_args.bridge_master and get_master(cli_args.bridge) != cli_args.bridge_master: + handle, pw_prompted = SysCommandWorker(f'sudo ip link set dev {cli_args.bridge_master} master {cli_args.bridge}'), False + print(gray(f'Setting interface {cli_args.bridge_master} master to {cli_args}')) while handle.is_alive(): if b'password for' in handle and pw_prompted is False: - ensure_sudo() - handle.write(bytes(sudo_password, 'UTF-8')) + sudo_pw = get_sudo_password() + handle.write(bytes(sudo_pw, 'UTF-8')) pw_prompted = True - print(gray(f'Setting interface {args.tap} master to {args.bridge}')) - handle, pw_prompted = SysCommandWorker(f'sudo ip link set dev {args.tap} master {args.bridge}'), False + print(gray(f'Setting interface {cli_args.tap} master to {cli_args.bridge}')) + handle, pw_prompted = SysCommandWorker(f'sudo ip link set dev {cli_args.tap} master {cli_args.bridge}'), False while handle.is_alive(): if b'password for' in handle and pw_prompted is False: - ensure_sudo() - handle.write(bytes(sudo_password, 'UTF-8')) + sudo_pw = get_sudo_password() + handle.write(bytes(sudo_pw, 'UTF-8')) pw_prompted = True - print(gray(f'Bringing up bridge {args.bridge}')) - handle, pw_prompted = SysCommandWorker(f'sudo ip link set dev {args.bridge} up'), False + print(gray(f'Bringing up bridge {cli_args.bridge}')) + handle, pw_prompted = SysCommandWorker(f'sudo ip link set dev {cli_args.bridge} up'), False while handle.is_alive(): if b'password for' in handle and pw_prompted is False: - ensure_sudo() - handle.write(bytes(sudo_password, 'UTF-8')) + sudo_pw = get_sudo_password() + handle.write(bytes(sudo_pw, 'UTF-8')) pw_prompted = True - print(gray(f'Bringing interface {args.tap} up')) - handle, pw_prompted = SysCommandWorker(f'sudo ip link set dev {args.tap} up'), False + print(gray(f'Bringing interface {cli_args.tap} up')) + handle, pw_prompted = SysCommandWorker(f'sudo ip link set dev {cli_args.tap} up'), False while handle.is_alive(): if b'password for' in handle and pw_prompted is False: - ensure_sudo() - handle.write(bytes(sudo_password, 'UTF-8')) + sudo_pw = get_sudo_password() + handle.write(bytes(sudo_pw, 'UTF-8')) pw_prompted = True -def setup_disks(): - if args.harddrive: - for harddrive_arg in args.harddrive: +def setup_disks() -> None: + if cli_args.harddrive: + for harddrive_arg in cli_args.harddrive: path, size = harddrive_arg.split(':') path = pathlib.Path(path.strip()).expanduser().resolve().absolute() harddrives[path] = size.strip() @@ -425,7 +435,8 @@ def setup_disks(): setup_networking() setup_disks() -if args.uki or args.bios is False: +disk_paths_hash = '' +if cli_args.uki or cli_args.bios is False: disk_paths_hash = hashlib.sha1((''.join(sorted([str(x) for x in harddrives.keys()]))).encode()).hexdigest() shutil.copy2('/usr/share/ovmf/x64/OVMF_CODE.secboot.4m.fd', f'./OVMF_CODE.secboot.4m.fd.{disk_paths_hash}') @@ -439,16 +450,16 @@ qemu += ' -machine q35,accel=kvm' qemu += ' -object rng-random,filename=/dev/urandom,id=rng0' qemu += ' -device virtio-rng-pci,rng=rng0' qemu += ' -global driver=cfi.pflash01,property=secure,value=on' -qemu += f' -smp {args.cpu},sockets=1,dies=1,cores={args.cpu},threads=1' +qemu += f' -smp {cli_args.cpu},sockets=1,dies=1,cores={cli_args.cpu},threads=1' # qemu += f' -vga vga' -qemu += f' -device VGA,edid=on,xres={args.resolution.split("x")[0]},yres={args.resolution.split("x")[1]}' +qemu += f' -device VGA,edid=on,xres={cli_args.resolution.split("x")[0]},yres={cli_args.resolution.split("x")[1]}' qemu += ' -device intel-iommu,device-iotlb=on,caching-mode=on' -qemu += f' -m {args.memory}' -if args.bios is False: +qemu += f' -m {cli_args.memory}' +if cli_args.bios is False: qemu += f' -drive if=pflash,format=raw,readonly=on,file=./OVMF_CODE.secboot.4m.fd.{disk_paths_hash}' qemu += f' -drive if=pflash,format=raw,file=./OVMF_VARS.4m.fd.{disk_paths_hash}' -if args.uki: - qemu += f' -kernel {args.uki}' +if cli_args.uki: + qemu += f' -kernel {cli_args.uki}' boot_index += 1 scsi_index = 0 for scsi_index, hdd in enumerate(harddrives.keys()): @@ -460,18 +471,18 @@ for scsi_index, hdd in enumerate(harddrives.keys()): qemu += f' -blockdev \'{{"driver":"file","filename":"{hdd}","aio":"threads","node-name":"libvirt-{scsi_index}-storage","cache":{{"direct":false,"no-flush":false}},"auto-read-only":true,"discard":"unmap"}}\'' # noqa: E501 qemu += f' -blockdev \'{{"node-name":"libvirt-{scsi_index}-format","read-only":false,"discard":"unmap","cache":{{"direct":true,"no-flush":false}},"driver":"qcow2","file":"libvirt-{scsi_index}-storage","backing":null}}\'' # noqa: E501 boot_index += 1 -if args.iso: +if cli_args.iso: qemu += f' -device virtio-scsi-pci,bus=pcie.0,id=scsi{scsi_index + 1}' qemu += f' -device scsi-cd,drive=cdrom0,bus=scsi{scsi_index + 1}.0,bootindex={boot_index}' - qemu += f' -drive file={args.iso},media=cdrom,if=none,format=raw,cache=none,id=cdrom0' + qemu += f' -drive file={cli_args.iso},media=cdrom,if=none,format=raw,cache=none,id=cdrom0' boot_index += 1 -# if args.vfio: -# qemu += f' -drive file={args.vfio},index=2,media=cdrom' +# if cli_args.vfio: +# qemu += f' -drive file={cli_args.vfio},index=2,media=cdrom' -if args.tap: - qemu += f' -device virtio-net-pci,mac={args.tap_mac},id=network0,netdev=network0.0,status=on,bus=pcie.0' - qemu += f' -netdev tap,ifname={args.tap},id=network0.0,script=no,downscript=no' +if cli_args.tap: + qemu += f' -device virtio-net-pci,mac={cli_args.tap_mac},id=network0,netdev=network0.0,status=on,bus=pcie.0' + qemu += f' -netdev tap,ifname={cli_args.tap},id=network0.0,script=no,downscript=no' print(gray(qemu)) From c60385a6f7affa2fe7ad7e9e8452f11141586135 Mon Sep 17 00:00:00 2001 From: Christos Longros <98426896+chrislongros@users.noreply.github.com> Date: Sun, 12 Jul 2026 14:21:58 +0300 Subject: [PATCH 27/35] Update Greek translations: TUI navigation strings (#4621) --- archinstall/locales/el/LC_MESSAGES/base.mo | Bin 40162 -> 43145 bytes archinstall/locales/el/LC_MESSAGES/base.po | 100 ++++++++++----------- 2 files changed, 50 insertions(+), 50 deletions(-) diff --git a/archinstall/locales/el/LC_MESSAGES/base.mo b/archinstall/locales/el/LC_MESSAGES/base.mo index cee51a48df5cd78c3c70966eda3d8ec0fd3e8c3a..6e052eafaf9b8c934ab1bcf3db3a19ea25464b7b 100644 GIT binary patch delta 9053 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 delta 6164 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 diff --git a/archinstall/locales/el/LC_MESSAGES/base.po b/archinstall/locales/el/LC_MESSAGES/base.po index 5a56491a..41db88f9 100644 --- a/archinstall/locales/el/LC_MESSAGES/base.po +++ b/archinstall/locales/el/LC_MESSAGES/base.po @@ -1423,7 +1423,7 @@ msgid "Yes" msgstr "ναι" msgid "No" -msgstr "" +msgstr "όχι" #, fuzzy msgid "Archinstall help" @@ -1434,7 +1434,7 @@ msgid " (default)" msgstr "(προκαθορισμένο)" msgid "Press Ctrl+h for help" -msgstr "" +msgstr "Πατήστε Ctrl+h για βοήθεια" #, fuzzy msgid "Choose an option to give Sway access to your hardware" @@ -1621,7 +1621,7 @@ msgid "Select execution mode" msgstr "Επιλέξτε μία ενέργεια για '{}'" msgid "Press ? for help" -msgstr "" +msgstr "Πατήστε ? για βοήθεια" #, fuzzy msgid "Choose an option to give Hyprland access to your hardware" @@ -1754,31 +1754,31 @@ msgid "Only ASCII characters are supported" msgstr "" msgid "Show help" -msgstr "" +msgstr "Εμφάνιση βοήθειας" msgid "Exit help" -msgstr "" +msgstr "Έξοδος από τη βοήθεια" msgid "Preview scroll up" -msgstr "" +msgstr "Κύλιση προεπισκόπησης πάνω" msgid "Preview scroll down" -msgstr "" +msgstr "Κύλιση προεπισκόπησης κάτω" msgid "Move up" -msgstr "" +msgstr "Μετακίνηση πάνω" msgid "Move down" -msgstr "" +msgstr "Μετακίνηση κάτω" msgid "Move right" -msgstr "" +msgstr "Μετακίνηση δεξιά" msgid "Move left" -msgstr "" +msgstr "Μετακίνηση αριστερά" msgid "Jump to entry" -msgstr "" +msgstr "Μετάβαση σε καταχώρηση" msgid "Skip selection (if available)" msgstr "" @@ -1795,20 +1795,20 @@ msgid "Select on multi select" msgstr "Επιλέξτε μία ζώνη ώρας" msgid "Reset" -msgstr "" +msgstr "Επαναφορά" #, fuzzy msgid "Skip selection menu" msgstr "Επιλέξτε μία ενέργεια για '{}'" msgid "Start search mode" -msgstr "" +msgstr "Έναρξη λειτουργίας αναζήτησης" msgid "Exit search mode" -msgstr "" +msgstr "Έξοδος από τη λειτουργία αναζήτησης" msgid "General" -msgstr "" +msgstr "Γενικά" #, fuzzy msgid "Navigation" @@ -1819,115 +1819,115 @@ msgid "Selection" msgstr "Επιλέξτε διεπαφή προς προσθήκη" msgid "Search" -msgstr "" +msgstr "Αναζήτηση" msgid "Down" -msgstr "" +msgstr "Κάτω" msgid "Up" -msgstr "" +msgstr "Πάνω" #, fuzzy msgid "Confirm" msgstr "Επιβεβαίωση και έξοδος" msgid "Focus right" -msgstr "" +msgstr "Εστίαση δεξιά" msgid "Focus left" -msgstr "" +msgstr "Εστίαση αριστερά" msgid "Toggle" -msgstr "" +msgstr "Εναλλαγή" msgid "Show/Hide help" -msgstr "" +msgstr "Εμφάνιση/Απόκρυψη βοήθειας" msgid "Quit" -msgstr "" +msgstr "Έξοδος" msgid "First" -msgstr "" +msgstr "Πρώτο" msgid "Last" -msgstr "" +msgstr "Τελευταίο" #, fuzzy msgid "Select" msgstr "Επιλέξτε διεπαφή προς προσθήκη" msgid "Page Up" -msgstr "" +msgstr "Σελίδα πάνω" msgid "Page Down" -msgstr "" +msgstr "Σελίδα κάτω" msgid "Page up" -msgstr "" +msgstr "Σελίδα πάνω" msgid "Page down" -msgstr "" +msgstr "Σελίδα κάτω" msgid "Page Left" -msgstr "" +msgstr "Σελίδα αριστερά" msgid "Page Right" -msgstr "" +msgstr "Σελίδα δεξιά" msgid "Cursor up" -msgstr "" +msgstr "Δρομέας πάνω" msgid "Cursor down" -msgstr "" +msgstr "Δρομέας κάτω" msgid "Cursor right" -msgstr "" +msgstr "Δρομέας δεξιά" msgid "Cursor left" -msgstr "" +msgstr "Δρομέας αριστερά" msgid "Top" -msgstr "" +msgstr "Κορυφή" msgid "Bottom" -msgstr "" +msgstr "Βάση" msgid "Home" -msgstr "" +msgstr "Αρχή" msgid "End" -msgstr "" +msgstr "Τέλος" #, fuzzy msgid "Toggle option" msgstr "Επιλογές υποόγκου" msgid "Scroll Up" -msgstr "" +msgstr "Κύλιση πάνω" msgid "Scroll Down" -msgstr "" +msgstr "Κύλιση κάτω" msgid "Scroll Left" -msgstr "" +msgstr "Κύλιση αριστερά" msgid "Scroll Right" -msgstr "" +msgstr "Κύλιση δεξιά" msgid "Scroll Home" -msgstr "" +msgstr "Κύλιση στην αρχή" msgid "Scroll End" -msgstr "" +msgstr "Κύλιση στο τέλος" msgid "Focus Next" -msgstr "" +msgstr "Εστίαση στο επόμενο" msgid "Focus Previous" -msgstr "" +msgstr "Εστίαση στο προηγούμενο" msgid "Copy selected text" -msgstr "" +msgstr "Αντιγραφή επιλεγμένου κειμένου" msgid "labwc needs access to your seat (collection of hardware devices i.e. keyboard, mouse, etc)" msgstr "" @@ -2115,7 +2115,7 @@ msgid "Enter wifi password" msgstr "Εισάγετε κωδικό: " msgid "Ok" -msgstr "" +msgstr "Εντάξει" msgid "Removable" msgstr "" From 3f4f815a345b87b8f29e08d8f291301bf3e70e08 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 13 Jul 2026 07:04:41 +1000 Subject: [PATCH 28/35] Update dependency arch/python-textual to v8.2.8 (#4624) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index e7217bdf..fbeaa888 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,7 +21,7 @@ dependencies = [ "pyparted==3.13.0", "pydantic==2.13.4", "cryptography==49.0.0", - "textual==8.2.7", + "textual==8.2.8", "markdown-it-py==4.0.0", "linkify-it-py==2.1.0", ] From 34c299e42ee034a78bbe83a0870a4329f8b16c47 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 13 Jul 2026 07:05:31 +1000 Subject: [PATCH 29/35] Update astral-sh/ruff-action action to v4.1.0 (#4625) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/ruff-format.yaml | 2 +- .github/workflows/ruff-lint.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ruff-format.yaml b/.github/workflows/ruff-format.yaml index 3dd4644d..6c0e99bf 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@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 - - uses: astral-sh/ruff-action@0ce1b0bf8b818ef400413f810f8a11cdbda0034b # v4.0.0 + - uses: astral-sh/ruff-action@278981a28ce3188b1e39527901f38254bf3aac89 # v4.1.0 - run: ruff format --diff diff --git a/.github/workflows/ruff-lint.yaml b/.github/workflows/ruff-lint.yaml index d329c42c..56ae13a6 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@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 - - uses: astral-sh/ruff-action@0ce1b0bf8b818ef400413f810f8a11cdbda0034b # v4.0.0 + - uses: astral-sh/ruff-action@278981a28ce3188b1e39527901f38254bf3aac89 # v4.1.0 From 781728b91b7a6e0b143f2397a589db045df7583d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 13 Jul 2026 13:08:47 +1000 Subject: [PATCH 30/35] Update dependency ruff to v0.15.21 (#4622) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index fbeaa888..94ee1cd0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -37,7 +37,7 @@ dev = [ "mypy==2.1.0", "flake8==7.3.0", "pre-commit==4.6.0", - "ruff==0.15.20", + "ruff==0.15.21", "pylint==4.0.6", "pytest==9.1.1", "hypothesis>=6.152.4", From e3e9d433240302ad58026a403d1d184c668aff0c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 13 Jul 2026 13:09:05 +1000 Subject: [PATCH 31/35] Update pre-commit hook astral-sh/ruff-pre-commit to v0.15.21 (#4623) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index b3bb8f3b..4b967467 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.15.20 + rev: v0.15.21 hooks: # fix unused imports and sort them - id: ruff From 2531825b597d39db668cd344d591670a9d0ba4ff Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 13 Jul 2026 13:09:27 +1000 Subject: [PATCH 32/35] Update dependency mypy to v2.2.0 (#4626) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 94ee1cd0..23def4c5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -34,7 +34,7 @@ Source = "https://github.com/archlinux/archinstall" [project.optional-dependencies] log = ["systemd_python==236"] dev = [ - "mypy==2.1.0", + "mypy==2.2.0", "flake8==7.3.0", "pre-commit==4.6.0", "ruff==0.15.21", From 12baa2e64a50892eaf94d92a0e0e0697a44f928c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 13 Jul 2026 13:09:55 +1000 Subject: [PATCH 33/35] Update pre-commit hook pre-commit/mirrors-mypy to v2.2.0 (#4627) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 4b967467..fae367cf 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -31,7 +31,7 @@ repos: args: [--config=.flake8] fail_fast: true - repo: https://github.com/pre-commit/mirrors-mypy - rev: v2.1.0 + rev: v2.2.0 hooks: - id: mypy args: [ From 46320deb3352af70696ebd79ba7ae7a326f120bd Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 14 Jul 2026 10:13:43 +1000 Subject: [PATCH 34/35] Update dependency mypy to v2.3.0 (#4628) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 23def4c5..6c6ac0c2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -34,7 +34,7 @@ Source = "https://github.com/archlinux/archinstall" [project.optional-dependencies] log = ["systemd_python==236"] dev = [ - "mypy==2.2.0", + "mypy==2.3.0", "flake8==7.3.0", "pre-commit==4.6.0", "ruff==0.15.21", From 53158a8aadd2714f46013b594d9ac00565d56e75 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 14 Jul 2026 10:14:03 +1000 Subject: [PATCH 35/35] Update pre-commit hook pre-commit/mirrors-mypy to v2.3.0 (#4629) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index fae367cf..188bbcf3 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -31,7 +31,7 @@ repos: args: [--config=.flake8] fail_fast: true - repo: https://github.com/pre-commit/mirrors-mypy - rev: v2.2.0 + rev: v2.3.0 hooks: - id: mypy args: [