From 5c9bd235d3d0e653ba8d643748fd3d776359978b Mon Sep 17 00:00:00 2001 From: Anton Hvornum Date: Sat, 28 May 2022 10:06:22 +0200 Subject: Fixes additional encryption prompt even tho partitions was marked for encryption (#1264) Corrected the check for partitions marked with `encrypt: true` --- archinstall/lib/disk/helpers.py | 7 ++++--- archinstall/lib/menu/global_menu.py | 17 +++++++++-------- archinstall/lib/user_interaction/partitioning_conf.py | 2 -- 3 files changed, 13 insertions(+), 13 deletions(-) (limited to 'archinstall') diff --git a/archinstall/lib/disk/helpers.py b/archinstall/lib/disk/helpers.py index 99856aad..65d7a006 100644 --- a/archinstall/lib/disk/helpers.py +++ b/archinstall/lib/disk/helpers.py @@ -433,9 +433,10 @@ def disk_layouts() -> Optional[Dict[str, Any]]: def encrypted_partitions(blockdevices :Dict[str, Any]) -> bool: - for partition in blockdevices.values(): - if partition.get('encrypted', False): - yield partition + for blockdevice in blockdevices.values(): + for partition in blockdevice.get('partitions', []): + if partition.get('encrypted', False): + yield partition def find_partition_by_mountpoint(block_devices :List[BlockDevice], relative_mountpoint :str) -> Partition: for device in block_devices: diff --git a/archinstall/lib/menu/global_menu.py b/archinstall/lib/menu/global_menu.py index 5cb27cab..3ffb6f15 100644 --- a/archinstall/lib/menu/global_menu.py +++ b/archinstall/lib/menu/global_menu.py @@ -204,14 +204,15 @@ class GlobalMenu(GeneralMenu): # Then we need to identify which partitions to encrypt. This will default to / (root). if len(list(encrypted_partitions(storage['arguments'].get('disk_layouts', [])))) == 0: for blockdevice in storage['arguments']['disk_layouts']: - for partition_index in select_encrypted_partitions( - title="Select which partitions to encrypt:", - partitions=storage['arguments']['disk_layouts'][blockdevice]['partitions'] - ): - - partition = storage['arguments']['disk_layouts'][blockdevice]['partitions'][partition_index] - partition['encrypted'] = True - partition['!password'] = storage['arguments']['!encryption-password'] + if storage['arguments']['disk_layouts'][blockdevice].get('partitions'): + for partition_index in select_encrypted_partitions( + title="Select which partitions to encrypt:", + partitions=storage['arguments']['disk_layouts'][blockdevice]['partitions'] + ): + + partition = storage['arguments']['disk_layouts'][blockdevice]['partitions'][partition_index] + partition['encrypted'] = True + partition['!password'] = storage['arguments']['!encryption-password'] def _install_text(self): missing = len(self._missing_configs()) diff --git a/archinstall/lib/user_interaction/partitioning_conf.py b/archinstall/lib/user_interaction/partitioning_conf.py index bfff5705..1f41f9b0 100644 --- a/archinstall/lib/user_interaction/partitioning_conf.py +++ b/archinstall/lib/user_interaction/partitioning_conf.py @@ -374,8 +374,6 @@ def select_encrypted_partitions( if len(partition_indexes) == 0: return None - title = _('Select which partitions to mark for formatting:') - # show current partition layout: if len(partitions): title += current_partition_layout(partitions) + '\n' -- cgit v1.2.3-54-g00ecf From 486ad7dd6d195dd435c5da58d241e14742f60485 Mon Sep 17 00:00:00 2001 From: Anton Hvornum Date: Sat, 28 May 2022 15:40:36 +0200 Subject: Removes btrfs subvolume warnings on incorrect subvolume locations (#1267) * Adding debug information * Adding debug information * Adding debug information * Removed a 'already-a-subvolume' check as it requires more information. * Adding debug information * Adding debug information * Made sure Partition().subvolumes() only attempts to retrieve btrfs subvolume information if fstype==btrfs. * Removed debug information --- archinstall/lib/disk/btrfs/btrfspartition.py | 8 ++++++-- archinstall/lib/disk/partition.py | 10 ++++++---- 2 files changed, 12 insertions(+), 6 deletions(-) (limited to 'archinstall') diff --git a/archinstall/lib/disk/btrfs/btrfspartition.py b/archinstall/lib/disk/btrfs/btrfspartition.py index 5020133d..299357b8 100644 --- a/archinstall/lib/disk/btrfs/btrfspartition.py +++ b/archinstall/lib/disk/btrfs/btrfspartition.py @@ -108,9 +108,13 @@ class BTRFSPartition(Partition): if glob.glob(str(subvolume / '*')): raise DiskError(f"Cannot create subvolume at {subvolume} because it contains data (non-empty folder target is not supported by BTRFS)") - elif subvolinfo := subvolume_info_from_path(subvolume): - raise DiskError(f"Destination {subvolume} is already a subvolume: {subvolinfo}") + # Ideally we would like to check if the destination is already a subvolume. + # But then we would need the mount-point at this stage as well. + # So we'll comment out this check: + # elif subvolinfo := subvolume_info_from_path(subvolume): + # raise DiskError(f"Destination {subvolume} is already a subvolume: {subvolinfo}") + # And deal with it here: SysCommand(f"btrfs subvolume create {subvolume}") return subvolume_info_from_path(subvolume) \ No newline at end of file diff --git a/archinstall/lib/disk/partition.py b/archinstall/lib/disk/partition.py index 73c88597..151775b1 100644 --- a/archinstall/lib/disk/partition.py +++ b/archinstall/lib/disk/partition.py @@ -310,8 +310,9 @@ class Partition: def iterate_children_recursively(information): for child in information.get('children', []): if target := child.get('target'): - if subvolume := subvolume_info_from_path(pathlib.Path(target)): - yield subvolume + if child.get('fstype') == 'btrfs': + if subvolume := subvolume_info_from_path(pathlib.Path(target)): + yield subvolume if child.get('children'): for subchild in iterate_children_recursively(child): @@ -320,8 +321,9 @@ class Partition: for mountpoint in self.mount_information: if result := findmnt(pathlib.Path(mountpoint['target'])): for filesystem in result.get('filesystems', []): - if subvolume := subvolume_info_from_path(pathlib.Path(mountpoint['target'])): - yield subvolume + if mountpoint.get('fstype') == 'btrfs': + if subvolume := subvolume_info_from_path(pathlib.Path(mountpoint['target'])): + yield subvolume for child in iterate_children_recursively(filesystem): yield child -- cgit v1.2.3-54-g00ecf From 2e77393cf8397197e8006293c230dd93c4378bad Mon Sep 17 00:00:00 2001 From: "Dylan M. Taylor" Date: Sat, 28 May 2022 10:29:46 -0400 Subject: Fix issue with multiples spaces in additional packages (#1262) * Try to fix issue 1259 * trim -> strip --- archinstall/lib/user_interaction/general_conf.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'archinstall') diff --git a/archinstall/lib/user_interaction/general_conf.py b/archinstall/lib/user_interaction/general_conf.py index d4dc60db..f1d56fc1 100644 --- a/archinstall/lib/user_interaction/general_conf.py +++ b/archinstall/lib/user_interaction/general_conf.py @@ -172,8 +172,8 @@ def ask_additional_packages_to_install(pre_set_packages: List[str] = []) -> List def read_packages(already_defined: list = []) -> list: display = ' '.join(already_defined) - input_packages = TextInput(_('Write additional packages to install (space separated, leave blank to skip): '), display).run() - return input_packages.split(' ') if input_packages else [] + input_packages = TextInput(_('Write additional packages to install (space separated, leave blank to skip): '), display).run().strip() + return input_packages.split() if input_packages else [] pre_set_packages = pre_set_packages if pre_set_packages else [] packages = read_packages(pre_set_packages) -- cgit v1.2.3-54-g00ecf From 121e077b4eff56196e12511e12866ac94f944e46 Mon Sep 17 00:00:00 2001 From: walken <61562049+walken11@users.noreply.github.com> Date: Sat, 28 May 2022 16:33:25 +0200 Subject: Czech localization update (#1266) * Updates and corrections for Czech localization * Updates and corrections for Czech localization --- archinstall/locales/cs/LC_MESSAGES/base.mo | Bin 23934 -> 23958 bytes archinstall/locales/cs/LC_MESSAGES/base.po | 38 ++++++++++++++--------------- 2 files changed, 19 insertions(+), 19 deletions(-) (limited to 'archinstall') diff --git a/archinstall/locales/cs/LC_MESSAGES/base.mo b/archinstall/locales/cs/LC_MESSAGES/base.mo index f9aa3407..0f9ad704 100644 Binary files a/archinstall/locales/cs/LC_MESSAGES/base.mo and b/archinstall/locales/cs/LC_MESSAGES/base.mo differ diff --git a/archinstall/locales/cs/LC_MESSAGES/base.po b/archinstall/locales/cs/LC_MESSAGES/base.po index 935f9ba2..51cce8ac 100644 --- a/archinstall/locales/cs/LC_MESSAGES/base.po +++ b/archinstall/locales/cs/LC_MESSAGES/base.po @@ -3,7 +3,7 @@ msgstr "" "Project-Id-Version: \n" "POT-Creation-Date: \n" "PO-Revision-Date: \n" -"Last-Translator: tajnymag\n" +"Last-Translator: walken \n" "Language-Team: \n" "Language: cs\n" "MIME-Version: 1.0\n" @@ -51,13 +51,13 @@ msgid "Choose an audio server" msgstr "Zvolte audio server" msgid "Only packages such as base, base-devel, linux, linux-firmware, efibootmgr and optional profile packages are installed." -msgstr "Bude nainstalovány pouze balíčky jako base, base-devel, linux, linux-firmware, efibootmgr a volitelné balíčky profilu." +msgstr "Budou nainstalovány pouze balíčky jako base, base-devel, linux, linux-firmware, efibootmgr a volitelné balíčky profilu." msgid "If you desire a web browser, such as firefox or chromium, you may specify it in the following prompt." -msgstr "Pokud si přejete nainstalovat webový prohlížeč, jako je například firefox nebo chromium, můžete jej zadat do následujícího pole." +msgstr "Pokud si přejete nainstalovat webový prohlížeč, jako je například Firefox nebo Chromium, můžete jej zadat do následujícího pole." msgid "Write additional packages to install (space separated, leave blank to skip): " -msgstr "Zadejte další balíčky k instalaci (odělené mezerou, ponechte prázdné k přeskočení): " +msgstr "Zadejte další balíčky k instalaci (oddělené mezerou, ponechte prázdné k přeskočení): " msgid "Copy ISO network configuration to installation" msgstr "Zkopírovat do instalace konfiguraci sítě z ISO" @@ -66,7 +66,7 @@ msgid "Use NetworkManager (necessary to configure internet graphically in GNOME msgstr "Použít NetworkManager (potřebné pro grafickou konfiguraci v GNOME a KDE)" msgid "Select one network interface to configure" -msgstr "Zvolte zařízení, které konfigurovat" +msgstr "Zvolte zařízení ke konfiguraci" msgid "Select which mode to configure for \"{}\" or skip to use default mode \"{}\"" msgstr "Zvolte který režim má být nastaven pro \"{}\" nebo přeskočte pro použití výchozího režimu \"{}\"" @@ -185,7 +185,7 @@ msgid "Select keyboard layout" msgstr "Zvolte rozložení klávesnice" msgid "Select one of the regions to download packages from" -msgstr "Zvolte jeden z regionů ze kterého stahovat balíčky" +msgstr "Zvolte region ze kterého se budou stahovat balíčky" msgid "Select one or more hard drives to use and configure" msgstr "Zvolte jeden nebo více pevných disků k použití a konfiguraci" @@ -272,7 +272,7 @@ msgid "Superuser account" msgstr "Účet superuživatele" msgid "User account" -msgstr "Uživatelský úšet" +msgstr "Uživatelský účet" msgid "Profile" msgstr "Profil" @@ -374,7 +374,7 @@ msgid "Create a required super-user with sudo privileges: " msgstr "Vytvořte povinný účet superuživatele s oprávněními sudo: " msgid "Enter root password (leave blank to disable root): " -msgstr "Zadejte heslo uživatele root (ponechte prázdné k zakázání uživatele root)" +msgstr "Zadejte heslo uživatele root (ponechte prázdné k zakázání uživatele root): " msgid "Password for user \"{}\": " msgstr "Heslo pro uživatele \"{}\": " @@ -390,7 +390,7 @@ msgid "" "For more information, please check the Arch wiki" msgstr "" "Pro fungování NTP může být vyžadován hardwarový čas a další kroky po konfiguraci.\n" -"Pro další informace navštivte Arch Wiki." +"Pro další informace navštivte Arch Wiki" msgid "Enter a username to create an additional user (leave blank to skip): " msgstr "Zadejte uživatelské jméno k přidání dalšího uživatele (ponechte prázdné k přeskočení): " @@ -540,13 +540,13 @@ msgid "Manage ordinary user accounts: " msgstr "Spravovat běžné účty: " msgid " Subvolume :{:16}" -msgstr "Podsvazek :{:16}" +msgstr " Podsvazek :{:16}" msgid " mounted at {:16}" -msgstr "připojen na :{:16}" +msgstr " připojen na :{:16}" msgid " with option {}" -msgstr "s přepínačem {}" +msgstr " s přepínačem {}" msgid "" "\n" @@ -556,7 +556,7 @@ msgstr "" "Zadejte požadované hodnoty pro nový podsvazek \n" msgid "Subvolume name " -msgstr "Název podsvazku" +msgstr "Název podsvazku " msgid "Subvolume mountpoint" msgstr "Přípojný bod podsvazku" @@ -568,16 +568,16 @@ msgid "Save" msgstr "Uložit" msgid "Subvolume name :" -msgstr "Název podsvazku" +msgstr "Název podsvazku:" msgid "Select a mount point :" msgstr "Zvolte přípojný bod:" msgid "Select the desired subvolume options " -msgstr "Zvolte požadované přepínače podsvazku" +msgstr "Zvolte požadované přepínače podsvazku " msgid "Define users with sudo privilege, by username: " -msgstr "Specifikace uživatelů s oprávněními sudo, pomocí uživatelského jména:" +msgstr "Specifikace uživatelů s oprávněními sudo, pomocí uživatelského jména: " msgid "[!] A log file has been created here: {}" msgstr "[!] Soubor s protokoly byl uložen zde: {}" @@ -703,13 +703,13 @@ msgid "" msgstr "Pomocí CTRL+C zrušíte stávající výběr\n" msgid "Copy to: " -msgstr "Zkopírovat do:" +msgstr "Zkopírovat do: " msgid "Edit: " -msgstr "Upravit:" +msgstr "Upravit: " msgid "Key: " -msgstr "Klíč:" +msgstr "Klíč: " msgid "Edit {}: " msgstr "Upravit {}: " -- cgit v1.2.3-54-g00ecf From b2f85889a7a935a4d9638fe0fec5aac45e721b09 Mon Sep 17 00:00:00 2001 From: "Dylan M. Taylor" Date: Sun, 29 May 2022 03:25:22 -0400 Subject: Don't offer to encrypt /boot, exlude it from the set available to the user (#1273) * WIP: Don't offer to encrypt /boot * This filter might work * Ref: https://github.com/archlinux/archinstall/blob/master/archinstall/lib/storage.py * Use list comprehension * I wonder if I can use this filter_ argument that exists already * flake8 fix * Show index --- archinstall/lib/menu/global_menu.py | 5 +++-- archinstall/lib/user_interaction/partitioning_conf.py | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) (limited to 'archinstall') diff --git a/archinstall/lib/menu/global_menu.py b/archinstall/lib/menu/global_menu.py index 3ffb6f15..a758d8c6 100644 --- a/archinstall/lib/menu/global_menu.py +++ b/archinstall/lib/menu/global_menu.py @@ -206,8 +206,9 @@ class GlobalMenu(GeneralMenu): for blockdevice in storage['arguments']['disk_layouts']: if storage['arguments']['disk_layouts'][blockdevice].get('partitions'): for partition_index in select_encrypted_partitions( - title="Select which partitions to encrypt:", - partitions=storage['arguments']['disk_layouts'][blockdevice]['partitions'] + title=_('Select which partitions to encrypt:'), + partitions=storage['arguments']['disk_layouts'][blockdevice]['partitions'], + filter_=(lambda p: p['mountpoint'] != '/boot') ): partition = storage['arguments']['disk_layouts'][blockdevice]['partitions'][partition_index] diff --git a/archinstall/lib/user_interaction/partitioning_conf.py b/archinstall/lib/user_interaction/partitioning_conf.py index 1f41f9b0..1ecba8be 100644 --- a/archinstall/lib/user_interaction/partitioning_conf.py +++ b/archinstall/lib/user_interaction/partitioning_conf.py @@ -376,7 +376,7 @@ def select_encrypted_partitions( # show current partition layout: if len(partitions): - title += current_partition_layout(partitions) + '\n' + title += current_partition_layout(partitions, with_idx=True) + '\n' choice = Menu(title, partition_indexes, multi=multiple).run() -- cgit v1.2.3-54-g00ecf From 2de153003ed5de1018639070fabc9c9e583c49d1 Mon Sep 17 00:00:00 2001 From: Kian-Meng Ang Date: Sun, 29 May 2022 15:31:18 +0800 Subject: Fix typos (#1265) --- README.md | 4 ++-- archinstall/__init__.py | 4 ++-- archinstall/lib/disk/btrfs/__init__.py | 4 ++-- archinstall/lib/disk/btrfs/btrfs_helpers.py | 4 ++-- archinstall/lib/disk/btrfs/btrfspartition.py | 4 ++-- archinstall/lib/disk/btrfs/btrfssubvolume.py | 4 ++-- archinstall/lib/disk/filesystem.py | 4 ++-- archinstall/lib/disk/helpers.py | 6 +++--- archinstall/lib/general.py | 6 +++--- archinstall/lib/installer.py | 4 ++-- archinstall/lib/menu/list_manager.py | 4 ++-- archinstall/lib/menu/menu.py | 2 +- archinstall/lib/menu/selection_menu.py | 4 ++-- archinstall/lib/menu/simple_menu.py | 2 +- archinstall/lib/models/users.py | 4 ++-- archinstall/lib/storage.py | 4 ++-- archinstall/lib/systemd.py | 2 +- archinstall/lib/translation.py | 2 +- archinstall/lib/user_interaction/backwards_compatible_conf.py | 2 +- archinstall/lib/user_interaction/partitioning_conf.py | 2 +- docs/index.rst | 2 +- docs/installing/guided.rst | 4 ++-- examples/swiss.py | 8 ++++---- profiles/server.py | 2 +- 24 files changed, 44 insertions(+), 44 deletions(-) (limited to 'archinstall') diff --git a/README.md b/README.md index 79fae095..20224eea 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ Some additional options that are not needed by most users are hidden behind the ## Running from a declarative configuration file or URL -Prequisites: +Prerequisites: 1. Edit the [configuration file](https://github.com/archlinux/archinstall/blob/master/examples/config-sample.json) according to your requirements. Assuming you are on a Arch Linux live-ISO and booted into EFI mode. @@ -55,7 +55,7 @@ The guided installer itself is also optional to use if so desired and not forced Archinstall has one fundamental function which is to be a flexible library to manage services, packages and other aspects inside the installed system. This library is in turn used by the provided guided installer but is also for anyone who wants to script their own installations. -Therefore, Archinstall will try its best to not introduce any breaking changes except for major releases which may break backwards compability after notifying about such changes. +Therefore, Archinstall will try its best to not introduce any breaking changes except for major releases which may break backwards compatibility after notifying about such changes. # Scripting your own installation diff --git a/archinstall/__init__.py b/archinstall/__init__.py index 7edeaa80..786be1c5 100644 --- a/archinstall/__init__.py +++ b/archinstall/__init__.py @@ -91,7 +91,7 @@ def parse_unspecified_argument_list(unknowns :list, multiple :bool = False, erro --argument=value --argument = value --argument (boolean as default) - the optional paramters to the function alter a bit its behaviour: + the optional parameters to the function alter a bit its behaviour: * multiple allows multivalued arguments, each value separated by whitespace. They're returned as a list * error. If set any non correctly specified argument-value pair to raise an exception. Else, simply notifies the existence of a problem and continues processing. @@ -104,7 +104,7 @@ def parse_unspecified_argument_list(unknowns :list, multiple :bool = False, erro key = None last_key = None while tmp_list: - element = tmp_list.pop(0) # retreive an element of the list + element = tmp_list.pop(0) # retrieve an element of the list if element.startswith('--'): # is an argument ? if '=' in element: # uses the arg=value syntax ? key, value = [x.strip() for x in element[2:].split('=', 1)] diff --git a/archinstall/lib/disk/btrfs/__init__.py b/archinstall/lib/disk/btrfs/__init__.py index 84b9c0f6..90c58145 100644 --- a/archinstall/lib/disk/btrfs/__init__.py +++ b/archinstall/lib/disk/btrfs/__init__.py @@ -73,7 +73,7 @@ def create_subvolume(installation :Installer, subvolume_location :Union[pathlib. def _has_option(option :str,options :list) -> bool: """ auxiliary routine to check if an option is present in a list. - we check if the string appears in one of the options, 'cause it can appear in severl forms (option, option=val,...) + we check if the string appears in one of the options, 'cause it can appear in several forms (option, option=val,...) """ if not options: return False @@ -110,7 +110,7 @@ def manage_btrfs_subvolumes(installation :Installer, subvolumes = partition['btrfs']['subvolumes'] for name, right_hand in subvolumes.items(): try: - # we normalize the subvolume name (getting rid of slash at the start if exists. In our implemenation has no semantic load - every subvolume is created from the top of the hierarchy- and simplifies its further use + # we normalize the subvolume name (getting rid of slash at the start if exists. In our implementation has no semantic load - every subvolume is created from the top of the hierarchy- and simplifies its further use if name.startswith('/'): name = name[1:] # renormalize the right hand. diff --git a/archinstall/lib/disk/btrfs/btrfs_helpers.py b/archinstall/lib/disk/btrfs/btrfs_helpers.py index d577d82b..5fa94314 100644 --- a/archinstall/lib/disk/btrfs/btrfs_helpers.py +++ b/archinstall/lib/disk/btrfs/btrfs_helpers.py @@ -10,7 +10,7 @@ from .btrfssubvolume import BtrfsSubvolume def mount_subvolume(installation, device, name, subvolume_information): - # we normalize the subvolume name (getting rid of slash at the start if exists. In our implemenation has no semantic load. + # we normalize the subvolume name (getting rid of slash at the start if exists. In our implementation has no semantic load. # Every subvolume is created from the top of the hierarchy- and simplifies its further use name = name.lstrip('/') @@ -53,7 +53,7 @@ def setup_subvolumes(installation, partition_dict): """ log(f"Setting up subvolumes: {partition_dict['btrfs']['subvolumes']}", level=logging.INFO, fg="gray") for name, right_hand in partition_dict['btrfs']['subvolumes'].items(): - # we normalize the subvolume name (getting rid of slash at the start if exists. In our implemenation has no semantic load. + # we normalize the subvolume name (getting rid of slash at the start if exists. In our implementation has no semantic load. # Every subvolume is created from the top of the hierarchy- and simplifies its further use name = name.lstrip('/') diff --git a/archinstall/lib/disk/btrfs/btrfspartition.py b/archinstall/lib/disk/btrfs/btrfspartition.py index 299357b8..6f7487e4 100644 --- a/archinstall/lib/disk/btrfs/btrfspartition.py +++ b/archinstall/lib/disk/btrfs/btrfspartition.py @@ -62,13 +62,13 @@ class BTRFSPartition(Partition): if not installation: installation = storage.get('installation_session') - # Determain if the path given, is an absolute path or a releative path. + # Determain if the path given, is an absolute path or a relative path. # We do this by checking if the path contains a known mountpoint. if str(subvolume)[0] == '/': if filesystems := findmnt(subvolume, traverse=True).get('filesystems'): if (target := filesystems[0].get('target')) and target != '/' and str(subvolume).startswith(target): # Path starts with a known mountpoint which isn't / - # Which means it's an absolut path to a mounted location. + # Which means it's an absolute path to a mounted location. pass else: # Since it's not an absolute position with a known start. diff --git a/archinstall/lib/disk/btrfs/btrfssubvolume.py b/archinstall/lib/disk/btrfs/btrfssubvolume.py index a96e2a94..bc7db612 100644 --- a/archinstall/lib/disk/btrfs/btrfssubvolume.py +++ b/archinstall/lib/disk/btrfs/btrfssubvolume.py @@ -68,9 +68,9 @@ class BtrfsSubvolume: from .btrfs_helpers import subvolume_info_from_path # TODO: Make this function traverse storage['MOUNT_POINT'] and find the first - # occurance of a mountpoint that is a btrfs volume instead of lazy assume / is a subvolume. + # occurrence of a mountpoint that is a btrfs volume instead of lazy assume / is a subvolume. # It would also be nice if it could use findmnt(self.full_path) and traverse backwards - # finding the last occurance of a subvolume which 'self' belongs to. + # finding the last occurrence of a subvolume which 'self' belongs to. if volume := subvolume_info_from_path(storage['MOUNT_POINT']): return self.full_path == volume.full_path diff --git a/archinstall/lib/disk/filesystem.py b/archinstall/lib/disk/filesystem.py index f94b4b47..cc29a491 100644 --- a/archinstall/lib/disk/filesystem.py +++ b/archinstall/lib/disk/filesystem.py @@ -74,7 +74,7 @@ class Filesystem: raise KeyError(f"Could not create a GPT label on {self}") elif self.mode == MBR: if not self.parted_mklabel(self.blockdevice.device, "msdos"): - raise KeyError(f"Could not create a MSDOS label on {self}") + raise KeyError(f"Could not create a MS-DOS label on {self}") self.blockdevice.flush_cache() time.sleep(3) @@ -221,7 +221,7 @@ class Filesystem: raise KeyError(f"Could not create a GPT label on {self}") elif self.mode == MBR: if not self.parted_mklabel(self.blockdevice.device, "msdos"): - raise KeyError(f"Could not create a MSDOS label on {self}") + raise KeyError(f"Could not create a MS-DOS label on {self}") self.blockdevice.flush_cache() diff --git a/archinstall/lib/disk/helpers.py b/archinstall/lib/disk/helpers.py index 65d7a006..47cc81c4 100644 --- a/archinstall/lib/disk/helpers.py +++ b/archinstall/lib/disk/helpers.py @@ -112,7 +112,7 @@ def cleanup_bash_escapes(data :str) -> str: def blkid(cmd :str) -> Dict[str, Any]: if '-o' in cmd and '-o export' not in cmd: - raise ValueError(f"blkid() requires '-o export' to be used and can therefor not continue reliably.") + raise ValueError(f"blkid() requires '-o export' to be used and can therefore not continue reliably.") elif '-o' not in cmd: cmd += ' -o export' @@ -133,7 +133,7 @@ def blkid(cmd :str) -> Dict[str, Any]: key, val = line.split('=', 1) if key.lower() == 'devname': devname = val - # Lowercase for backwards compatability with all_disks() previous use cases + # Lowercase for backwards compatibility with all_disks() previous use cases result[devname] = { "path": devname, "PATH": devname @@ -475,7 +475,7 @@ def has_mountpoint(partition: Union[dict,Partition,MapperDev], target: str, stri Input parms: :parm partition the partition we check - :type Either a Partition object or a dict with the contents of a partition definiton in the disk_layouts schema + :type Either a Partition object or a dict with the contents of a partition definition in the disk_layouts schema :parm target (a string representing a mount path we want to check for. :type str diff --git a/archinstall/lib/general.py b/archinstall/lib/general.py index b99e4a45..3ec1d685 100644 --- a/archinstall/lib/general.py +++ b/archinstall/lib/general.py @@ -207,7 +207,7 @@ class SysCommandWorker: self.cmd = cmd self.callbacks = callbacks self.peak_output = peak_output - # define the standard locale for command outputs. For now the C ascii one. Can be overriden + # define the standard locale for command outputs. For now the C ascii one. Can be overridden self.environment_vars = {**storage.get('CMD_LOCALE',{}),**environment_vars} self.logfile = logfile self.working_directory = working_directory @@ -354,7 +354,7 @@ class SysCommandWorker: # Note: If for any reason, we get a Python exception between here # and until os.close(), the traceback will get locked inside # stdout of the child_fd object. `os.read(self.child_fd, 8192)` is the - # only way to get the traceback without loosing it. + # only way to get the traceback without losing it. self.pid, self.child_fd = pty.fork() @@ -547,7 +547,7 @@ def json_stream_to_structure(configuration_identifier : str, stream :str, target parsed_url = urllib.parse.urlparse(stream) - if parsed_url.scheme: # The stream is in fact a URL that should be grabed + if parsed_url.scheme: # The stream is in fact a URL that should be grabbed with urllib.request.urlopen(urllib.request.Request(stream, headers={'User-Agent': 'ArchInstall'})) as response: target.update(json.loads(response.read())) else: diff --git a/archinstall/lib/installer.py b/archinstall/lib/installer.py index b2cd6306..7af6006f 100644 --- a/archinstall/lib/installer.py +++ b/archinstall/lib/installer.py @@ -195,7 +195,7 @@ class Installer: return True def _create_keyfile(self,luks_handle , partition :dict, password :str): - """ roiutine to create keyfiles, so it can be moved elsewere + """ roiutine to create keyfiles, so it can be moved elsewhere """ if partition.get('generate-encryption-key-file'): if not (cryptkey_dir := pathlib.Path(f"{self.target}/etc/cryptsetup-keys.d")).exists(): @@ -413,7 +413,7 @@ class Installer: try: run_pacman('-Syy', default_cmd='/usr/bin/pacman') except SysCallError as error: - self.log(f'Could not sync a new package databse: {error}', level=logging.ERROR, fg="red") + self.log(f'Could not sync a new package database: {error}', level=logging.ERROR, fg="red") if storage['arguments'].get('silent', False) is False: if input('Would you like to re-try this download? (Y/n): ').lower().strip() in ('', 'y'): diff --git a/archinstall/lib/menu/list_manager.py b/archinstall/lib/menu/list_manager.py index cb567093..7e051528 100644 --- a/archinstall/lib/menu/list_manager.py +++ b/archinstall/lib/menu/list_manager.py @@ -54,7 +54,7 @@ The default implementation can handle simple lists and a key:value dictionary. T A sample of basic usage is included at the end of the source. More sophisticaded uses can be achieved by -* changing the action list and the null_action during intialization +* changing the action list and the null_action during initialization ``` opciones = ListManager('Vamos alla',opciones,[str(_('Add')),str(_('Delete'))],_('Add')).run() ``` @@ -198,7 +198,7 @@ class ListManager: else: self.target = self._data[data_formatted[target.value]] - # Possible enhacement. If run_actions returns false a message line indicating the failure + # Possible enhancement. If run_actions returns false a message line indicating the failure self.run_actions(target.value) if target.value == self.cancel_action: # TODO dubious diff --git a/archinstall/lib/menu/menu.py b/archinstall/lib/menu/menu.py index c34814eb..3a26f6e7 100644 --- a/archinstall/lib/menu/menu.py +++ b/archinstall/lib/menu/menu.py @@ -115,7 +115,7 @@ class Menu(TerminalMenu): # We check that the options are iterable. If not we abort. Else we copy them to lists # it options is a dictionary we use the values as entries of the list # if options is a string object, each character becomes an entry - # if options is a list, we implictily build a copy to mantain immutability + # if options is a list, we implictily build a copy to maintain immutability if not isinstance(p_options,Iterable): log(f"Objects of type {type(p_options)} is not iterable, and are not supported at Menu",fg="red") log(f"invalid parameter at Menu() call was at <{sys._getframe(1).f_code.co_name}>",level=logging.WARNING) diff --git a/archinstall/lib/menu/selection_menu.py b/archinstall/lib/menu/selection_menu.py index 57e290f1..6a693730 100644 --- a/archinstall/lib/menu/selection_menu.py +++ b/archinstall/lib/menu/selection_menu.py @@ -219,7 +219,7 @@ class GeneralMenu: def _setup_selection_menu_options(self): """ Define the menu options. - Menu options can be defined here in a subclass or done per progam calling self.set_option() + Menu options can be defined here in a subclass or done per program calling self.set_option() """ return @@ -347,7 +347,7 @@ class GeneralMenu: return self.exec_option(config_name, selector) def exec_option(self, config_name :str, p_selector :Selector = None) -> bool: - """ processes the exection of a given menu entry + """ processes the execution of a given menu entry - pre process callback - selection function - post process callback diff --git a/archinstall/lib/menu/simple_menu.py b/archinstall/lib/menu/simple_menu.py index 947259eb..f7a2cf23 100644 --- a/archinstall/lib/menu/simple_menu.py +++ b/archinstall/lib/menu/simple_menu.py @@ -619,7 +619,7 @@ class TerminalMenu: else: unit_separated_entry = escaped_separator_pattern.sub("|", separator_pattern.sub("\\1\x1F", entry)) match_obj = menu_entry_pattern.match(unit_separated_entry) - # this is none in case the entry was an emtpy string which + # this is none in case the entry was an empty string which # will be interpreted as a separator assert match_obj is not None shortcut_key = match_obj.group(1) diff --git a/archinstall/lib/models/users.py b/archinstall/lib/models/users.py index 6052b73a..a3057291 100644 --- a/archinstall/lib/models/users.py +++ b/archinstall/lib/models/users.py @@ -64,13 +64,13 @@ class User: ) -> List['User']: users = [] - # backwards compability + # backwards compatibility if isinstance(config_users, dict): users += cls._parse_backwards_compatible(config_users, False) else: users += cls._parse(config_users) - # backwards compability + # backwards compatibility if isinstance(config_superusers, dict): users += cls._parse_backwards_compatible(config_superusers, True) diff --git a/archinstall/lib/storage.py b/archinstall/lib/storage.py index dd7ddc88..8c358161 100644 --- a/archinstall/lib/storage.py +++ b/archinstall/lib/storage.py @@ -17,13 +17,13 @@ storage: Dict[str, Any] = { # os.path.abspath(f'{os.path.dirname(__file__)}/../examples') ], 'UPSTREAM_URL': 'https://raw.githubusercontent.com/archlinux/archinstall/master/profiles', - 'PROFILE_DB': None, # Used in cases when listing profiles is desired, not mandatory for direct profile grabing. + 'PROFILE_DB': None, # Used in cases when listing profiles is desired, not mandatory for direct profile grabbing. 'LOG_PATH': '/var/log/archinstall', 'LOG_FILE': 'install.log', 'MOUNT_POINT': '/mnt/archinstall', 'ENC_IDENTIFIER': 'ainst', 'DISK_TIMEOUTS' : 1, # seconds 'DISK_RETRY_ATTEMPTS' : 5, # RETRY_ATTEMPTS * DISK_TIMEOUTS is used in disk operations - 'CMD_LOCALE':{'LC_ALL':'C'}, # default locale for execution commands. Can be overriden with set_cmd_locale() + 'CMD_LOCALE':{'LC_ALL':'C'}, # default locale for execution commands. Can be overridden with set_cmd_locale() 'CMD_LOCALE_DEFAULT':{'LC_ALL':'C'}, # should be the same as the former. Not be used except in reset_cmd_locale() } diff --git a/archinstall/lib/systemd.py b/archinstall/lib/systemd.py index 3d2f0385..f459f94b 100644 --- a/archinstall/lib/systemd.py +++ b/archinstall/lib/systemd.py @@ -88,7 +88,7 @@ class Boot: if len(args) >= 2 and args[1]: log(args[1], level=logging.ERROR, fg='red') - log(f"The error above occured in a temporary boot-up of the installation {self.instance}", level=logging.ERROR, fg="red") + log(f"The error above occurred in a temporary boot-up of the installation {self.instance}", level=logging.ERROR, fg="red") shutdown = None shutdown_exit_code = -1 diff --git a/archinstall/lib/translation.py b/archinstall/lib/translation.py index 1a0e94e4..79e0198a 100644 --- a/archinstall/lib/translation.py +++ b/archinstall/lib/translation.py @@ -28,7 +28,7 @@ class LanguageDefinitions: if entry['abbr'] == abbr: return entry['lang'] - raise ValueError(f'No language with abbrevation "{abbr}" found') + raise ValueError(f'No language with abbreviation "{abbr}" found') class DeferredTranslation: diff --git a/archinstall/lib/user_interaction/backwards_compatible_conf.py b/archinstall/lib/user_interaction/backwards_compatible_conf.py index d91690eb..296572d2 100644 --- a/archinstall/lib/user_interaction/backwards_compatible_conf.py +++ b/archinstall/lib/user_interaction/backwards_compatible_conf.py @@ -40,7 +40,7 @@ def generic_select( # We check that the options are iterable. If not we abort. Else we copy them to lists # it options is a dictionary we use the values as entries of the list # if options is a string object, each character becomes an entry - # if options is a list, we implictily build a copy to mantain immutability + # if options is a list, we implictily build a copy to maintain immutability if not isinstance(p_options, Iterable): log(f"Objects of type {type(p_options)} is not iterable, and are not supported at generic_select", fg="red") log(f"invalid parameter at Menu() call was at <{sys._getframe(1).f_code.co_name}>", level=logging.WARNING) diff --git a/archinstall/lib/user_interaction/partitioning_conf.py b/archinstall/lib/user_interaction/partitioning_conf.py index 1ecba8be..caf5f5df 100644 --- a/archinstall/lib/user_interaction/partitioning_conf.py +++ b/archinstall/lib/user_interaction/partitioning_conf.py @@ -224,7 +224,7 @@ def manage_new_and_existing_partitions(block_device: 'BlockDevice') -> Dict[str, continue block_device_struct["partitions"].append({ - "type": "primary", # Strictly only allowed under MSDOS, but GPT accepts it so it's "safe" to inject + "type": "primary", # Strictly only allowed under MS-DOS, but GPT accepts it so it's "safe" to inject "start": start, "size": end, "mountpoint": None, diff --git a/docs/index.rst b/docs/index.rst index 3e4b5203..a76a58d6 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -12,7 +12,7 @@ Some of the features of Archinstall are: * **Context friendly.** The library always executes calls in sequential order to ensure installation-steps don't overlap or execute in the wrong order. It also supports *(and uses)* context wrappers to ensure cleanup and final tasks such as ``mkinitcpio`` are called when needed. -* **Full transparancy** Logs and insights can be found at ``/var/log/archinstall`` both in the live ISO and the installed system. +* **Full transparency** Logs and insights can be found at ``/var/log/archinstall`` both in the live ISO and the installed system. * **Accessibility friendly** Archinstall works with ``espeakup`` and other accessibility tools thanks to the use of a TUI. diff --git a/docs/installing/guided.rst b/docs/installing/guided.rst index 569b2d05..b7d4db4f 100644 --- a/docs/installing/guided.rst +++ b/docs/installing/guided.rst @@ -115,7 +115,7 @@ Options for ``--config`` +----------------------+--------------------------------------------------------+---------------------------------------------------------------------------------------------+-----------------------------------------------+ | hostname | any | Hostname of machine after installation. Default will be ``archinstall`` | No | +----------------------+--------------------------------------------------------+---------------------------------------------------------------------------------------------+-----------------------------------------------+ -| kernels | [ "kernel1", "kernel2"] | List of kernels to install eg: linux, linux-lts, linux-zen etc | Atleast 1 | +| kernels | [ "kernel1", "kernel2"] | List of kernels to install eg: linux, linux-lts, linux-zen etc | At least 1 | +----------------------+--------------------------------------------------------+---------------------------------------------------------------------------------------------+-----------------------------------------------+ | keyboard-language | Any valid layout given by ``localectl list-keymaps`` | eg: ``us``, ``de`` or ``de-latin1`` etc. Defaults to ``us`` | No | +----------------------+--------------------------------------------------------+---------------------------------------------------------------------------------------------+-----------------------------------------------+ @@ -149,7 +149,7 @@ Options for ``--config`` +----------------------+--------------------------------------------------------+---------------------------------------------------------------------------------------------+-----------------------------------------------+ .. note:: - [1] If no entires are found in ``harddrives``, archinstall guided installation will use whatever is mounted currently under ``/mnt/archinstall``. + [1] If no entries are found in ``harddrives``, archinstall guided installation will use whatever is mounted currently under ``/mnt/archinstall``. Options for ``--creds`` ----------------------- diff --git a/examples/swiss.py b/examples/swiss.py index d0f02dc1..6742358e 100644 --- a/examples/swiss.py +++ b/examples/swiss.py @@ -1,14 +1,14 @@ """ Script swiss (army knife) -Designed to make different workflows for the installation process. Which is controled by the argument --mode +Designed to make different workflows for the installation process. Which is controlled by the argument --mode mode full guides the full process of installation mode only_hd only proceeds to the creation of the disk infraestructure (partition, mount points, encryption) mode only_os processes only the installation of Archlinux and software at --mountpoint (or /mnt/archinstall) mode minimal (still not implemented) mode lineal. Instead of a menu, shows a sequence of selection screens (eq. to the old mode for guided.py) -When using the argument --advanced. an aditional menu for several special parameters needed during installation appears +When using the argument --advanced. an additional menu for several special parameters needed during installation appears This script respects the --dry_run argument @@ -180,7 +180,7 @@ class SetupMenu(archinstall.GeneralMenu): self.set_option(item, archinstall.Selector( f'{get_locale_mode_text(item)} locale', - lambda x,item=item: select_installed_locale(item), # the parmeter is needed for the lambda in the loop + lambda x,item=item: select_installed_locale(item), # the parameter is needed for the lambda in the loop enabled=True, dependencies_not=['LC_ALL'] if item != 'LC_ALL' else [])) self.option('LC_ALL').set_enabled(True) @@ -286,7 +286,7 @@ class MyMenu(archinstall.GlobalMenu): """ -Instalation general subroutines +Installation general subroutines """ def get_current_status(): diff --git a/profiles/server.py b/profiles/server.py index 21681c2f..f3e32d26 100644 --- a/profiles/server.py +++ b/profiles/server.py @@ -33,7 +33,7 @@ def _prep_function(*args, **kwargs): before continuing any further. """ choice = Menu(str(_( - 'Choose which servers to install, if none then a minimal installation wil be done')), + 'Choose which servers to install, if none then a minimal installation will be done')), available_servers, preset_values=kwargs['servers'], multi=True -- cgit v1.2.3-54-g00ecf From 7daf9b32d0c32d9fa1ba5aa9750376ad47c6d7e6 Mon Sep 17 00:00:00 2001 From: demostanis <40673815+demostanis@users.noreply.github.com> Date: Sun, 29 May 2022 07:34:32 +0000 Subject: Fix "Unknown device" error when using erofs (#1232) (#1275) --- archinstall/lib/disk/helpers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'archinstall') diff --git a/archinstall/lib/disk/helpers.py b/archinstall/lib/disk/helpers.py index 47cc81c4..85c0390f 100644 --- a/archinstall/lib/disk/helpers.py +++ b/archinstall/lib/disk/helpers.py @@ -244,7 +244,7 @@ def all_blockdevices(mappers=False, partitions=False, error=False) -> Dict[str, instances[path] = Partition(path, block_device=BlockDevice(get_parent_of_partition(pathlib.Path(path)))) elif path_info.get('PTTYPE', False) is not False or path_info.get('TYPE') == 'loop': instances[path] = BlockDevice(path, path_info) - elif path_info.get('TYPE') == 'squashfs': + elif path_info.get('TYPE') in ('squashfs', 'erofs'): # We can ignore squashfs devices (usually /dev/loop0 on Arch ISO) continue else: -- cgit v1.2.3-54-g00ecf From 0601956b5bdf27ec497a94e7313ea22cf21ecbe0 Mon Sep 17 00:00:00 2001 From: Anton Hvornum Date: Sun, 29 May 2022 09:44:31 +0200 Subject: Moved genfstab() to guided.py instead of __exit__ of Installer(). This is a breaking change. --- archinstall/lib/installer.py | 2 -- examples/guided.py | 2 ++ 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'archinstall') diff --git a/archinstall/lib/installer.py b/archinstall/lib/installer.py index 7af6006f..7e66559f 100644 --- a/archinstall/lib/installer.py +++ b/archinstall/lib/installer.py @@ -158,8 +158,6 @@ class Installer: print(_(" Please submit this issue (and file) to https://github.com/archlinux/archinstall/issues")) raise args[1] - self.genfstab() - if not (missing_steps := self.post_install_check()): self.log('Installation completed without any errors. You may now reboot.', fg='green', level=logging.INFO) self.sync_log_to_install_medium() diff --git a/examples/guided.py b/examples/guided.py index 19b0d638..635baf6a 100644 --- a/examples/guided.py +++ b/examples/guided.py @@ -253,6 +253,8 @@ def perform_installation(mountpoint): if archinstall.arguments.get('custom-commands', None): archinstall.run_custom_user_commands(archinstall.arguments['custom-commands'], installation) + installation.genfstab() + installation.log("For post-installation tips, see https://wiki.archlinux.org/index.php/Installation_guide#Post-installation", fg="yellow") if not archinstall.arguments.get('silent'): prompt = str(_('Would you like to chroot into the newly created installation and perform post-installation configuration?')) -- cgit v1.2.3-54-g00ecf From 51714587962570c71fc2dd70de526a5172ad5b5c Mon Sep 17 00:00:00 2001 From: Daniel Girtler Date: Sun, 29 May 2022 18:59:55 +1000 Subject: Fix subvol selection (#1277) * Fix subvolume selection * Update Co-authored-by: Daniel Girtler --- archinstall/lib/menu/selection_menu.py | 12 ++++---- .../lib/user_interaction/subvolume_config.py | 33 ++++++++++++++-------- 2 files changed, 27 insertions(+), 18 deletions(-) (limited to 'archinstall') diff --git a/archinstall/lib/menu/selection_menu.py b/archinstall/lib/menu/selection_menu.py index 6a693730..d4a7ceef 100644 --- a/archinstall/lib/menu/selection_menu.py +++ b/archinstall/lib/menu/selection_menu.py @@ -227,7 +227,7 @@ class GeneralMenu: """ will be called before each action in the menu """ return - def post_callback(self, selector_name :str, value :Any): + def post_callback(self, selection_name: str = None, value: Any = None): """ will be called after each action in the menu """ return True @@ -327,12 +327,12 @@ class GeneralMenu: break cursor_pos += 1 - value = value.strip() + value = value.strip() - # if this calls returns false, we exit the menu - # we allow for an callback for special processing on realeasing control - if not self._process_selection(value): - break + # if this calls returns false, we exit the menu + # we allow for an callback for special processing on realeasing control + if not self._process_selection(value): + break if not self.is_context_mgr: self.__exit__() diff --git a/archinstall/lib/user_interaction/subvolume_config.py b/archinstall/lib/user_interaction/subvolume_config.py index af783639..94e6f5d7 100644 --- a/archinstall/lib/user_interaction/subvolume_config.py +++ b/archinstall/lib/user_interaction/subvolume_config.py @@ -80,24 +80,33 @@ class SubvolumeMenu(GeneralMenu): super().__init__(data_store=self.ds) def _setup_selection_menu_options(self): - # [str(_('Add')),str(_('Copy')),str(_('Edit')),str(_('Delete'))] - self._menu_options['name'] = Selector(str(_('Subvolume name ')), - self._select_subvolume_name if not self.action or self.action in (str(_('Add')),str(_('Copy'))) else None, + self._menu_options['name'] = Selector( + str(_('Subvolume name ')), + self._select_subvolume_name if not self.action or self.action in (str(_('Add')), str(_('Copy'))) else None, mandatory=True, enabled=True) - self._menu_options['mountpoint'] = Selector(str(_('Subvolume mountpoint')), + + self._menu_options['mountpoint'] = Selector( + str(_('Subvolume mountpoint')), self._select_subvolume_mount_point if not self.action or self.action in (str(_('Add')),str(_('Edit'))) else None, enabled=True) - self._menu_options['options'] = Selector(str(_('Subvolume options')), + + self._menu_options['options'] = Selector( + str(_('Subvolume options')), self._select_subvolume_options if not self.action or self.action in (str(_('Add')),str(_('Edit'))) else None, enabled=True) - self._menu_options['save'] = Selector(str(_('Save')), - exec_func=lambda n,v:True, - enabled=True) - self._menu_options['cancel'] = Selector(str(_('Cancel')), - # func = lambda pre:True, - exec_func=lambda n,v:self.fast_exit(n), - enabled=True) + + self._menu_options['save'] = Selector( + str(_('Save')), + exec_func=lambda n,v:True, + enabled=True) + + self._menu_options['cancel'] = Selector( + str(_('Cancel')), + # func = lambda pre:True, + exec_func=lambda n,v:self.fast_exit(n), + enabled=True) + self.cancel_action = 'cancel' self.save_action = 'save' self.bottom_list = [self.save_action,self.cancel_action] -- cgit v1.2.3-54-g00ecf From 7dbea73514b35cbaa18c156895bf6f416b2345ca Mon Sep 17 00:00:00 2001 From: Anton Hvornum Date: Sun, 29 May 2022 11:25:28 +0200 Subject: Cleanup and version changes in prep for release --- PKGBUILD | 2 +- archinstall/lib/disk/partition.py | 10 ---------- 2 files changed, 1 insertion(+), 11 deletions(-) (limited to 'archinstall') diff --git a/PKGBUILD b/PKGBUILD index 5821bee8..d8e89ae2 100644 --- a/PKGBUILD +++ b/PKGBUILD @@ -4,7 +4,7 @@ # Contributor: demostanis worlds pkgname=archinstall -pkgver=2.4.3rc1 +pkgver=2.5.0 #pkgver=$(git describe --long | sed 's/\([^-]*-g\)/r\1/;s/-/./g') pkgrel=1 pkgdesc="Just another guided/automated Arch Linux installer with a twist" diff --git a/archinstall/lib/disk/partition.py b/archinstall/lib/disk/partition.py index 151775b1..2c9f50c2 100644 --- a/archinstall/lib/disk/partition.py +++ b/archinstall/lib/disk/partition.py @@ -160,16 +160,6 @@ class Partition: def boot(self) -> bool: output = json.loads(SysCommand(f"sfdisk --json {self.block_device.path}").decode('UTF-8')) - # Get the bootable flag from the sfdisk output: - # { - # "partitiontable": { - # "device":"/dev/loop0", - # "partitions": [ - # {"node":"/dev/loop0p1", "start":2048, "size":10483712, "type":"83", "bootable":true} - # ] - # } - # } - for partition in output.get('partitiontable', {}).get('partitions', []): if partition['node'] == self.path: # first condition is for MBR disks, second for GPT disks -- cgit v1.2.3-54-g00ecf From c75e6a1da3c243126eaf59ee12f0b2464449e5e2 Mon Sep 17 00:00:00 2001 From: Anton Hvornum Date: Sun, 29 May 2022 13:59:25 +0200 Subject: Made sure generate-encryption-key-file is set for supplementary partitions to / (#1281) --- archinstall/lib/installer.py | 4 ++-- archinstall/lib/menu/global_menu.py | 5 +++++ 2 files changed, 7 insertions(+), 2 deletions(-) (limited to 'archinstall') diff --git a/archinstall/lib/installer.py b/archinstall/lib/installer.py index 7e66559f..bf296c2e 100644 --- a/archinstall/lib/installer.py +++ b/archinstall/lib/installer.py @@ -253,8 +253,8 @@ class Installer: # note that we DON'T auto_unmount (i.e. close the encrypted device so it can be used with (luks_handle := luks2(partition['device_instance'], loopdev, password, auto_unmount=False)) as unlocked_device: - if partition.get('generate-encryption-key-file',False) and not self._has_root(partition): - list_luks_handles.append([luks_handle,partition,password]) + if partition.get('generate-encryption-key-file', False) and not self._has_root(partition): + list_luks_handles.append([luks_handle, partition, password]) # this way all the requesrs will be to the dm_crypt device and not to the physical partition partition['device_instance'] = unlocked_device diff --git a/archinstall/lib/menu/global_menu.py b/archinstall/lib/menu/global_menu.py index a758d8c6..cb61168d 100644 --- a/archinstall/lib/menu/global_menu.py +++ b/archinstall/lib/menu/global_menu.py @@ -215,6 +215,11 @@ class GlobalMenu(GeneralMenu): partition['encrypted'] = True partition['!password'] = storage['arguments']['!encryption-password'] + # We make sure generate-encryption-key-file is set on additional partitions + # other than the root partition. Otherwise they won't unlock properly #1279 + if partition['mountpoint'] != '/': + partition['generate-encryption-key-file'] = True + def _install_text(self): missing = len(self._missing_configs()) if missing > 0: -- cgit v1.2.3-54-g00ecf From 4448dd2ef40943d4df98f4bc086af940468699b5 Mon Sep 17 00:00:00 2001 From: toto6038 <50100922+toto6038@users.noreply.github.com> Date: Tue, 31 May 2022 14:58:32 +0800 Subject: Divide Chinese locales into 2 variants (#1290) --- archinstall/locales/languages.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'archinstall') diff --git a/archinstall/locales/languages.json b/archinstall/locales/languages.json index c649e346..bf076f94 100644 --- a/archinstall/locales/languages.json +++ b/archinstall/locales/languages.json @@ -180,5 +180,6 @@ {"abbr": "yi", "lang": "Yiddish"}, {"abbr": "yo", "lang": "Yoruba"}, {"abbr": "za", "lang": "Zhuang"}, - {"abbr": "zh", "lang": "Chinese"}, - {"abbr": "zu", "lang": "Zulu"}] \ No newline at end of file + {"abbr": "zh-TW", "lang": "Traditional Chinese"}, + {"abbr": "zh-CN", "lang": "Simplified Chinese"}, + {"abbr": "zu", "lang": "Zulu"}] -- cgit v1.2.3-54-g00ecf From c2be07e7dc543fd6c5b60e67153061b2136b8575 Mon Sep 17 00:00:00 2001 From: Roxfr <52124613+roxfr@users.noreply.github.com> Date: Tue, 31 May 2022 09:00:56 +0200 Subject: Update for french language (#1291) Hello, Here is the update for the French language. Regards, Roxfr --- archinstall/locales/fr/LC_MESSAGES/base.mo | Bin 24262 -> 25735 bytes archinstall/locales/fr/LC_MESSAGES/base.po | 349 +++++++++++++++++++++-------- 2 files changed, 259 insertions(+), 90 deletions(-) (limited to 'archinstall') diff --git a/archinstall/locales/fr/LC_MESSAGES/base.mo b/archinstall/locales/fr/LC_MESSAGES/base.mo index 918fe21d..364b8964 100644 Binary files a/archinstall/locales/fr/LC_MESSAGES/base.mo and b/archinstall/locales/fr/LC_MESSAGES/base.mo differ diff --git a/archinstall/locales/fr/LC_MESSAGES/base.po b/archinstall/locales/fr/LC_MESSAGES/base.po index 9b038e8c..0e783a58 100644 --- a/archinstall/locales/fr/LC_MESSAGES/base.po +++ b/archinstall/locales/fr/LC_MESSAGES/base.po @@ -3,7 +3,7 @@ msgstr "" "Project-Id-Version: \n" "POT-Creation-Date: \n" "PO-Revision-Date: \n" -"Last-Translator: Aleksandr Melman \n" +"Last-Translator: roxfr \n" "Language-Team: \n" "Language: fr\n" "MIME-Version: 1.0\n" @@ -14,8 +14,12 @@ msgstr "" msgid "[!] A log file has been created here: {} {}" msgstr "[!] Un fichier journal a été créé ici : {} {}" -msgid " Please submit this issue (and file) to https://github.com/archlinux/archinstall/issues" -msgstr " Veuillez soumettre ce problème (et le fichier) à https://github.com/archlinux/archinstall/issues" +msgid "" +" Please submit this issue (and file) to https://github.com/archlinux/" +"archinstall/issues" +msgstr "" +" Veuillez soumettre ce problème (et le fichier) à https://github.com/" +"archlinux/archinstall/issues" msgid "Do you really want to abort?" msgstr "Voulez-vous vraiment abandonner ?" @@ -30,10 +34,13 @@ msgid "Desired hostname for the installation: " msgstr "Nom d'hôte souhaité pour l'installation : " msgid "Username for required superuser with sudo privileges: " -msgstr "Nom d'utilisateur pour le superutilisateur requis avec les privilèges sudo : " +msgstr "" +"Nom d'utilisateur pour le superutilisateur requis avec les privilèges sudo : " msgid "Any additional users to install (leave blank for no users): " -msgstr "Utilisateur supplémentaire à installer (laisser vide pour aucun utilisateur) : " +msgstr "" +"Utilisateur supplémentaire à installer (laisser vide pour aucun " +"utilisateur) : " msgid "Should this user be a superuser (sudoer)?" msgstr "Cet utilisateur doit-il être un superutilisateur (sudoer) ?" @@ -42,7 +49,9 @@ msgid "Select a timezone" msgstr "Sélectionner un fuseau horaire" msgid "Would you like to use GRUB as a bootloader instead of systemd-boot?" -msgstr "Souhaitez-vous utiliser GRUB comme chargeur de démarrage au lieu de systemd-boot ?" +msgstr "" +"Souhaitez-vous utiliser GRUB comme chargeur de démarrage au lieu de systemd-" +"boot ?" msgid "Choose a bootloader" msgstr "Choisir un chargeur de démarrage" @@ -50,38 +59,60 @@ msgstr "Choisir un chargeur de démarrage" msgid "Choose an audio server" msgstr "Choisir un serveur audio" -msgid "Only packages such as base, base-devel, linux, linux-firmware, efibootmgr and optional profile packages are installed." -msgstr "Seuls les packages tels que base, base-devel, linux, linux-firmware, efibootmgr et les packages de profil optionnels sont installés." +msgid "" +"Only packages such as base, base-devel, linux, linux-firmware, efibootmgr " +"and optional profile packages are installed." +msgstr "" +"Seuls les packages tels que base, base-devel, linux, linux-firmware, " +"efibootmgr et les packages de profil optionnels sont installés." -msgid "If you desire a web browser, such as firefox or chromium, you may specify it in the following prompt." -msgstr "Si vous désirez un navigateur Web, tel que firefox ou chrome, vous pouvez le spécifier dans l'invite suivante." +msgid "" +"If you desire a web browser, such as firefox or chromium, you may specify it " +"in the following prompt." +msgstr "" +"Si vous désirez un navigateur Web, tel que firefox ou chrome, vous pouvez le " +"spécifier dans l'invite suivante." -msgid "Write additional packages to install (space separated, leave blank to skip): " -msgstr "Écrire des packages supplémentaires à installer (espaces séparés, laisser vide pour ignorer) : " +msgid "" +"Write additional packages to install (space separated, leave blank to skip): " +msgstr "" +"Écrire des packages supplémentaires à installer (espaces séparés, laisser " +"vide pour ignorer) : " msgid "Copy ISO network configuration to installation" msgstr "Copier la configuration réseau ISO dans l'installation" -msgid "Use NetworkManager (necessary to configure internet graphically in GNOME and KDE)" -msgstr "Utiliser NetworkManager (nécessaire pour configurer graphiquement Internet dans GNOME et KDE)" +msgid "" +"Use NetworkManager (necessary to configure internet graphically in GNOME and " +"KDE)" +msgstr "" +"Utiliser NetworkManager (nécessaire pour configurer graphiquement Internet " +"dans GNOME et KDE)" msgid "Select one network interface to configure" msgstr "Sélectionner une interface réseau à configurer" -msgid "Select which mode to configure for \"{}\" or skip to use default mode \"{}\"" -msgstr "Sélectionner le mode à configurer pour \"{}\" ou ignorer pour utiliser le mode par défaut \"{}\"" +msgid "" +"Select which mode to configure for \"{}\" or skip to use default mode \"{}\"" +msgstr "" +"Sélectionner le mode à configurer pour \"{}\" ou ignorer pour utiliser le " +"mode par défaut \"{}\"" msgid "Enter the IP and subnet for {} (example: 192.168.0.5/24): " msgstr "Entrer l'IP et le sous-réseau pour {} (exemple : 192.168.0.5/24) : " msgid "Enter your gateway (router) IP address or leave blank for none: " -msgstr "Entrer l'adresse IP de votre passerelle (routeur) ou laisser vide pour aucune : " +msgstr "" +"Entrer l'adresse IP de votre passerelle (routeur) ou laisser vide pour " +"aucune : " msgid "Enter your DNS servers (space separated, blank for none): " msgstr "Entrer vos serveurs DNS (séparés par des espaces, vide pour aucun) : " msgid "Select which filesystem your main partition should use" -msgstr "Sélectionner le système de fichiers que votre partition principale doit utiliser" +msgstr "" +"Sélectionner le système de fichiers que votre partition principale doit " +"utiliser" msgid "Current partition layout" msgstr "Disposition actuelle des partitions" @@ -97,13 +128,20 @@ msgid "Enter a desired filesystem type for the partition" msgstr "Entrer un type de système de fichiers souhaité pour la partition" msgid "Enter the start sector (percentage or block number, default: {}): " -msgstr "Entrer le secteur de début (pourcentage ou numéro de bloc, par défaut : {}) : " +msgstr "" +"Entrer le secteur de début (pourcentage ou numéro de bloc, par défaut : " +"{}) : " -msgid "Enter the end sector of the partition (percentage or block number, ex: {}): " -msgstr "Entrer le secteur de fin de la partition (pourcentage ou numéro de bloc, ex : {}) : " +msgid "" +"Enter the end sector of the partition (percentage or block number, ex: {}): " +msgstr "" +"Entrer le secteur de fin de la partition (pourcentage ou numéro de bloc, " +"ex : {}) : " msgid "{} contains queued partitions, this will remove those, are you sure?" -msgstr "{} contient des partitions en file d'attente, cela les supprimera, êtes-vous sûr ?" +msgstr "" +"{} contient des partitions en file d'attente, cela les supprimera, êtes-vous " +"sûr ?" msgid "" "{}\n" @@ -123,11 +161,17 @@ msgstr "" "\n" "Sélectionner par index où et quelle partition montée" -msgid " * Partition mount-points are relative to inside the installation, the boot would be /boot as an example." -msgstr " * Les points de montage de la partition sont relatifs à l'intérieur de l'installation, le démarrage serait /boot par exemple." +msgid "" +" * Partition mount-points are relative to inside the installation, the boot " +"would be /boot as an example." +msgstr "" +" * Les points de montage de la partition sont relatifs à l'intérieur de " +"l'installation, le démarrage serait /boot par exemple." msgid "Select where to mount partition (leave blank to remove mountpoint): " -msgstr "Sélectionner où monter la partition (laisser vide pour supprimer le point de montage) : " +msgstr "" +"Sélectionner où monter la partition (laisser vide pour supprimer le point de " +"montage) : " msgid "" "{}\n" @@ -172,34 +216,58 @@ msgid "Archinstall language" msgstr "Langue d'Archinstall" msgid "Wipe all selected drives and use a best-effort default partition layout" -msgstr "Effacer tous les lecteurs sélectionnés et utiliser une disposition de partition par défaut optimale" +msgstr "" +"Effacer tous les lecteurs sélectionnés et utiliser une disposition de " +"partition par défaut optimale" -msgid "Select what to do with each individual drive (followed by partition usage)" -msgstr "Sélectionner ce qu'il faut faire avec chaque lecteur individuel (suivi de l'utilisation de la partition)" +msgid "" +"Select what to do with each individual drive (followed by partition usage)" +msgstr "" +"Sélectionner ce qu'il faut faire avec chaque lecteur individuel (suivi de " +"l'utilisation de la partition)" msgid "Select what you wish to do with the selected block devices" -msgstr "Sélectionner ce que vous souhaitez faire avec les périphériques de bloc sélectionnés" +msgstr "" +"Sélectionner ce que vous souhaitez faire avec les périphériques de bloc " +"sélectionnés" -msgid "This is a list of pre-programmed profiles, they might make it easier to install things like desktop environments" -msgstr "Ceci est une liste de profils préprogrammés, ils pourraient faciliter l'installation d'outils comme les environnements de bureau" +msgid "" +"This is a list of pre-programmed profiles, they might make it easier to " +"install things like desktop environments" +msgstr "" +"Ceci est une liste de profils préprogrammés, ils pourraient faciliter " +"l'installation d'outils comme les environnements de bureau" msgid "Select keyboard layout" msgstr "Sélectionner la disposition du clavier" msgid "Select one of the regions to download packages from" -msgstr "Sélectionner l'une des régions depuis lesquelles télécharger les packages" +msgstr "" +"Sélectionner l'une des régions depuis lesquelles télécharger les packages" msgid "Select one or more hard drives to use and configure" msgstr "Sélectionner un ou plusieurs disques durs à utiliser et à configurer" -msgid "For the best compatibility with your AMD hardware, you may want to use either the all open-source or AMD / ATI options." -msgstr "Pour une meilleure compatibilité avec votre matériel AMD, vous pouvez utiliser les options entièrement open source ou AMD / ATI." +msgid "" +"For the best compatibility with your AMD hardware, you may want to use " +"either the all open-source or AMD / ATI options." +msgstr "" +"Pour une meilleure compatibilité avec votre matériel AMD, vous pouvez " +"utiliser les options entièrement open source ou 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 "Pour une compatibilité optimale avec votre matériel Intel, vous pouvez utiliser les options entièrement open source ou Intel.\n" +msgid "" +"For the best compatibility with your Intel hardware, you may want to use " +"either the all open-source or Intel options.\n" +msgstr "" +"Pour une compatibilité optimale avec votre matériel Intel, vous pouvez " +"utiliser les options entièrement open source ou Intel.\n" -msgid "For the best compatibility with your Nvidia hardware, you may want to use the Nvidia proprietary driver.\n" -msgstr "Pour une meilleure compatibilité avec votre matériel Nvidia, vous pouvez utiliser le pilote propriétaire Nvidia.\n" +msgid "" +"For the best compatibility with your Nvidia hardware, you may want to use " +"the Nvidia proprietary driver.\n" +msgstr "" +"Pour une meilleure compatibilité avec votre matériel Nvidia, vous pouvez " +"utiliser le pilote propriétaire Nvidia.\n" msgid "" "\n" @@ -208,7 +276,8 @@ msgid "" msgstr "" "\n" "\n" -"Sélectionner un pilote graphique ou laisser vide pour installer tous les pilotes open-source" +"Sélectionner un pilote graphique ou laisser vide pour installer tous les " +"pilotes open-source" msgid "All open-source (default)" msgstr "Tout open-source (par défaut)" @@ -231,8 +300,12 @@ msgstr "Sélectionner une ou plusieurs des options ci-dessous : " msgid "Adding partition...." msgstr "Ajout de la partition...." -msgid "You need to enter a valid fs-type in order to continue. See `man parted` for valid fs-type's." -msgstr "Vous devez entrer un type de fs valide pour continuer. Voir `man parted` pour les types de fs valides." +msgid "" +"You need to enter a valid fs-type in order to continue. See `man parted` for " +"valid fs-type's." +msgstr "" +"Vous devez entrer un type de fs valide pour continuer. Voir `man parted` " +"pour les types de fs valides." msgid "Error: Listing profiles on URL \"{}\" resulted in:" msgstr "Erreur : la liste des profils sur l'URL \"{}\" a entraîné :" @@ -255,13 +328,11 @@ msgstr "Encodage des paramètres régionaux" msgid "Drive(s)" msgstr "Disques durs" -#, fuzzy msgid "Disk layout" -msgstr "Enregistrer la disposition du disque" +msgstr "Disposition du disque" -#, fuzzy msgid "Encryption password" -msgstr "Définir le mot de passe de chiffrement" +msgstr "Mot de passe de cryptage" msgid "Swap" msgstr "Swap" @@ -269,7 +340,6 @@ msgstr "Swap" msgid "Bootloader" msgstr "Chargeur de démarrage" -#, fuzzy msgid "Root password" msgstr "Mot de passe root" @@ -308,7 +378,8 @@ msgid "" msgstr "" "Vous avez décidé d'ignorer la sélection du disque dur\n" "et vous utiliserez la configuration de disque montée sur {} (expérimental)\n" -"ATTENTION : Archinstall ne vérifiera pas l'adéquation de cette configuration\n" +"ATTENTION : Archinstall ne vérifiera pas l'adéquation de cette " +"configuration\n" "Souhaitez-vous continuer ?" msgid "Re-using partition instance: {}" @@ -333,7 +404,8 @@ msgid "Mark/Unmark a partition as encrypted" msgstr "Marquer/Démarquer une partition comme chiffrée" msgid "Mark/Unmark a partition as bootable (automatic for /boot)" -msgstr "Marquer/Démarquer une partition comme amorçable (automatique pour /boot)" +msgstr "" +"Marquer/Démarquer une partition comme amorçable (automatique pour /boot)" msgid "Set desired filesystem for a partition" msgstr "Définir le système de fichiers souhaité pour une partition" @@ -373,7 +445,9 @@ msgid "Enter a encryption password for {}" msgstr "Entrer un mot de passe de cryptage pour {}" msgid "Enter disk encryption password (leave blank for no encryption): " -msgstr "Entrer le mot de passe de chiffrement du disque (laisser vide pour aucun chiffrement) : " +msgstr "" +"Entrer le mot de passe de chiffrement du disque (laisser vide pour aucun " +"chiffrement) : " msgid "Create a required super-user with sudo privileges: " msgstr "Créer un super-utilisateur requis avec les privilèges sudo : " @@ -384,31 +458,44 @@ msgstr "Entrer le mot de passe root (laisser vide pour désactiver root) : " msgid "Password for user \"{}\": " msgstr "Mot de passe pour l'utilisateur \"{}\" : " -msgid "Verifying that additional packages exist (this might take a few seconds)" -msgstr "Vérifier que des packages supplémentaires existent (cela peut prendre quelques secondes)" +msgid "" +"Verifying that additional packages exist (this might take a few seconds)" +msgstr "" +"Vérifier que des packages supplémentaires existent (cela peut prendre " +"quelques secondes)" -msgid "Would you like to use automatic time synchronization (NTP) with the default time servers?\n" -msgstr "Souhaitez-vous utiliser la synchronisation automatique de l'heure (NTP) avec les serveurs de temps par défaut ?\n" +msgid "" +"Would you like to use automatic time synchronization (NTP) with the default " +"time servers?\n" +msgstr "" +"Souhaitez-vous utiliser la synchronisation automatique de l'heure (NTP) avec " +"les serveurs de temps par défaut ?\n" msgid "" -"Hardware time and other post-configuration steps might be required in order for NTP to work.\n" +"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 "" -"Le temps matériel et d'autres étapes de post-configuration peuvent être nécessaires pour que NTP fonctionne.\n" +"Le temps matériel et d'autres étapes de post-configuration peuvent être " +"nécessaires pour que NTP fonctionne.\n" "Pour plus d'informations, veuillez consulter le wiki Arch" msgid "Enter a username to create an additional user (leave blank to skip): " -msgstr "Entrer un nom d'utilisateur pour créer un utilisateur supplémentaire (laisser vide pour ignorer) : " +msgstr "" +"Entrer un nom d'utilisateur pour créer un utilisateur supplémentaire " +"(laisser vide pour ignorer) : " msgid "Use ESC to skip\n" msgstr "Utiliser ESC pour ignorer\n" msgid "" "\n" -" Choose an object from the list, and select one of the available actions for it to execute" +" Choose an object from the list, and select one of the available actions for " +"it to execute" msgstr "" "\n" -"Choisir un objet dans la liste et sélectionner l'une des actions disponibles pour qu'il s'exécute" +"Choisir un objet dans la liste et sélectionner l'une des actions disponibles " +"pour qu'il s'exécute" msgid "Cancel" msgstr "Annuler" @@ -444,11 +531,18 @@ msgstr "" "\n" "Voici la configuration choisie :" -msgid "Pacman is already running, waiting maximum 10 minutes for it to terminate." -msgstr "Pacman est déjà en cours d'exécution, attendez au maximum 10 minutes pour qu'il se termine." +msgid "" +"Pacman is already running, waiting maximum 10 minutes for it to terminate." +msgstr "" +"Pacman est déjà en cours d'exécution, attendez au maximum 10 minutes pour " +"qu'il se termine." -msgid "Pre-existing pacman lock never exited. Please clean up any existing pacman sessions before using archinstall." -msgstr "Le verrou pacman préexistant n'a jamais été fermé. Veuillez nettoyer toutes les sessions pacman existantes avant d'utiliser archinstall." +msgid "" +"Pre-existing pacman lock never exited. Please clean up any existing pacman " +"sessions before using archinstall." +msgstr "" +"Le verrou pacman préexistant n'a jamais été fermé. Veuillez nettoyer toutes " +"les sessions pacman existantes avant d'utiliser archinstall." msgid "Choose which optional additional repositories to enable" msgstr "Choisir les référentiels supplémentaires en option à activer" @@ -548,7 +642,7 @@ msgid "Manage ordinary user accounts: " msgstr "Gérer les comptes d'utilisateurs ordinaires : " msgid " Subvolume :{:16}" -msgstr " Sous-volume :{:16}" +msgstr " Sous-volume : {:16}" msgid " mounted at {:16}" msgstr " monté à {:16}" @@ -585,13 +679,16 @@ msgid "Select the desired subvolume options " msgstr "Sélectionner les options de sous-volume souhaitées " msgid "Define users with sudo privilege, by username: " -msgstr "Définir les utilisateurs avec le privilège sudo, par nom d'utilisateur : " +msgstr "" +"Définir les utilisateurs avec le privilège sudo, par nom d'utilisateur : " msgid "[!] A log file has been created here: {}" msgstr "[!] Un fichier journal a été créé ici : {}" msgid "Would you like to use BTRFS subvolumes with a default structure?" -msgstr "Souhaitez-vous utiliser des sous-volumes BTRFS avec une structure par défaut ?" +msgstr "" +"Souhaitez-vous utiliser des sous-volumes BTRFS avec une structure par " +"défaut ?" msgid "Would you like to use BTRFS compression?" msgstr "Souhaitez-vous utiliser la compression BTRFS ?" @@ -599,8 +696,12 @@ msgstr "Souhaitez-vous utiliser la compression BTRFS ?" msgid "Would you like to create a separate partition for /home?" msgstr "Souhaitez-vous créer une partition séparée pour /home ?" -msgid "The selected drives do not have the minimum capacity required for an automatic suggestion\n" -msgstr "Les disques sélectionnés n'ont pas la capacité minimale requise pour une suggestion automatique\n" +msgid "" +"The selected drives do not have the minimum capacity required for an " +"automatic suggestion\n" +msgstr "" +"Les disques sélectionnés n'ont pas la capacité minimale requise pour une " +"suggestion automatique\n" msgid "Minimum capacity for /home partition: {}GB\n" msgstr "Capacité minimale pour la partition /home : {} Go\n" @@ -627,7 +728,9 @@ msgid "No iface specified for manual configuration" msgstr "Aucun iface spécifié pour la configuration manuelle" msgid "Manual nic configuration with no auto DHCP requires an IP address" -msgstr "La configuration manuelle de la carte réseau sans DHCP automatique nécessite une adresse IP" +msgstr "" +"La configuration manuelle de la carte réseau sans DHCP automatique nécessite " +"une adresse IP" msgid "Add interface" msgstr "Ajouter une interface" @@ -647,23 +750,42 @@ msgstr "Configuration manuelle" msgid "Mark/Unmark a partition as compressed (btrfs only)" msgstr "Marquer/Démarquer une partition comme compressée (btrfs uniquement)" -msgid "The password you are using seems to be weak, are you sure you want to use it?" -msgstr "Le mot de passe que vous utilisez semble faible, êtes-vous sûr de vouloir l'utiliser ?" +msgid "" +"The password you are using seems to be weak, are you sure you want to use it?" +msgstr "" +"Le mot de passe que vous utilisez semble faible, êtes-vous sûr de vouloir " +"l'utiliser ?" -msgid "Provides a selection of desktop environments and tiling window managers, e.g. gnome, kde, sway" -msgstr "Fournit une sélection d'environnements de bureau et de gestionnaires de fenêtres en mosaïque, par ex. gnome, kde, sway" +msgid "" +"Provides a selection of desktop environments and tiling window managers, e." +"g. gnome, kde, sway" +msgstr "" +"Fournit une sélection d'environnements de bureau et de gestionnaires de " +"fenêtres en mosaïque, par ex. gnome, kde, sway" msgid "Select your desired desktop environment" msgstr "Sélectionner l'environnement de bureau souhaité" -msgid "A very basic installation that allows you to customize Arch Linux as you see fit." -msgstr "Une installation très basique qui vous permet de personnaliser Arch Linux comme bon vous semble." +msgid "" +"A very basic installation that allows you to customize Arch Linux as you see " +"fit." +msgstr "" +"Une installation très basique qui vous permet de personnaliser Arch Linux " +"comme bon vous semble." -msgid "Provides a selection of various server packages to install and enable, e.g. httpd, nginx, mariadb" -msgstr "Fournit une sélection de divers paquets de serveur à installer et à activer, par ex. httpd, nginx, mariadb" +msgid "" +"Provides a selection of various server packages to install and enable, e.g. " +"httpd, nginx, mariadb" +msgstr "" +"Fournit une sélection de divers paquets de serveur à installer et à activer, " +"par ex. httpd, nginx, mariadb" -msgid "Choose which servers to install, if none then a minimal installation wil be done" -msgstr "Choisir les serveurs à installer, s'il n'y en a pas, une installation minimale sera effectuée" +msgid "" +"Choose which servers to install, if none then a minimal installation wil be " +"done" +msgstr "" +"Choisir les serveurs à installer, s'il n'y en a pas, une installation " +"minimale sera effectuée" msgid "Installs a minimal system as well as xorg and graphics drivers." msgstr "Installe un système minimal ainsi que les pilotes graphiques et xorg." @@ -671,8 +793,12 @@ msgstr "Installe un système minimal ainsi que les pilotes graphiques et xorg." msgid "Press Enter to continue." msgstr "Appuyer sur Entrée pour continuer." -msgid "Would you like to chroot into the newly created installation and perform post-installation configuration?" -msgstr "Souhaitez-vous chrooter dans l'installation nouvellement créée et effectuer la configuration post-installation ?" +msgid "" +"Would you like to chroot into the newly created installation and perform " +"post-installation configuration?" +msgstr "" +"Souhaitez-vous chrooter dans l'installation nouvellement créée et effectuer " +"la configuration post-installation ?" msgid "Are you sure you want to reset this setting?" msgstr "Voulez-vous vraiment réinitialiser ce paramètre ?" @@ -681,10 +807,16 @@ msgid "Select one or more hard drives to use and configure\n" msgstr "Sélectionner un ou plusieurs disques durs à utiliser et à configurer\n" msgid "Any modifications to the existing setting will reset the disk layout!" -msgstr "Toute modification du paramètre existant réinitialisera la disposition du disque !" +msgstr "" +"Toute modification du paramètre existant réinitialisera la disposition du " +"disque !" -msgid "If you reset the harddrive selection this will also reset the current disk layout. Are you sure?" -msgstr "Si vous réinitialisez la sélection du disque dur, cela réinitialisera également la disposition actuelle du disque. Êtes-vous sûr ?" +msgid "" +"If you reset the harddrive selection this will also reset the current disk " +"layout. Are you sure?" +msgstr "" +"Si vous réinitialisez la sélection du disque dur, cela réinitialisera " +"également la disposition actuelle du disque. Êtes-vous sûr ?" msgid "Save and exit" msgstr "Sauvegarder et quitter" @@ -694,7 +826,8 @@ msgid "" "contains queued partitions, this will remove those, are you sure?" msgstr "" "{}\n" -"contient des partitions en file d'attente, cela les supprimera, êtes-vous sûr ?" +"contient des partitions en file d'attente, cela les supprimera, êtes-vous " +"sûr ?" msgid "No audio server" msgstr "Pas de serveur audio" @@ -713,16 +846,16 @@ msgstr "" "\n" msgid "Copy to: " -msgstr "Copier vers: " +msgstr "Copier vers : " msgid "Edit: " -msgstr "Modifier: " +msgstr "Modifier : " msgid "Key: " -msgstr "Clé: " +msgstr "Clé : " msgid "Edit {}: " -msgstr "Modifier {}: " +msgstr "Modifier {} : " msgid "Add: " msgstr "Ajouter: " @@ -730,15 +863,51 @@ msgstr "Ajouter: " msgid "Value: " msgstr "Valeur: " -msgid "You can skip selecting a drive and partitioning and use whatever drive-setup is mounted at /mnt (experimental)" +msgid "" +"You can skip selecting a drive and partitioning and use whatever drive-setup " +"is mounted at /mnt (experimental)" msgstr "" +"Vous pouvez ignorer la sélection d'un lecteur et le partitionnement et " +"utiliser n'importe quelle configuration de lecteur montée sur /mnt " +"(expérimental)" msgid "Select one of the disks or skip and use /mnt as default" -msgstr "" +msgstr "Sélectionner l'un des disques ou ignorer et utiliser /mnt par défaut" msgid "Select which partitions to mark for formatting:" msgstr "Sélectionner la partition à masquer pour le formatage:" +msgid "Use HSM to unlock encrypted drive" +msgstr "Utiliser HSM pour déverrouiller le lecteur chiffré" + +msgid "Device" +msgstr "Dispositif" + +msgid "Size" +msgstr "Taille" + +msgid "Free space" +msgstr "Espace libre" + +msgid "Bus-type" +msgstr "Type de bus" + +msgid "" +"Either root-password or at least 1 user with sudo privileges must be " +"specified" +msgstr "" +"Le mot de passe root ou au moins 1 utilisateur avec des privilèges sudo doit " +"être spécifié" + +msgid "Enter username (leave blank to skip): " +msgstr "Entrer le nom d'utilisateur (laisser vide pour passer) :" + +msgid "The username you entered is invalid. Try again" +msgstr "Le nom d'utilisateur que vous avez saisi n'est pas valide. Réessayer" + +msgid "Should \"{}\" be a superuser (sudo)?" +msgstr "\"{}\" devrait-il être un superutilisateur (sudo) ?" + #~ msgid "Select disk layout" #~ msgstr "Sélectionner la disposition du disque" -- cgit v1.2.3-54-g00ecf From 7943dd82365fd9fb5034a0f1c05de3ccabda468a Mon Sep 17 00:00:00 2001 From: Anton Hvornum Date: Thu, 2 Jun 2022 13:32:42 +0200 Subject: Added more offline functionality, such as skipping package search (#1296) * Added more offline functionality, such as skipping package search * Disabled list_mirrors() from going online if --offline is given. Defaults to /etc/pacman.d/mirrorlist instead. * Forgot import of pathlib * Made list_mirrors() open /etc/pacman.d/mirrorlist in byte mode to better emulate the result of urllib response reading. * Forgot variable declaration * Made list_mirrors include activated server definitions --- archinstall/__init__.py | 3 ++ archinstall/lib/mirrors.py | 27 ++++++++++++----- archinstall/lib/user_interaction/general_conf.py | 37 ++++++++++++------------ examples/guided.py | 2 +- 4 files changed, 43 insertions(+), 26 deletions(-) (limited to 'archinstall') diff --git a/archinstall/__init__.py b/archinstall/__init__.py index 786be1c5..ee5e5f45 100644 --- a/archinstall/__init__.py +++ b/archinstall/__init__.py @@ -81,6 +81,8 @@ def define_arguments(): parser.add_argument("--script", default="guided", nargs="?", help="Script to run for installation", type=str) parser.add_argument("--mount-point","--mount_point", nargs="?", type=str, help="Define an alternate mount point for installation") parser.add_argument("--debug", action="store_true", default=False, help="Adds debug info into the log") + parser.add_argument("--offline", action="store_true", default=False, help="Disabled online upstream services such as package search and key-ring auto update.") + parser.add_argument("--no-pkg-lookups", action="store_true", default=False, help="Disabled package validation specifically prior to starting installation.") parser.add_argument("--plugin", nargs="?", type=str) def parse_unspecified_argument_list(unknowns :list, multiple :bool = False, error :bool = False) -> dict: @@ -172,6 +174,7 @@ def get_arguments() -> Dict[str, Any]: # avoiding a compatibility issue if 'dry-run' in config: del config['dry-run'] + return config def load_config(): diff --git a/archinstall/lib/mirrors.py b/archinstall/lib/mirrors.py index 73921cef..d76e0473 100644 --- a/archinstall/lib/mirrors.py +++ b/archinstall/lib/mirrors.py @@ -1,10 +1,12 @@ import logging +import pathlib import urllib.error import urllib.request from typing import Union, Mapping, Iterable, Dict, Any, List from .general import SysCommand from .output import log +from .storage import storage def sort_mirrorlist(raw_data :bytes, sort_order=["https", "http"]) -> bytes: """ @@ -144,16 +146,22 @@ def re_rank_mirrors( def list_mirrors(sort_order :List[str] = ["https", "http"]) -> Dict[str, Any]: - url = "https://archlinux.org/mirrorlist/?protocol=https&protocol=http&ip_version=4&ip_version=6&use_mirror_status=on" regions = {} - try: - response = urllib.request.urlopen(url) - except urllib.error.URLError as err: - log(f'Could not fetch an active mirror-list: {err}', level=logging.WARNING, fg="orange") - return regions + if storage['arguments']['offline']: + with pathlib.Path('/etc/pacman.d/mirrorlist').open('rb') as fh: + mirrorlist = fh.read() + else: + url = "https://archlinux.org/mirrorlist/?protocol=https&protocol=http&ip_version=4&ip_version=6&use_mirror_status=on" + + try: + response = urllib.request.urlopen(url) + except urllib.error.URLError as err: + log(f'Could not fetch an active mirror-list: {err}', level=logging.WARNING, fg="orange") + return regions + + mirrorlist = response.read() - mirrorlist = response.read() if sort_order: mirrorlist = sort_mirrorlist(mirrorlist, sort_order=sort_order) @@ -170,5 +178,10 @@ def list_mirrors(sort_order :List[str] = ["https", "http"]) -> Dict[str, Any]: url = line.lstrip('#Server = ') regions[region][url] = True + elif line.startswith('Server = '): + regions.setdefault(region, {}) + + url = line.lstrip('Server = ') + regions[region][url] = True return regions diff --git a/archinstall/lib/user_interaction/general_conf.py b/archinstall/lib/user_interaction/general_conf.py index f1d56fc1..70a0e73f 100644 --- a/archinstall/lib/user_interaction/general_conf.py +++ b/archinstall/lib/user_interaction/general_conf.py @@ -3,8 +3,6 @@ from __future__ import annotations import logging from typing import List, Any, Optional, Dict, TYPE_CHECKING -import archinstall - from ..menu.menu import MenuSelectionType from ..menu.text_input import TextInput @@ -17,6 +15,8 @@ from ..mirrors import list_mirrors from ..translation import Translation from ..packages.packages import validate_package_list +from ..storage import storage + if TYPE_CHECKING: _: Any @@ -155,11 +155,11 @@ def select_profile(preset) -> Optional[Profile]: case MenuSelectionType.Selection: return options[selection.value] if selection.value is not None else None case MenuSelectionType.Ctrl_c: - archinstall.storage['profile_minimal'] = False - archinstall.storage['_selected_servers'] = [] - archinstall.storage['_desktop_profile'] = None - archinstall.arguments['desktop-environment'] = None - archinstall.arguments['gfx_driver_packages'] = None + storage['profile_minimal'] = False + storage['_selected_servers'] = [] + storage['_desktop_profile'] = None + storage['arguments']['desktop-environment'] = None + storage['arguments']['gfx_driver_packages'] = None return None case MenuSelectionType.Esc: return None @@ -178,17 +178,18 @@ def ask_additional_packages_to_install(pre_set_packages: List[str] = []) -> List pre_set_packages = pre_set_packages if pre_set_packages else [] packages = read_packages(pre_set_packages) - while True: - if len(packages): - # Verify packages that were given - print(_("Verifying that additional packages exist (this might take a few seconds)")) - valid, invalid = validate_package_list(packages) - - if invalid: - log(f"Some packages could not be found in the repository: {invalid}", level=logging.WARNING, fg='red') - packages = read_packages(valid) - continue - break + if not storage['arguments']['offline'] and not storage['arguments']['no_pkg_lookups']: + while True: + if len(packages): + # Verify packages that were given + print(_("Verifying that additional packages exist (this might take a few seconds)")) + valid, invalid = validate_package_list(packages) + + if invalid: + log(f"Some packages could not be found in the repository: {invalid}", level=logging.WARNING, fg='red') + packages = read_packages(valid) + continue + break return packages diff --git a/examples/guided.py b/examples/guided.py index 635baf6a..8693b98f 100644 --- a/examples/guided.py +++ b/examples/guided.py @@ -274,7 +274,7 @@ if not (archinstall.check_mirror_reachable() or archinstall.arguments.get('skip- archinstall.log(f"Arch Linux mirrors are not reachable. Please check your internet connection and the log file '{log_file}'.", level=logging.INFO, fg="red") exit(1) -if not archinstall.arguments.get('offline', False): +if not archinstall.arguments['offline']: latest_version_archlinux_keyring = max([k.pkg_version for k in archinstall.find_package('archlinux-keyring')]) # If we want to check for keyring updates -- cgit v1.2.3-54-g00ecf From f2492ca574448fe4bd44604316da322720e70040 Mon Sep 17 00:00:00 2001 From: Daniel Girtler Date: Mon, 6 Jun 2022 21:04:50 +1000 Subject: Fix #1304 - Make password validation less intrusive (#1308) * Make password validation less intrusive * Update Co-authored-by: Daniel Girtler --- archinstall/lib/models/password_strength.py | 85 +++++++++++++++++++++++++++++ archinstall/lib/models/users.py | 7 ++- archinstall/lib/user_interaction/utils.py | 32 +++-------- 3 files changed, 97 insertions(+), 27 deletions(-) create mode 100644 archinstall/lib/models/password_strength.py (limited to 'archinstall') diff --git a/archinstall/lib/models/password_strength.py b/archinstall/lib/models/password_strength.py new file mode 100644 index 00000000..61986bf0 --- /dev/null +++ b/archinstall/lib/models/password_strength.py @@ -0,0 +1,85 @@ +from enum import Enum + + +class PasswordStrength(Enum): + VERY_WEAK = 'very weak' + WEAK = 'weak' + MODERATE = 'moderate' + STRONG = 'strong' + + @property + def value(self): + match self: + case PasswordStrength.VERY_WEAK: return str(_('very weak')) + case PasswordStrength.WEAK: return str(_('weak')) + case PasswordStrength.MODERATE: return str(_('moderate')) + case PasswordStrength.STRONG: return str(_('strong')) + + def color(self): + match self: + case PasswordStrength.VERY_WEAK: return 'red' + case PasswordStrength.WEAK: return 'red' + case PasswordStrength.MODERATE: return 'yellow' + case PasswordStrength.STRONG: return 'green' + + @classmethod + def strength(cls, password: str) -> 'PasswordStrength': + digit = any(character.isdigit() for character in password) + upper = any(character.isupper() for character in password) + lower = any(character.islower() for character in password) + symbol = any(not character.isalnum() for character in password) + return cls._check_password_strength(digit, upper, lower, symbol, len(password)) + + @classmethod + def _check_password_strength( + cls, + digit: bool, + upper: bool, + lower: bool, + symbol: bool, + length: int + ) -> 'PasswordStrength': + # suggested evaluation + # https://github.com/archlinux/archinstall/issues/1304#issuecomment-1146768163 + if digit and upper and lower and symbol: + match length: + case num if 13 <= num: + return PasswordStrength.STRONG + case num if 11 <= num <= 12: + return PasswordStrength.MODERATE + case num if 7 <= num <= 10: + return PasswordStrength.WEAK + case num if num <= 6: + return PasswordStrength.VERY_WEAK + elif digit and upper and lower: + match length: + case num if 14 <= num: + return PasswordStrength.STRONG + case num if 11 <= num <= 13: + return PasswordStrength.MODERATE + case num if 7 <= num <= 10: + return PasswordStrength.WEAK + case num if num <= 6: + return PasswordStrength.VERY_WEAK + elif upper and lower: + match length: + case num if 15 <= num: + return PasswordStrength.STRONG + case num if 12 <= num <= 14: + return PasswordStrength.MODERATE + case num if 7 <= num <= 11: + return PasswordStrength.WEAK + case num if num <= 6: + return PasswordStrength.VERY_WEAK + elif lower or upper: + match length: + case num if 18 <= num: + return PasswordStrength.STRONG + case num if 14 <= num <= 17: + return PasswordStrength.MODERATE + case num if 9 <= num <= 13: + return PasswordStrength.WEAK + case num if num <= 8: + return PasswordStrength.VERY_WEAK + + return PasswordStrength.VERY_WEAK diff --git a/archinstall/lib/models/users.py b/archinstall/lib/models/users.py index a3057291..f72cabde 100644 --- a/archinstall/lib/models/users.py +++ b/archinstall/lib/models/users.py @@ -1,6 +1,8 @@ from dataclasses import dataclass from typing import Dict, List, Union, Any, TYPE_CHECKING +from .password_strength import PasswordStrength + if TYPE_CHECKING: _: Any @@ -25,8 +27,9 @@ class User: } def display(self) -> str: - password = '*' * len(self.password) - return f'{_("Username")}: {self.username:16} {_("Password")}: {password:16} sudo: {str(self.sudo)}' + strength = PasswordStrength.strength(self.password) + password = '*' * len(self.password) + f' ({strength.value})' + return f'{_("Username")}: {self.username:16} {_("Password")}: {password:20} sudo: {str(self.sudo)}' @classmethod def _parse(cls, config_users: List[Dict[str, Any]]) -> List['User']: diff --git a/archinstall/lib/user_interaction/utils.py b/archinstall/lib/user_interaction/utils.py index fa079bc2..7ee6fc07 100644 --- a/archinstall/lib/user_interaction/utils.py +++ b/archinstall/lib/user_interaction/utils.py @@ -7,6 +7,7 @@ import time from typing import Any, Optional, TYPE_CHECKING from ..menu import Menu +from ..models.password_strength import PasswordStrength from ..output import log if TYPE_CHECKING: @@ -16,42 +17,23 @@ if TYPE_CHECKING: SIG_TRIGGER = None -def check_password_strong(passwd: str) -> bool: - symbol_count = 0 - if any(character.isdigit() for character in passwd): - symbol_count += 10 - if any(character.isupper() for character in passwd): - symbol_count += 26 - if any(character.islower() for character in passwd): - symbol_count += 26 - if any(not character.isalnum() for character in passwd): - symbol_count += 40 - - if symbol_count**len(passwd) < 10e20: - prompt = str(_("The password you are using seems to be weak, are you sure you want to use it?")) - choice = Menu(prompt, Menu.yes_no(), default_option=Menu.yes()).run() - return choice.value == Menu.yes() - - return True - - def get_password(prompt: str = '') -> Optional[str]: if not prompt: prompt = _("Enter a password: ") - while passwd := getpass.getpass(prompt): - if len(passwd.strip()) <= 0: + while password := getpass.getpass(prompt): + if len(password.strip()) <= 0: break - if not check_password_strong(passwd): - continue + strength = PasswordStrength.strength(password) + log(f'Password strength: {strength.value}', fg=strength.color()) passwd_verification = getpass.getpass(prompt=_('And one more time for verification: ')) - if passwd != passwd_verification: + if password != passwd_verification: log(' * Passwords did not match * ', fg='red') continue - return passwd + return password return None -- cgit v1.2.3-54-g00ecf From 2d4b2620462a0fb4c9496ed0629d7ab8930fc73a Mon Sep 17 00:00:00 2001 From: Daniel Girtler Date: Tue, 7 Jun 2022 01:26:27 +1000 Subject: Handle cyrillic characters (#1309) * Handle cyrillic characters * Update Co-authored-by: Daniel Girtler --- .github/workflows/mypy.yaml | 2 +- archinstall/__init__.py | 7 ----- archinstall/lib/menu/selection_menu.py | 10 +------ archinstall/lib/translation.py | 34 +++++++++++++++++++++++- archinstall/lib/user_interaction/general_conf.py | 9 ++++--- archinstall/locales/cyrillic.json | 19 +++++++++++++ 6 files changed, 60 insertions(+), 21 deletions(-) create mode 100644 archinstall/locales/cyrillic.json (limited to 'archinstall') diff --git a/.github/workflows/mypy.yaml b/.github/workflows/mypy.yaml index d14d8553..8463afda 100644 --- a/.github/workflows/mypy.yaml +++ b/.github/workflows/mypy.yaml @@ -15,4 +15,4 @@ jobs: # one day this will be enabled # run: mypy --strict --module archinstall || exit 0 - name: run mypy - run: mypy --follow-imports=silent archinstall/lib/menu/selection_menu.py archinstall/lib/menu/global_menu.py archinstall/lib/models/network_configuration.py archinstall/lib/menu/list_manager.py archinstall/lib/user_interaction/network_conf.py archinstall/lib/models/users.py + run: mypy --follow-imports=silent archinstall/lib/menu/selection_menu.py archinstall/lib/menu/global_menu.py archinstall/lib/models/network_configuration.py archinstall/lib/menu/list_manager.py archinstall/lib/user_interaction/network_conf.py archinstall/lib/models/users.py archinstall/lib/translation.py diff --git a/archinstall/__init__.py b/archinstall/__init__.py index ee5e5f45..abcad3ba 100644 --- a/archinstall/__init__.py +++ b/archinstall/__init__.py @@ -58,10 +58,6 @@ storage['__version__'] = __version__ DeferredTranslation.install() -def set_unicode_font(): - SysCommand('setfont UniCyr_8x16') - - def define_arguments(): """ Define which explicit arguments do we allow. @@ -249,9 +245,6 @@ def post_process_arguments(arguments): load_config() -# to ensure that cyrillic characters work in the installer -# set_unicode_font() - define_arguments() arguments = get_arguments() post_process_arguments(arguments) diff --git a/archinstall/lib/menu/selection_menu.py b/archinstall/lib/menu/selection_menu.py index d4a7ceef..8dd6fcce 100644 --- a/archinstall/lib/menu/selection_menu.py +++ b/archinstall/lib/menu/selection_menu.py @@ -15,15 +15,6 @@ if TYPE_CHECKING: _: Any -def select_archinstall_language(preset_value: str) -> Optional[Any]: - """ - copied from user_interaction/general_conf.py as a temporary measure - """ - languages = Translation.get_available_lang() - language = Menu(_('Archinstall language'), languages, preset_values=preset_value).run() - return language.value - - class Selector: def __init__( self, @@ -462,6 +453,7 @@ class GeneralMenu: return mandatory_fields, mandatory_waiting def _select_archinstall_language(self, preset_value: str) -> str: + from ... import select_archinstall_language language = select_archinstall_language(preset_value) if language is not None: self._translation.activate(language) diff --git a/archinstall/lib/translation.py b/archinstall/lib/translation.py index 79e0198a..c20a4285 100644 --- a/archinstall/lib/translation.py +++ b/archinstall/lib/translation.py @@ -1,6 +1,7 @@ from __future__ import annotations import json +import logging import os import gettext @@ -13,12 +14,19 @@ if TYPE_CHECKING: class LanguageDefinitions: + _languages = 'languages.json' + _cyrillic = 'cyrillic.json' + def __init__(self): self._mappings = self._get_language_mappings() + self._cyrillic_languages = self._get_cyrillic_languages() + + def is_cyrillic(self, language: str) -> bool: + return language in self._cyrillic_languages def _get_language_mappings(self) -> List[Dict[str, str]]: locales_dir = Translation.get_locales_dir() - languages = Path.joinpath(locales_dir, 'languages.json') + languages = Path.joinpath(locales_dir, self._languages) with open(languages, 'r') as fp: return json.load(fp) @@ -30,6 +38,14 @@ class LanguageDefinitions: raise ValueError(f'No language with abbreviation "{abbr}" found') + def _get_cyrillic_languages(self) -> List[str]: + locales_dir = Translation.get_locales_dir() + languages = Path.joinpath(locales_dir, self._cyrillic) + + with open(languages, 'r') as fp: + data = json.load(fp) + return data['languages'] + class DeferredTranslation: def __init__(self, message: str): @@ -78,10 +94,26 @@ class Translation: def activate(self, name): if language := self._languages.get(name, None): + languages = LanguageDefinitions() + + if languages.is_cyrillic(name): + self._set_font('UniCyr_8x16') + else: + # this will reset a possible previously set font to a default font + self._set_font('') + language.install() else: raise ValueError(f'Language not supported: {name}') + def _set_font(self, font: str): + from archinstall import SysCommand, log + try: + log(f'Setting new font: {font}', level=logging.DEBUG) + SysCommand(f'setfont {font}') + except Exception: + log(f'Unable to set font {font}', level=logging.ERROR) + @classmethod def load_nationalization(cls) -> Translation: locales_dir = cls.get_locales_dir() diff --git a/archinstall/lib/user_interaction/general_conf.py b/archinstall/lib/user_interaction/general_conf.py index 70a0e73f..15c42b86 100644 --- a/archinstall/lib/user_interaction/general_conf.py +++ b/archinstall/lib/user_interaction/general_conf.py @@ -118,10 +118,13 @@ def select_mirror_regions(preset_values: Dict[str, Any] = {}) -> Dict[str, Any]: case _: return {selected: mirrors[selected] for selected in selected_mirror.value} -def select_archinstall_language(default='English'): +def select_archinstall_language(preset_values: str): languages = Translation.get_available_lang() - language = Menu(_('Archinstall language'), languages, default_option=default).run() - return language + choice = Menu(_('Archinstall language'), languages, default_option=preset_values).run() + + match choice.type_: + case MenuSelectionType.Esc: return preset_values + case MenuSelectionType.Selection: return choice.value def select_profile(preset) -> Optional[Profile]: diff --git a/archinstall/locales/cyrillic.json b/archinstall/locales/cyrillic.json new file mode 100644 index 00000000..13f11ad0 --- /dev/null +++ b/archinstall/locales/cyrillic.json @@ -0,0 +1,19 @@ +{ + "languages": [ + "Abkhazian", + "Azerbaijani", + "Bashkir", + "Belarusian", + "Bulgarian", + "Chuvash", + "Komi", + "Macedonian", + "Mongolian", + "Russian", + "Serbo-Croatian", + "Tajik", + "Tatar", + "Ukrainian", + "Uzbek" + ] +} -- cgit v1.2.3-54-g00ecf From a7ca037a26de53fd242f89bc6a90fd53337b4d13 Mon Sep 17 00:00:00 2001 From: Daniel Girtler Date: Tue, 7 Jun 2022 01:28:46 +1000 Subject: Update the subvolume menu - fix for #1278 (#1297) * Update subvolume * Add mypy compliance Co-authored-by: Daniel Girtler Co-authored-by: Anton Hvornum --- .github/workflows/mypy.yaml | 2 +- archinstall/__init__.py | 6 +- archinstall/lib/disk/btrfs/__init__.py | 130 +------------ archinstall/lib/disk/btrfs/btrfs_helpers.py | 94 ++++------ archinstall/lib/disk/btrfs/btrfspartition.py | 6 +- archinstall/lib/disk/btrfs/btrfssubvolume.py | 191 -------------------- archinstall/lib/disk/btrfs/btrfssubvolumeinfo.py | 192 ++++++++++++++++++++ archinstall/lib/disk/helpers.py | 9 +- archinstall/lib/disk/mapperdev.py | 10 +- archinstall/lib/disk/partition.py | 10 +- archinstall/lib/disk/user_guides.py | 19 +- archinstall/lib/installer.py | 55 ++---- archinstall/lib/menu/global_menu.py | 33 ++-- archinstall/lib/menu/list_manager.py | 39 ++-- archinstall/lib/models/subvolume.py | 68 +++++++ archinstall/lib/models/users.py | 6 +- .../lib/user_interaction/partitioning_conf.py | 12 +- .../lib/user_interaction/subvolume_config.py | 201 +++++++-------------- 18 files changed, 462 insertions(+), 621 deletions(-) delete mode 100644 archinstall/lib/disk/btrfs/btrfssubvolume.py create mode 100644 archinstall/lib/disk/btrfs/btrfssubvolumeinfo.py create mode 100644 archinstall/lib/models/subvolume.py (limited to 'archinstall') diff --git a/.github/workflows/mypy.yaml b/.github/workflows/mypy.yaml index 8463afda..b0901b38 100644 --- a/.github/workflows/mypy.yaml +++ b/.github/workflows/mypy.yaml @@ -15,4 +15,4 @@ jobs: # one day this will be enabled # run: mypy --strict --module archinstall || exit 0 - name: run mypy - run: mypy --follow-imports=silent archinstall/lib/menu/selection_menu.py archinstall/lib/menu/global_menu.py archinstall/lib/models/network_configuration.py archinstall/lib/menu/list_manager.py archinstall/lib/user_interaction/network_conf.py archinstall/lib/models/users.py archinstall/lib/translation.py + run: mypy --follow-imports=silent archinstall/lib/menu/selection_menu.py archinstall/lib/menu/global_menu.py archinstall/lib/models/network_configuration.py archinstall/lib/menu/list_manager.py archinstall/lib/user_interaction/network_conf.py archinstall/lib/models/users.py archinstall/lib/user_interaction/subvolume_config.py archinstall/lib/disk/btrfs/btrfs_helpers.py archinstall/lib/translation.py diff --git a/archinstall/__init__.py b/archinstall/__init__.py index abcad3ba..1a360c67 100644 --- a/archinstall/__init__.py +++ b/archinstall/__init__.py @@ -226,8 +226,6 @@ def post_process_arguments(arguments): load_plugin(arguments['plugin']) if arguments.get('disk_layouts', None) is not None: - # if 'disk_layouts' not in storage: - # storage['disk_layouts'] = {} layout_storage = {} if not json_stream_to_structure('--disk_layouts',arguments['disk_layouts'],layout_storage): exit(1) @@ -236,10 +234,12 @@ def post_process_arguments(arguments): arguments['harddrives'] = [disk for disk in layout_storage] # backward compatibility. Change partition.format for partition.wipe for disk in layout_storage: - for i,partition in enumerate(layout_storage[disk].get('partitions',[])): + for i, partition in enumerate(layout_storage[disk].get('partitions',[])): if 'format' in partition: partition['wipe'] = partition['format'] del partition['format'] + elif 'btrfs' in partition: + partition['btrfs']['subvolumes'] = Subvolume.parse_arguments(partition['btrfs']['subvolumes']) arguments['disk_layouts'] = layout_storage load_config() diff --git a/archinstall/lib/disk/btrfs/__init__.py b/archinstall/lib/disk/btrfs/__init__.py index 90c58145..3c183112 100644 --- a/archinstall/lib/disk/btrfs/__init__.py +++ b/archinstall/lib/disk/btrfs/__init__.py @@ -2,8 +2,7 @@ from __future__ import annotations import pathlib import glob import logging -import re -from typing import Union, Dict, TYPE_CHECKING, Any, Iterator +from typing import Union, Dict, TYPE_CHECKING # https://stackoverflow.com/a/39757388/929999 if TYPE_CHECKING: @@ -15,30 +14,15 @@ from .btrfs_helpers import ( setup_subvolumes as setup_subvolumes, mount_subvolume as mount_subvolume ) -from .btrfssubvolume import BtrfsSubvolume as BtrfsSubvolume +from .btrfssubvolumeinfo import BtrfsSubvolumeInfo as BtrfsSubvolume from .btrfspartition import BTRFSPartition as BTRFSPartition -from ..helpers import get_mount_info from ...exceptions import DiskError, Deprecated from ...general import SysCommand from ...output import log -from ...exceptions import SysCallError -def get_subvolume_info(path :pathlib.Path) -> Dict[str, Any]: - try: - output = SysCommand(f"btrfs subvol show {path}").decode() - except SysCallError as error: - print('Error:', error) - result = {} - for line in output.replace('\r\n', '\n').split('\n'): - if ':' in line: - key, val = line.replace('\t', '').split(':', 1) - result[key.strip().lower().replace(' ', '_')] = val.strip() - - return result - -def create_subvolume(installation :Installer, subvolume_location :Union[pathlib.Path, str]) -> bool: +def create_subvolume(installation: Installer, subvolume_location :Union[pathlib.Path, str]) -> bool: """ This function uses btrfs to create a subvolume. @@ -71,112 +55,6 @@ def create_subvolume(installation :Installer, subvolume_location :Union[pathlib. if (cmd := SysCommand(f"btrfs subvolume create {target}")).exit_code != 0: raise DiskError(f"Could not create a subvolume at {target}: {cmd}") -def _has_option(option :str,options :list) -> bool: - """ auxiliary routine to check if an option is present in a list. - we check if the string appears in one of the options, 'cause it can appear in several forms (option, option=val,...) - """ - if not options: - return False - - for item in options: - if option in item: - return True - - return False - -def manage_btrfs_subvolumes(installation :Installer, - partition :Dict[str, str],) -> list: +def manage_btrfs_subvolumes(installation :Installer, partition :Dict[str, str]) -> list: raise Deprecated("Use setup_subvolumes() instead.") - - from copy import deepcopy - """ we do the magic with subvolumes in a centralized place - parameters: - * the installation object - * the partition dictionary entry which represents the physical partition - returns - * mountpoinst, the list which contains all the "new" partititon to be mounted - - We expect the partition has been mounted as / , and it to be unmounted after the processing - Then we create all the subvolumes inside btrfs as demand - We clone then, both the partition dictionary and the object inside it and adapt it to the subvolume needs - Then we return a list of "new" partitions to be processed as "normal" partitions - # TODO For encrypted devices we need some special processing prior to it - """ - # We process each of the pairs - # th mount info dict has an entry for the path of the mountpoint (named 'mountpoint') and 'options' which is a list - # of mount options (or similar used by brtfs) - mountpoints = [] - subvolumes = partition['btrfs']['subvolumes'] - for name, right_hand in subvolumes.items(): - try: - # we normalize the subvolume name (getting rid of slash at the start if exists. In our implementation has no semantic load - every subvolume is created from the top of the hierarchy- and simplifies its further use - if name.startswith('/'): - name = name[1:] - # renormalize the right hand. - location = None - subvol_options = [] - # no contents, so it is not to be mounted - if not right_hand: - location = None - # just a string. per backward compatibility the mount point - elif isinstance(right_hand,str): - location = right_hand - # a dict. two elements 'mountpoint' (obvious) and and a mount options list ¿? - elif isinstance(right_hand,dict): - location = right_hand.get('mountpoint',None) - subvol_options = right_hand.get('options',[]) - # we create the subvolume - create_subvolume(installation,name) - # Make the nodatacow processing now - # It will be the main cause of creation of subvolumes which are not to be mounted - # it is not an options which can be established by subvolume (but for whole file systems), and can be - # set up via a simple attribute change in a directory (if empty). And here the directories are brand new - if 'nodatacow' in subvol_options: - if (cmd := SysCommand(f"chattr +C {installation.target}/{name}")).exit_code != 0: - raise DiskError(f"Could not set nodatacow attribute at {installation.target}/{name}: {cmd}") - # entry is deleted so nodatacow doesn't propagate to the mount options - del subvol_options[subvol_options.index('nodatacow')] - # Make the compress processing now - # it is not an options which can be established by subvolume (but for whole file systems), and can be - # set up via a simple attribute change in a directory (if empty). And here the directories are brand new - # in this way only zstd compression is activaded - # TODO WARNING it is not clear if it should be a standard feature, so it might need to be deactivated - if 'compress' in subvol_options: - if not _has_option('compress',partition.get('filesystem',{}).get('mount_options',[])): - if (cmd := SysCommand(f"chattr +c {installation.target}/{name}")).exit_code != 0: - raise DiskError(f"Could not set compress attribute at {installation.target}/{name}: {cmd}") - # entry is deleted so compress doesn't propagate to the mount options - del subvol_options[subvol_options.index('compress')] - # END compress processing. - # we do not mount if THE basic partition will be mounted or if we exclude explicitly this subvolume - if not partition['mountpoint'] and location is not None: - # we begin to create a fake partition entry. First we copy the original -the one that corresponds to - # the primary partition. We make a deepcopy to avoid altering the original content in any case - fake_partition = deepcopy(partition) - # we start to modify entries in the "fake partition" to match the needs of the subvolumes - # to avoid any chance of entering in a loop (not expected) we delete the list of subvolumes in the copy - del fake_partition['btrfs'] - fake_partition['encrypted'] = False - fake_partition['generate-encryption-key-file'] = False - # Mount destination. As of now the right hand part - fake_partition['mountpoint'] = location - # we load the name in an attribute called subvolume, but i think it is not needed anymore, 'cause the mount logic uses a different path. - fake_partition['subvolume'] = name - # here we add the special mount options for the subvolume, if any. - # if the original partition['options'] is not a list might give trouble - if fake_partition.get('filesystem',{}).get('mount_options',[]): - fake_partition['filesystem']['mount_options'].extend(subvol_options) - else: - fake_partition['filesystem']['mount_options'] = subvol_options - # Here comes the most exotic part. The dictionary attribute 'device_instance' contains an instance of Partition. This instance will be queried along the mount process at the installer. - # As the rest will query there the path of the "partition" to be mounted, we feed it with the bind name needed to mount subvolumes - # As we made a deepcopy we have a fresh instance of this object we can manipulate problemless - fake_partition['device_instance'].path = f"{partition['device_instance'].path}[/{name}]" - - # Well, now that this "fake partition" is ready, we add it to the list of the ones which are to be mounted, - # as "normal" ones - mountpoints.append(fake_partition) - except Exception as e: - raise e - return mountpoints diff --git a/archinstall/lib/disk/btrfs/btrfs_helpers.py b/archinstall/lib/disk/btrfs/btrfs_helpers.py index 5fa94314..ab528388 100644 --- a/archinstall/lib/disk/btrfs/btrfs_helpers.py +++ b/archinstall/lib/disk/btrfs/btrfs_helpers.py @@ -1,72 +1,42 @@ -import pathlib import logging -from typing import Optional +from pathlib import Path +from typing import Optional, Dict, Any, TYPE_CHECKING +from ...models.subvolume import Subvolume from ...exceptions import SysCallError, DiskError from ...general import SysCommand from ...output import log from ..helpers import get_mount_info -from .btrfssubvolume import BtrfsSubvolume +from .btrfssubvolumeinfo import BtrfsSubvolumeInfo +if TYPE_CHECKING: + from .btrfspartition import BTRFSPartition + from ...installer import Installer -def mount_subvolume(installation, device, name, subvolume_information): - # we normalize the subvolume name (getting rid of slash at the start if exists. In our implementation has no semantic load. - # Every subvolume is created from the top of the hierarchy- and simplifies its further use - name = name.lstrip('/') - - # renormalize the right hand. - mountpoint = subvolume_information.get('mountpoint', None) - if not mountpoint: - return None - - if type(mountpoint) == str: - mountpoint = pathlib.Path(mountpoint) - installation_target = installation.target - if type(installation_target) == str: - installation_target = pathlib.Path(installation_target) +def mount_subvolume(installation: 'Installer', device: 'BTRFSPartition', subvolume: Subvolume): + # we normalize the subvolume name (getting rid of slash at the start if exists. + # In our implementation has no semantic load. + # Every subvolume is created from the top of the hierarchy- and simplifies its further use + name = subvolume.name.lstrip('/') + mountpoint = Path(subvolume.mountpoint) + installation_target = Path(installation.target) mountpoint = installation_target / mountpoint.relative_to(mountpoint.anchor) mountpoint.mkdir(parents=True, exist_ok=True) - - mount_options = subvolume_information.get('options', []) - if not any('subvol=' in x for x in mount_options): - mount_options += [f'subvol={name}'] + mount_options = subvolume.options + [f'subvol={name}'] log(f"Mounting subvolume {name} on {device} to {mountpoint}", level=logging.INFO, fg="gray") SysCommand(f"mount {device.path} {mountpoint} -o {','.join(mount_options)}") -def setup_subvolumes(installation, partition_dict): - """ - Taken from: ..user_guides.py - - partition['btrfs'] = { - "subvolumes" : { - "@": "/", - "@home": "/home", - "@log": "/var/log", - "@pkg": "/var/cache/pacman/pkg", - "@.snapshots": "/.snapshots" - } - } - """ +def setup_subvolumes(installation: 'Installer', partition_dict: Dict[str, Any]): log(f"Setting up subvolumes: {partition_dict['btrfs']['subvolumes']}", level=logging.INFO, fg="gray") - for name, right_hand in partition_dict['btrfs']['subvolumes'].items(): + + for subvolume in partition_dict['btrfs']['subvolumes']: # we normalize the subvolume name (getting rid of slash at the start if exists. In our implementation has no semantic load. # Every subvolume is created from the top of the hierarchy- and simplifies its further use - name = name.lstrip('/') - - # renormalize the right hand. - # mountpoint = None - subvol_options = [] - - match right_hand: - # case str(): # backwards-compatability - # mountpoint = right_hand - case dict(): - # mountpoint = right_hand.get('mountpoint', None) - subvol_options = right_hand.get('options', []) + name = subvolume.name.lstrip('/') # We create the subvolume using the BTRFSPartition instance. # That way we ensure not only easy access, but also accurate mount locations etc. @@ -76,27 +46,25 @@ def setup_subvolumes(installation, partition_dict): # It will be the main cause of creation of subvolumes which are not to be mounted # it is not an options which can be established by subvolume (but for whole file systems), and can be # set up via a simple attribute change in a directory (if empty). And here the directories are brand new - if 'nodatacow' in subvol_options: + if subvolume.nodatacow: if (cmd := SysCommand(f"chattr +C {installation.target}/{name}")).exit_code != 0: raise DiskError(f"Could not set nodatacow attribute at {installation.target}/{name}: {cmd}") - # entry is deleted so nodatacow doesn't propagate to the mount options - del subvol_options[subvol_options.index('nodatacow')] + # Make the compress processing now # it is not an options which can be established by subvolume (but for whole file systems), and can be # set up via a simple attribute change in a directory (if empty). And here the directories are brand new # in this way only zstd compression is activaded # TODO WARNING it is not clear if it should be a standard feature, so it might need to be deactivated - if 'compress' in subvol_options: + if subvolume.compress: if not any(['compress' in filesystem_option for filesystem_option in partition_dict.get('filesystem', {}).get('mount_options', [])]): if (cmd := SysCommand(f"chattr +c {installation.target}/{name}")).exit_code != 0: raise DiskError(f"Could not set compress attribute at {installation.target}/{name}: {cmd}") - # entry is deleted so compress doesn't propagate to the mount options - del subvol_options[subvol_options.index('compress')] -def subvolume_info_from_path(path :pathlib.Path) -> Optional[BtrfsSubvolume]: + +def subvolume_info_from_path(path: Path) -> Optional[BtrfsSubvolumeInfo]: try: - subvolume_name = None + subvolume_name = '' result = {} for index, line in enumerate(SysCommand(f"btrfs subvolume show {path}")): if index == 0: @@ -110,14 +78,14 @@ def subvolume_info_from_path(path :pathlib.Path) -> Optional[BtrfsSubvolume]: # allows for hooking in a pre-processor to do this we have to do it here: result[key.lower().replace(' ', '_').replace('(s)', 's')] = value.strip() - return BtrfsSubvolume(**{'full_path' : path, 'name' : subvolume_name, **result}) - + return BtrfsSubvolumeInfo(**{'full_path' : path, 'name' : subvolume_name, **result}) # type: ignore except SysCallError as error: log(f"Could not retrieve subvolume information from {path}: {error}", level=logging.WARNING, fg="orange") return None -def find_parent_subvolume(path :pathlib.Path, filters=[]): + +def find_parent_subvolume(path: Path, filters=[]) -> Optional[BtrfsSubvolumeInfo]: # A root path cannot have a parent if str(path) == '/': return None @@ -127,6 +95,8 @@ def find_parent_subvolume(path :pathlib.Path, filters=[]): if found_mount['target'] == '/': return None - return find_parent_subvolume(path.parent, traverse=True, filters=[*filters, found_mount['target']]) + return find_parent_subvolume(path.parent, filters=[*filters, found_mount['target']]) + + return subvolume - return subvolume \ No newline at end of file + return None diff --git a/archinstall/lib/disk/btrfs/btrfspartition.py b/archinstall/lib/disk/btrfs/btrfspartition.py index 6f7487e4..a05f1527 100644 --- a/archinstall/lib/disk/btrfs/btrfspartition.py +++ b/archinstall/lib/disk/btrfs/btrfspartition.py @@ -15,7 +15,7 @@ from .btrfs_helpers import ( if TYPE_CHECKING: from ...installer import Installer - from .btrfssubvolume import BtrfsSubvolume + from .btrfssubvolumeinfo import BtrfsSubvolumeInfo class BTRFSPartition(Partition): def __init__(self, *args, **kwargs): @@ -50,7 +50,7 @@ class BTRFSPartition(Partition): for child in iterate_children(filesystem): yield child - def create_subvolume(self, subvolume :pathlib.Path, installation :Optional['Installer'] = None) -> 'BtrfsSubvolume': + def create_subvolume(self, subvolume :pathlib.Path, installation :Optional['Installer'] = None) -> 'BtrfsSubvolumeInfo': """ Subvolumes have to be created within a mountpoint. This means we need to get the current installation target. @@ -117,4 +117,4 @@ class BTRFSPartition(Partition): # And deal with it here: SysCommand(f"btrfs subvolume create {subvolume}") - return subvolume_info_from_path(subvolume) \ No newline at end of file + return subvolume_info_from_path(subvolume) diff --git a/archinstall/lib/disk/btrfs/btrfssubvolume.py b/archinstall/lib/disk/btrfs/btrfssubvolume.py deleted file mode 100644 index bc7db612..00000000 --- a/archinstall/lib/disk/btrfs/btrfssubvolume.py +++ /dev/null @@ -1,191 +0,0 @@ -import pathlib -import datetime -import logging -import string -import random -import shutil -from dataclasses import dataclass -from typing import Optional, List# , TYPE_CHECKING -from functools import cached_property - -# if TYPE_CHECKING: -# from ..blockdevice import BlockDevice - -from ...exceptions import DiskError -from ...general import SysCommand -from ...output import log -from ...storage import storage - -@dataclass -class BtrfsSubvolume: - full_path :pathlib.Path - name :str - uuid :str - parent_uuid :str - creation_time :datetime.datetime - subvolume_id :int - generation :int - gen_at_creation :int - parent_id :int - top_level_id :int - send_transid :int - send_time :datetime.datetime - receive_transid :int - received_uuid :Optional[str] = None - flags :Optional[str] = None - receive_time :Optional[datetime.datetime] = None - snapshots :Optional[List] = None - - def __post_init__(self): - self.full_path = pathlib.Path(self.full_path) - - # Convert "-" entries to `None` - if self.parent_uuid == "-": - self.parent_uuid = None - if self.received_uuid == "-": - self.received_uuid = None - if self.flags == "-": - self.flags = None - if self.receive_time == "-": - self.receive_time = None - if self.snapshots == "": - self.snapshots = [] - - # Convert timestamps into datetime workable objects (and preserve timezone by using ISO formats) - self.creation_time = datetime.datetime.fromisoformat(self.convert_to_ISO_format(self.creation_time)) - self.send_time = datetime.datetime.fromisoformat(self.convert_to_ISO_format(self.send_time)) - if self.receive_time: - self.receive_time = datetime.datetime.fromisoformat(self.convert_to_ISO_format(self.receive_time)) - - @property - def parent_subvolume(self): - from .btrfs_helpers import find_parent_subvolume - - return find_parent_subvolume(self.full_path) - - @property - def root(self) -> bool: - from .btrfs_helpers import subvolume_info_from_path - - # TODO: Make this function traverse storage['MOUNT_POINT'] and find the first - # occurrence of a mountpoint that is a btrfs volume instead of lazy assume / is a subvolume. - # It would also be nice if it could use findmnt(self.full_path) and traverse backwards - # finding the last occurrence of a subvolume which 'self' belongs to. - if volume := subvolume_info_from_path(storage['MOUNT_POINT']): - return self.full_path == volume.full_path - - return False - - @cached_property - def partition(self): - from ..helpers import findmnt, get_parent_of_partition, all_blockdevices - from ..partition import Partition - from ..blockdevice import BlockDevice - from ..mapperdev import MapperDev - from .btrfspartition import BTRFSPartition - from .btrfs_helpers import subvolume_info_from_path - - try: - # If the subvolume is mounted, it's pretty trivial to lookup the partition (parent) device. - if filesystem := findmnt(self.full_path).get('filesystems', []): - if source := filesystem[0].get('source', None): - # Strip away subvolume definitions from findmnt - if '[' in source: - source = source[:source.find('[')] - - if filesystem[0].get('fstype', '') == 'btrfs': - return BTRFSPartition(source, BlockDevice(get_parent_of_partition(pathlib.Path(source)))) - elif filesystem[0].get('source', '').startswith('/dev/mapper'): - return MapperDev(source) - else: - return Partition(source, BlockDevice(get_parent_of_partition(pathlib.Path(source)))) - except DiskError: - # Subvolume has never been mounted, we have no reliable way of finding where it is. - # But we have the UUID of the partition, and can begin looking for it by mounting - # all blockdevices that we can reliably support.. This is taxing tho and won't cover all devices. - - log(f"Looking up {self}, this might take time.", fg="orange", level=logging.WARNING) - for blockdevice, instance in all_blockdevices(mappers=True, partitions=True, error=True).items(): - if type(instance) in (Partition, MapperDev): - we_mounted_it = False - detection_mountpoint = instance.mountpoint - if not detection_mountpoint: - if type(instance) == Partition and instance.encrypted: - # TODO: Perhaps support unlocking encrypted volumes? - # This will cause a lot of potential user interactions tho. - log(f"Ignoring {blockdevice} because it's encrypted.", fg="gray", level=logging.DEBUG) - continue - - detection_mountpoint = pathlib.Path(f"/tmp/{''.join([random.choice(string.ascii_letters) for x in range(20)])}") - detection_mountpoint.mkdir(parents=True, exist_ok=True) - - instance.mount(str(detection_mountpoint)) - we_mounted_it = True - - if (filesystem := findmnt(detection_mountpoint)) and (filesystem := filesystem.get('filesystems', [])): - if subvolume := subvolume_info_from_path(filesystem[0]['target']): - if subvolume.uuid == self.uuid: - # The top level subvolume matched of ourselves, - # which means the instance we're iterating has the subvol we're looking for. - log(f"Found the subvolume on device {instance}", level=logging.DEBUG, fg="gray") - return instance - - def iterate_children(struct): - for child in struct.get('children', []): - if '[' in child.get('source', ''): - yield subvolume_info_from_path(child['target']) - - for sub_child in iterate_children(child): - yield sub_child - - for child in iterate_children(filesystem[0]): - if child.uuid == self.uuid: - # We found a child within the instance that has the subvol we're looking for. - log(f"Found the subvolume on device {instance}", level=logging.DEBUG, fg="gray") - return instance - - if we_mounted_it: - instance.unmount() - shutil.rmtree(detection_mountpoint) - - @cached_property - def mount_options(self) -> Optional[List[str]]: - from ..helpers import findmnt - - if filesystem := findmnt(self.full_path).get('filesystems', []): - return filesystem[0].get('options').split(',') - - def convert_to_ISO_format(self, time_string): - time_string_almost_done = time_string.replace(' ', 'T', 1).replace(' ', '') - iso_string = f"{time_string_almost_done[:-2]}:{time_string_almost_done[-2:]}" - return iso_string - - def mount(self, mountpoint :pathlib.Path, options=None, include_previously_known_options=True): - from ..helpers import findmnt - - try: - if mnt_info := findmnt(pathlib.Path(mountpoint), traverse=False): - log(f"Unmounting {mountpoint} as it was already mounted using {mnt_info}") - SysCommand(f"umount {mountpoint}") - except DiskError: - # No previously mounted device at the mountpoint - pass - - if not options: - options = [] - - try: - if include_previously_known_options and (cached_options := self.mount_options): - options += cached_options - except DiskError: - pass - - if not any('subvol=' in x for x in options): - options += f'subvol={self.name}' - - SysCommand(f"mount {self.partition.path} {mountpoint} -o {','.join(options)}") - log(f"{self} has successfully been mounted to {mountpoint}", level=logging.INFO, fg="gray") - - def unmount(self, recurse :bool = True): - SysCommand(f"umount {'-R' if recurse else ''} {self.full_path}") - log(f"Successfully unmounted {self}", level=logging.INFO, fg="gray") \ No newline at end of file diff --git a/archinstall/lib/disk/btrfs/btrfssubvolumeinfo.py b/archinstall/lib/disk/btrfs/btrfssubvolumeinfo.py new file mode 100644 index 00000000..5f5bdea6 --- /dev/null +++ b/archinstall/lib/disk/btrfs/btrfssubvolumeinfo.py @@ -0,0 +1,192 @@ +import pathlib +import datetime +import logging +import string +import random +import shutil +from dataclasses import dataclass +from typing import Optional, List# , TYPE_CHECKING +from functools import cached_property + +# if TYPE_CHECKING: +# from ..blockdevice import BlockDevice + +from ...exceptions import DiskError +from ...general import SysCommand +from ...output import log +from ...storage import storage + + +@dataclass +class BtrfsSubvolumeInfo: + full_path :pathlib.Path + name :str + uuid :str + parent_uuid :str + creation_time :datetime.datetime + subvolume_id :int + generation :int + gen_at_creation :int + parent_id :int + top_level_id :int + send_transid :int + send_time :datetime.datetime + receive_transid :int + received_uuid :Optional[str] = None + flags :Optional[str] = None + receive_time :Optional[datetime.datetime] = None + snapshots :Optional[List] = None + + def __post_init__(self): + self.full_path = pathlib.Path(self.full_path) + + # Convert "-" entries to `None` + if self.parent_uuid == "-": + self.parent_uuid = None + if self.received_uuid == "-": + self.received_uuid = None + if self.flags == "-": + self.flags = None + if self.receive_time == "-": + self.receive_time = None + if self.snapshots == "": + self.snapshots = [] + + # Convert timestamps into datetime workable objects (and preserve timezone by using ISO formats) + self.creation_time = datetime.datetime.fromisoformat(self.convert_to_ISO_format(self.creation_time)) + self.send_time = datetime.datetime.fromisoformat(self.convert_to_ISO_format(self.send_time)) + if self.receive_time: + self.receive_time = datetime.datetime.fromisoformat(self.convert_to_ISO_format(self.receive_time)) + + @property + def parent_subvolume(self): + from .btrfs_helpers import find_parent_subvolume + + return find_parent_subvolume(self.full_path) + + @property + def root(self) -> bool: + from .btrfs_helpers import subvolume_info_from_path + + # TODO: Make this function traverse storage['MOUNT_POINT'] and find the first + # occurrence of a mountpoint that is a btrfs volume instead of lazy assume / is a subvolume. + # It would also be nice if it could use findmnt(self.full_path) and traverse backwards + # finding the last occurrence of a subvolume which 'self' belongs to. + if volume := subvolume_info_from_path(storage['MOUNT_POINT']): + return self.full_path == volume.full_path + + return False + + @cached_property + def partition(self): + from ..helpers import findmnt, get_parent_of_partition, all_blockdevices + from ..partition import Partition + from ..blockdevice import BlockDevice + from ..mapperdev import MapperDev + from .btrfspartition import BTRFSPartition + from .btrfs_helpers import subvolume_info_from_path + + try: + # If the subvolume is mounted, it's pretty trivial to lookup the partition (parent) device. + if filesystem := findmnt(self.full_path).get('filesystems', []): + if source := filesystem[0].get('source', None): + # Strip away subvolume definitions from findmnt + if '[' in source: + source = source[:source.find('[')] + + if filesystem[0].get('fstype', '') == 'btrfs': + return BTRFSPartition(source, BlockDevice(get_parent_of_partition(pathlib.Path(source)))) + elif filesystem[0].get('source', '').startswith('/dev/mapper'): + return MapperDev(source) + else: + return Partition(source, BlockDevice(get_parent_of_partition(pathlib.Path(source)))) + except DiskError: + # Subvolume has never been mounted, we have no reliable way of finding where it is. + # But we have the UUID of the partition, and can begin looking for it by mounting + # all blockdevices that we can reliably support.. This is taxing tho and won't cover all devices. + + log(f"Looking up {self}, this might take time.", fg="orange", level=logging.WARNING) + for blockdevice, instance in all_blockdevices(mappers=True, partitions=True, error=True).items(): + if type(instance) in (Partition, MapperDev): + we_mounted_it = False + detection_mountpoint = instance.mountpoint + if not detection_mountpoint: + if type(instance) == Partition and instance.encrypted: + # TODO: Perhaps support unlocking encrypted volumes? + # This will cause a lot of potential user interactions tho. + log(f"Ignoring {blockdevice} because it's encrypted.", fg="gray", level=logging.DEBUG) + continue + + detection_mountpoint = pathlib.Path(f"/tmp/{''.join([random.choice(string.ascii_letters) for x in range(20)])}") + detection_mountpoint.mkdir(parents=True, exist_ok=True) + + instance.mount(str(detection_mountpoint)) + we_mounted_it = True + + if (filesystem := findmnt(detection_mountpoint)) and (filesystem := filesystem.get('filesystems', [])): + if subvolume := subvolume_info_from_path(filesystem[0]['target']): + if subvolume.uuid == self.uuid: + # The top level subvolume matched of ourselves, + # which means the instance we're iterating has the subvol we're looking for. + log(f"Found the subvolume on device {instance}", level=logging.DEBUG, fg="gray") + return instance + + def iterate_children(struct): + for child in struct.get('children', []): + if '[' in child.get('source', ''): + yield subvolume_info_from_path(child['target']) + + for sub_child in iterate_children(child): + yield sub_child + + for child in iterate_children(filesystem[0]): + if child.uuid == self.uuid: + # We found a child within the instance that has the subvol we're looking for. + log(f"Found the subvolume on device {instance}", level=logging.DEBUG, fg="gray") + return instance + + if we_mounted_it: + instance.unmount() + shutil.rmtree(detection_mountpoint) + + @cached_property + def mount_options(self) -> Optional[List[str]]: + from ..helpers import findmnt + + if filesystem := findmnt(self.full_path).get('filesystems', []): + return filesystem[0].get('options').split(',') + + def convert_to_ISO_format(self, time_string): + time_string_almost_done = time_string.replace(' ', 'T', 1).replace(' ', '') + iso_string = f"{time_string_almost_done[:-2]}:{time_string_almost_done[-2:]}" + return iso_string + + def mount(self, mountpoint :pathlib.Path, options=None, include_previously_known_options=True): + from ..helpers import findmnt + + try: + if mnt_info := findmnt(pathlib.Path(mountpoint), traverse=False): + log(f"Unmounting {mountpoint} as it was already mounted using {mnt_info}") + SysCommand(f"umount {mountpoint}") + except DiskError: + # No previously mounted device at the mountpoint + pass + + if not options: + options = [] + + try: + if include_previously_known_options and (cached_options := self.mount_options): + options += cached_options + except DiskError: + pass + + if not any('subvol=' in x for x in options): + options += f'subvol={self.name}' + + SysCommand(f"mount {self.partition.path} {mountpoint} -o {','.join(options)}") + log(f"{self} has successfully been mounted to {mountpoint}", level=logging.INFO, fg="gray") + + def unmount(self, recurse :bool = True): + SysCommand(f"umount {'-R' if recurse else ''} {self.full_path}") + log(f"Successfully unmounted {self}", level=logging.INFO, fg="gray") diff --git a/archinstall/lib/disk/helpers.py b/archinstall/lib/disk/helpers.py index 85c0390f..660594ed 100644 --- a/archinstall/lib/disk/helpers.py +++ b/archinstall/lib/disk/helpers.py @@ -8,6 +8,8 @@ import time import glob from typing import Union, List, Iterator, Dict, Optional, Any, TYPE_CHECKING # https://stackoverflow.com/a/39757388/929999 +from ..models.subvolume import Subvolume + if TYPE_CHECKING: from .partition import Partition @@ -469,6 +471,7 @@ def convert_device_to_uuid(path :str) -> str: raise DiskError(f"Could not retrieve the UUID of {path} within a timely manner.") + def has_mountpoint(partition: Union[dict,Partition,MapperDev], target: str, strict: bool = True) -> bool: """ Determine if a certain partition is mounted (or has a mountpoint) as specific target (path) Coded for clarity rather than performance @@ -485,10 +488,12 @@ def has_mountpoint(partition: Union[dict,Partition,MapperDev], target: str, stri """ # we create the mountpoint list if isinstance(partition,dict): - subvols = partition.get('btrfs',{}).get('subvolumes',{}) - mountpoints = [partition.get('mountpoint'),] + [subvols[subvol] if isinstance(subvols[subvol],str) or not subvols[subvol] else subvols[subvol].get('mountpoint') for subvol in subvols] + subvolumes: List[Subvolume] = partition.get('btrfs',{}).get('subvolumes', []) + mountpoints = [partition.get('mountpoint')] + mountpoints += [volume.mountpoint for volume in subvolumes] else: mountpoints = [partition.mountpoint,] + [subvol.target for subvol in partition.subvolumes] + # we check if strict or target == '/': if target in mountpoints: diff --git a/archinstall/lib/disk/mapperdev.py b/archinstall/lib/disk/mapperdev.py index 913dbc13..49137ae9 100644 --- a/archinstall/lib/disk/mapperdev.py +++ b/archinstall/lib/disk/mapperdev.py @@ -10,7 +10,7 @@ from ..general import SysCommand from ..output import log if TYPE_CHECKING: - from .btrfs import BtrfsSubvolume + from .btrfs import BtrfsSubvolumeInfo @dataclass class MapperDev: @@ -37,12 +37,12 @@ class MapperDev: for slave in glob.glob(f"/sys/class/block/{dm_device.name}/slaves/*"): partition_belonging_to_dmcrypt_device = pathlib.Path(slave).name - + try: uevent_data = SysCommand(f"blkid -o export /dev/{partition_belonging_to_dmcrypt_device}").decode() except SysCallError as error: log(f"Could not get information on device /dev/{partition_belonging_to_dmcrypt_device}: {error}", level=logging.ERROR, fg="red") - + information = uevent(uevent_data) block_device = BlockDevice(get_parent_of_partition('/dev/' / pathlib.Path(information['DEVNAME']))) @@ -75,10 +75,10 @@ class MapperDev: return get_filesystem_type(self.path) @property - def subvolumes(self) -> Iterator['BtrfsSubvolume']: + def subvolumes(self) -> Iterator['BtrfsSubvolumeInfo']: from .btrfs import subvolume_info_from_path for mountpoint in self.mount_information: if target := mountpoint.get('target'): if subvolume := subvolume_info_from_path(pathlib.Path(target)): - yield subvolume \ No newline at end of file + yield subvolume diff --git a/archinstall/lib/disk/partition.py b/archinstall/lib/disk/partition.py index 2c9f50c2..6f25a5f7 100644 --- a/archinstall/lib/disk/partition.py +++ b/archinstall/lib/disk/partition.py @@ -14,7 +14,7 @@ from ..exceptions import DiskError, SysCallError, UnknownFilesystemFormat from ..output import log from ..general import SysCommand from .btrfs.btrfs_helpers import subvolume_info_from_path -from .btrfs.btrfssubvolume import BtrfsSubvolume +from .btrfs.btrfssubvolumeinfo import BtrfsSubvolumeInfo class Partition: def __init__(self, @@ -185,7 +185,7 @@ class Partition: for i in range(storage['DISK_RETRY_ATTEMPTS']): if not self.partprobe(): raise DiskError(f"Could not perform partprobe on {self.device_path}") - + time.sleep(max(0.1, storage['DISK_TIMEOUTS'] * i)) partuuid = self._safe_part_uuid @@ -294,9 +294,9 @@ class Partition: return bind_name @property - def subvolumes(self) -> Iterator[BtrfsSubvolume]: + def subvolumes(self) -> Iterator[BtrfsSubvolumeInfo]: from .helpers import findmnt - + def iterate_children_recursively(information): for child in information.get('children', []): if target := child.get('target'): @@ -452,7 +452,7 @@ class Partition: if retry is True: log(f"Retrying in {storage.get('DISK_TIMEOUTS', 1)} seconds.", level=logging.WARNING, fg="orange") time.sleep(storage.get('DISK_TIMEOUTS', 1)) - + return self.format(filesystem, path, log_formatting, options, retry=False) if get_filesystem_type(path) == 'crypto_LUKS' or get_filesystem_type(self.real_device) == 'crypto_LUKS': diff --git a/archinstall/lib/disk/user_guides.py b/archinstall/lib/disk/user_guides.py index 5fa6bfdc..5809c073 100644 --- a/archinstall/lib/disk/user_guides.py +++ b/archinstall/lib/disk/user_guides.py @@ -3,6 +3,8 @@ import logging from typing import Optional, Dict, Any, List, TYPE_CHECKING # https://stackoverflow.com/a/39757388/929999 +from ..models.subvolume import Subvolume + if TYPE_CHECKING: from .blockdevice import BlockDevice _: Any @@ -107,17 +109,14 @@ def suggest_single_disk_layout(block_device :BlockDevice, # https://unix.stackexchange.com/questions/246976/btrfs-subvolume-uuid-clash # https://github.com/classy-giraffe/easy-arch/blob/main/easy-arch.sh layout[block_device.path]['partitions'][1]['btrfs'] = { - "subvolumes" : { - "@":"/", - "@home": "/home", - "@log": "/var/log", - "@pkg": "/var/cache/pacman/pkg", - "@.snapshots": "/.snapshots" - } + 'subvolumes': [ + Subvolume('@', '/'), + Subvolume('@home', '/home'), + Subvolume('@log', '/var/log'), + Subvolume('@pkg', '/var/cache/pacman/pkg'), + Subvolume('@.snapshots', '/.snapshots') + ] } - # else: - # pass # ... implement a guided setup - elif using_home_partition: # If we don't want to use subvolumes, # But we want to be able to re-use data between re-installs.. diff --git a/archinstall/lib/installer.py b/archinstall/lib/installer.py index bf296c2e..97c2492d 100644 --- a/archinstall/lib/installer.py +++ b/archinstall/lib/installer.py @@ -24,6 +24,7 @@ from .disk.partition import get_mount_fs_type from .exceptions import DiskError, ServiceException, RequirementError, HardwareIncompatibilityError, SysCallError from .hsm import fido2_enroll from .models.users import User +from .models.subvolume import Subvolume if TYPE_CHECKING: _: Any @@ -263,47 +264,25 @@ class Installer: hsm_device_path = storage['arguments']['HSM'] fido2_enroll(hsm_device_path, partition['device_instance'], password) - # we manage the btrfs partitions - if any(btrfs_subvolumes := [entry for entry in list_part if entry.get('btrfs', {}).get('subvolumes', {})]): - for partition in btrfs_subvolumes: - if mount_options := ','.join(partition.get('filesystem',{}).get('mount_options',[])): - self.mount(partition['device_instance'], "/", options=mount_options) - else: - self.mount(partition['device_instance'], "/") - - setup_subvolumes( - installation=self, - partition_dict=partition - ) + btrfs_subvolumes = [entry for entry in list_part if entry.get('btrfs', {}).get('subvolumes', [])] - partition['device_instance'].unmount() + for partition in btrfs_subvolumes: + device_instance = partition['device_instance'] + mount_options = partition.get('filesystem', {}).get('mount_options', []) + self.mount(device_instance, "/", options=','.join(mount_options)) + setup_subvolumes(installation=self, partition_dict=partition) + device_instance.unmount() # We then handle any special cases, such as btrfs - if any(btrfs_subvolumes := [entry for entry in list_part if entry.get('btrfs', {}).get('subvolumes', {})]): - for partition_information in btrfs_subvolumes: - for name, mountpoint in sorted(partition_information['btrfs']['subvolumes'].items(), key=lambda item: item[1]): - btrfs_subvolume_information = {} - - match mountpoint: - case str(): # backwards-compatability - btrfs_subvolume_information['mountpoint'] = mountpoint - btrfs_subvolume_information['options'] = [] - case dict(): - btrfs_subvolume_information['mountpoint'] = mountpoint.get('mountpoint', None) - btrfs_subvolume_information['options'] = mountpoint.get('options', []) - case _: - continue - - if mountpoint_parsed := btrfs_subvolume_information.get('mountpoint'): - # We cache the mount call for later - mount_queue[mountpoint_parsed] = lambda device=partition_information['device_instance'], \ - name=name, \ - subvolume_information=btrfs_subvolume_information: mount_subvolume( - installation=self, - device=device, - name=name, - subvolume_information=subvolume_information - ) + for partition in btrfs_subvolumes: + subvolumes: List[Subvolume] = partition['btrfs']['subvolumes'] + for subvolume in sorted(subvolumes, key=lambda item: item.mountpoint): + # We cache the mount call for later + mount_queue[subvolume.mountpoint] = lambda sub_vol=subvolume, device=partition['device_instance']: mount_subvolume( + installation=self, + device=device, + subvolume=sub_vol + ) # We mount ordinary partitions, and we sort them by the mountpoint for partition in sorted([entry for entry in list_part if entry.get('mountpoint', False)], key=lambda part: part['mountpoint']): diff --git a/archinstall/lib/menu/global_menu.py b/archinstall/lib/menu/global_menu.py index cb61168d..49083517 100644 --- a/archinstall/lib/menu/global_menu.py +++ b/archinstall/lib/menu/global_menu.py @@ -325,22 +325,23 @@ class GlobalMenu(GeneralMenu): def _select_harddrives(self, old_harddrives : list) -> List: harddrives = select_harddrives(old_harddrives) - if len(harddrives) == 0: - prompt = _( - "You decided to skip harddrive selection\nand 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?" - ).format(storage['MOUNT_POINT']) - - choice = Menu(prompt, Menu.yes_no(), default_option=Menu.yes(), skip=False).run() - - if choice.value == Menu.no(): - return self._select_harddrives(old_harddrives) - - # in case the harddrives got changed we have to reset the disk layout as well - if old_harddrives != harddrives: - self._menu_options['disk_layouts'].set_current_selection(None) - storage['arguments']['disk_layouts'] = {} + if harddrives: + if len(harddrives) == 0: + prompt = _( + "You decided to skip harddrive selection\nand 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?" + ).format(storage['MOUNT_POINT']) + + choice = Menu(prompt, Menu.yes_no(), default_option=Menu.yes(), skip=False).run() + + if choice.value == Menu.no(): + return self._select_harddrives(old_harddrives) + + # in case the harddrives got changed we have to reset the disk layout as well + if old_harddrives != harddrives: + self._menu_options['disk_layouts'].set_current_selection(None) + storage['arguments']['disk_layouts'] = {} return harddrives diff --git a/archinstall/lib/menu/list_manager.py b/archinstall/lib/menu/list_manager.py index 7e051528..40d01ce3 100644 --- a/archinstall/lib/menu/list_manager.py +++ b/archinstall/lib/menu/list_manager.py @@ -137,34 +137,35 @@ class ListManager: else: self._default_action = [str(default_action),] - self.header = header if header else None - self.cancel_action = str(_('Cancel')) - self.confirm_action = str(_('Confirm and exit')) - self.separator = '' - self.bottom_list = [self.confirm_action,self.cancel_action] - self.bottom_item = [self.cancel_action] - self.base_actions = base_actions if base_actions else [str(_('Add')),str(_('Copy')),str(_('Edit')),str(_('Delete'))] + self._header = header if header else None + self._cancel_action = str(_('Cancel')) + self._confirm_action = str(_('Confirm and exit')) + self._separator = '' + self._bottom_list = [self._confirm_action, self._cancel_action] + self._bottom_item = [self._cancel_action] + self._base_actions = base_actions if base_actions else [str(_('Add')), str(_('Copy')), str(_('Edit')), str(_('Delete'))] self._original_data = copy.deepcopy(base_list) self._data = copy.deepcopy(base_list) # as refs, changes are immediate + # default values for the null case self.target: Optional[Any] = None self.action = self._null_action - if len(self._data) == 0 and self._null_action: - self._data = self.exec_action(self._data) - def run(self): while True: # this will return a dictionary with the key as the menu entry to be displayed # and the value is the original value from the self._data container + data_formatted = self.reformat(self._data) options = list(data_formatted.keys()) - options.append(self.separator) + + if len(options) > 0: + options.append(self._separator) if self._default_action: options += self._default_action - options += self.bottom_list + options += self._bottom_list system('clear') @@ -174,12 +175,12 @@ class ListManager: sort=False, clear_screen=False, clear_menu_on_exit=False, - header=self.header, + header=self._header, skip_empty_entries=True, skip=False ).run() - if not target.value or target.value in self.bottom_list: + if not target.value or target.value in self._bottom_list: self.action = target break @@ -201,13 +202,13 @@ class ListManager: # Possible enhancement. If run_actions returns false a message line indicating the failure self.run_actions(target.value) - if target.value == self.cancel_action: # TODO dubious + if target.value == self._cancel_action: # TODO dubious return self._original_data # return the original list else: return self._data def run_actions(self,prompt_data=None): - options = self.action_list() + self.bottom_item + options = self.action_list() + self._bottom_item prompt = _("Select an action for < {} >").format(prompt_data if prompt_data else self.target) choice = Menu( prompt, @@ -215,13 +216,13 @@ class ListManager: sort=False, clear_screen=False, clear_menu_on_exit=False, - preset_values=self.bottom_item, + preset_values=self._bottom_item, show_search_hint=False ).run() self.action = choice.value - if self.action and self.action != self.cancel_action: + if self.action and self.action != self._cancel_action: self._data = self.exec_action(self._data) """ @@ -243,7 +244,7 @@ class ListManager: can define alternate action list or customize the list for each item. Executed after any item is selected, contained in self.target """ - return self.base_actions + return self._base_actions def exec_action(self, data: Any): """ diff --git a/archinstall/lib/models/subvolume.py b/archinstall/lib/models/subvolume.py new file mode 100644 index 00000000..34a09227 --- /dev/null +++ b/archinstall/lib/models/subvolume.py @@ -0,0 +1,68 @@ +from dataclasses import dataclass +from typing import List, Any, Dict + + +@dataclass +class Subvolume: + name: str + mountpoint: str + compress: bool = False + nodatacow: bool = False + + def display(self) -> str: + options_str = ','.join(self.options) + return f'{_("Subvolume")}: {self.name:15} {_("Mountpoint")}: {self.mountpoint:20} {_("Options")}: {options_str}' + + @property + def options(self) -> List[str]: + options = [ + 'compress' if self.compress else '', + 'nodatacow' if self.nodatacow else '' + ] + return [o for o in options if len(o)] + + def json(self) -> Dict[str, Any]: + return { + 'name': self.name, + 'mountpoint': self.mountpoint, + 'compress': self.compress, + 'nodatacow': self.nodatacow + } + + @classmethod + def _parse(cls, config_subvolumes: List[Dict[str, Any]]) -> List['Subvolume']: + subvolumes = [] + for entry in config_subvolumes: + if not entry.get('name', None) or not entry.get('mountpoint', None): + continue + + subvolumes.append( + Subvolume( + entry['name'], + entry['mountpoint'], + entry.get('compress', False), + entry.get('nodatacow', False) + ) + ) + + return subvolumes + + @classmethod + def _parse_backwards_compatible(cls, config_subvolumes) -> List['Subvolume']: + subvolumes = [] + for name, mountpoint in config_subvolumes.items(): + if not name or not mountpoint: + continue + + subvolumes.append(Subvolume(name, mountpoint)) + + return subvolumes + + @classmethod + def parse_arguments(cls, config_subvolumes: Any) -> List['Subvolume']: + if isinstance(config_subvolumes, list): + return cls._parse(config_subvolumes) + elif isinstance(config_subvolumes, dict): + return cls._parse_backwards_compatible(config_subvolumes) + + raise ValueError('Unknown disk layout btrfs subvolume format') diff --git a/archinstall/lib/models/users.py b/archinstall/lib/models/users.py index f72cabde..a8feb9ef 100644 --- a/archinstall/lib/models/users.py +++ b/archinstall/lib/models/users.py @@ -27,8 +27,10 @@ class User: } def display(self) -> str: - strength = PasswordStrength.strength(self.password) - password = '*' * len(self.password) + f' ({strength.value})' + password = '*' * (len(self.password) if self.password else 0) + if password: + strength = PasswordStrength.strength(self.password) + password += f' ({strength.value})' return f'{_("Username")}: {self.username:16} {_("Password")}: {password:20} sudo: {str(self.sudo)}' @classmethod diff --git a/archinstall/lib/user_interaction/partitioning_conf.py b/archinstall/lib/user_interaction/partitioning_conf.py index caf5f5df..63b7c7df 100644 --- a/archinstall/lib/user_interaction/partitioning_conf.py +++ b/archinstall/lib/user_interaction/partitioning_conf.py @@ -351,18 +351,16 @@ def manage_new_and_existing_partitions(block_device: 'BlockDevice') -> Dict[str, if partition is not None: if not block_device_struct["partitions"][partition].get('btrfs', {}): block_device_struct["partitions"][partition]['btrfs'] = {} - if not block_device_struct["partitions"][partition]['btrfs'].get('subvolumes', {}): - block_device_struct["partitions"][partition]['btrfs']['subvolumes'] = {} + if not block_device_struct["partitions"][partition]['btrfs'].get('subvolumes', []): + block_device_struct["partitions"][partition]['btrfs']['subvolumes'] = [] prev = block_device_struct["partitions"][partition]['btrfs']['subvolumes'] - result = SubvolumeList(_("Manage btrfs subvolumes for current partition"),prev).run() - if result: - block_device_struct["partitions"][partition]['btrfs']['subvolumes'] = result - else: - del block_device_struct["partitions"][partition]['btrfs'] + result = SubvolumeList(_("Manage btrfs subvolumes for current partition"), prev).run() + block_device_struct["partitions"][partition]['btrfs']['subvolumes'] = result return block_device_struct + def select_encrypted_partitions( title :str, partitions :List[Partition], diff --git a/archinstall/lib/user_interaction/subvolume_config.py b/archinstall/lib/user_interaction/subvolume_config.py index 94e6f5d7..a54ec891 100644 --- a/archinstall/lib/user_interaction/subvolume_config.py +++ b/archinstall/lib/user_interaction/subvolume_config.py @@ -1,155 +1,94 @@ -from typing import Dict, List +from typing import Dict, List, Optional, Any, TYPE_CHECKING from ..menu.list_manager import ListManager from ..menu.menu import MenuSelectionType -from ..menu.selection_menu import Selector, GeneralMenu from ..menu.text_input import TextInput from ..menu import Menu +from ..models.subvolume import Subvolume + +if TYPE_CHECKING: + _: Any -""" -UI classes -""" class SubvolumeList(ListManager): - def __init__(self,prompt,list): - self.ObjectNullAction = None # str(_('Add')) - self.ObjectDefaultAction = str(_('Add')) - super().__init__(prompt,list,None,self.ObjectNullAction,self.ObjectDefaultAction) - - def reformat(self, data: Dict) -> Dict: - def presentation(key :str, value :Dict): - text = _(" Subvolume :{:16}").format(key) - if isinstance(value,str): - text += _(" mounted at {:16}").format(value) - else: - if value.get('mountpoint'): - text += _(" mounted at {:16}").format(value['mountpoint']) - else: - text += (' ' * 28) - - if value.get('options',[]): - text += _(" with option {}").format(', '.join(value['options'])) - return text - - formatted = {presentation(k, v): k for k, v in data.items()} - return {k: v for k, v in sorted(formatted.items(), key=lambda e: e[0])} + def __init__(self, prompt: str, current_volumes: List[Subvolume]): + self._actions = [ + str(_('Add subvolume')), + str(_('Edit subvolume')), + str(_('Delete subvolume')) + ] + super().__init__(prompt, current_volumes, self._actions, self._actions[0]) - def action_list(self): - return super().action_list() + def reformat(self, data: List[Subvolume]) -> Dict[str, Subvolume]: + return {e.display(): e for e in data} - def exec_action(self, data: Dict): - if self.target: - origkey, origval = list(self.target.items())[0] - else: - origkey = None + def action_list(self): + active_user = self.target if self.target else None - if self.action == str(_('Delete')): - del data[origkey] + if active_user is None: + return [self._actions[0]] else: - if self.action == str(_('Add')): - self.target = {} - print(_('\n Fill the desired values for a new subvolume \n')) - with SubvolumeMenu(self.target,self.action) as add_menu: - for elem in ['name','mountpoint','options']: - add_menu.exec_option(elem) - else: - SubvolumeMenu(self.target,self.action).run() + return self._actions[1:] - data.update(self.target) + def _prompt_options(self, editing: Optional[Subvolume] = None) -> List[str]: + preset_options = [] + if editing: + preset_options = editing.options - return data - - -class SubvolumeMenu(GeneralMenu): - def __init__(self,parameters,action=None): - self.data = parameters - self.action = action - self.ds = {} - self.ds['name'] = None - self.ds['mountpoint'] = None - self.ds['options'] = None - if self.data: - origkey,origval = list(self.data.items())[0] - self.ds['name'] = origkey - if isinstance(origval,str): - self.ds['mountpoint'] = origval - else: - self.ds['mountpoint'] = self.data[origkey].get('mountpoint') - self.ds['options'] = self.data[origkey].get('options') - - super().__init__(data_store=self.ds) - - def _setup_selection_menu_options(self): - self._menu_options['name'] = Selector( - str(_('Subvolume name ')), - self._select_subvolume_name if not self.action or self.action in (str(_('Add')), str(_('Copy'))) else None, - mandatory=True, - enabled=True) - - self._menu_options['mountpoint'] = Selector( - str(_('Subvolume mountpoint')), - self._select_subvolume_mount_point if not self.action or self.action in (str(_('Add')),str(_('Edit'))) else None, - enabled=True) - - self._menu_options['options'] = Selector( - str(_('Subvolume options')), - self._select_subvolume_options if not self.action or self.action in (str(_('Add')),str(_('Edit'))) else None, - enabled=True) - - self._menu_options['save'] = Selector( - str(_('Save')), - exec_func=lambda n,v:True, - enabled=True) - - self._menu_options['cancel'] = Selector( - str(_('Cancel')), - # func = lambda pre:True, - exec_func=lambda n,v:self.fast_exit(n), - enabled=True) - - self.cancel_action = 'cancel' - self.save_action = 'save' - self.bottom_list = [self.save_action,self.cancel_action] - - def fast_exit(self,accion): - if self.option(accion).get_selection(): - for item in self.list_options(): - if self.option(item).is_mandatory(): - self.option(item).set_mandatory(False) - return True - - def exit_callback(self): - # we exit without moving data - if self.option(self.cancel_action).get_selection(): - return - if not self.ds['name']: - return - else: - key = self.ds['name'] - value = {} - if self.ds['mountpoint']: - value['mountpoint'] = self.ds['mountpoint'] - if self.ds['options']: - value['options'] = self.ds['options'] - self.data.update({key : value}) - - def _select_subvolume_name(self,value): - return TextInput(str(_("Subvolume name :")),value).run() - - def _select_subvolume_mount_point(self,value): - return TextInput(str(_("Select a mount point :")),value).run() - - def _select_subvolume_options(self,value) -> List[str]: - # def __init__(self, title, p_options, skip=True, multi=False, default_option=None, sort=True): choice = Menu( str(_("Select the desired subvolume options ")), ['nodatacow','compress'], skip=True, - preset_values=value, + preset_values=preset_options, multi=True ).run() if choice.type_ == MenuSelectionType.Selection: - return choice.value + return choice.value # type: ignore return [] + + def _add_subvolume(self, editing: Optional[Subvolume] = None) -> Optional[Subvolume]: + name = TextInput(f'\n\n{_("Subvolume name")}: ', editing.name if editing else '').run() + + if not name: + return None + + mountpoint = TextInput(f'\n{_("Subvolume mountpoint")}: ', editing.mountpoint if editing else '').run() + + if not mountpoint: + return None + + options = self._prompt_options(editing) + + subvolume = Subvolume(name, mountpoint) + subvolume.compress = 'compress' in options + subvolume.nodatacow = 'nodatacow' in options + + return subvolume + + def exec_action(self, data: List[Subvolume]) -> List[Subvolume]: + if self.target: + active_subvolume = self.target + else: + active_subvolume = None + + if self.action == self._actions[0]: # add + new_subvolume = self._add_subvolume() + + if new_subvolume is not None: + # in case a user with the same username as an existing user + # was created we'll replace the existing one + data = [d for d in data if d.name != new_subvolume.name] + data += [new_subvolume] + elif self.action == self._actions[1]: # edit subvolume + new_subvolume = self._add_subvolume(active_subvolume) + + if new_subvolume is not None: + # we'll remove the original subvolume and add the modified version + data = [d for d in data if d.name != active_subvolume.name and d.name != new_subvolume.name] + data += [new_subvolume] + elif self.action == self._actions[2]: # delete + data = [d for d in data if d != active_subvolume] + + return data -- cgit v1.2.3-54-g00ecf From 644b80d0bd1323bdd47be5103a6ac854679ff5e0 Mon Sep 17 00:00:00 2001 From: Daniel Girtler Date: Tue, 7 Jun 2022 18:56:15 +1000 Subject: Don't generate any backup locales files (#1313) Co-authored-by: Daniel Girtler --- archinstall/locales/locales_generator.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'archinstall') diff --git a/archinstall/locales/locales_generator.sh b/archinstall/locales/locales_generator.sh index 9432f83f..cdd5be31 100755 --- a/archinstall/locales/locales_generator.sh +++ b/archinstall/locales/locales_generator.sh @@ -7,6 +7,6 @@ find . -type f -iname "*.py" | xargs xgettext --join-existing --no-location --om for file in $(find locales/ -name "base.po"); do echo "Updating: $file" path=$(dirname $file) - msgmerge --quiet --no-location --width 512 --update $file locales/base.pot + msgmerge --quiet --no-location --width 512 --backup none --update $file locales/base.pot msgfmt -o $path/base.mo $file done -- cgit v1.2.3-54-g00ecf From fd131c8fe956858fef802f8e53a530daa0b5df47 Mon Sep 17 00:00:00 2001 From: Daniel Girtler Date: Tue, 7 Jun 2022 19:00:48 +1000 Subject: Update blockdevice (#1289) * Update blockdevice class Co-authored-by: Daniel Girtler --- .github/workflows/mypy.yaml | 2 +- archinstall/lib/disk/blockdevice.py | 344 +++++++++++++++++------------------- archinstall/lib/disk/filesystem.py | 2 +- archinstall/lib/disk/partition.py | 14 +- archinstall/lib/menu/global_menu.py | 2 +- archinstall/lib/output.py | 4 +- 6 files changed, 177 insertions(+), 191 deletions(-) (limited to 'archinstall') diff --git a/.github/workflows/mypy.yaml b/.github/workflows/mypy.yaml index b0901b38..01d4741f 100644 --- a/.github/workflows/mypy.yaml +++ b/.github/workflows/mypy.yaml @@ -15,4 +15,4 @@ jobs: # one day this will be enabled # run: mypy --strict --module archinstall || exit 0 - name: run mypy - run: mypy --follow-imports=silent archinstall/lib/menu/selection_menu.py archinstall/lib/menu/global_menu.py archinstall/lib/models/network_configuration.py archinstall/lib/menu/list_manager.py archinstall/lib/user_interaction/network_conf.py archinstall/lib/models/users.py archinstall/lib/user_interaction/subvolume_config.py archinstall/lib/disk/btrfs/btrfs_helpers.py archinstall/lib/translation.py + run: mypy --follow-imports=silent archinstall/lib/menu/selection_menu.py archinstall/lib/menu/global_menu.py archinstall/lib/models/network_configuration.py archinstall/lib/menu/list_manager.py archinstall/lib/user_interaction/network_conf.py archinstall/lib/models/users.py archinstall/lib/disk/blockdevice.py archinstall/lib/user_interaction/subvolume_config.py archinstall/lib/disk/btrfs/btrfs_helpers.py archinstall/lib/translation.py diff --git a/archinstall/lib/disk/blockdevice.py b/archinstall/lib/disk/blockdevice.py index c7b69205..4e207bf4 100644 --- a/archinstall/lib/disk/blockdevice.py +++ b/archinstall/lib/disk/blockdevice.py @@ -1,13 +1,11 @@ from __future__ import annotations -import os import json import logging import time -from functools import cached_property -from typing import Optional, Dict, Any, Iterator, Tuple, List, TYPE_CHECKING -# https://stackoverflow.com/a/39757388/929999 -if TYPE_CHECKING: - from .partition import Partition + +from collections import OrderedDict +from dataclasses import dataclass +from typing import Optional, Dict, Any, Iterator, List, TYPE_CHECKING from ..exceptions import DiskError, SysCallError from ..output import log @@ -15,18 +13,44 @@ from ..general import SysCommand from ..storage import storage +if TYPE_CHECKING: + from .partition import Partition + _: Any + + +@dataclass +class BlockSizeInfo: + start: str + end: str + size: str + + +@dataclass +class BlockInfo: + pttype: str + ptuuid: str + size: int + tran: Optional[str] + rota: bool + free_space: Optional[List[BlockSizeInfo]] + + class BlockDevice: def __init__(self, path :str, info :Optional[Dict[str, Any]] = None): if not info: from .helpers import all_blockdevices # If we don't give any information, we need to auto-fill it. # Otherwise any subsequent usage will break. - info = all_blockdevices(partitions=False)[path].info + self.info = all_blockdevices(partitions=False)[path].info + else: + self.info = info - self.path = path - self.info = info + self._path = path self.keep_partitions = True - self.part_cache = {} + self._block_info = self._fetch_information() + self._partitions: Dict[str, 'Partition'] = {} + + self._load_partitions() # TODO: Currently disk encryption is a BIT misleading. # It's actually partition-encryption, but for future-proofing this @@ -35,70 +59,114 @@ class BlockDevice: def __repr__(self, *args :str, **kwargs :str) -> str: return self._str_repr - @cached_property + @property + def path(self) -> str: + return self._path + + @property def _str_repr(self) -> str: - return f"BlockDevice({self.device_or_backfile}, size={self._safe_size}GB, free_space={self._safe_free_space}, bus_type={self.bus_type})" - - @cached_property - def display_info(self) -> str: - columns = { - str(_('Device')): self.device_or_backfile, - str(_('Size')): f'{self._safe_size}GB', - str(_('Free space')): f'{self._safe_free_space}', + return f"BlockDevice({self._device_or_backfile}, size={self.size}GB, free_space={self._safe_free_space()}, bus_type={self.bus_type})" + + def as_json(self) -> Dict[str, Any]: + return { + str(_('Device')): self._device_or_backfile, + str(_('Size')): f'{self.size}GB', + str(_('Free space')): f'{self._safe_free_space()}', str(_('Bus-type')): f'{self.bus_type}' } - padding = max([len(k) for k in columns.keys()]) - - pretty = '' - for k, v in columns.items(): - k = k.ljust(padding, ' ') - pretty += f'{k} = {v}\n' - - return pretty.rstrip() - - def __iter__(self) -> Iterator[Partition]: + def __iter__(self) -> Iterator['Partition']: for partition in self.partitions: yield self.partitions[partition] def __getitem__(self, key :str, *args :str, **kwargs :str) -> Any: if hasattr(self, key): return getattr(self, key) - elif key not in self.info: - raise KeyError(f'{self} does not contain information: "{key}"') - return self.info[key] + + if self.info and key in self.info: + return self.info[key] + + raise KeyError(f'{self.info} does not contain information: "{key}"') def __len__(self) -> int: return len(self.partitions) def __lt__(self, left_comparitor :'BlockDevice') -> bool: - return self.path < left_comparitor.path + return self._path < left_comparitor.path def json(self) -> str: """ json() has precedence over __dump__, so this is a way to give less/partial information for user readability. """ - return self.path + return self._path def __dump__(self) -> Dict[str, Dict[str, Any]]: return { - self.path : { - 'partuuid' : self.uuid, - 'wipe' : self.info.get('wipe', None), - 'partitions' : [part.__dump__() for part in self.partitions.values()] + self._path: { + 'partuuid': self.uuid, + 'wipe': self.info.get('wipe', None), + 'partitions': [part.__dump__() for part in self.partitions.values()] } } - @property - def partition_type(self) -> str: - output = json.loads(SysCommand(f"lsblk --json -o+PTTYPE {self.path}").decode('UTF-8')) + def _call_lsblk(self, path: str) -> Dict[str, Any]: + output = SysCommand(f'lsblk --json -b -o+SIZE,PTTYPE,ROTA,TRAN,PTUUID {self._path}').decode('UTF-8') + if output: + lsblk_info = json.loads(output) + return lsblk_info + + raise DiskError(f'Failed to read disk "{self.path}" with lsblk') + + def _load_partitions(self): + from .partition import Partition - for device in output['blockdevices']: - return device['pttype'] + lsblk_info = self._call_lsblk(self._path) + device = lsblk_info['blockdevices'][0] + self._partitions.clear() - @cached_property - def device_or_backfile(self) -> str: + if children := device.get('children', None): + root = f'/dev/{device["name"]}' + for child in children: + part_id = child['name'].removeprefix(device['name']) + self._partitions[part_id] = Partition(root + part_id, block_device=self, part_id=part_id) + + def _get_free_space(self) -> Optional[List[BlockSizeInfo]]: + # NOTE: parted -s will default to `cancel` on prompt, skipping any partition + # that is "outside" the disk. in /dev/sr0 this is usually the case with Archiso, + # so the free will ignore the ESP partition and just give the "free" space. + # Doesn't harm us, but worth noting in case something weird happens. + try: + output = SysCommand(f"parted -s --machine {self._path} print free").decode('utf-8') + if output: + free_lines = [line for line in output.split('\n') if 'free' in line] + sizes = [] + for free_space in free_lines: + _, start, end, size, *_ = free_space.strip('\r\n;').split(':') + sizes.append(BlockSizeInfo(start, end, size)) + + return sizes + except SysCallError as error: + log(f"Could not get free space on {self._path}: {error}", level=logging.DEBUG) + + return None + + def _fetch_information(self) -> BlockInfo: + lsblk_info = self._call_lsblk(self._path) + device = lsblk_info['blockdevices'][0] + free_space = self._get_free_space() + + return BlockInfo( + pttype=device['pttype'], + ptuuid=device['ptuuid'], + size=device['size'], + tran=device['tran'], + rota=device['rota'], + free_space=free_space + ) + + @property + def _device_or_backfile(self) -> Optional[str]: """ Returns the actual device-endpoint of the BlockDevice. If it's a loop-back-device it returns the back-file, @@ -118,7 +186,7 @@ class BlockDevice: return None @property - def device(self) -> str: + def device(self) -> Optional[str]: """ Returns the device file of the BlockDevice. If it's a loop-back-device it returns the /dev/X device, @@ -126,168 +194,84 @@ class BlockDevice: And if it's a crypto-device it returns the parent device """ if "DEVTYPE" not in self.info: - raise DiskError(f'Could not locate backplane info for "{self.path}"') + raise DiskError(f'Could not locate backplane info for "{self._path}"') if self.info['DEVTYPE'] in ['disk','loop']: - return self.path + return self._path elif self.info['DEVTYPE'][:4] == 'raid': # This should catch /dev/md## raid devices - return self.path + return self._path elif self.info['DEVTYPE'] == 'crypt': if 'pkname' not in self.info: - raise DiskError(f'A crypt device ({self.path}) without a parent kernel device name.') + raise DiskError(f'A crypt device ({self._path}) without a parent kernel device name.') return f"/dev/{self.info['pkname']}" else: - log(f"Unknown blockdevice type for {self.path}: {self.info['DEVTYPE']}", level=logging.DEBUG) + log(f"Unknown blockdevice type for {self._path}: {self.info['DEVTYPE']}", level=logging.DEBUG) - # if not stat.S_ISBLK(os.stat(full_path).st_mode): - # raise DiskError(f'Selected disk "{full_path}" is not a block device.') - - @property - def partitions(self) -> Dict[str, Partition]: - from .filesystem import Partition - - self.partprobe() - result = SysCommand(['/usr/bin/lsblk', '-J', self.path]) - - if b'not a block device' in result: - raise DiskError(f'Can not read partitions off something that isn\'t a block device: {self.path}') - - if not result[:1] == b'{': - raise DiskError('Error getting JSON output from:', f'/usr/bin/lsblk -J {self.path}') - - r = json.loads(result.decode('UTF-8')) - if len(r['blockdevices']) and 'children' in r['blockdevices'][0]: - root_path = f"/dev/{r['blockdevices'][0]['name']}" - for part in r['blockdevices'][0]['children']: - part_id = part['name'][len(os.path.basename(self.path)):] - if part_id not in self.part_cache: - # TODO: Force over-write even if in cache? - if part_id not in self.part_cache or self.part_cache[part_id].size != part['size']: - self.part_cache[part_id] = Partition(root_path + part_id, block_device=self, part_id=part_id) - - return {k: self.part_cache[k] for k in sorted(self.part_cache)} + return None @property - def partition(self) -> Partition: - all_partitions = self.partitions - return [all_partitions[k] for k in all_partitions] + def partition_type(self) -> str: + return self._block_info.pttype @property - def partition_table_type(self) -> int: - # TODO: Don't hardcode :) - # Remove if we don't use this function anywhere - from .filesystem import GPT - return GPT - - @cached_property def uuid(self) -> str: - log('BlockDevice().uuid is untested!', level=logging.WARNING, fg='yellow') - """ - Returns the disk UUID as returned by lsblk. - This is more reliable than relying on /dev/disk/by-partuuid as - it doesn't seam to be able to detect md raid partitions. - """ - return SysCommand(f'blkid -s PTUUID -o value {self.path}').decode('UTF-8') - - @cached_property - def _safe_size(self) -> float: - from .helpers import convert_size_to_gb - - try: - output = json.loads(SysCommand(f"lsblk --json -b -o+SIZE {self.path}").decode('UTF-8')) - except SysCallError: - return -1.0 + return self._block_info.ptuuid - for device in output['blockdevices']: - return convert_size_to_gb(device['size']) - - @cached_property + @property def size(self) -> float: from .helpers import convert_size_to_gb + return convert_size_to_gb(self._block_info.size) - output = json.loads(SysCommand(f"lsblk --json -b -o+SIZE {self.path}").decode('UTF-8')) - - for device in output['blockdevices']: - return convert_size_to_gb(device['size']) - - @cached_property - def bus_type(self) -> str: - output = json.loads(SysCommand(f"lsblk --json -o+ROTA,TRAN {self.path}").decode('UTF-8')) - - for device in output['blockdevices']: - return device['tran'] + @property + def bus_type(self) -> Optional[str]: + return self._block_info.tran - @cached_property + @property def spinning(self) -> bool: - output = json.loads(SysCommand(f"lsblk --json -o+ROTA,TRAN {self.path}").decode('UTF-8')) + return self._block_info.rota - for device in output['blockdevices']: - return device['rota'] is True + @property + def partitions(self) -> Dict[str, 'Partition']: + self._partprobe() + self._load_partitions() + return OrderedDict(sorted(self._partitions.items())) - @cached_property - def _safe_free_space(self) -> Tuple[str, ...]: - try: - return '+'.join(part[2] for part in self.free_space) - except SysCallError: - return '?' + @property + def partition(self) -> List['Partition']: + return list(self.partitions.values()) - @cached_property - def free_space(self) -> Tuple[str, ...]: - # NOTE: parted -s will default to `cancel` on prompt, skipping any partition - # that is "outside" the disk. in /dev/sr0 this is usually the case with Archiso, - # so the free will ignore the ESP partition and just give the "free" space. - # Doesn't harm us, but worth noting in case something weird happens. - try: - for line in SysCommand(f"parted -s --machine {self.path} print free"): - if 'free' in (free_space := line.decode('UTF-8')): - _, start, end, size, *_ = free_space.strip('\r\n;').split(':') - yield (start, end, size) - except SysCallError as error: - log(f"Could not get free space on {self.path}: {error}", level=logging.DEBUG) - - @cached_property - def largest_free_space(self) -> List[str]: - info = [] - for space_info in self.free_space: - if not info: - info = space_info - else: - # [-1] = size - if space_info[-1] > info[-1]: - info = space_info - return info - - @cached_property + @property def first_free_sector(self) -> str: - if info := self.largest_free_space: - start = info[0] + if block_size := self._largest_free_space(): + return block_size.start else: - start = '512MB' - return start + return '512MB' - @cached_property + @property def first_end_sector(self) -> str: - if info := self.largest_free_space: - end = info[1] + if block_size := self._largest_free_space(): + return block_size.end else: - end = f"{self.size}GB" - return end - - def partprobe(self) -> bool: - return SysCommand(['partprobe', self.path]).exit_code == 0 + return f"{self.size}GB" + + def _safe_free_space(self) -> str: + if self._block_info.free_space: + sizes = [free_space.size for free_space in self._block_info.free_space] + return '+'.join(sizes) + return '?' + + def _largest_free_space(self) -> Optional[BlockSizeInfo]: + if self._block_info.free_space: + sorted_sizes = sorted(self._block_info.free_space, key=lambda x: x.size, reverse=True) + return sorted_sizes[0] + return None - def has_partitions(self) -> int: - return len(self.partitions) - - def has_mount_point(self, mountpoint :str) -> bool: - for partition in self.partitions: - if self.partitions[partition].mountpoint == mountpoint: - return True - return False + def _partprobe(self) -> bool: + return SysCommand(['partprobe', self._path]).exit_code == 0 def flush_cache(self) -> None: - self.part_cache = {} + self._load_partitions() def get_partition(self, uuid :Optional[str] = None, partuuid :Optional[str] = None) -> Partition: if not uuid and not partuuid: @@ -296,7 +280,7 @@ class BlockDevice: for count in range(storage.get('DISK_RETRY_ATTEMPTS', 5)): for partition_index, partition in self.partitions.items(): try: - if uuid and partition.uuid.lower() == uuid.lower(): + if uuid and partition.uuid and partition.uuid.lower() == uuid.lower(): return partition elif partuuid and partition.part_uuid.lower() == partuuid.lower(): return partition @@ -308,8 +292,8 @@ class BlockDevice: log(f"uuid {uuid} or {partuuid} not found. Waiting {storage.get('DISK_TIMEOUTS', 1) * count}s for next attempt",level=logging.DEBUG) time.sleep(storage.get('DISK_TIMEOUTS', 1) * count) - + log(f"Could not find {uuid}/{partuuid} in disk after 5 retries", level=logging.INFO) - log(f"Cache: {self.part_cache}") + log(f"Cache: {self._partitions}") log(f"Partitions: {self.partitions.items()}") raise DiskError(f"Partition {uuid}/{partuuid} was never found on {self} despite several attempts.") diff --git a/archinstall/lib/disk/filesystem.py b/archinstall/lib/disk/filesystem.py index cc29a491..1c7a801b 100644 --- a/archinstall/lib/disk/filesystem.py +++ b/archinstall/lib/disk/filesystem.py @@ -100,7 +100,7 @@ class Filesystem: partition['device_instance'] = self.blockdevice.get_partition(uuid=partition_uuid) except DiskError: partition['device_instance'] = self.blockdevice.get_partition(partuuid=partition_uuid) - + log(_("Re-using partition instance: {}").format(partition['device_instance']), level=logging.DEBUG, fg="gray") else: log(f"{self}.load_layout() doesn't know how to work without 'wipe' being set or UUID ({partition.get('PARTUUID')}) was given and found.", fg="yellow", level=logging.WARNING) diff --git a/archinstall/lib/disk/partition.py b/archinstall/lib/disk/partition.py index 6f25a5f7..062c79ab 100644 --- a/archinstall/lib/disk/partition.py +++ b/archinstall/lib/disk/partition.py @@ -175,7 +175,7 @@ class Partition: return device['pttype'] @property - def part_uuid(self) -> Optional[str]: + def part_uuid(self) -> str: """ Returns the PARTUUID as returned by lsblk. This is more reliable than relying on /dev/disk/by-partuuid as @@ -222,7 +222,7 @@ class Partition: For instance when you want to get a __repr__ of the class. """ if not self.partprobe(): - if self.block_device.info.get('TYPE') == 'iso9660': + if self.block_device.partition_type == 'iso9660': return None log(f"Could not reliably refresh PARTUUID of partition {self.device_path} due to partprobe error.", level=logging.DEBUG) @@ -230,7 +230,7 @@ class Partition: try: return SysCommand(f'blkid -s UUID -o value {self.device_path}').decode('UTF-8').strip() except SysCallError as error: - if self.block_device.info.get('TYPE') == 'iso9660': + if self.block_device.partition_type == 'iso9660': # Parent device is a Optical Disk (.iso dd'ed onto a device for instance) return None @@ -244,15 +244,15 @@ class Partition: For instance when you want to get a __repr__ of the class. """ if not self.partprobe(): - if self.block_device.info.get('TYPE') == 'iso9660': + if self.block_device.partition_type == 'iso9660': return None log(f"Could not reliably refresh PARTUUID of partition {self.device_path} due to partprobe error.", level=logging.DEBUG) try: - return SysCommand(f'blkid -s PARTUUID -o value {self.device_path}').decode('UTF-8').strip() + return self.block_device.uuid except SysCallError as error: - if self.block_device.info.get('TYPE') == 'iso9660': + if self.block_device.partition_type == 'iso9660': # Parent device is a Optical Disk (.iso dd'ed onto a device for instance) return None @@ -399,7 +399,7 @@ class Partition: elif filesystem == 'vfat': options = ['-F32'] + options - + log(f"/usr/bin/mkfs.vfat {' '.join(options)} {path}") if (handle := SysCommand(f"/usr/bin/mkfs.vfat {' '.join(options)} {path}")).exit_code != 0: raise DiskError(f"Could not format {path} with {filesystem} because: {handle.decode('UTF-8')}") self.filesystem = filesystem diff --git a/archinstall/lib/menu/global_menu.py b/archinstall/lib/menu/global_menu.py index 49083517..abd652a9 100644 --- a/archinstall/lib/menu/global_menu.py +++ b/archinstall/lib/menu/global_menu.py @@ -240,7 +240,7 @@ class GlobalMenu(GeneralMenu): selector = self._menu_options['harddrives'] if selector.has_selection(): drives = selector.current_selection - return '\n\n'.join([d.display_info for d in drives]) + return FormattedOutput.as_table(drives) return None def _prev_disk_layouts(self) -> Optional[str]: diff --git a/archinstall/lib/output.py b/archinstall/lib/output.py index 29b73bc4..e2b38ce6 100644 --- a/archinstall/lib/output.py +++ b/archinstall/lib/output.py @@ -11,7 +11,9 @@ class FormattedOutput: @classmethod def values(cls, o: Any) -> Dict[str, Any]: - if hasattr(o, 'json'): + if hasattr(o, 'as_json'): + return o.as_json() + elif hasattr(o, 'json'): return o.json() else: return o.__dict__ -- cgit v1.2.3-54-g00ecf From 99a9d3ff375cc5e419a34a6fda847cb62762144d Mon Sep 17 00:00:00 2001 From: Alexmelman88 <99257010+Alexmelman88@users.noreply.github.com> Date: Tue, 7 Jun 2022 12:01:42 +0300 Subject: Updated base.pot, languages.json, global_menu.py, ru locale (#1292) * Add files via upload * Add files via upload * Add files via upload * Add files via upload * Add files via upload --- archinstall/lib/menu/global_menu.py | 4 ++-- archinstall/locales/base.pot | 26 +++++++++++++++++++++++++- archinstall/locales/languages.json | 1 + archinstall/locales/ru/LC_MESSAGES/base.mo | Bin 32928 -> 33402 bytes archinstall/locales/ru/LC_MESSAGES/base.po | 26 +++++++++++++++++++++++++- 5 files changed, 53 insertions(+), 4 deletions(-) (limited to 'archinstall') diff --git a/archinstall/lib/menu/global_menu.py b/archinstall/lib/menu/global_menu.py index abd652a9..b73fb48f 100644 --- a/archinstall/lib/menu/global_menu.py +++ b/archinstall/lib/menu/global_menu.py @@ -296,10 +296,10 @@ class GlobalMenu(GeneralMenu): if not check('!root-password') and not has_superuser(): missing += [str(_('Either root-password or at least 1 user with sudo privileges must be specified'))] if not check('harddrives'): - missing += ['Hard drives'] + missing += [str(_('Drive(s)'))] if check('harddrives'): if not self._menu_options['harddrives'].is_empty() and not check('disk_layouts'): - missing += ['Disk layout'] + missing += [str(_('Disk layout'))] return missing diff --git a/archinstall/locales/base.pot b/archinstall/locales/base.pot index 6db91789..54ddbba3 100644 --- a/archinstall/locales/base.pot +++ b/archinstall/locales/base.pot @@ -652,7 +652,7 @@ msgid "" msgstr "" msgid "" -"Choose which servers to install, if none then a minimal installation wil be " +"Choose which servers to install, if none then a minimal installation will be " "done" msgstr "" @@ -760,3 +760,27 @@ msgstr "" msgid "Should \"{}\" be a superuser (sudo)?" msgstr "" + +msgid "Select which partitions to encrypt:" +msgstr "" + +msgid "very weak" +msgstr "" + +msgid "weak" +msgstr "" + +msgid "moderate" +msgstr "" + +msgid "strong" +msgstr "" + +msgid "Add subvolume" +msgstr "" + +msgid "Edit subvolume" +msgstr "" + +msgid "Delete subvolume" +msgstr "" diff --git a/archinstall/locales/languages.json b/archinstall/locales/languages.json index bf076f94..c3c9d2c2 100644 --- a/archinstall/locales/languages.json +++ b/archinstall/locales/languages.json @@ -128,6 +128,7 @@ {"abbr": "pi", "lang": "Pali"}, {"abbr": "pl", "lang": "Polish"}, {"abbr": "pt", "lang": "Portuguese"}, + {"abbr": "pt_BR", "lang": "Brazilian Portuguese"}, {"abbr": "ps", "lang": "Pushto"}, {"abbr": "qu", "lang": "Quechua"}, {"abbr": "rm", "lang": "Romansh"}, diff --git a/archinstall/locales/ru/LC_MESSAGES/base.mo b/archinstall/locales/ru/LC_MESSAGES/base.mo index be3405fe..8c0dc224 100644 Binary files a/archinstall/locales/ru/LC_MESSAGES/base.mo and b/archinstall/locales/ru/LC_MESSAGES/base.mo differ diff --git a/archinstall/locales/ru/LC_MESSAGES/base.po b/archinstall/locales/ru/LC_MESSAGES/base.po index 27f86e23..5a6f440a 100644 --- a/archinstall/locales/ru/LC_MESSAGES/base.po +++ b/archinstall/locales/ru/LC_MESSAGES/base.po @@ -771,7 +771,7 @@ msgstr "" "например, httpd, nginx, mariadb" msgid "" -"Choose which servers to install, if none then a minimal installation wil be " +"Choose which servers to install, if none then a minimal installation will be " "done" msgstr "" "Выберите серверы для установки, если их нет, то будет выполнена минимальная " @@ -897,6 +897,30 @@ msgstr "Введенное вами имя пользователя недейс msgid "Should \"{}\" be a superuser (sudo)?" msgstr "Должен ли \"{}\" быть суперпользователем (sudo)?" +msgid "Select which partitions to encrypt:" +msgstr "Выберите разделы для шифрования:" + +msgid "very weak" +msgstr "очень слабый" + +msgid "weak" +msgstr "слабый" + +msgid "moderate" +msgstr "умеренный" + +msgid "strong" +msgstr "надежный" + +msgid "Add subvolume" +msgstr "Добавить подтом" + +msgid "Edit subvolume" +msgstr "Редактировать подтом" + +msgid "Delete subvolume" +msgstr "Удалить подтом" + #, python-brace-format #~ msgid "Edit {origkey} :" #~ msgstr "Редактировать {origkey}:" -- cgit v1.2.3-54-g00ecf From c26200d5f106557f46d4cbf938d5eba8f9d55704 Mon Sep 17 00:00:00 2001 From: Franco Castillo Date: Tue, 7 Jun 2022 06:01:57 -0300 Subject: Update Spanish translation (#1293) * Update Spanish translation Signed-off-by: Franco Castillo * Update Spanish translation Signed-off-by: Franco Castillo --- archinstall/locales/es/LC_MESSAGES/base.mo | Bin 24891 -> 24988 bytes archinstall/locales/es/LC_MESSAGES/base.po | 51 +++++++++++++++-------------- 2 files changed, 27 insertions(+), 24 deletions(-) (limited to 'archinstall') diff --git a/archinstall/locales/es/LC_MESSAGES/base.mo b/archinstall/locales/es/LC_MESSAGES/base.mo index 08b79e92..d5efa958 100644 Binary files a/archinstall/locales/es/LC_MESSAGES/base.mo and b/archinstall/locales/es/LC_MESSAGES/base.mo differ diff --git a/archinstall/locales/es/LC_MESSAGES/base.po b/archinstall/locales/es/LC_MESSAGES/base.po index 58afcbc3..0373a40d 100644 --- a/archinstall/locales/es/LC_MESSAGES/base.po +++ b/archinstall/locales/es/LC_MESSAGES/base.po @@ -21,7 +21,7 @@ msgid "Do you really want to abort?" msgstr "¿Realmente desea abortar?" msgid "And one more time for verification: " -msgstr "Una última vez para verificación: " +msgstr "Una vez más para verificar: " msgid "Would you like to use swap on zram?" msgstr "¿Te gustaría usar swap en zram?" @@ -33,7 +33,7 @@ msgid "Username for required superuser with sudo privileges: " msgstr "Nombre de usuario para el superusuario con privilegios sudo: " msgid "Any additional users to install (leave blank for no users): " -msgstr "Algún usuario adicional a instalar (deje en blanco para no agregar ninguno): " +msgstr "Algún usuario adicional a instalar (déjelo en blanco para no agregar ninguno): " msgid "Should this user be a superuser (sudoer)?" msgstr "Debería este usuario ser un superusuario (sudoer)?" @@ -45,10 +45,10 @@ msgid "Would you like to use GRUB as a bootloader instead of systemd-boot?" msgstr "Te gustaría usar GRUB como gestor de arranque en lugar de systemd-boot?" msgid "Choose a bootloader" -msgstr "Elige un gestor de arranque" +msgstr "Elija un gestor de arranque" msgid "Choose an audio server" -msgstr "Elige un servidor de audio" +msgstr "Elija un servidor de audio" msgid "Only packages such as base, base-devel, linux, linux-firmware, efibootmgr and optional profile packages are installed." msgstr "Solo paquetes como base, base-devel, linux, linux-firmware, efibootmgr y paquetes opcionales de perfil se instalan." @@ -66,7 +66,7 @@ msgid "Use NetworkManager (necessary to configure internet graphically in GNOME msgstr "Usar NetworkManager (necesario para configurar internet gráficamente en GNOME y KDE)" msgid "Select one network interface to configure" -msgstr "Selecciona una interfaz de red para configurar" +msgstr "Seleccione una interfaz de red para configurar" msgid "Select which mode to configure for \"{}\" or skip to use default mode \"{}\"" msgstr "Seleccione qué modo configurar para \"{}\" o salte para usar el modo predeterminado \"{}\"" @@ -75,13 +75,13 @@ msgid "Enter the IP and subnet for {} (example: 192.168.0.5/24): " msgstr "Escriba la IP y subred para {} (ejemplo: 192.168.0.5/24): " msgid "Enter your gateway (router) IP address or leave blank for none: " -msgstr "Escriba la IP de su puerta de enlace (enrutador) o deje en blanco para no usar ninguna: " +msgstr "Escriba la IP de su puerta de enlace (enrutador) o déjelo en blanco para no usar ninguna: " msgid "Enter your DNS servers (space separated, blank for none): " -msgstr "Escriba los servidores DNS (separados por espacios, en blanco para no usar ninguno): " +msgstr "Ingrese sus servidores DNS (separados por espacios, en blanco para ninguno): " msgid "Select which filesystem your main partition should use" -msgstr "Selecciona el sistema de archivos que su partición principal debe usar" +msgstr "Seleccione qué sistema de archivos debe usar su partición principal" msgid "Current partition layout" msgstr "Distribución actual de las particiones" @@ -90,17 +90,17 @@ msgid "" "Select what to do with\n" "{}" msgstr "" -"Selecciona qué hacer con\n" +"Seleccione qué hacer con\n" "{}" msgid "Enter a desired filesystem type for the partition" msgstr "Ingrese un tipo de sistema de archivos deseado para la partición" msgid "Enter the start sector (percentage or block number, default: {}): " -msgstr "Escriba el sector de inicio (porcentaje o número de bloque, por defecto: {}): " +msgstr "Introduzca el sector de inicio (porcentaje o número de bloque, predeterminado: {}): " msgid "Enter the end sector of the partition (percentage or block number, ex: {}): " -msgstr "Escriba el sector final de la partición (porcentaje o número de bloque, ej: {}): " +msgstr "Ingrese el sector final de la partición (porcentaje o número de bloque, ej: {}): " msgid "{} contains queued partitions, this will remove those, are you sure?" msgstr "{} contiene particiones en cola, esto eliminará esas particiones, ¿estás seguro?" @@ -112,7 +112,7 @@ msgid "" msgstr "" "{}\n" "\n" -"Selecciona por índice las particiones a eliminar" +"Seleccione por índice qué particiones eliminar" msgid "" "{}\n" @@ -121,13 +121,13 @@ msgid "" msgstr "" "{}\n" "\n" -"Selecciona por índice la ubicación de la partición a montar" +"Seleccione por índice la ubicación de la partición a montar" msgid " * Partition mount-points are relative to inside the installation, the boot would be /boot as an example." msgstr " * Los puntos de montaje de partición son relativos a la instalación, el arranque sería /boot como ejemplo." msgid "Select where to mount partition (leave blank to remove mountpoint): " -msgstr "Seleccione dónde montar la partición (deja en blanco para eliminar el punto de montaje): " +msgstr "Seleccione dónde montar la partición (déjelo en blanco para eliminar el punto de montaje): " msgid "" "{}\n" @@ -166,7 +166,7 @@ msgstr "" "Seleccione en qué partición establecer un sistema de archivos" msgid "Enter a desired filesystem type for the partition: " -msgstr "Escriba el tipo de sistema de archivos que desea para la partición: " +msgstr "Ingrese un tipo de sistema de archivos deseado para la partición: " msgid "Archinstall language" msgstr "Idioma de Archinstall" @@ -193,13 +193,13 @@ msgid "Select one or more hard drives to use and configure" msgstr "Seleccione uno o más discos duros para usar y configurar" msgid "For the best compatibility with your AMD hardware, you may want to use either the all open-source or AMD / ATI options." -msgstr "Para la mejor compatibilidad con tu hardware AMD, puedes querer usar tanto la opción de todo código abierto como la opción AMD / ATI." +msgstr "Para obtener la mejor compatibilidad con su hardware AMD, es posible que desee utilizar las opciones de código abierto o 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 "Para la mejor compatibilidad con tu hardware Intel, puedes querer usar tanto la opción de todo código abierto como la opción Intel.\n" +msgstr "Para obtener la mejor compatibilidad con su hardware Intel, es posible que desee utilizar las opciones de código abierto o de Intel.\n" msgid "For the best compatibility with your Nvidia hardware, you may want to use the Nvidia proprietary driver.\n" -msgstr "Para la mejor compatibilidad con tu hardware Nvidia, puedes querer usar el controlador propietario Nvidia.\n" +msgstr "Para obtener la mejor compatibilidad con su hardware de Nvidia, es posible que desee utilizar el controlador patentado de Nvidia.\n" msgid "" "\n" @@ -211,16 +211,16 @@ msgstr "" "Seleccione un controlador de gráficos o déjelo en blanco para instalar todos los controladores de código abierto" msgid "All open-source (default)" -msgstr "Todo de código abierto (predeterminado)" +msgstr "Todos de código abierto (predeterminado)" msgid "Choose which kernels to use or leave blank for default \"{}\"" -msgstr "Elige qué kernels usar o deja en blanco para usar los por defecto \"{}\"" +msgstr "Elija qué kernel usar o déjelo en blanco para usar el kernel \"{}\" predeterminado" msgid "Choose which locale language to use" -msgstr "Elige qué idioma local usar" +msgstr "Elija qué idioma local usar" msgid "Choose which locale encoding to use" -msgstr "Elige qué codificación local usar" +msgstr "Elija qué codificación local usar" msgid "Select one of the values shown below: " msgstr "Seleccione uno de los valores que se muestran a continuación: " @@ -232,7 +232,7 @@ msgid "Adding partition...." msgstr "Añadiendo partición..." msgid "You need to enter a valid fs-type in order to continue. See `man parted` for valid fs-type's." -msgstr "Necesitas ingresar un tip de filesystem valido para continuar. Vea `man parted` para tipos de sistemas de archivos válidos." +msgstr "Debe ingresar un tipo de fs válido para continuar. Consulte `man parted` para conocer los tipos de fs válidos." msgid "Error: Listing profiles on URL \"{}\" resulted in:" msgstr "Error: Enlistar perfiles en la URL \"{}\" resultó en:" @@ -265,7 +265,7 @@ msgid "Swap" msgstr "Swap" msgid "Bootloader" -msgstr "Cargador de arranque" +msgstr "Gestor de arranque" msgid "Root password" msgstr "Contraseña de root" @@ -761,6 +761,9 @@ msgstr "El nombre de usuario que ingresó no es válido. Intente nuevamente" msgid "Should \"{}\" be a superuser (sudo)?" msgstr "¿Debe \"{}\" ser un superusuario (sudo)?" +msgid "Select which partitions to encrypt:" +msgstr "Seleccione qué particiones cifrar:" + #~ msgid "Select disk layout" #~ msgstr "Seleccione el diseño del disco" -- cgit v1.2.3-54-g00ecf From aec86eb04e96f4c178cf89f7e72a257d12019fdc Mon Sep 17 00:00:00 2001 From: Daniel Girtler Date: Tue, 7 Jun 2022 20:15:39 +1000 Subject: Fix disk layout display (#1314) Co-authored-by: Daniel Girtler --- .../lib/user_interaction/partitioning_conf.py | 32 ++++++++++++++++++---- 1 file changed, 27 insertions(+), 5 deletions(-) (limited to 'archinstall') diff --git a/archinstall/lib/user_interaction/partitioning_conf.py b/archinstall/lib/user_interaction/partitioning_conf.py index 63b7c7df..0f4784b6 100644 --- a/archinstall/lib/user_interaction/partitioning_conf.py +++ b/archinstall/lib/user_interaction/partitioning_conf.py @@ -5,7 +5,7 @@ from typing import List, Any, Dict, Union, TYPE_CHECKING, Callable, Optional from ..menu import Menu from ..menu.menu import MenuSelectionType -from ..output import log +from ..output import log, FormattedOutput from ..disk.validators import fs_types @@ -28,16 +28,31 @@ def current_partition_layout(partitions: List[Dict[str, Any]], with_idx: bool = pad_right = spaces - pad_left return f'{pad_right * " "}{name}{pad_left * " "}|' + def flatten_data(data: Dict[str, Any]) -> Dict[str, Any]: + flattened = {} + for k, v in data.items(): + if k == 'filesystem': + flat = flatten_data(v) + flattened.update(flat) + elif k == 'btrfs': + # we're going to create a separate table for the btrfs subvolumes + pass + else: + flattened[k] = v + return flattened + + display_data: List[Dict[str, Any]] = [flatten_data(entry) for entry in partitions] + column_names = {} # this will add an initial index to the table for each partition if with_idx: - column_names['index'] = max([len(str(len(partitions))), len('index')]) + column_names['index'] = max([len(str(len(display_data))), len('index')]) # determine all attribute names and the max length - # of the value among all partitions to know the width + # of the value among all display_data to know the width # of the table cells - for p in partitions: + for p in display_data: for attribute, value in p.items(): if attribute in column_names.keys(): column_names[attribute] = max([column_names[attribute], len(str(value)), len(attribute)]) @@ -50,7 +65,7 @@ def current_partition_layout(partitions: List[Dict[str, Any]], with_idx: bool = current_layout = f'{current_layout[:-1]}\n{"-" * len(current_layout)}\n' - for idx, p in enumerate(partitions): + for idx, p in enumerate(display_data): row = '' for name, max_len in column_names.items(): if name == 'index': @@ -62,6 +77,13 @@ def current_partition_layout(partitions: List[Dict[str, Any]], with_idx: bool = current_layout += f'{row[:-1]}\n' + # we'll create a separate table for the btrfs subvolumes + btrfs_subvolumes = [partition['btrfs']['subvolumes'] for partition in partitions if partition.get('btrfs', None)] + if len(btrfs_subvolumes) > 0: + for subvolumes in btrfs_subvolumes: + output = FormattedOutput.as_table(subvolumes) + current_layout += f'\n{output}' + if with_title: title = str(_('Current partition layout')) return f'\n\n{title}:\n\n{current_layout}' -- cgit v1.2.3-54-g00ecf From 0bdb46f3081aaed095f87e35b18b3714d8782ed1 Mon Sep 17 00:00:00 2001 From: Daniel Girtler Date: Thu, 9 Jun 2022 22:54:12 +1000 Subject: Fancy user interface (#1320) * Display submenus as tables * Update * Update * Update * Update Co-authored-by: Daniel Girtler --- archinstall/lib/menu/global_menu.py | 16 +- archinstall/lib/menu/list_manager.py | 100 +++--- archinstall/lib/menu/menu.py | 21 +- archinstall/lib/models/network_configuration.py | 67 ++-- .../lib/user_interaction/manage_users_conf.py | 42 ++- archinstall/lib/user_interaction/network_conf.py | 96 +++--- .../lib/user_interaction/subvolume_config.py | 24 +- archinstall/locales/base.pot | 2 +- archinstall/locales/cs/LC_MESSAGES/base.mo | Bin 23958 -> 23739 bytes archinstall/locales/cs/LC_MESSAGES/base.po | 52 +++- archinstall/locales/de/LC_MESSAGES/base.mo | Bin 23664 -> 23285 bytes archinstall/locales/de/LC_MESSAGES/base.po | 81 ++++- archinstall/locales/en/LC_MESSAGES/base.po | 61 +++- archinstall/locales/es/LC_MESSAGES/base.mo | Bin 24988 -> 24797 bytes archinstall/locales/es/LC_MESSAGES/base.po | 30 +- archinstall/locales/fr/LC_MESSAGES/base.mo | Bin 25735 -> 25482 bytes archinstall/locales/fr/LC_MESSAGES/base.po | 342 +++++++-------------- archinstall/locales/it/LC_MESSAGES/base.mo | Bin 23979 -> 23841 bytes archinstall/locales/it/LC_MESSAGES/base.po | 52 +++- archinstall/locales/nl/LC_MESSAGES/base.mo | Bin 18181 -> 18002 bytes archinstall/locales/nl/LC_MESSAGES/base.po | 80 ++++- archinstall/locales/pl/LC_MESSAGES/base.mo | Bin 22542 -> 22346 bytes archinstall/locales/pl/LC_MESSAGES/base.po | 67 +++- archinstall/locales/pt/LC_MESSAGES/base.mo | Bin 16887 -> 16667 bytes archinstall/locales/pt/LC_MESSAGES/base.po | 80 ++++- archinstall/locales/pt_BR/LC_MESSAGES/base.mo | Bin 23641 -> 23362 bytes archinstall/locales/pt_BR/LC_MESSAGES/base.po | 280 ++++++++--------- archinstall/locales/ru/LC_MESSAGES/base.mo | Bin 33402 -> 33398 bytes archinstall/locales/ru/LC_MESSAGES/base.po | 4 +- archinstall/locales/sv/LC_MESSAGES/base.mo | Bin 23439 -> 23045 bytes archinstall/locales/sv/LC_MESSAGES/base.po | 81 ++++- archinstall/locales/tr/LC_MESSAGES/base.mo | Bin 24972 -> 24757 bytes archinstall/locales/tr/LC_MESSAGES/base.po | 330 ++++++++------------ archinstall/locales/ur/LC_MESSAGES/base.mo | Bin 21216 -> 20880 bytes archinstall/locales/ur/LC_MESSAGES/base.po | 80 ++++- 35 files changed, 1184 insertions(+), 804 deletions(-) (limited to 'archinstall') diff --git a/archinstall/lib/menu/global_menu.py b/archinstall/lib/menu/global_menu.py index b73fb48f..1a292476 100644 --- a/archinstall/lib/menu/global_menu.py +++ b/archinstall/lib/menu/global_menu.py @@ -163,7 +163,8 @@ class GlobalMenu(GeneralMenu): Selector( _('Network configuration'), ask_to_configure_network, - display_func=lambda x: self._prev_network_configuration(x), + display_func=lambda x: self._display_network_conf(x), + preview_func=self._prev_network_config, default={}) self._menu_options['timezone'] = \ Selector( @@ -226,16 +227,23 @@ class GlobalMenu(GeneralMenu): return _('Install ({} config(s) missing)').format(missing) return _('Install') - def _prev_network_configuration(self, cur_value: Union[NetworkConfiguration, List[NetworkConfiguration]]) -> str: + def _display_network_conf(self, cur_value: Union[NetworkConfiguration, List[NetworkConfiguration]]) -> str: if not cur_value: return _('Not configured, unavailable unless setup manually') else: if isinstance(cur_value, list): - ifaces = [x.iface for x in cur_value] - return f'Configured ifaces: {ifaces}' + return str(_('Configured {} interfaces')).format(len(cur_value)) else: return str(cur_value) + def _prev_network_config(self) -> Optional[str]: + selector = self._menu_options['nic'] + if selector.has_selection(): + ifaces = selector.current_selection + if isinstance(ifaces, list): + return FormattedOutput.as_table(ifaces) + return None + def _prev_harddrives(self) -> Optional[str]: selector = self._menu_options['harddrives'] if selector.has_selection(): diff --git a/archinstall/lib/menu/list_manager.py b/archinstall/lib/menu/list_manager.py index 40d01ce3..fe491caa 100644 --- a/archinstall/lib/menu/list_manager.py +++ b/archinstall/lib/menu/list_manager.py @@ -86,7 +86,7 @@ The contents in the base class of this methods serve for a very basic usage, and """ import copy from os import system -from typing import Union, Any, TYPE_CHECKING, Dict, Optional +from typing import Union, Any, TYPE_CHECKING, Dict, Optional, Tuple, List from .text_input import TextInput from .menu import Menu @@ -135,9 +135,9 @@ class ListManager: elif isinstance(default_action,(list,tuple)): self._default_action = default_action else: - self._default_action = [str(default_action),] + self._default_action = [str(default_action)] - self._header = header if header else None + self._header = header if header else '' self._cancel_action = str(_('Cancel')) self._confirm_action = str(_('Confirm and exit')) self._separator = '' @@ -155,61 +155,81 @@ class ListManager: while True: # this will return a dictionary with the key as the menu entry to be displayed # and the value is the original value from the self._data container - data_formatted = self.reformat(self._data) - options = list(data_formatted.keys()) - - if len(options) > 0: - options.append(self._separator) + options, header = self._prepare_selection(data_formatted) - if self._default_action: - options += self._default_action + menu_header = self._header - options += self._bottom_list + if header: + menu_header += header system('clear') - target = Menu( + choice = Menu( self._prompt, options, sort=False, clear_screen=False, clear_menu_on_exit=False, - header=self._header, + header=header, skip_empty_entries=True, - skip=False + skip=False, + show_search_hint=False ).run() - if not target.value or target.value in self._bottom_list: - self.action = target + if not choice.value or choice.value in self._bottom_list: + self.action = choice break - if target.value and target.value in self._default_action: - self.action = target.value + if choice.value and choice.value in self._default_action: + self.action = choice.value self.target = None self._data = self.exec_action(self._data) continue - if isinstance(self._data,dict): - data_key = data_formatted[target.value] + if isinstance(self._data, dict): + data_key = data_formatted[choice.value] key = self._data[data_key] self.target = {data_key: key} elif isinstance(self._data, list): - self.target = [d for d in self._data if d == data_formatted[target.value]][0] + self.target = [d for d in self._data if d == data_formatted[choice.value]][0] else: - self.target = self._data[data_formatted[target.value]] + self.target = self._data[data_formatted[choice.value]] # Possible enhancement. If run_actions returns false a message line indicating the failure - self.run_actions(target.value) + self.run_actions(choice.value) - if target.value == self._cancel_action: # TODO dubious + if choice.value == self._cancel_action: return self._original_data # return the original list else: return self._data - def run_actions(self,prompt_data=None): + def _prepare_selection(self, data_formatted: Dict[str, Any]) -> Tuple[List[str], str]: + # header rows are mapped to None so make sure + # to exclude those from the selectable data + options: List[str] = [key for key, val in data_formatted.items() if val is not None] + header = '' + + if len(options) > 0: + table_header = [key for key, val in data_formatted.items() if val is None] + header = '\n'.join(table_header) + + if len(options) > 0: + options.append(self._separator) + + if self._default_action: + # done only for mypy -> todo fix the self._default_action declaration + options += [action for action in self._default_action if action] + + options += self._bottom_list + return options, header + + def run_actions(self,prompt_data=''): options = self.action_list() + self._bottom_item - prompt = _("Select an action for < {} >").format(prompt_data if prompt_data else self.target) + display_value = self.selected_action_display(self.target) if self.target else prompt_data + + prompt = _("Select an action for '{}'").format(display_value) + choice = Menu( prompt, options, @@ -225,26 +245,28 @@ class ListManager: if self.action and self.action != self._cancel_action: self._data = self.exec_action(self._data) - """ - The following methods are expected to be overwritten by the user if the needs of the list are beyond the simple case - """ + def selected_action_display(self, selection: Any) -> str: + # this will return the value to be displayed in the + # "Select an action for '{}'" string + raise NotImplementedError('Please implement me in the child class') - def reformat(self, data: Any) -> Dict[str, Any]: - """ - method to get the data in a format suitable to be shown - It is executed once for run loop and processes the whole self._data structure - """ - if isinstance(data,dict): - return {f'{k}: {v}': k for k, v in data.items()} - else: - return {str(k): k for k in data} + def reformat(self, data: List[Any]) -> Dict[str, Any]: + # this should return a dictionary of display string to actual data entry + # mapping; if the value for a given display string is None it will be used + # in the header value (useful when displaying tables) + raise NotImplementedError('Please implement me in the child class') def action_list(self): """ can define alternate action list or customize the list for each item. Executed after any item is selected, contained in self.target """ - return self._base_actions + active_entry = self.target if self.target else None + + if active_entry is None: + return [self._base_actions[0]] + else: + return self._base_actions[1:] def exec_action(self, data: Any): """ diff --git a/archinstall/lib/menu/menu.py b/archinstall/lib/menu/menu.py index 3a26f6e7..80982db0 100644 --- a/archinstall/lib/menu/menu.py +++ b/archinstall/lib/menu/menu.py @@ -1,5 +1,6 @@ from dataclasses import dataclass from enum import Enum, auto +from os import system from typing import Dict, List, Union, Any, TYPE_CHECKING, Optional from archinstall.lib.menu.simple_menu import TerminalMenu @@ -57,7 +58,11 @@ class Menu(TerminalMenu): header :Union[List[str],str] = None, explode_on_interrupt :bool = False, explode_warning :str = '', - **kwargs + clear_screen: bool = True, + show_search_hint: bool = True, + cycle_cursor: bool = True, + clear_menu_on_exit: bool = True, + skip_empty_entries: bool = False ): """ Creates a new menu @@ -153,8 +158,7 @@ class Menu(TerminalMenu): if header: if not isinstance(header,(list,tuple)): header = [header] - header = '\n'.join(header) - menu_title += f'\n{header}\n' + menu_title += '\n'.join(header) action_info = '' if skip: @@ -178,10 +182,6 @@ class Menu(TerminalMenu): cursor = "> " main_menu_cursor_style = ("fg_cyan", "bold") main_menu_style = ("bg_blue", "fg_gray") - # defaults that can be changed up the stack - kwargs['clear_screen'] = kwargs.get('clear_screen',True) - kwargs['show_search_hint'] = kwargs.get('show_search_hint',True) - kwargs['cycle_cursor'] = kwargs.get('cycle_cursor',True) super().__init__( menu_entries=self._menu_options, @@ -200,7 +200,11 @@ class Menu(TerminalMenu): preview_title=preview_title, explode_on_interrupt=self._explode_on_interrupt, multi_select_select_on_accept=False, - **kwargs, + clear_screen=clear_screen, + show_search_hint=show_search_hint, + cycle_cursor=cycle_cursor, + clear_menu_on_exit=clear_menu_on_exit, + skip_empty_entries=skip_empty_entries ) def _show(self) -> MenuSelection: @@ -238,6 +242,7 @@ class Menu(TerminalMenu): return self.run() if ret.type_ is not MenuSelectionType.Selection and not self._skip: + system('clear') return self.run() return ret diff --git a/archinstall/lib/models/network_configuration.py b/archinstall/lib/models/network_configuration.py index 4f135da5..e026e97b 100644 --- a/archinstall/lib/models/network_configuration.py +++ b/archinstall/lib/models/network_configuration.py @@ -39,8 +39,22 @@ class NetworkConfiguration: else: return 'Unknown type' - # for json serialization when calling json.dumps(...) on this class - def json(self): + def as_json(self) -> Dict: + exclude_fields = ['type'] + data = {} + for k, v in self.__dict__.items(): + if k not in exclude_fields: + if isinstance(v, list) and len(v) == 0: + v = '' + elif v is None: + v = '' + + data[k] = v + + return data + + def json(self) -> Dict: + # for json serialization when calling json.dumps(...) on this class return self.__dict__ def is_iso(self) -> bool: @@ -111,19 +125,10 @@ class NetworkConfigurationHandler: else: # not recognized return None - def _parse_manual_config(self, config: Dict[str, Any]) -> Union[None, List[NetworkConfiguration]]: - manual_configs: List = config.get('config', []) - - if not manual_configs: - return None - - if not isinstance(manual_configs, list): - log(_('Manual configuration setting must be a list')) - exit(1) - + def _parse_manual_config(self, configs: List[Dict[str, Any]]) -> Optional[List[NetworkConfiguration]]: configurations = [] - for manual_config in manual_configs: + for manual_config in configs: iface = manual_config.get('iface', None) if iface is None: @@ -135,7 +140,7 @@ class NetworkConfigurationHandler: NetworkConfiguration(NicType.MANUAL, iface=iface) ) else: - ip = config.get('ip', '') + ip = manual_config.get('ip', '') if not ip: log(_('Manual nic configuration with no auto DHCP requires an IP address'), fg='red') exit(1) @@ -145,32 +150,34 @@ class NetworkConfigurationHandler: NicType.MANUAL, iface=iface, ip=ip, - gateway=config.get('gateway', ''), - dns=config.get('dns', []), + gateway=manual_config.get('gateway', ''), + dns=manual_config.get('dns', []), dhcp=False ) ) return configurations - def parse_arguments(self, config: Any): - nic_type = config.get('type', None) - - if not nic_type: - # old style definitions - network_config = self._backwards_compability_config(config) - if network_config: - return network_config - return None - + def _parse_nic_type(self, nic_type: str) -> NicType: try: - type_ = NicType(nic_type) + return NicType(nic_type) except ValueError: options = [e.value for e in NicType] log(_('Unknown nic type: {}. Possible values are {}').format(nic_type, options), fg='red') exit(1) - if type_ != NicType.MANUAL: - self._configuration = NetworkConfiguration(type_) - else: # manual configuration settings + def parse_arguments(self, config: Any): + if isinstance(config, list): # new data format self._configuration = self._parse_manual_config(config) + elif nic_type := config.get('type', None): # new data format + type_ = self._parse_nic_type(nic_type) + + if type_ != NicType.MANUAL: + self._configuration = NetworkConfiguration(type_) + else: # manual configuration settings + self._configuration = self._parse_manual_config([config]) + else: # old style definitions + network_config = self._backwards_compability_config(config) + if network_config: + return network_config + return None diff --git a/archinstall/lib/user_interaction/manage_users_conf.py b/archinstall/lib/user_interaction/manage_users_conf.py index 567a2964..33c31342 100644 --- a/archinstall/lib/user_interaction/manage_users_conf.py +++ b/archinstall/lib/user_interaction/manage_users_conf.py @@ -7,6 +7,7 @@ from .utils import get_password from ..menu import Menu from ..menu.list_manager import ListManager from ..models.users import User +from ..output import FormattedOutput if TYPE_CHECKING: _: Any @@ -18,13 +19,6 @@ class UserList(ListManager): """ def __init__(self, prompt: str, lusers: List[User]): - """ - param: prompt - type: str - param: lusers dict with the users already defined for the system - type: Dict - param: sudo. boolean to determine if we handle superusers or users. If None handles both types - """ self._actions = [ str(_('Add a user')), str(_('Change password')), @@ -34,21 +28,25 @@ class UserList(ListManager): super().__init__(prompt, lusers, self._actions, self._actions[0]) def reformat(self, data: List[User]) -> Dict[str, User]: - return {e.display(): e for e in data} + table = FormattedOutput.as_table(data) + rows = table.split('\n') - def action_list(self): - active_user = self.target if self.target else None + # these are the header rows of the table and do not map to any User obviously + # we're adding 2 spaces as prefix because the menu selector '> ' will be put before + # the selectable rows so the header has to be aligned + display_data = {f' {rows[0]}': None, f' {rows[1]}': None} + + for row, user in zip(rows[2:], data): + row = row.replace('|', '\\|') + display_data[row] = user - if active_user is None: - return [self._actions[0]] - else: - return self._actions[1:] + return display_data + + def selected_action_display(self, user: User) -> str: + return user.username def exec_action(self, data: List[User]) -> List[User]: - if self.target: - active_user = self.target - else: - active_user = None + active_user = self.target if self.target else None if self.action == self._actions[0]: # add new_user = self._add_user() @@ -77,8 +75,7 @@ class UserList(ListManager): return False def _add_user(self) -> Optional[User]: - print(_('\nDefine a new user\n')) - prompt = str(_('Enter username (leave blank to skip): ')) + prompt = '\n\n' + str(_('Enter username (leave blank to skip): ')) while True: username = input(prompt).strip(' ') @@ -94,7 +91,9 @@ class UserList(ListManager): choice = Menu( str(_('Should "{}" be a superuser (sudo)?')).format(username), Menu.yes_no(), skip=False, - default_option=Menu.no() + default_option=Menu.no(), + clear_screen=False, + show_search_hint=False ).run() sudo = True if choice.value == Menu.yes() else False @@ -102,6 +101,5 @@ class UserList(ListManager): def ask_for_additional_users(prompt: str = '', defined_users: List[User] = []) -> List[User]: - prompt = prompt if prompt else _('Enter username (leave blank to skip): ') users = UserList(prompt, defined_users).run() return users diff --git a/archinstall/lib/user_interaction/network_conf.py b/archinstall/lib/user_interaction/network_conf.py index 5154d8b1..4f22b790 100644 --- a/archinstall/lib/user_interaction/network_conf.py +++ b/archinstall/lib/user_interaction/network_conf.py @@ -2,7 +2,7 @@ from __future__ import annotations import ipaddress import logging -from typing import Any, Optional, TYPE_CHECKING, List, Union +from typing import Any, Optional, TYPE_CHECKING, List, Union, Dict from ..menu.menu import MenuSelectionType from ..menu.text_input import TextInput @@ -10,7 +10,7 @@ from ..models.network_configuration import NetworkConfiguration, NicType from ..networking import list_interfaces from ..menu import Menu -from ..output import log +from ..output import log, FormattedOutput from ..menu.list_manager import ListManager if TYPE_CHECKING: @@ -19,55 +19,57 @@ if TYPE_CHECKING: class ManualNetworkConfig(ListManager): """ - subclass of ListManager for the managing of network configuration accounts + subclass of ListManager for the managing of network configurations """ - def __init__(self, prompt: str, ifaces: Union[None, NetworkConfiguration, List[NetworkConfiguration]]): - """ - param: prompt - type: str - param: ifaces already defined previously - type: Dict - """ + def __init__(self, prompt: str, ifaces: List[NetworkConfiguration]): + self._actions = [ + str(_('Add interface')), + str(_('Edit interface')), + str(_('Delete interface')) + ] - if ifaces is not None and isinstance(ifaces, list): - display_values = {iface.iface: iface for iface in ifaces} - else: - display_values = {} + super().__init__(prompt, ifaces, self._actions, self._actions[0]) + + def reformat(self, data: List[NetworkConfiguration]) -> Dict[str, Optional[NetworkConfiguration]]: + table = FormattedOutput.as_table(data) + rows = table.split('\n') - self._action_add = str(_('Add interface')) - self._action_edit = str(_('Edit interface')) - self._action_delete = str(_('Delete interface')) + # these are the header rows of the table and do not map to any User obviously + # we're adding 2 spaces as prefix because the menu selector '> ' will be put before + # the selectable rows so the header has to be aligned + display_data: Dict[str, Optional[NetworkConfiguration]] = {f' {rows[0]}': None, f' {rows[1]}': None} - self._iface_actions = [self._action_edit, self._action_delete] + for row, iface in zip(rows[2:], data): + row = row.replace('|', '\\|') + display_data[row] = iface - super().__init__(prompt, display_values, self._iface_actions, self._action_add) + return display_data - def run_manual(self) -> List[NetworkConfiguration]: - ifaces = super().run() - if ifaces is not None: - return list(ifaces.values()) - return [] + def selected_action_display(self, iface: NetworkConfiguration) -> str: + return iface.iface if iface.iface else '' - def exec_action(self, data: Any): - if self.action == self._action_add: - iface_name = self._select_iface(data.keys()) + def exec_action(self, data: List[NetworkConfiguration]): + active_iface: Optional[NetworkConfiguration] = self.target if self.target else None + + if self.action == self._actions[0]: # add + iface_name = self._select_iface(data) if iface_name: iface = NetworkConfiguration(NicType.MANUAL, iface=iface_name) - data[iface_name] = self._edit_iface(iface) - elif self.target: - iface_name = list(self.target.keys())[0] - iface = data[iface_name] - - if self.action == self._action_edit: - data[iface_name] = self._edit_iface(iface) - elif self.action == self._action_delete: - del data[iface_name] + iface = self._edit_iface(iface) + data += [iface] + elif active_iface: + if self.action == self._actions[1]: # edit interface + data = [d for d in data if d.iface != active_iface.iface] + data.append(self._edit_iface(active_iface)) + elif self.action == self._actions[2]: # delete + data = [d for d in data if d != active_iface] return data - def _select_iface(self, existing_ifaces: List[str]) -> Optional[Any]: + def _select_iface(self, data: List[NetworkConfiguration]) -> Optional[Any]: all_ifaces = list_interfaces().values() + existing_ifaces = [d.iface for d in data] available = set(all_ifaces) - set(existing_ifaces) choice = Menu(str(_('Select interface to add')), list(available), skip=True).run() @@ -76,7 +78,7 @@ class ManualNetworkConfig(ListManager): return choice.value - def _edit_iface(self, edit_iface :NetworkConfiguration): + def _edit_iface(self, edit_iface: NetworkConfiguration): iface_name = edit_iface.iface modes = ['DHCP (auto detect)', 'IP (static)'] default_mode = 'DHCP (auto detect)' @@ -99,11 +101,13 @@ class ManualNetworkConfig(ListManager): gateway = None while 1: - gateway_input = TextInput(_('Enter your gateway (router) IP address or leave blank for none: '), - edit_iface.gateway).run().strip() + gateway = TextInput( + _('Enter your gateway (router) IP address or leave blank for none: '), + edit_iface.gateway + ).run().strip() try: - if len(gateway_input) > 0: - ipaddress.ip_address(gateway_input) + if len(gateway) > 0: + ipaddress.ip_address(gateway) break except ValueError: log("You need to enter a valid gateway (router) IP address.", level=logging.WARNING, fg='red') @@ -124,7 +128,9 @@ class ManualNetworkConfig(ListManager): return NetworkConfiguration(NicType.MANUAL, iface=iface_name) -def ask_to_configure_network(preset: Union[None, NetworkConfiguration, List[NetworkConfiguration]]) -> Optional[Union[List[NetworkConfiguration], NetworkConfiguration]]: +def ask_to_configure_network( + preset: Union[NetworkConfiguration, List[NetworkConfiguration]] +) -> Optional[NetworkConfiguration | List[NetworkConfiguration]]: """ Configure the network on the newly installed system """ @@ -165,7 +171,7 @@ def ask_to_configure_network(preset: Union[None, NetworkConfiguration, List[Netw elif choice.value == network_options['network_manager']: return NetworkConfiguration(NicType.NM) elif choice.value == network_options['manual']: - manual = ManualNetworkConfig('Configure interfaces', preset) - return manual.run_manual() + preset_ifaces = preset if isinstance(preset, list) else [] + return ManualNetworkConfig('Configure interfaces', preset_ifaces).run() return preset diff --git a/archinstall/lib/user_interaction/subvolume_config.py b/archinstall/lib/user_interaction/subvolume_config.py index a54ec891..e2797bba 100644 --- a/archinstall/lib/user_interaction/subvolume_config.py +++ b/archinstall/lib/user_interaction/subvolume_config.py @@ -5,6 +5,7 @@ from ..menu.menu import MenuSelectionType from ..menu.text_input import TextInput from ..menu import Menu from ..models.subvolume import Subvolume +from ... import FormattedOutput if TYPE_CHECKING: _: Any @@ -19,16 +20,23 @@ class SubvolumeList(ListManager): ] super().__init__(prompt, current_volumes, self._actions, self._actions[0]) - def reformat(self, data: List[Subvolume]) -> Dict[str, Subvolume]: - return {e.display(): e for e in data} + def reformat(self, data: List[Subvolume]) -> Dict[str, Optional[Subvolume]]: + table = FormattedOutput.as_table(data) + rows = table.split('\n') - def action_list(self): - active_user = self.target if self.target else None + # these are the header rows of the table and do not map to any User obviously + # we're adding 2 spaces as prefix because the menu selector '> ' will be put before + # the selectable rows so the header has to be aligned + display_data: Dict[str, Optional[Subvolume]] = {f' {rows[0]}': None, f' {rows[1]}': None} - if active_user is None: - return [self._actions[0]] - else: - return self._actions[1:] + for row, subvol in zip(rows[2:], data): + row = row.replace('|', '\\|') + display_data[row] = subvol + + return display_data + + def selected_action_display(self, subvolume: Subvolume) -> str: + return subvolume.name def _prompt_options(self, editing: Optional[Subvolume] = None) -> List[str]: preset_options = [] diff --git a/archinstall/locales/base.pot b/archinstall/locales/base.pot index 54ddbba3..baaf622c 100644 --- a/archinstall/locales/base.pot +++ b/archinstall/locales/base.pot @@ -414,7 +414,7 @@ msgstr "" msgid "Delete" msgstr "" -msgid "Select an action for < {} >" +msgid "Select an action for '{}'" msgstr "" msgid "Copy to new key:" diff --git a/archinstall/locales/cs/LC_MESSAGES/base.mo b/archinstall/locales/cs/LC_MESSAGES/base.mo index 0f9ad704..6a54b145 100644 Binary files a/archinstall/locales/cs/LC_MESSAGES/base.mo and b/archinstall/locales/cs/LC_MESSAGES/base.mo differ diff --git a/archinstall/locales/cs/LC_MESSAGES/base.po b/archinstall/locales/cs/LC_MESSAGES/base.po index 51cce8ac..143e815c 100644 --- a/archinstall/locales/cs/LC_MESSAGES/base.po +++ b/archinstall/locales/cs/LC_MESSAGES/base.po @@ -423,8 +423,8 @@ msgstr "Upravit" msgid "Delete" msgstr "Smazat" -msgid "Select an action for < {} >" -msgstr "Zvolte akci pro < {} >" +msgid "Select an action for '{}'" +msgstr "Zvolte akci pro '{}'" msgid "Copy to new key:" msgstr "Zkopírovat k novému klíči:" @@ -654,7 +654,8 @@ msgstr "Základní instalace, která vám umožní si nastavit Arch Linux jakkol msgid "Provides a selection of various server packages to install and enable, e.g. httpd, nginx, mariadb" msgstr "Nabízí výběr různých serverových balíčků k instalaci a aktivaci, např. httpd, nginx, mariadb" -msgid "Choose which servers to install, if none then a minimal installation wil be done" +#, fuzzy +msgid "Choose which servers to install, if none then a minimal installation will be done" msgstr "Vyberte servery, které mají být nainstalovány, pokud nezvolíte žádné, bude provedena jen základní instalace" msgid "Installs a minimal system as well as xorg and graphics drivers." @@ -743,3 +744,48 @@ msgstr "Volné místo" msgid "Bus-type" msgstr "Typ sběrnice" + +#, fuzzy +msgid "Either root-password or at least 1 user with sudo privileges must be specified" +msgstr "Musí být zadáno heslo správce (root) nebo musí existovat alespoň jeden superuživatel" + +#, fuzzy +msgid "Enter username (leave blank to skip): " +msgstr "Zadejte uživatelské jméno k přidání dalšího uživatele (ponechte prázdné k přeskočení): " + +msgid "The username you entered is invalid. Try again" +msgstr "" + +#, fuzzy +msgid "Should \"{}\" be a superuser (sudo)?" +msgstr "Má být {} superuživatelem (sudoer)?" + +#, fuzzy +msgid "Select which partitions to encrypt:" +msgstr "" +"{}\n" +"\n" +"Zvolte oddíl, který bude označen jako šifrovaný" + +msgid "very weak" +msgstr "" + +msgid "weak" +msgstr "" + +msgid "moderate" +msgstr "" + +msgid "strong" +msgstr "" + +#, fuzzy +msgid "Add subvolume" +msgstr " Podsvazek :{:16}" + +msgid "Edit subvolume" +msgstr "" + +#, fuzzy +msgid "Delete subvolume" +msgstr "Smazat uživatele" diff --git a/archinstall/locales/de/LC_MESSAGES/base.mo b/archinstall/locales/de/LC_MESSAGES/base.mo index 3d58d749..ca3f2971 100644 Binary files a/archinstall/locales/de/LC_MESSAGES/base.mo and b/archinstall/locales/de/LC_MESSAGES/base.mo differ diff --git a/archinstall/locales/de/LC_MESSAGES/base.po b/archinstall/locales/de/LC_MESSAGES/base.po index 51ecd8e9..ee40cea5 100644 --- a/archinstall/locales/de/LC_MESSAGES/base.po +++ b/archinstall/locales/de/LC_MESSAGES/base.po @@ -255,10 +255,12 @@ msgstr "Lokale Kodierung" msgid "Drive(s)" msgstr "Laufwerke" -msgid "Select disk layout" -msgstr "Laufwerke-layout auswählen" +#, fuzzy +msgid "Disk layout" +msgstr "Laufwerke-layout speichern" -msgid "Set encryption password" +#, fuzzy +msgid "Encryption password" msgstr "Verschlüsselungspasswort angeben" msgid "Swap" @@ -267,7 +269,8 @@ msgstr "Swap" msgid "Bootloader" msgstr "Bootloader" -msgid "root password" +#, fuzzy +msgid "Root password" msgstr "Root Passwort" msgid "Superuser account" @@ -425,8 +428,8 @@ msgstr "Bearbeiten" msgid "Delete" msgstr "Löschen" -msgid "Select an action for < {} >" -msgstr "Wählen sie eine Aktion aus für < {} >" +msgid "Select an action for '{}'" +msgstr "Wählen sie eine Aktion aus für '{}'" msgid "Copy to new key:" msgstr "Kopieren nach neuem Schlüssel:" @@ -659,7 +662,8 @@ msgstr "Eine sehr minimale Installation welche es erlaubt Arch Linux weitgehend msgid "Provides a selection of various server packages to install and enable, e.g. httpd, nginx, mariadb" msgstr "Auswahl von Serverpaketen welche installiert werden sollen, z.B. httpd, nginx, mariadb" -msgid "Choose which servers to install, if none then a minimal installation wil be done" +#, fuzzy +msgid "Choose which servers to install, if none then a minimal installation will be done" msgstr "Wählen sie die gewünschten Server aus welche installiert werden sollen" msgid "Installs a minimal system as well as xorg and graphics drivers." @@ -741,6 +745,69 @@ msgstr "" "\n" "Bitte wählen sie welche Partition formatiert werden soll" +msgid "Use HSM to unlock encrypted drive" +msgstr "" + +msgid "Device" +msgstr "" + +msgid "Size" +msgstr "" + +msgid "Free space" +msgstr "" + +msgid "Bus-type" +msgstr "" + +#, fuzzy +msgid "Either root-password or at least 1 user with sudo privileges must be specified" +msgstr "Entweder root Passwort oder wenigstens 1 super-user muss konfiguriert sein" + +#, fuzzy +msgid "Enter username (leave blank to skip): " +msgstr "Geben sie einen weiteren Benutzernamen an der angelegt werden soll (leer lassen um zu Überspringen): " + +msgid "The username you entered is invalid. Try again" +msgstr "" + +#, fuzzy +msgid "Should \"{}\" be a superuser (sudo)?" +msgstr "Soll {} ein superuser sein (sudoer)?" + +#, fuzzy +msgid "Select which partitions to encrypt:" +msgstr "" +"{}\n" +"\n" +"Bitte wählen sie welche Partition verschlüsselt werden soll" + +msgid "very weak" +msgstr "" + +msgid "weak" +msgstr "" + +msgid "moderate" +msgstr "" + +msgid "strong" +msgstr "" + +#, fuzzy +msgid "Add subvolume" +msgstr " Subvolume :{:16}" + +msgid "Edit subvolume" +msgstr "" + +#, fuzzy +msgid "Delete subvolume" +msgstr "Benutzerkonto löschen" + +#~ msgid "Select disk layout" +#~ msgstr "Laufwerke-layout auswählen" + #~ msgid "Add :" #~ msgstr "Hinzufügen :" diff --git a/archinstall/locales/en/LC_MESSAGES/base.po b/archinstall/locales/en/LC_MESSAGES/base.po index 531e20a9..63e9f804 100644 --- a/archinstall/locales/en/LC_MESSAGES/base.po +++ b/archinstall/locales/en/LC_MESSAGES/base.po @@ -232,10 +232,10 @@ msgstr "" msgid "Drive(s)" msgstr "" -msgid "Select disk layout" +msgid "Disk layout" msgstr "" -msgid "Set encryption password" +msgid "Encryption password" msgstr "" msgid "Swap" @@ -244,7 +244,7 @@ msgstr "" msgid "Bootloader" msgstr "" -msgid "root password" +msgid "Root password" msgstr "" msgid "Superuser account" @@ -392,7 +392,7 @@ msgstr "" msgid "Delete" msgstr "" -msgid "Select an action for < {} >" +msgid "Select an action for '{}'" msgstr "" msgid "Copy to new key:" @@ -617,7 +617,7 @@ msgstr "" msgid "Provides a selection of various server packages to install and enable, e.g. httpd, nginx, mariadb" msgstr "" -msgid "Choose which servers to install, if none then a minimal installation wil be done" +msgid "Choose which servers to install, if none then a minimal installation will be done" msgstr "" msgid "Installs a minimal system as well as xorg and graphics drivers." @@ -689,3 +689,54 @@ msgstr "" msgid "Select which partitions to mark for formatting:" msgstr "" + +msgid "Use HSM to unlock encrypted drive" +msgstr "" + +msgid "Device" +msgstr "" + +msgid "Size" +msgstr "" + +msgid "Free space" +msgstr "" + +msgid "Bus-type" +msgstr "" + +msgid "Either root-password or at least 1 user with sudo privileges must be specified" +msgstr "" + +msgid "Enter username (leave blank to skip): " +msgstr "" + +msgid "The username you entered is invalid. Try again" +msgstr "" + +msgid "Should \"{}\" be a superuser (sudo)?" +msgstr "" + +msgid "Select which partitions to encrypt:" +msgstr "" + +msgid "very weak" +msgstr "" + +msgid "weak" +msgstr "" + +msgid "moderate" +msgstr "" + +msgid "strong" +msgstr "" + +msgid "Add subvolume" +msgstr "" + +msgid "Edit subvolume" +msgstr "" + +msgid "Delete subvolume" +msgstr "" diff --git a/archinstall/locales/es/LC_MESSAGES/base.mo b/archinstall/locales/es/LC_MESSAGES/base.mo index d5efa958..6006c274 100644 Binary files a/archinstall/locales/es/LC_MESSAGES/base.mo and b/archinstall/locales/es/LC_MESSAGES/base.mo differ diff --git a/archinstall/locales/es/LC_MESSAGES/base.po b/archinstall/locales/es/LC_MESSAGES/base.po index 0373a40d..6f18c5f8 100644 --- a/archinstall/locales/es/LC_MESSAGES/base.po +++ b/archinstall/locales/es/LC_MESSAGES/base.po @@ -423,8 +423,8 @@ msgstr "Editar" msgid "Delete" msgstr "Eliminar" -msgid "Select an action for < {} >" -msgstr "Seleccione una acción para < {} >" +msgid "Select an action for '{}'" +msgstr "Seleccione una acción para '{}'" msgid "Copy to new key:" msgstr "Copiar a nueva clave:" @@ -657,7 +657,8 @@ msgstr "Una instalación muy básica que te permite personalizar Arch Linux como msgid "Provides a selection of various server packages to install and enable, e.g. httpd, nginx, mariadb" msgstr "Proporciona una selección de varios paquetes de servidor para instalar y habilitar, p.e. httpd, nginx, mariadb" -msgid "Choose which servers to install, if none then a minimal installation wil be done" +#, fuzzy +msgid "Choose which servers to install, if none then a minimal installation will be done" msgstr "Elija qué servidores instalar, si no hay ninguno, se realizará una instalación mínima" msgid "Installs a minimal system as well as xorg and graphics drivers." @@ -764,6 +765,29 @@ msgstr "¿Debe \"{}\" ser un superusuario (sudo)?" msgid "Select which partitions to encrypt:" msgstr "Seleccione qué particiones cifrar:" +msgid "very weak" +msgstr "" + +msgid "weak" +msgstr "" + +msgid "moderate" +msgstr "" + +msgid "strong" +msgstr "" + +#, fuzzy +msgid "Add subvolume" +msgstr " Subvolumen :{:16}" + +msgid "Edit subvolume" +msgstr "" + +#, fuzzy +msgid "Delete subvolume" +msgstr "Eliminar usuario" + #~ msgid "Select disk layout" #~ msgstr "Seleccione el diseño del disco" diff --git a/archinstall/locales/fr/LC_MESSAGES/base.mo b/archinstall/locales/fr/LC_MESSAGES/base.mo index 364b8964..b8f19aa7 100644 Binary files a/archinstall/locales/fr/LC_MESSAGES/base.mo and b/archinstall/locales/fr/LC_MESSAGES/base.mo differ diff --git a/archinstall/locales/fr/LC_MESSAGES/base.po b/archinstall/locales/fr/LC_MESSAGES/base.po index 0e783a58..359dbdd7 100644 --- a/archinstall/locales/fr/LC_MESSAGES/base.po +++ b/archinstall/locales/fr/LC_MESSAGES/base.po @@ -14,12 +14,8 @@ msgstr "" msgid "[!] A log file has been created here: {} {}" msgstr "[!] Un fichier journal a été créé ici : {} {}" -msgid "" -" Please submit this issue (and file) to https://github.com/archlinux/" -"archinstall/issues" -msgstr "" -" Veuillez soumettre ce problème (et le fichier) à https://github.com/" -"archlinux/archinstall/issues" +msgid " Please submit this issue (and file) to https://github.com/archlinux/archinstall/issues" +msgstr " Veuillez soumettre ce problème (et le fichier) à https://github.com/archlinux/archinstall/issues" msgid "Do you really want to abort?" msgstr "Voulez-vous vraiment abandonner ?" @@ -34,13 +30,10 @@ msgid "Desired hostname for the installation: " msgstr "Nom d'hôte souhaité pour l'installation : " msgid "Username for required superuser with sudo privileges: " -msgstr "" -"Nom d'utilisateur pour le superutilisateur requis avec les privilèges sudo : " +msgstr "Nom d'utilisateur pour le superutilisateur requis avec les privilèges sudo : " msgid "Any additional users to install (leave blank for no users): " -msgstr "" -"Utilisateur supplémentaire à installer (laisser vide pour aucun " -"utilisateur) : " +msgstr "Utilisateur supplémentaire à installer (laisser vide pour aucun utilisateur) : " msgid "Should this user be a superuser (sudoer)?" msgstr "Cet utilisateur doit-il être un superutilisateur (sudoer) ?" @@ -49,9 +42,7 @@ msgid "Select a timezone" msgstr "Sélectionner un fuseau horaire" msgid "Would you like to use GRUB as a bootloader instead of systemd-boot?" -msgstr "" -"Souhaitez-vous utiliser GRUB comme chargeur de démarrage au lieu de systemd-" -"boot ?" +msgstr "Souhaitez-vous utiliser GRUB comme chargeur de démarrage au lieu de systemd-boot ?" msgid "Choose a bootloader" msgstr "Choisir un chargeur de démarrage" @@ -59,60 +50,38 @@ msgstr "Choisir un chargeur de démarrage" msgid "Choose an audio server" msgstr "Choisir un serveur audio" -msgid "" -"Only packages such as base, base-devel, linux, linux-firmware, efibootmgr " -"and optional profile packages are installed." -msgstr "" -"Seuls les packages tels que base, base-devel, linux, linux-firmware, " -"efibootmgr et les packages de profil optionnels sont installés." +msgid "Only packages such as base, base-devel, linux, linux-firmware, efibootmgr and optional profile packages are installed." +msgstr "Seuls les packages tels que base, base-devel, linux, linux-firmware, efibootmgr et les packages de profil optionnels sont installés." -msgid "" -"If you desire a web browser, such as firefox or chromium, you may specify it " -"in the following prompt." -msgstr "" -"Si vous désirez un navigateur Web, tel que firefox ou chrome, vous pouvez le " -"spécifier dans l'invite suivante." +msgid "If you desire a web browser, such as firefox or chromium, you may specify it in the following prompt." +msgstr "Si vous désirez un navigateur Web, tel que firefox ou chrome, vous pouvez le spécifier dans l'invite suivante." -msgid "" -"Write additional packages to install (space separated, leave blank to skip): " -msgstr "" -"Écrire des packages supplémentaires à installer (espaces séparés, laisser " -"vide pour ignorer) : " +msgid "Write additional packages to install (space separated, leave blank to skip): " +msgstr "Écrire des packages supplémentaires à installer (espaces séparés, laisser vide pour ignorer) : " msgid "Copy ISO network configuration to installation" msgstr "Copier la configuration réseau ISO dans l'installation" -msgid "" -"Use NetworkManager (necessary to configure internet graphically in GNOME and " -"KDE)" -msgstr "" -"Utiliser NetworkManager (nécessaire pour configurer graphiquement Internet " -"dans GNOME et KDE)" +msgid "Use NetworkManager (necessary to configure internet graphically in GNOME and KDE)" +msgstr "Utiliser NetworkManager (nécessaire pour configurer graphiquement Internet dans GNOME et KDE)" msgid "Select one network interface to configure" msgstr "Sélectionner une interface réseau à configurer" -msgid "" -"Select which mode to configure for \"{}\" or skip to use default mode \"{}\"" -msgstr "" -"Sélectionner le mode à configurer pour \"{}\" ou ignorer pour utiliser le " -"mode par défaut \"{}\"" +msgid "Select which mode to configure for \"{}\" or skip to use default mode \"{}\"" +msgstr "Sélectionner le mode à configurer pour \"{}\" ou ignorer pour utiliser le mode par défaut \"{}\"" msgid "Enter the IP and subnet for {} (example: 192.168.0.5/24): " msgstr "Entrer l'IP et le sous-réseau pour {} (exemple : 192.168.0.5/24) : " msgid "Enter your gateway (router) IP address or leave blank for none: " -msgstr "" -"Entrer l'adresse IP de votre passerelle (routeur) ou laisser vide pour " -"aucune : " +msgstr "Entrer l'adresse IP de votre passerelle (routeur) ou laisser vide pour aucune : " msgid "Enter your DNS servers (space separated, blank for none): " msgstr "Entrer vos serveurs DNS (séparés par des espaces, vide pour aucun) : " msgid "Select which filesystem your main partition should use" -msgstr "" -"Sélectionner le système de fichiers que votre partition principale doit " -"utiliser" +msgstr "Sélectionner le système de fichiers que votre partition principale doit utiliser" msgid "Current partition layout" msgstr "Disposition actuelle des partitions" @@ -128,20 +97,13 @@ msgid "Enter a desired filesystem type for the partition" msgstr "Entrer un type de système de fichiers souhaité pour la partition" msgid "Enter the start sector (percentage or block number, default: {}): " -msgstr "" -"Entrer le secteur de début (pourcentage ou numéro de bloc, par défaut : " -"{}) : " +msgstr "Entrer le secteur de début (pourcentage ou numéro de bloc, par défaut : {}) : " -msgid "" -"Enter the end sector of the partition (percentage or block number, ex: {}): " -msgstr "" -"Entrer le secteur de fin de la partition (pourcentage ou numéro de bloc, " -"ex : {}) : " +msgid "Enter the end sector of the partition (percentage or block number, ex: {}): " +msgstr "Entrer le secteur de fin de la partition (pourcentage ou numéro de bloc, ex : {}) : " msgid "{} contains queued partitions, this will remove those, are you sure?" -msgstr "" -"{} contient des partitions en file d'attente, cela les supprimera, êtes-vous " -"sûr ?" +msgstr "{} contient des partitions en file d'attente, cela les supprimera, êtes-vous sûr ?" msgid "" "{}\n" @@ -161,17 +123,11 @@ msgstr "" "\n" "Sélectionner par index où et quelle partition montée" -msgid "" -" * Partition mount-points are relative to inside the installation, the boot " -"would be /boot as an example." -msgstr "" -" * Les points de montage de la partition sont relatifs à l'intérieur de " -"l'installation, le démarrage serait /boot par exemple." +msgid " * Partition mount-points are relative to inside the installation, the boot would be /boot as an example." +msgstr " * Les points de montage de la partition sont relatifs à l'intérieur de l'installation, le démarrage serait /boot par exemple." msgid "Select where to mount partition (leave blank to remove mountpoint): " -msgstr "" -"Sélectionner où monter la partition (laisser vide pour supprimer le point de " -"montage) : " +msgstr "Sélectionner où monter la partition (laisser vide pour supprimer le point de montage) : " msgid "" "{}\n" @@ -216,58 +172,34 @@ msgid "Archinstall language" msgstr "Langue d'Archinstall" msgid "Wipe all selected drives and use a best-effort default partition layout" -msgstr "" -"Effacer tous les lecteurs sélectionnés et utiliser une disposition de " -"partition par défaut optimale" +msgstr "Effacer tous les lecteurs sélectionnés et utiliser une disposition de partition par défaut optimale" -msgid "" -"Select what to do with each individual drive (followed by partition usage)" -msgstr "" -"Sélectionner ce qu'il faut faire avec chaque lecteur individuel (suivi de " -"l'utilisation de la partition)" +msgid "Select what to do with each individual drive (followed by partition usage)" +msgstr "Sélectionner ce qu'il faut faire avec chaque lecteur individuel (suivi de l'utilisation de la partition)" msgid "Select what you wish to do with the selected block devices" -msgstr "" -"Sélectionner ce que vous souhaitez faire avec les périphériques de bloc " -"sélectionnés" +msgstr "Sélectionner ce que vous souhaitez faire avec les périphériques de bloc sélectionnés" -msgid "" -"This is a list of pre-programmed profiles, they might make it easier to " -"install things like desktop environments" -msgstr "" -"Ceci est une liste de profils préprogrammés, ils pourraient faciliter " -"l'installation d'outils comme les environnements de bureau" +msgid "This is a list of pre-programmed profiles, they might make it easier to install things like desktop environments" +msgstr "Ceci est une liste de profils préprogrammés, ils pourraient faciliter l'installation d'outils comme les environnements de bureau" msgid "Select keyboard layout" msgstr "Sélectionner la disposition du clavier" msgid "Select one of the regions to download packages from" -msgstr "" -"Sélectionner l'une des régions depuis lesquelles télécharger les packages" +msgstr "Sélectionner l'une des régions depuis lesquelles télécharger les packages" msgid "Select one or more hard drives to use and configure" msgstr "Sélectionner un ou plusieurs disques durs à utiliser et à configurer" -msgid "" -"For the best compatibility with your AMD hardware, you may want to use " -"either the all open-source or AMD / ATI options." -msgstr "" -"Pour une meilleure compatibilité avec votre matériel AMD, vous pouvez " -"utiliser les options entièrement open source ou AMD / ATI." +msgid "For the best compatibility with your AMD hardware, you may want to use either the all open-source or AMD / ATI options." +msgstr "Pour une meilleure compatibilité avec votre matériel AMD, vous pouvez utiliser les options entièrement open source ou 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 "" -"Pour une compatibilité optimale avec votre matériel Intel, vous pouvez " -"utiliser les options entièrement open source ou Intel.\n" +msgid "For the best compatibility with your Intel hardware, you may want to use either the all open-source or Intel options.\n" +msgstr "Pour une compatibilité optimale avec votre matériel Intel, vous pouvez utiliser les options entièrement open source ou Intel.\n" -msgid "" -"For the best compatibility with your Nvidia hardware, you may want to use " -"the Nvidia proprietary driver.\n" -msgstr "" -"Pour une meilleure compatibilité avec votre matériel Nvidia, vous pouvez " -"utiliser le pilote propriétaire Nvidia.\n" +msgid "For the best compatibility with your Nvidia hardware, you may want to use the Nvidia proprietary driver.\n" +msgstr "Pour une meilleure compatibilité avec votre matériel Nvidia, vous pouvez utiliser le pilote propriétaire Nvidia.\n" msgid "" "\n" @@ -276,8 +208,7 @@ msgid "" msgstr "" "\n" "\n" -"Sélectionner un pilote graphique ou laisser vide pour installer tous les " -"pilotes open-source" +"Sélectionner un pilote graphique ou laisser vide pour installer tous les pilotes open-source" msgid "All open-source (default)" msgstr "Tout open-source (par défaut)" @@ -300,12 +231,8 @@ msgstr "Sélectionner une ou plusieurs des options ci-dessous : " msgid "Adding partition...." msgstr "Ajout de la partition...." -msgid "" -"You need to enter a valid fs-type in order to continue. See `man parted` for " -"valid fs-type's." -msgstr "" -"Vous devez entrer un type de fs valide pour continuer. Voir `man parted` " -"pour les types de fs valides." +msgid "You need to enter a valid fs-type in order to continue. See `man parted` for valid fs-type's." +msgstr "Vous devez entrer un type de fs valide pour continuer. Voir `man parted` pour les types de fs valides." msgid "Error: Listing profiles on URL \"{}\" resulted in:" msgstr "Erreur : la liste des profils sur l'URL \"{}\" a entraîné :" @@ -378,8 +305,7 @@ msgid "" msgstr "" "Vous avez décidé d'ignorer la sélection du disque dur\n" "et vous utiliserez la configuration de disque montée sur {} (expérimental)\n" -"ATTENTION : Archinstall ne vérifiera pas l'adéquation de cette " -"configuration\n" +"ATTENTION : Archinstall ne vérifiera pas l'adéquation de cette configuration\n" "Souhaitez-vous continuer ?" msgid "Re-using partition instance: {}" @@ -404,8 +330,7 @@ msgid "Mark/Unmark a partition as encrypted" msgstr "Marquer/Démarquer une partition comme chiffrée" msgid "Mark/Unmark a partition as bootable (automatic for /boot)" -msgstr "" -"Marquer/Démarquer une partition comme amorçable (automatique pour /boot)" +msgstr "Marquer/Démarquer une partition comme amorçable (automatique pour /boot)" msgid "Set desired filesystem for a partition" msgstr "Définir le système de fichiers souhaité pour une partition" @@ -445,9 +370,7 @@ msgid "Enter a encryption password for {}" msgstr "Entrer un mot de passe de cryptage pour {}" msgid "Enter disk encryption password (leave blank for no encryption): " -msgstr "" -"Entrer le mot de passe de chiffrement du disque (laisser vide pour aucun " -"chiffrement) : " +msgstr "Entrer le mot de passe de chiffrement du disque (laisser vide pour aucun chiffrement) : " msgid "Create a required super-user with sudo privileges: " msgstr "Créer un super-utilisateur requis avec les privilèges sudo : " @@ -458,44 +381,31 @@ msgstr "Entrer le mot de passe root (laisser vide pour désactiver root) : " msgid "Password for user \"{}\": " msgstr "Mot de passe pour l'utilisateur \"{}\" : " -msgid "" -"Verifying that additional packages exist (this might take a few seconds)" -msgstr "" -"Vérifier que des packages supplémentaires existent (cela peut prendre " -"quelques secondes)" +msgid "Verifying that additional packages exist (this might take a few seconds)" +msgstr "Vérifier que des packages supplémentaires existent (cela peut prendre quelques secondes)" -msgid "" -"Would you like to use automatic time synchronization (NTP) with the default " -"time servers?\n" -msgstr "" -"Souhaitez-vous utiliser la synchronisation automatique de l'heure (NTP) avec " -"les serveurs de temps par défaut ?\n" +msgid "Would you like to use automatic time synchronization (NTP) with the default time servers?\n" +msgstr "Souhaitez-vous utiliser la synchronisation automatique de l'heure (NTP) avec les serveurs de temps par défaut ?\n" msgid "" -"Hardware time and other post-configuration steps might be required in order " -"for NTP to work.\n" +"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 "" -"Le temps matériel et d'autres étapes de post-configuration peuvent être " -"nécessaires pour que NTP fonctionne.\n" +"Le temps matériel et d'autres étapes de post-configuration peuvent être nécessaires pour que NTP fonctionne.\n" "Pour plus d'informations, veuillez consulter le wiki Arch" msgid "Enter a username to create an additional user (leave blank to skip): " -msgstr "" -"Entrer un nom d'utilisateur pour créer un utilisateur supplémentaire " -"(laisser vide pour ignorer) : " +msgstr "Entrer un nom d'utilisateur pour créer un utilisateur supplémentaire (laisser vide pour ignorer) : " msgid "Use ESC to skip\n" msgstr "Utiliser ESC pour ignorer\n" msgid "" "\n" -" Choose an object from the list, and select one of the available actions for " -"it to execute" +" Choose an object from the list, and select one of the available actions for it to execute" msgstr "" "\n" -"Choisir un objet dans la liste et sélectionner l'une des actions disponibles " -"pour qu'il s'exécute" +"Choisir un objet dans la liste et sélectionner l'une des actions disponibles pour qu'il s'exécute" msgid "Cancel" msgstr "Annuler" @@ -515,8 +425,8 @@ msgstr "Modifier" msgid "Delete" msgstr "Supprimer" -msgid "Select an action for < {} >" -msgstr "Sélectionner une action pour < {} >" +msgid "Select an action for '{}'" +msgstr "Sélectionner une action pour '{}'" msgid "Copy to new key:" msgstr "Copier vers une nouvelle clé :" @@ -531,18 +441,11 @@ msgstr "" "\n" "Voici la configuration choisie :" -msgid "" -"Pacman is already running, waiting maximum 10 minutes for it to terminate." -msgstr "" -"Pacman est déjà en cours d'exécution, attendez au maximum 10 minutes pour " -"qu'il se termine." +msgid "Pacman is already running, waiting maximum 10 minutes for it to terminate." +msgstr "Pacman est déjà en cours d'exécution, attendez au maximum 10 minutes pour qu'il se termine." -msgid "" -"Pre-existing pacman lock never exited. Please clean up any existing pacman " -"sessions before using archinstall." -msgstr "" -"Le verrou pacman préexistant n'a jamais été fermé. Veuillez nettoyer toutes " -"les sessions pacman existantes avant d'utiliser archinstall." +msgid "Pre-existing pacman lock never exited. Please clean up any existing pacman sessions before using archinstall." +msgstr "Le verrou pacman préexistant n'a jamais été fermé. Veuillez nettoyer toutes les sessions pacman existantes avant d'utiliser archinstall." msgid "Choose which optional additional repositories to enable" msgstr "Choisir les référentiels supplémentaires en option à activer" @@ -679,16 +582,13 @@ msgid "Select the desired subvolume options " msgstr "Sélectionner les options de sous-volume souhaitées " msgid "Define users with sudo privilege, by username: " -msgstr "" -"Définir les utilisateurs avec le privilège sudo, par nom d'utilisateur : " +msgstr "Définir les utilisateurs avec le privilège sudo, par nom d'utilisateur : " msgid "[!] A log file has been created here: {}" msgstr "[!] Un fichier journal a été créé ici : {}" msgid "Would you like to use BTRFS subvolumes with a default structure?" -msgstr "" -"Souhaitez-vous utiliser des sous-volumes BTRFS avec une structure par " -"défaut ?" +msgstr "Souhaitez-vous utiliser des sous-volumes BTRFS avec une structure par défaut ?" msgid "Would you like to use BTRFS compression?" msgstr "Souhaitez-vous utiliser la compression BTRFS ?" @@ -696,12 +596,8 @@ msgstr "Souhaitez-vous utiliser la compression BTRFS ?" msgid "Would you like to create a separate partition for /home?" msgstr "Souhaitez-vous créer une partition séparée pour /home ?" -msgid "" -"The selected drives do not have the minimum capacity required for an " -"automatic suggestion\n" -msgstr "" -"Les disques sélectionnés n'ont pas la capacité minimale requise pour une " -"suggestion automatique\n" +msgid "The selected drives do not have the minimum capacity required for an automatic suggestion\n" +msgstr "Les disques sélectionnés n'ont pas la capacité minimale requise pour une suggestion automatique\n" msgid "Minimum capacity for /home partition: {}GB\n" msgstr "Capacité minimale pour la partition /home : {} Go\n" @@ -728,9 +624,7 @@ msgid "No iface specified for manual configuration" msgstr "Aucun iface spécifié pour la configuration manuelle" msgid "Manual nic configuration with no auto DHCP requires an IP address" -msgstr "" -"La configuration manuelle de la carte réseau sans DHCP automatique nécessite " -"une adresse IP" +msgstr "La configuration manuelle de la carte réseau sans DHCP automatique nécessite une adresse IP" msgid "Add interface" msgstr "Ajouter une interface" @@ -750,42 +644,24 @@ msgstr "Configuration manuelle" msgid "Mark/Unmark a partition as compressed (btrfs only)" msgstr "Marquer/Démarquer une partition comme compressée (btrfs uniquement)" -msgid "" -"The password you are using seems to be weak, are you sure you want to use it?" -msgstr "" -"Le mot de passe que vous utilisez semble faible, êtes-vous sûr de vouloir " -"l'utiliser ?" +msgid "The password you are using seems to be weak, are you sure you want to use it?" +msgstr "Le mot de passe que vous utilisez semble faible, êtes-vous sûr de vouloir l'utiliser ?" -msgid "" -"Provides a selection of desktop environments and tiling window managers, e." -"g. gnome, kde, sway" -msgstr "" -"Fournit une sélection d'environnements de bureau et de gestionnaires de " -"fenêtres en mosaïque, par ex. gnome, kde, sway" +msgid "Provides a selection of desktop environments and tiling window managers, e.g. gnome, kde, sway" +msgstr "Fournit une sélection d'environnements de bureau et de gestionnaires de fenêtres en mosaïque, par ex. gnome, kde, sway" msgid "Select your desired desktop environment" msgstr "Sélectionner l'environnement de bureau souhaité" -msgid "" -"A very basic installation that allows you to customize Arch Linux as you see " -"fit." -msgstr "" -"Une installation très basique qui vous permet de personnaliser Arch Linux " -"comme bon vous semble." +msgid "A very basic installation that allows you to customize Arch Linux as you see fit." +msgstr "Une installation très basique qui vous permet de personnaliser Arch Linux comme bon vous semble." -msgid "" -"Provides a selection of various server packages to install and enable, e.g. " -"httpd, nginx, mariadb" -msgstr "" -"Fournit une sélection de divers paquets de serveur à installer et à activer, " -"par ex. httpd, nginx, mariadb" +msgid "Provides a selection of various server packages to install and enable, e.g. httpd, nginx, mariadb" +msgstr "Fournit une sélection de divers paquets de serveur à installer et à activer, par ex. httpd, nginx, mariadb" -msgid "" -"Choose which servers to install, if none then a minimal installation wil be " -"done" -msgstr "" -"Choisir les serveurs à installer, s'il n'y en a pas, une installation " -"minimale sera effectuée" +#, fuzzy +msgid "Choose which servers to install, if none then a minimal installation will be done" +msgstr "Choisir les serveurs à installer, s'il n'y en a pas, une installation minimale sera effectuée" msgid "Installs a minimal system as well as xorg and graphics drivers." msgstr "Installe un système minimal ainsi que les pilotes graphiques et xorg." @@ -793,12 +669,8 @@ msgstr "Installe un système minimal ainsi que les pilotes graphiques et xorg." msgid "Press Enter to continue." msgstr "Appuyer sur Entrée pour continuer." -msgid "" -"Would you like to chroot into the newly created installation and perform " -"post-installation configuration?" -msgstr "" -"Souhaitez-vous chrooter dans l'installation nouvellement créée et effectuer " -"la configuration post-installation ?" +msgid "Would you like to chroot into the newly created installation and perform post-installation configuration?" +msgstr "Souhaitez-vous chrooter dans l'installation nouvellement créée et effectuer la configuration post-installation ?" msgid "Are you sure you want to reset this setting?" msgstr "Voulez-vous vraiment réinitialiser ce paramètre ?" @@ -807,16 +679,10 @@ msgid "Select one or more hard drives to use and configure\n" msgstr "Sélectionner un ou plusieurs disques durs à utiliser et à configurer\n" msgid "Any modifications to the existing setting will reset the disk layout!" -msgstr "" -"Toute modification du paramètre existant réinitialisera la disposition du " -"disque !" +msgstr "Toute modification du paramètre existant réinitialisera la disposition du disque !" -msgid "" -"If you reset the harddrive selection this will also reset the current disk " -"layout. Are you sure?" -msgstr "" -"Si vous réinitialisez la sélection du disque dur, cela réinitialisera " -"également la disposition actuelle du disque. Êtes-vous sûr ?" +msgid "If you reset the harddrive selection this will also reset the current disk layout. Are you sure?" +msgstr "Si vous réinitialisez la sélection du disque dur, cela réinitialisera également la disposition actuelle du disque. Êtes-vous sûr ?" msgid "Save and exit" msgstr "Sauvegarder et quitter" @@ -826,8 +692,7 @@ msgid "" "contains queued partitions, this will remove those, are you sure?" msgstr "" "{}\n" -"contient des partitions en file d'attente, cela les supprimera, êtes-vous " -"sûr ?" +"contient des partitions en file d'attente, cela les supprimera, êtes-vous sûr ?" msgid "No audio server" msgstr "Pas de serveur audio" @@ -863,13 +728,8 @@ msgstr "Ajouter: " msgid "Value: " msgstr "Valeur: " -msgid "" -"You can skip selecting a drive and partitioning and use whatever drive-setup " -"is mounted at /mnt (experimental)" -msgstr "" -"Vous pouvez ignorer la sélection d'un lecteur et le partitionnement et " -"utiliser n'importe quelle configuration de lecteur montée sur /mnt " -"(expérimental)" +msgid "You can skip selecting a drive and partitioning and use whatever drive-setup is mounted at /mnt (experimental)" +msgstr "Vous pouvez ignorer la sélection d'un lecteur et le partitionnement et utiliser n'importe quelle configuration de lecteur montée sur /mnt (expérimental)" msgid "Select one of the disks or skip and use /mnt as default" msgstr "Sélectionner l'un des disques ou ignorer et utiliser /mnt par défaut" @@ -892,12 +752,8 @@ msgstr "Espace libre" msgid "Bus-type" msgstr "Type de bus" -msgid "" -"Either root-password or at least 1 user with sudo privileges must be " -"specified" -msgstr "" -"Le mot de passe root ou au moins 1 utilisateur avec des privilèges sudo doit " -"être spécifié" +msgid "Either root-password or at least 1 user with sudo privileges must be specified" +msgstr "Le mot de passe root ou au moins 1 utilisateur avec des privilèges sudo doit être spécifié" msgid "Enter username (leave blank to skip): " msgstr "Entrer le nom d'utilisateur (laisser vide pour passer) :" @@ -908,6 +764,36 @@ msgstr "Le nom d'utilisateur que vous avez saisi n'est pas valide. Réessayer" msgid "Should \"{}\" be a superuser (sudo)?" msgstr "\"{}\" devrait-il être un superutilisateur (sudo) ?" +#, fuzzy +msgid "Select which partitions to encrypt:" +msgstr "" +"{}\n" +"\n" +"Sélectionner la partition à marquer comme chiffrée" + +msgid "very weak" +msgstr "" + +msgid "weak" +msgstr "" + +msgid "moderate" +msgstr "" + +msgid "strong" +msgstr "" + +#, fuzzy +msgid "Add subvolume" +msgstr " Sous-volume : {:16}" + +msgid "Edit subvolume" +msgstr "" + +#, fuzzy +msgid "Delete subvolume" +msgstr "Supprimer l'utilisateur" + #~ msgid "Select disk layout" #~ msgstr "Sélectionner la disposition du disque" diff --git a/archinstall/locales/it/LC_MESSAGES/base.mo b/archinstall/locales/it/LC_MESSAGES/base.mo index 34a6c898..c6d984c3 100644 Binary files a/archinstall/locales/it/LC_MESSAGES/base.mo and b/archinstall/locales/it/LC_MESSAGES/base.mo differ diff --git a/archinstall/locales/it/LC_MESSAGES/base.po b/archinstall/locales/it/LC_MESSAGES/base.po index 36e8d5b4..529fb47b 100644 --- a/archinstall/locales/it/LC_MESSAGES/base.po +++ b/archinstall/locales/it/LC_MESSAGES/base.po @@ -425,8 +425,8 @@ msgstr "Modifica" msgid "Delete" msgstr "Elimina" -msgid "Select an action for < {} >" -msgstr "Seleziona un'azione per < {} >" +msgid "Select an action for '{}'" +msgstr "Seleziona un'azione per '{}'" msgid "Copy to new key:" msgstr "Copia su nuova chiave:" @@ -659,7 +659,8 @@ msgstr "Un'installazione molto semplice che ti consente di personalizzare Arch L msgid "Provides a selection of various server packages to install and enable, e.g. httpd, nginx, mariadb" msgstr "Fornisce una selezione di vari pacchetti server da installare e abilitare, per esempio httpd, nginx, mariadb" -msgid "Choose which servers to install, if none then a minimal installation wil be done" +#, fuzzy +msgid "Choose which servers to install, if none then a minimal installation will be done" msgstr "Scegli quali server installare, se nessuno verrà eseguita un'installazione minima" msgid "Installs a minimal system as well as xorg and graphics drivers." @@ -750,3 +751,48 @@ msgstr "Spazio libero" msgid "Bus-type" msgstr "Tipo di bus" + +#, fuzzy +msgid "Either root-password or at least 1 user with sudo privileges must be specified" +msgstr "È necessario specificare la password di root o almeno 1 superuser" + +#, fuzzy +msgid "Enter username (leave blank to skip): " +msgstr "Inserisci un nome utente per creare un utente aggiuntivo (lascia vuoto per saltare): " + +msgid "The username you entered is invalid. Try again" +msgstr "" + +#, fuzzy +msgid "Should \"{}\" be a superuser (sudo)?" +msgstr "{} dovrebbe essere un superutente? (sudoer)" + +#, fuzzy +msgid "Select which partitions to encrypt:" +msgstr "" +"{}\n" +"\n" +"Seleziona quale partizione contrassegnare come crittografata" + +msgid "very weak" +msgstr "" + +msgid "weak" +msgstr "" + +msgid "moderate" +msgstr "" + +msgid "strong" +msgstr "" + +#, fuzzy +msgid "Add subvolume" +msgstr " Sottovolume :{:16}" + +msgid "Edit subvolume" +msgstr "" + +#, fuzzy +msgid "Delete subvolume" +msgstr "Elimina utente" diff --git a/archinstall/locales/nl/LC_MESSAGES/base.mo b/archinstall/locales/nl/LC_MESSAGES/base.mo index d7dcabc6..62b7af82 100644 Binary files a/archinstall/locales/nl/LC_MESSAGES/base.mo and b/archinstall/locales/nl/LC_MESSAGES/base.mo differ diff --git a/archinstall/locales/nl/LC_MESSAGES/base.po b/archinstall/locales/nl/LC_MESSAGES/base.po index b712d8ca..72547f7a 100644 --- a/archinstall/locales/nl/LC_MESSAGES/base.po +++ b/archinstall/locales/nl/LC_MESSAGES/base.po @@ -256,10 +256,12 @@ msgstr "Taalvariant" msgid "Drive(s)" msgstr "Harde schijven" -msgid "Select disk layout" -msgstr "Kies een schijfindeling" +#, fuzzy +msgid "Disk layout" +msgstr "Schijfindeling vastleggen" -msgid "Set encryption password" +#, fuzzy +msgid "Encryption password" msgstr "Versleutelwachtwoord instellen" msgid "Swap" @@ -268,7 +270,8 @@ msgstr "Wisselgeheugen" msgid "Bootloader" msgstr "Opstartlader" -msgid "root password" +#, fuzzy +msgid "Root password" msgstr "Rootwachtwoord" msgid "Superuser account" @@ -426,8 +429,8 @@ msgstr "Bewerken" msgid "Delete" msgstr "Verwijderen" -msgid "Select an action for < {} >" -msgstr "Kies een actie voor < {} >" +msgid "Select an action for '{}'" +msgstr "Kies een actie voor '{}'" msgid "Copy to new key:" msgstr "Kopiëren naar nieuwe sleutel:" @@ -670,7 +673,7 @@ msgstr "" msgid "Provides a selection of various server packages to install and enable, e.g. httpd, nginx, mariadb" msgstr "" -msgid "Choose which servers to install, if none then a minimal installation wil be done" +msgid "Choose which servers to install, if none then a minimal installation will be done" msgstr "" msgid "Installs a minimal system as well as xorg and graphics drivers." @@ -757,6 +760,69 @@ msgstr "" "\n" "Kies welke partitie moet worden gemaskeerd alvorens te formatteren" +msgid "Use HSM to unlock encrypted drive" +msgstr "" + +msgid "Device" +msgstr "" + +msgid "Size" +msgstr "" + +msgid "Free space" +msgstr "" + +msgid "Bus-type" +msgstr "" + +#, fuzzy +msgid "Either root-password or at least 1 user with sudo privileges must be specified" +msgstr "Stel een rootwachtwoord of minimaal één beheerder in" + +#, fuzzy +msgid "Enter username (leave blank to skip): " +msgstr "Voer een gebruikersnaam in om een tweede account toe te voegen (laat leeg om over te slaan): " + +msgid "The username you entered is invalid. Try again" +msgstr "" + +#, fuzzy +msgid "Should \"{}\" be a superuser (sudo)?" +msgstr "Moet {} gebruiker een beheerder (sudoer) worden?" + +#, fuzzy +msgid "Select which partitions to encrypt:" +msgstr "" +"{}\n" +"\n" +"Kies welke partitie moet worden versleuteld" + +msgid "very weak" +msgstr "" + +msgid "weak" +msgstr "" + +msgid "moderate" +msgstr "" + +msgid "strong" +msgstr "" + +#, fuzzy +msgid "Add subvolume" +msgstr " Subvolume :{:16}" + +msgid "Edit subvolume" +msgstr "" + +#, fuzzy +msgid "Delete subvolume" +msgstr "Gebruiker verwijderen" + +#~ msgid "Select disk layout" +#~ msgstr "Kies een schijfindeling" + #~ msgid "Add :" #~ msgstr "Toevoegen:" diff --git a/archinstall/locales/pl/LC_MESSAGES/base.mo b/archinstall/locales/pl/LC_MESSAGES/base.mo index dc26f1d7..d60d939a 100644 Binary files a/archinstall/locales/pl/LC_MESSAGES/base.mo and b/archinstall/locales/pl/LC_MESSAGES/base.mo differ diff --git a/archinstall/locales/pl/LC_MESSAGES/base.po b/archinstall/locales/pl/LC_MESSAGES/base.po index d92637ad..f6730462 100644 --- a/archinstall/locales/pl/LC_MESSAGES/base.po +++ b/archinstall/locales/pl/LC_MESSAGES/base.po @@ -428,8 +428,8 @@ msgstr "Edytuj" msgid "Delete" msgstr "Usuń" -msgid "Select an action for < {} >" -msgstr "Wybierz akcję dla < {} >" +msgid "Select an action for '{}'" +msgstr "Wybierz akcję dla '{}'" msgid "Copy to new key:" msgstr "Skopiuj do nowego klucza:" @@ -663,7 +663,8 @@ msgstr "Bardzo podstawowa instalacja pozwalająca ci dostosowanie Arch Linuxa do msgid "Provides a selection of various server packages to install and enable, e.g. httpd, nginx, mariadb" msgstr "Dostarcza wybór różnych pakietów serwerowych do zainstalowania i uruchomienia, np. httpd, nginx, mariadb" -msgid "Choose which servers to install, if none then a minimal installation wil be done" +#, fuzzy +msgid "Choose which servers to install, if none then a minimal installation will be done" msgstr "Wybierz jakie serwery zainstalować, jeżeli żadne, wtedy minimalna instalacja będzie użyta" msgid "Installs a minimal system as well as xorg and graphics drivers." @@ -745,6 +746,66 @@ msgstr "" msgid "Select which partitions to mark for formatting:" msgstr "Wybierz partycja która ma zostać sformatowana:" +msgid "Use HSM to unlock encrypted drive" +msgstr "" + +msgid "Device" +msgstr "" + +msgid "Size" +msgstr "" + +msgid "Free space" +msgstr "" + +msgid "Bus-type" +msgstr "" + +#, fuzzy +msgid "Either root-password or at least 1 user with sudo privileges must be specified" +msgstr "Musi być podane albo hasło root, albo co najmniej jednego superużytkownika" + +#, fuzzy +msgid "Enter username (leave blank to skip): " +msgstr "Wprowadź nazwę użytkownika, aby utworzyć dodatkowego użytkownika (pozostaw puste, aby pominąć): " + +msgid "The username you entered is invalid. Try again" +msgstr "" + +#, fuzzy +msgid "Should \"{}\" be a superuser (sudo)?" +msgstr "Czy {} powinien być superuserem (sudoer)?" + +#, fuzzy +msgid "Select which partitions to encrypt:" +msgstr "" +"{}\n" +"\n" +"Wybierz partycja która ma zostać zaszyfrowana" + +msgid "very weak" +msgstr "" + +msgid "weak" +msgstr "" + +msgid "moderate" +msgstr "" + +msgid "strong" +msgstr "" + +#, fuzzy +msgid "Add subvolume" +msgstr " Subwolumin :{:16}" + +msgid "Edit subvolume" +msgstr "" + +#, fuzzy +msgid "Delete subvolume" +msgstr "Usuń użytkownika" + #~ msgid "Select disk layout" #~ msgstr "Wybierz układ dysku" diff --git a/archinstall/locales/pt/LC_MESSAGES/base.mo b/archinstall/locales/pt/LC_MESSAGES/base.mo index 3b9f7c26..113b26a6 100644 Binary files a/archinstall/locales/pt/LC_MESSAGES/base.mo and b/archinstall/locales/pt/LC_MESSAGES/base.mo differ diff --git a/archinstall/locales/pt/LC_MESSAGES/base.po b/archinstall/locales/pt/LC_MESSAGES/base.po index 4352cf34..e44a0133 100644 --- a/archinstall/locales/pt/LC_MESSAGES/base.po +++ b/archinstall/locales/pt/LC_MESSAGES/base.po @@ -254,10 +254,12 @@ msgstr "Codificação de localização" msgid "Drive(s)" msgstr "Discos rígidos" -msgid "Select disk layout" -msgstr "Seleciona o esquema de disco" +#, fuzzy +msgid "Disk layout" +msgstr "Selecionar esquema de disco" -msgid "Set encryption password" +#, fuzzy +msgid "Encryption password" msgstr "Define a palavra-passe de encriptação" msgid "Swap" @@ -266,7 +268,8 @@ msgstr "Swap" msgid "Bootloader" msgstr "Carregador de arranque" -msgid "root password" +#, fuzzy +msgid "Root password" msgstr "Palavra-passe de root" msgid "Superuser account" @@ -429,8 +432,8 @@ msgid "Delete" msgstr "Eliminar" #, fuzzy -msgid "Select an action for < {} >" -msgstr "Selecione uma ação para < {} >" +msgid "Select an action for '{}'" +msgstr "Selecione uma ação para '{}'" msgid "Copy to new key:" msgstr "Copiar para nova chave:" @@ -688,7 +691,7 @@ msgstr "" msgid "Provides a selection of various server packages to install and enable, e.g. httpd, nginx, mariadb" msgstr "" -msgid "Choose which servers to install, if none then a minimal installation wil be done" +msgid "Choose which servers to install, if none then a minimal installation will be done" msgstr "" msgid "Installs a minimal system as well as xorg and graphics drivers." @@ -777,6 +780,69 @@ msgstr "" "\n" "Seleciona a partição a mascar para formatar" +msgid "Use HSM to unlock encrypted drive" +msgstr "" + +msgid "Device" +msgstr "" + +msgid "Size" +msgstr "" + +msgid "Free space" +msgstr "" + +msgid "Bus-type" +msgstr "" + +#, fuzzy +msgid "Either root-password or at least 1 user with sudo privileges must be specified" +msgstr "É necessário especificar uma senha de root ou pelo menos 1 super-utilizador" + +#, fuzzy +msgid "Enter username (leave blank to skip): " +msgstr "Introduzir um nome de utilizador para criar um utilizador adicional (deixar em branco para saltar): " + +msgid "The username you entered is invalid. Try again" +msgstr "" + +#, fuzzy +msgid "Should \"{}\" be a superuser (sudo)?" +msgstr "Deve {} ser um superutilizador (sudoer)?" + +#, fuzzy +msgid "Select which partitions to encrypt:" +msgstr "" +"{}\n" +"\n" +"Seleciona a partição a marcar como encriptada" + +msgid "very weak" +msgstr "" + +msgid "weak" +msgstr "" + +msgid "moderate" +msgstr "" + +msgid "strong" +msgstr "" + +#, fuzzy +msgid "Add subvolume" +msgstr " Subvolume :{:16}" + +msgid "Edit subvolume" +msgstr "" + +#, fuzzy +msgid "Delete subvolume" +msgstr "Eliminar Utilizador" + +#~ msgid "Select disk layout" +#~ msgstr "Seleciona o esquema de disco" + #~ msgid "Add :" #~ msgstr "Adicionar :" diff --git a/archinstall/locales/pt_BR/LC_MESSAGES/base.mo b/archinstall/locales/pt_BR/LC_MESSAGES/base.mo index 9c71d906..bfc9645c 100644 Binary files a/archinstall/locales/pt_BR/LC_MESSAGES/base.mo and b/archinstall/locales/pt_BR/LC_MESSAGES/base.mo differ diff --git a/archinstall/locales/pt_BR/LC_MESSAGES/base.po b/archinstall/locales/pt_BR/LC_MESSAGES/base.po index 35db5f95..004ad022 100644 --- a/archinstall/locales/pt_BR/LC_MESSAGES/base.po +++ b/archinstall/locales/pt_BR/LC_MESSAGES/base.po @@ -9,12 +9,8 @@ msgstr "" msgid "[!] A log file has been created here: {} {}" msgstr "[!] Um arquivo de log foi criado aqui: {} {}" -msgid "" -" Please submit this issue (and file) to https://github.com/archlinux/" -"archinstall/issues" -msgstr "" -" Por favor, envie este problema (e o arquivo) para: " -"https://github.com/archlinux/archinstall/issues" +msgid " Please submit this issue (and file) to https://github.com/archlinux/archinstall/issues" +msgstr " Por favor, envie este problema (e o arquivo) para: https://github.com/archlinux/archinstall/issues" msgid "Do you really want to abort?" msgstr "Deseja realmente abortar?" @@ -49,42 +45,26 @@ msgstr "Escolha um bootloader" msgid "Choose an audio server" msgstr "Escolha um servidor de áudio" -msgid "" -"Only packages such as base, base-devel, linux, linux-firmware, efibootmgr " -"and optional profile packages are installed." -msgstr "" -"Apenas pacotes como base, base-devel, linux, linux-firmware, efibootmgr " -"e pacotes opcionais de perfil são instalados." +msgid "Only packages such as base, base-devel, linux, linux-firmware, efibootmgr and optional profile packages are installed." +msgstr "Apenas pacotes como base, base-devel, linux, linux-firmware, efibootmgr e pacotes opcionais de perfil são instalados." -msgid "" -"If you desire a web browser, such as firefox or chromium, you may specify it " -"in the following prompt." -msgstr "" -"Se deseja um navegador web, como firefox ou chromium, pode especificá-lo " -"no próximo prompt." +msgid "If you desire a web browser, such as firefox or chromium, you may specify it in the following prompt." +msgstr "Se deseja um navegador web, como firefox ou chromium, pode especificá-lo no próximo prompt." -msgid "" -"Write additional packages to install (space separated, leave blank to skip): " -msgstr "" -"Digite pacotes adicionais para instalar (separados por espaço, deixe em branco para pular): " +msgid "Write additional packages to install (space separated, leave blank to skip): " +msgstr "Digite pacotes adicionais para instalar (separados por espaço, deixe em branco para pular): " msgid "Copy ISO network configuration to installation" msgstr "Copiar a configuração de rede da ISO para a instalação" -msgid "" -"Use NetworkManager (necessary to configure internet graphically in GNOME and " -"KDE)" -msgstr "" -"Usar NetworkManager (necessário para configurar internet graficamente no GNOME e " -"KDE)" +msgid "Use NetworkManager (necessary to configure internet graphically in GNOME and KDE)" +msgstr "Usar NetworkManager (necessário para configurar internet graficamente no GNOME e KDE)" msgid "Select one network interface to configure" msgstr "Selecione uma interface de rede para configurar" -msgid "" -"Select which mode to configure for \"{}\" or skip to use default mode \"{}\"" -msgstr "" -"Selecione qual modo configurar para \"{}\" ou ignore para usar o modo padrão \"{}\"" +msgid "Select which mode to configure for \"{}\" or skip to use default mode \"{}\"" +msgstr "Selecione qual modo configurar para \"{}\" ou ignore para usar o modo padrão \"{}\"" msgid "Enter the IP and subnet for {} (example: 192.168.0.5/24): " msgstr "Digite o IP e a subrede para {} (exemplo: 192.168.0.5/24): " @@ -114,10 +94,8 @@ msgstr "Digite o tipo de sistema de arquivos desejado para a partição" msgid "Enter the start sector (percentage or block number, default: {}): " msgstr "Digite o setor de início (porcentagem ou número do bloco, padrão: {}): " -msgid "" -"Enter the end sector of the partition (percentage or block number, ex: {}): " -msgstr "" -"Digite o setor final da partição (porcentagem ou número de bloco, ex: {}): " +msgid "Enter the end sector of the partition (percentage or block number, ex: {}): " +msgstr "Digite o setor final da partição (porcentagem ou número de bloco, ex: {}): " msgid "{} contains queued partitions, this will remove those, are you sure?" msgstr "{} contém partições em fila, isto irá removê-las, tem certeza?" @@ -140,13 +118,8 @@ msgstr "" "\n" "Selecione por índice quais partições montar em" -msgid "" -" * Partition mount-points are relative to inside the installation, the boot " -"would be /boot as an example." -msgstr "" -" * Os pontos de montagem das partições são relativos aos de dentro da instalação, boot " -"por exemplo seria /boot." - +msgid " * Partition mount-points are relative to inside the installation, the boot would be /boot as an example." +msgstr " * Os pontos de montagem das partições são relativos aos de dentro da instalação, boot por exemplo seria /boot." msgid "Select where to mount partition (leave blank to remove mountpoint): " msgstr "Selecione onde montar a partição (deixe em branco para remover o ponto de montagem): " @@ -196,19 +169,14 @@ msgstr "Idioma do Archinstall" msgid "Wipe all selected drives and use a best-effort default partition layout" msgstr "Apagar todos os discos selecionados e usar um esquema de partições padrão de melhor desempenho" -msgid "" -"Select what to do with each individual drive (followed by partition usage)" -msgstr "" -"Selecione o que fazer com cada disco individual (seguido de uso da partição)" +msgid "Select what to do with each individual drive (followed by partition usage)" +msgstr "Selecione o que fazer com cada disco individual (seguido de uso da partição)" msgid "Select what you wish to do with the selected block devices" msgstr "Selecione o que deseja fazer com os dispositivos de bloco selecionados" -msgid "" -"This is a list of pre-programmed profiles, they might make it easier to " -"install things like desktop environments" -msgstr "Esta é uma lista de perfis pré-programados, que podem por exemplo " -"facilitar a instalação de ambientes gráficos" +msgid "This is a list of pre-programmed profiles, they might make it easier to install things like desktop environments" +msgstr "Esta é uma lista de perfis pré-programados, que podem por exemplo facilitar a instalação de ambientes gráficos" msgid "Select keyboard layout" msgstr "Selecione o layout de teclado" @@ -219,26 +187,14 @@ msgstr "Selecione uma das regiões de onde baixar os pacotes" msgid "Select one or more hard drives to use and configure" msgstr "Selecione um ou mais discos rígidos para usar e configurar" -msgid "" -"For the best compatibility with your AMD hardware, you may want to use " -"either the all open-source or AMD / ATI options." -msgstr "" -"Para melhor compatibilidade com o seu hardware AMD, talvez queira usar " -"a opção de drivers completamente open-source ou as opções da AMD / ATI." +msgid "For the best compatibility with your AMD hardware, you may want to use either the all open-source or AMD / ATI options." +msgstr "Para melhor compatibilidade com o seu hardware AMD, talvez queira usar a opção de drivers completamente open-source ou as opções da 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 "" -"Para melhor compatibilidade com o seu hardware Intel, talvez queira usar " -"a opção de drivers completamente open-source ou as opções da Intel.\n" +msgid "For the best compatibility with your Intel hardware, you may want to use either the all open-source or Intel options.\n" +msgstr "Para melhor compatibilidade com o seu hardware Intel, talvez queira usar a opção de drivers completamente open-source ou as opções da Intel.\n" -msgid "" -"For the best compatibility with your Nvidia hardware, you may want to use " -"the Nvidia proprietary driver.\n" -msgstr "" -"Para melhor compatibilidade com o seu hardware Nvidia, talvez queira usar " -"o driver proprietário da Nvidia.\n" +msgid "For the best compatibility with your Nvidia hardware, you may want to use the Nvidia proprietary driver.\n" +msgstr "Para melhor compatibilidade com o seu hardware Nvidia, talvez queira usar o driver proprietário da Nvidia.\n" msgid "" "\n" @@ -270,13 +226,8 @@ msgstr "Selecione uma ou mais das opções abaixo: " msgid "Adding partition...." msgstr "Adicionando partição...." -msgid "" -"You need to enter a valid fs-type in order to continue. See `man parted` for " -"valid fs-type's." -msgstr "" -"Você precisa definir um tipo de sistema de arquivo válido. Consulte o `man parted` para " -"verificar os tipos de sistemas de arquivo válido." - +msgid "You need to enter a valid fs-type in order to continue. See `man parted` for valid fs-type's." +msgstr "Você precisa definir um tipo de sistema de arquivo válido. Consulte o `man parted` para verificar os tipos de sistemas de arquivo válido." msgid "Error: Listing profiles on URL \"{}\" resulted in:" msgstr "Erro: Listando os perfis em URL \"{}\" resulta em:" @@ -425,25 +376,17 @@ msgstr "Digite uma senha de root (deixe em branco para desativar root): " msgid "Password for user \"{}\": " msgstr "Senha para o usuário \"{}\": " -msgid "" -"Verifying that additional packages exist (this might take a few seconds)" -msgstr "" -"Verificando se existem pacotes adicionais (isto pode demorar alguns segundos)" +msgid "Verifying that additional packages exist (this might take a few seconds)" +msgstr "Verificando se existem pacotes adicionais (isto pode demorar alguns segundos)" -msgid "" -"Would you like to use automatic time synchronization (NTP) with the default " -"time servers?\n" -msgstr "" -"Deseja usar sincronização de tempo automática (NTP) " -"com os servidores de tempo padrão?\n" +msgid "Would you like to use automatic time synchronization (NTP) with the default time servers?\n" +msgstr "Deseja usar sincronização de tempo automática (NTP) com os servidores de tempo padrão?\n" msgid "" -"Hardware time and other post-configuration steps might be required in order " -"for NTP to work.\n" +"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 "" -"A hora de hardware e outros passos de pós-configuração podem ser necessários " -"para que o NTP funcione.\n" +"A hora de hardware e outros passos de pós-configuração podem ser necessários para que o NTP funcione.\n" "Para mais informações, por favor visite a Arch wiki" msgid "Enter a username to create an additional user (leave blank to skip): " @@ -454,12 +397,10 @@ msgstr "Use ESC para pular\n" msgid "" "\n" -" Choose an object from the list, and select one of the available actions for " -"it to execute" +" Choose an object from the list, and select one of the available actions for it to execute" msgstr "" "\n" -" Escolha um objeto da lista, e selecione uma das ações disponíveis " -"para executar" +" Escolha um objeto da lista, e selecione uma das ações disponíveis para executar" msgid "Cancel" msgstr "Cancelar" @@ -479,8 +420,8 @@ msgstr "Editar" msgid "Delete" msgstr "Deletar" -msgid "Select an action for < {} >" -msgstr "Selecione uma ação para < {} >" +msgid "Select an action for '{}'" +msgstr "Selecione uma ação para '{}'" msgid "Copy to new key:" msgstr "Copiar para nova chave:" @@ -495,17 +436,11 @@ msgstr "" "\n" "Esta é a configuração escolhida escolhida por você:" -msgid "" -"Pacman is already running, waiting maximum 10 minutes for it to terminate." -msgstr "" -"O Pacman já está a rodando, aguarde no máximo até 10 minutos para terminar." +msgid "Pacman is already running, waiting maximum 10 minutes for it to terminate." +msgstr "O Pacman já está a rodando, aguarde no máximo até 10 minutos para terminar." -msgid "" -"Pre-existing pacman lock never exited. Please clean up any existing pacman " -"sessions before using archinstall." -msgstr "" -"Pacman lock não terminou. Por favor, limpe as sessões " -"de pacman existentes antes de usar o archinstall." +msgid "Pre-existing pacman lock never exited. Please clean up any existing pacman sessions before using archinstall." +msgstr "Pacman lock não terminou. Por favor, limpe as sessões de pacman existentes antes de usar o archinstall." msgid "Choose which optional additional repositories to enable" msgstr "Escolha quais repositórios adicionais opcionais ativar" @@ -656,12 +591,8 @@ msgstr "Deseja usar a compressão BTRFS?" msgid "Would you like to create a separate partition for /home?" msgstr "Deseja criar uma partição separada para /home?" -msgid "" -"The selected drives do not have the minimum capacity required for an " -"automatic suggestion\n" -msgstr "" -"As unidades selecionadas não tem a capacidade mínima para " -"sugestão automática\n" +msgid "The selected drives do not have the minimum capacity required for an automatic suggestion\n" +msgstr "As unidades selecionadas não tem a capacidade mínima para sugestão automática\n" msgid "Minimum capacity for /home partition: {}GB\n" msgstr "Capacidade mínima para partição /home : {}GB\n" @@ -708,41 +639,24 @@ msgstr "Configuração manual" msgid "Mark/Unmark a partition as compressed (btrfs only)" msgstr "Marcar/desmarcar a partição como comprimida (apenas btrfs)" -msgid "" -"The password you are using seems to be weak, are you sure you want to use it?" -msgstr "" -"A senha que você está usando parece ser fraca, tem certeza que deseja utilizá-la?" +msgid "The password you are using seems to be weak, are you sure you want to use it?" +msgstr "A senha que você está usando parece ser fraca, tem certeza que deseja utilizá-la?" -msgid "" -"Provides a selection of desktop environments and tiling window managers, e." -"g. gnome, kde, sway" -msgstr "" -"Proporciona uma seleção de ambientes gráficos e gerenciadores de janela como por exemplo " -"gnome, kde, sway" +msgid "Provides a selection of desktop environments and tiling window managers, e.g. gnome, kde, sway" +msgstr "Proporciona uma seleção de ambientes gráficos e gerenciadores de janela como por exemplo gnome, kde, sway" msgid "Select your desired desktop environment" msgstr "Selecione o ambiente gráfico desejado" -msgid "" -"A very basic installation that allows you to customize Arch Linux as you see " -"fit." -msgstr "" -"Uma instalação bem básica que permite a você customizar o Arch Linux " -"como desejar." +msgid "A very basic installation that allows you to customize Arch Linux as you see fit." +msgstr "Uma instalação bem básica que permite a você customizar o Arch Linux como desejar." -msgid "" -"Provides a selection of various server packages to install and enable, e.g. " -"httpd, nginx, mariadb" -msgstr "" -"Proporciona uma seleção de diversos pacotes de servidor para instalar e habilitar " -"como por exemplo httpd, nginx, mariadb" +msgid "Provides a selection of various server packages to install and enable, e.g. httpd, nginx, mariadb" +msgstr "Proporciona uma seleção de diversos pacotes de servidor para instalar e habilitar como por exemplo httpd, nginx, mariadb" -msgid "" -"Choose which servers to install, if none then a minimal installation wil be " -"done" -msgstr "" -"Selecione quais servidores instalar, se há nenhum uma instalação mínima será " -"feita" +#, fuzzy +msgid "Choose which servers to install, if none then a minimal installation will be done" +msgstr "Selecione quais servidores instalar, se há nenhum uma instalação mínima será feita" msgid "Installs a minimal system as well as xorg and graphics drivers." msgstr "Instala um sistema mínimo assim como xorg e drivers de vídeo." @@ -750,12 +664,8 @@ msgstr "Instala um sistema mínimo assim como xorg e drivers de vídeo." msgid "Press Enter to continue." msgstr "Tecle Enter para continuar." -msgid "" -"Would you like to chroot into the newly created installation and perform " -"post-installation configuration?" -msgstr "" -"Deseja fazer chroot para a nova instalação e realizar " -"configurações pós-instalação?" +msgid "Would you like to chroot into the newly created installation and perform post-installation configuration?" +msgstr "Deseja fazer chroot para a nova instalação e realizar configurações pós-instalação?" msgid "Are you sure you want to reset this setting?" msgstr "Tem certeza que desejar resetar essa configuração?" @@ -766,12 +676,8 @@ msgstr "Selecione uma ou mais unidades para usar e configurar\n" msgid "Any modifications to the existing setting will reset the disk layout!" msgstr "Quaisquer modificações para configurações existentes vão resetar o layout de disco!" -msgid "" -"If you reset the harddrive selection this will also reset the current disk " -"layout. Are you sure?" -msgstr "" -"Se você resetar a seleção de unidades isso também resetará o layout " -"da unidade atual. Tem certeza?" +msgid "If you reset the harddrive selection this will also reset the current disk layout. Are you sure?" +msgstr "Se você resetar a seleção de unidades isso também resetará o layout da unidade atual. Tem certeza?" msgid "Save and exit" msgstr "Salvar e sair" @@ -817,15 +723,71 @@ msgstr "Adicionar: " msgid "Value: " msgstr "Valor: " -msgid "" -"You can skip selecting a drive and partitioning and use whatever drive-setup " -"is mounted at /mnt (experimental)" -msgstr "" -"Você pode ignorar a seleção de unidade e particionar seja lá o que estiver " -"montado em /mnt (experimental)" +msgid "You can skip selecting a drive and partitioning and use whatever drive-setup is mounted at /mnt (experimental)" +msgstr "Você pode ignorar a seleção de unidade e particionar seja lá o que estiver montado em /mnt (experimental)" msgid "Select one of the disks or skip and use /mnt as default" msgstr "Selecione um dos discos ou ignore e use /mnt como padrão" msgid "Select which partitions to mark for formatting:" msgstr "Selecione quais partições marcar para formatar:" + +msgid "Use HSM to unlock encrypted drive" +msgstr "" + +msgid "Device" +msgstr "" + +msgid "Size" +msgstr "" + +msgid "Free space" +msgstr "" + +msgid "Bus-type" +msgstr "" + +#, fuzzy +msgid "Either root-password or at least 1 user with sudo privileges must be specified" +msgstr "Deve se especificar uma senha de root ou pelo menos 1 superusuário" + +#, fuzzy +msgid "Enter username (leave blank to skip): " +msgstr "Digite um nome de usuário para criar um usuário adicional (deixe em branco para pular): " + +msgid "The username you entered is invalid. Try again" +msgstr "" + +#, fuzzy +msgid "Should \"{}\" be a superuser (sudo)?" +msgstr "{} deve ser um superusuário (sudoer)?" + +#, fuzzy +msgid "Select which partitions to encrypt:" +msgstr "" +"{}\n" +"\n" +"Selecione qual partição marcar como encriptada" + +msgid "very weak" +msgstr "" + +msgid "weak" +msgstr "" + +msgid "moderate" +msgstr "" + +msgid "strong" +msgstr "" + +#, fuzzy +msgid "Add subvolume" +msgstr " Subvolume :{:16}" + +msgid "Edit subvolume" +msgstr "" + +#, fuzzy +msgid "Delete subvolume" +msgstr "Deletar usuário" diff --git a/archinstall/locales/ru/LC_MESSAGES/base.mo b/archinstall/locales/ru/LC_MESSAGES/base.mo index 8c0dc224..0930b800 100644 Binary files a/archinstall/locales/ru/LC_MESSAGES/base.mo and b/archinstall/locales/ru/LC_MESSAGES/base.mo differ diff --git a/archinstall/locales/ru/LC_MESSAGES/base.po b/archinstall/locales/ru/LC_MESSAGES/base.po index 5a6f440a..2a88a85f 100644 --- a/archinstall/locales/ru/LC_MESSAGES/base.po +++ b/archinstall/locales/ru/LC_MESSAGES/base.po @@ -508,8 +508,8 @@ msgstr "Редактировать" msgid "Delete" msgstr "Удалить" -msgid "Select an action for < {} >" -msgstr "Выберите действие для < {} >" +msgid "Select an action for '{}'" +msgstr "Выберите действие для '{}'" msgid "Copy to new key:" msgstr "Копировать в новый ключ:" diff --git a/archinstall/locales/sv/LC_MESSAGES/base.mo b/archinstall/locales/sv/LC_MESSAGES/base.mo index b7999fbb..f2798bd4 100644 Binary files a/archinstall/locales/sv/LC_MESSAGES/base.mo and b/archinstall/locales/sv/LC_MESSAGES/base.mo differ diff --git a/archinstall/locales/sv/LC_MESSAGES/base.po b/archinstall/locales/sv/LC_MESSAGES/base.po index 2c587af5..747e28a1 100644 --- a/archinstall/locales/sv/LC_MESSAGES/base.po +++ b/archinstall/locales/sv/LC_MESSAGES/base.po @@ -256,10 +256,12 @@ msgstr "Teckenuppsättning du vill använda" msgid "Drive(s)" msgstr "Hårddiskar" -msgid "Select disk layout" -msgstr "Välj hårddisk-layout" +#, fuzzy +msgid "Disk layout" +msgstr "Spara disk konfigurering" -msgid "Set encryption password" +#, fuzzy +msgid "Encryption password" msgstr "Välj ett krypterings-lösenord" msgid "Swap" @@ -268,7 +270,8 @@ msgstr "Swap" msgid "Bootloader" msgstr "Boot-loader" -msgid "root password" +#, fuzzy +msgid "Root password" msgstr "root-lösenord" msgid "Superuser account" @@ -426,8 +429,8 @@ msgstr "Editera" msgid "Delete" msgstr "Ta bort" -msgid "Select an action for < {} >" -msgstr "Välj vad du vill göra med < {} >" +msgid "Select an action for '{}'" +msgstr "Välj vad du vill göra med '{}'" msgid "Copy to new key:" msgstr "Kopiera till en ny nyckel:" @@ -660,7 +663,8 @@ msgstr "En väldigt minimal installation som möjliggör konfigurering av Arch L msgid "Provides a selection of various server packages to install and enable, e.g. httpd, nginx, mariadb" msgstr "Erbjuder ett urval av olika server-packeteringar, t.ex. httpd, nginx och mariadb" -msgid "Choose which servers to install, if none then a minimal installation wil be done" +#, fuzzy +msgid "Choose which servers to install, if none then a minimal installation will be done" msgstr "Välj vilka servrar du vill installera, en minimal installation sker om du hoppar över detta" msgid "Installs a minimal system as well as xorg and graphics drivers." @@ -736,3 +740,66 @@ msgstr "Välj en disk eller hoppa över och använd /mnt/archinstall utan format msgid "Select which partitions to mark for formatting:" msgstr "Välj vilken partition som skall markeras för formatering:" + +msgid "Use HSM to unlock encrypted drive" +msgstr "" + +msgid "Device" +msgstr "" + +msgid "Size" +msgstr "" + +msgid "Free space" +msgstr "" + +msgid "Bus-type" +msgstr "" + +#, fuzzy +msgid "Either root-password or at least 1 user with sudo privileges must be specified" +msgstr "Antingen måste ett root-lösenord sättas eller 1 superanvändarkonto skapas" + +#, fuzzy +msgid "Enter username (leave blank to skip): " +msgstr "Mata in ett användarnamn för att skapa ytterligare användare (lämna tom för att hoppa över): " + +msgid "The username you entered is invalid. Try again" +msgstr "" + +#, fuzzy +msgid "Should \"{}\" be a superuser (sudo)?" +msgstr "Är detta en superanvändare (sudo-rättigheter)?" + +#, fuzzy +msgid "Select which partitions to encrypt:" +msgstr "" +"{}\n" +"\n" +"Välj vilken partition som skall markeras för kryptering" + +msgid "very weak" +msgstr "" + +msgid "weak" +msgstr "" + +msgid "moderate" +msgstr "" + +msgid "strong" +msgstr "" + +#, fuzzy +msgid "Add subvolume" +msgstr " Sub-volym :{:16}" + +msgid "Edit subvolume" +msgstr "" + +#, fuzzy +msgid "Delete subvolume" +msgstr "Ta bort användare" + +#~ msgid "Select disk layout" +#~ msgstr "Välj hårddisk-layout" diff --git a/archinstall/locales/tr/LC_MESSAGES/base.mo b/archinstall/locales/tr/LC_MESSAGES/base.mo index 6eb05010..6a205da9 100644 Binary files a/archinstall/locales/tr/LC_MESSAGES/base.mo and b/archinstall/locales/tr/LC_MESSAGES/base.mo differ diff --git a/archinstall/locales/tr/LC_MESSAGES/base.po b/archinstall/locales/tr/LC_MESSAGES/base.po index 03125510..60475156 100644 --- a/archinstall/locales/tr/LC_MESSAGES/base.po +++ b/archinstall/locales/tr/LC_MESSAGES/base.po @@ -15,12 +15,8 @@ msgstr "" msgid "[!] A log file has been created here: {} {}" msgstr "[!] Burada bir günlük (log) dosyası oluşturuldu: {} {}" -msgid "" -" Please submit this issue (and file) to https://github.com/archlinux/" -"archinstall/issues" -msgstr "" -" Lütfen bu sorunu (ve dosyayı) https://github.com/archlinux/archinstall/" -"issues 'a bildirin" +msgid " Please submit this issue (and file) to https://github.com/archlinux/archinstall/issues" +msgstr " Lütfen bu sorunu (ve dosyayı) https://github.com/archlinux/archinstall/issues 'a bildirin" msgid "Do you really want to abort?" msgstr "Gerçekten iptal etmek istiyor musunuz?" @@ -35,12 +31,10 @@ msgid "Desired hostname for the installation: " msgstr "Kurulum için tercih edilen bilgisayar ismi: " msgid "Username for required superuser with sudo privileges: " -msgstr "" -"Sudo yetkilerine sahip, gerekli bir süper kullanıcı için kullanıcı adı: " +msgstr "Sudo yetkilerine sahip, gerekli bir süper kullanıcı için kullanıcı adı: " msgid "Any additional users to install (leave blank for no users): " -msgstr "" -"Kurulum için ek kullanıcılar (ek kullanıcı istemiyorsanız boş bırakın): " +msgstr "Kurulum için ek kullanıcılar (ek kullanıcı istemiyorsanız boş bırakın): " msgid "Should this user be a superuser (sudoer)?" msgstr "Bu kullanıcı bir süper kullanıcı (sudoer) olmalı mı?" @@ -57,55 +51,35 @@ msgstr "Bir önyükleyici seçin" msgid "Choose an audio server" msgstr "Bir ses sunucusu seçin" -msgid "" -"Only packages such as base, base-devel, linux, linux-firmware, efibootmgr " -"and optional profile packages are installed." -msgstr "" -"Sadece base, base-devel, linux, linux-firmware, efibootmgr ve tercihi profil " -"paketleri kuruldu." +msgid "Only packages such as base, base-devel, linux, linux-firmware, efibootmgr and optional profile packages are installed." +msgstr "Sadece base, base-devel, linux, linux-firmware, efibootmgr ve tercihi profil paketleri kuruldu." -msgid "" -"If you desire a web browser, such as firefox or chromium, you may specify it " -"in the following prompt." -msgstr "" -"Eğer bir internet tarayıcısı arzu ediyorsanız, Firefox ya da Chromium gibi, " -"sıra gelen ekranda belirtebilirsiniz." +msgid "If you desire a web browser, such as firefox or chromium, you may specify it in the following prompt." +msgstr "Eğer bir internet tarayıcısı arzu ediyorsanız, Firefox ya da Chromium gibi, sıra gelen ekranda belirtebilirsiniz." -msgid "" -"Write additional packages to install (space separated, leave blank to skip): " -msgstr "" -"Kurulacak ek paketleri yazınız (boşlukla ayrılmış, geçmek için boş bırakın): " +msgid "Write additional packages to install (space separated, leave blank to skip): " +msgstr "Kurulacak ek paketleri yazınız (boşlukla ayrılmış, geçmek için boş bırakın): " msgid "Copy ISO network configuration to installation" msgstr "Kuruluma ISO'dan ağ yapılandırmasını kopyala" -msgid "" -"Use NetworkManager (necessary to configure internet graphically in GNOME and " -"KDE)" -msgstr "" -"NetworkManager'ı kullan (GNOME ya da KDE'de interneti grafik olarak " -"yapılandırmak için gerekli)" +msgid "Use NetworkManager (necessary to configure internet graphically in GNOME and KDE)" +msgstr "NetworkManager'ı kullan (GNOME ya da KDE'de interneti grafik olarak yapılandırmak için gerekli)" msgid "Select one network interface to configure" msgstr "Yapılandırmak için bir ağ arayüzü seçin" -msgid "" -"Select which mode to configure for \"{}\" or skip to use default mode \"{}\"" -msgstr "" -"\"{}\"i yapılandırmak için bir yöntem seçin ya da varsayılan yöntemi \"{}\" " -"kullanmak için geçin" +msgid "Select which mode to configure for \"{}\" or skip to use default mode \"{}\"" +msgstr "\"{}\"i yapılandırmak için bir yöntem seçin ya da varsayılan yöntemi \"{}\" kullanmak için geçin" msgid "Enter the IP and subnet for {} (example: 192.168.0.5/24): " msgstr "{} için IP ve altağ girin (örnek: 192.168.0.5/24): " msgid "Enter your gateway (router) IP address or leave blank for none: " -msgstr "" -"Ağ geçidi (yönlendirici) IP adresini girin ya da kullanılmaması için boş " -"bırakın: " +msgstr "Ağ geçidi (yönlendirici) IP adresini girin ya da kullanılmaması için boş bırakın: " msgid "Enter your DNS servers (space separated, blank for none): " -msgstr "" -"DNS sunucularını girin (boşlukla ayrılmış, kullanılmaması için boş bırakın): " +msgstr "DNS sunucularını girin (boşlukla ayrılmış, kullanılmaması için boş bırakın): " msgid "Select which filesystem your main partition should use" msgstr "Ana disk bölümünde kullanması gereken dosya sistemini seçin" @@ -126,15 +100,11 @@ msgstr "Disk bölümü için arzu edilen bir dosya systemi tipi girin" msgid "Enter the start sector (percentage or block number, default: {}): " msgstr "Başlangıç kesimini girin (yüzde ya da blok numarası, varsayılan: {}): " -msgid "" -"Enter the end sector of the partition (percentage or block number, ex: {}): " -msgstr "" -"Disk bölümünün bitiş kesimini girin (yüzde ya da blok numarası, ör: {}): " +msgid "Enter the end sector of the partition (percentage or block number, ex: {}): " +msgstr "Disk bölümünün bitiş kesimini girin (yüzde ya da blok numarası, ör: {}): " msgid "{} contains queued partitions, this will remove those, are you sure?" -msgstr "" -"{} işlem sırasında bekleyen disk bölümleri bulunduruyor, bu onları " -"kaldıracak, emin misiniz?" +msgstr "{} işlem sırasında bekleyen disk bölümleri bulunduruyor, bu onları kaldıracak, emin misiniz?" msgid "" "{}\n" @@ -154,17 +124,11 @@ msgstr "" "\n" "Dizinden hangi disk bölümünün nereye mount (monte) edileceğini seçin" -msgid "" -" * Partition mount-points are relative to inside the installation, the boot " -"would be /boot as an example." -msgstr "" -" * Disk bölümü mount (monte) noktaları iç kurulumla ilişkilidir, örnek " -"olarak boot, /boot olacaktır." +msgid " * Partition mount-points are relative to inside the installation, the boot would be /boot as an example." +msgstr " * Disk bölümü mount (monte) noktaları iç kurulumla ilişkilidir, örnek olarak boot, /boot olacaktır." msgid "Select where to mount partition (leave blank to remove mountpoint): " -msgstr "" -"Disk bölümünün nereye mount (monte) edileceğini seçin (mount noktasını " -"kaldırmak için boş bırakın): " +msgstr "Disk bölümünün nereye mount (monte) edileceğini seçin (mount noktasını kaldırmak için boş bırakın): " msgid "" "{}\n" @@ -209,25 +173,16 @@ msgid "Archinstall language" msgstr "Archinstall dili" msgid "Wipe all selected drives and use a best-effort default partition layout" -msgstr "" -"Bütün seçilmiş diskleri temizle ve elden gelen en iyi varsayılan disk bölümü " -"düzenini kullan" +msgstr "Bütün seçilmiş diskleri temizle ve elden gelen en iyi varsayılan disk bölümü düzenini kullan" -msgid "" -"Select what to do with each individual drive (followed by partition usage)" -msgstr "" -"Her bir disk ile ne yapılacağını seçin (disk bölümü kullanımı ile takip " -"edilir)" +msgid "Select what to do with each individual drive (followed by partition usage)" +msgstr "Her bir disk ile ne yapılacağını seçin (disk bölümü kullanımı ile takip edilir)" msgid "Select what you wish to do with the selected block devices" msgstr "Seçili blok cihazları ile ne yapmak istediğinizi seçin" -msgid "" -"This is a list of pre-programmed profiles, they might make it easier to " -"install things like desktop environments" -msgstr "" -"Bu ön-programlanmış profillerin bir listesidir, bunlar masaüstü ortamları " -"gibi şeyler kurmayı kolaylaştırabilir" +msgid "This is a list of pre-programmed profiles, they might make it easier to install things like desktop environments" +msgstr "Bu ön-programlanmış profillerin bir listesidir, bunlar masaüstü ortamları gibi şeyler kurmayı kolaylaştırabilir" msgid "Select keyboard layout" msgstr "Klavye düzeni seçin" @@ -238,26 +193,14 @@ msgstr "Paketleri indirmek için bölgelerden birini seçin" msgid "Select one or more hard drives to use and configure" msgstr "Kullanmak ve yapılandırmak için bir veya daha fazla sabit disk seçin" -msgid "" -"For the best compatibility with your AMD hardware, you may want to use " -"either the all open-source or AMD / ATI options." -msgstr "" -"AMD donanımınızla en iyi uyumluluk için, tam açık-kaynak ya da AMD / ATI " -"ayarlarından birini kullanmak isteyebilirsiniz." +msgid "For the best compatibility with your AMD hardware, you may want to use either the all open-source or AMD / ATI options." +msgstr "AMD donanımınızla en iyi uyumluluk için, tam açık-kaynak ya da AMD / ATI ayarlarından birini kullanmak isteyebilirsiniz." -msgid "" -"For the best compatibility with your Intel hardware, you may want to use " -"either the all open-source or Intel options.\n" -msgstr "" -"Intel donanımınızla en iyi uyumluluk için, tam açık-kaynak ya da Intel " -"ayarlarından birini kullanmak isteyebilirsiniz.\n" +msgid "For the best compatibility with your Intel hardware, you may want to use either the all open-source or Intel options.\n" +msgstr "Intel donanımınızla en iyi uyumluluk için, tam açık-kaynak ya da Intel ayarlarından birini kullanmak isteyebilirsiniz.\n" -msgid "" -"For the best compatibility with your Nvidia hardware, you may want to use " -"the Nvidia proprietary driver.\n" -msgstr "" -"Nvidia donanımınızla en iyi uyumluluk için, Nvidia patentli sürücüyü " -"kullanmak isteyebilirsiniz.\n" +msgid "For the best compatibility with your Nvidia hardware, you may want to use the Nvidia proprietary driver.\n" +msgstr "Nvidia donanımınızla en iyi uyumluluk için, Nvidia patentli sürücüyü kullanmak isteyebilirsiniz.\n" msgid "" "\n" @@ -266,16 +209,13 @@ msgid "" msgstr "" "\n" "\n" -"Bir grafik sürücüsü seçin ya da bütün açık-kaynak sürücüleri kurmak için boş " -"bırakın" +"Bir grafik sürücüsü seçin ya da bütün açık-kaynak sürücüleri kurmak için boş bırakın" msgid "All open-source (default)" msgstr "Tam açık-kaynak (varsayılan)" msgid "Choose which kernels to use or leave blank for default \"{}\"" -msgstr "" -"Hangi çekirdekleri kullanmak istediğinizi seçin ya da varsayılan \"{}\" için " -"boş bırakın" +msgstr "Hangi çekirdekleri kullanmak istediğinizi seçin ya da varsayılan \"{}\" için boş bırakın" # Burada "locale" hesaba özgü yani profil içinde yerel anlamına geliyor olabilir. Kurulumda ilgili metin ile karşılaşmadığımdan karar veremiyorum. msgid "Choose which locale language to use" @@ -295,12 +235,8 @@ msgstr "Aşağıdaki seçeneklerden bir ya da daha fazlasını seçin: " msgid "Adding partition...." msgstr "Disk bölümü ekleniyor…." -msgid "" -"You need to enter a valid fs-type in order to continue. See `man parted` for " -"valid fs-type's." -msgstr "" -"Devam etmek için geçerli bir ds-tipi (fs-type) girmeniz gerekiyor. Geçerli " -"ds-tiplerini görmek için `man parted`a bakın." +msgid "You need to enter a valid fs-type in order to continue. See `man parted` for valid fs-type's." +msgstr "Devam etmek için geçerli bir ds-tipi (fs-type) girmeniz gerekiyor. Geçerli ds-tiplerini görmek için `man parted`a bakın." msgid "Error: Listing profiles on URL \"{}\" resulted in:" msgstr "Hata: Bağlantı \"{}\"daki profilleri listeleme şöyle sonuçlandı:" @@ -394,17 +330,13 @@ msgid "Assign mount-point for a partition" msgstr "Bir disk bölümü için mount (monte) noktası ata" msgid "Mark/Unmark a partition to be formatted (wipes data)" -msgstr "" -"Bir disk bölümünü biçimlendirilmek üzere işaretle/işareti kaldır (veriyi " -"temizler)" +msgstr "Bir disk bölümünü biçimlendirilmek üzere işaretle/işareti kaldır (veriyi temizler)" msgid "Mark/Unmark a partition as encrypted" msgstr "Bir disk bölümünü şifrelenmiş olarak işaretle/işareti kaldır" msgid "Mark/Unmark a partition as bootable (automatic for /boot)" -msgstr "" -"Bir disk bölümünü boot edilebilir olarak işaretle/işareti kaldır (/boot için " -"otomatik)" +msgstr "Bir disk bölümünü boot edilebilir olarak işaretle/işareti kaldır (/boot için otomatik)" msgid "Set desired filesystem for a partition" msgstr "Bir disk bölümü için arzu edilen dosya sistemini ayarla" @@ -448,48 +380,36 @@ msgid "Create a required super-user with sudo privileges: " msgstr "Gerekli bir sudo yetkilerine sahip süper-kullanıcı oluşturun: " msgid "Enter root password (leave blank to disable root): " -msgstr "" -"Root (kök) şifresi girin (root'u hizmet dışı bırakmak için boş bırakın): " +msgstr "Root (kök) şifresi girin (root'u hizmet dışı bırakmak için boş bırakın): " msgid "Password for user \"{}\": " msgstr "Kullanıcı \"{}\" için şifre: " -msgid "" -"Verifying that additional packages exist (this might take a few seconds)" +msgid "Verifying that additional packages exist (this might take a few seconds)" msgstr "Ek paketlerin varlığı doğrulanıyor (bu bir kaç saniye alabilir)" -msgid "" -"Would you like to use automatic time synchronization (NTP) with the default " -"time servers?\n" -msgstr "" -"Varsayılan zaman sunucularıyla otomatik zaman eşzamanlamasını (NTP) " -"kullanmak ister misiniz?\n" +msgid "Would you like to use automatic time synchronization (NTP) with the default time servers?\n" +msgstr "Varsayılan zaman sunucularıyla otomatik zaman eşzamanlamasını (NTP) kullanmak ister misiniz?\n" msgid "" -"Hardware time and other post-configuration steps might be required in order " -"for NTP to work.\n" +"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 "" -"NTP'nin çalışması için donanım zamanı ve diğer yapılandırma sonrası adımlar " -"gerekebilir.\n" +"NTP'nin çalışması için donanım zamanı ve diğer yapılandırma sonrası adımlar gerekebilir.\n" "Daha fazla bilgi için, lütfen Arch wikiye göz atın" msgid "Enter a username to create an additional user (leave blank to skip): " -msgstr "" -"Ek kullanıcı oluşturmak için bir kullanıcı adı girin (geçmek için boş " -"bırakın): " +msgstr "Ek kullanıcı oluşturmak için bir kullanıcı adı girin (geçmek için boş bırakın): " msgid "Use ESC to skip\n" msgstr "Geçmek için ESC'yi kullanın\n" msgid "" "\n" -" Choose an object from the list, and select one of the available actions for " -"it to execute" +" Choose an object from the list, and select one of the available actions for it to execute" msgstr "" "\n" -"Listeden bir obje seçin ve çalıştırılmak üzere mevcut eylemlerden birini " -"seçin" +"Listeden bir obje seçin ve çalıştırılmak üzere mevcut eylemlerden birini seçin" msgid "Cancel" msgstr "İptal et" @@ -509,8 +429,8 @@ msgstr "Düzenle" msgid "Delete" msgstr "Sil" -msgid "Select an action for < {} >" -msgstr "< {} > için bir eylem seçin" +msgid "Select an action for '{}'" +msgstr "'{}' için bir eylem seçin" msgid "Copy to new key:" msgstr "Yeni anahtara kopyala:" @@ -525,22 +445,14 @@ msgstr "" "\n" "Bu sizin seçilmiş yapılandırmanız:" -msgid "" -"Pacman is already running, waiting maximum 10 minutes for it to terminate." -msgstr "" -"Pacman hâlihazırda çalışıyor, işlemin sonlandırılması için en fazla 10 " -"dakika beklenecek." +msgid "Pacman is already running, waiting maximum 10 minutes for it to terminate." +msgstr "Pacman hâlihazırda çalışıyor, işlemin sonlandırılması için en fazla 10 dakika beklenecek." -msgid "" -"Pre-existing pacman lock never exited. Please clean up any existing pacman " -"sessions before using archinstall." -msgstr "" -"Önceden var olan pacman kilidi çıkış yapmadı. Lütfen archinstall'ı " -"kullanmadan once mevcut olan pacman oturumlarını temizleyin." +msgid "Pre-existing pacman lock never exited. Please clean up any existing pacman sessions before using archinstall." +msgstr "Önceden var olan pacman kilidi çıkış yapmadı. Lütfen archinstall'ı kullanmadan once mevcut olan pacman oturumlarını temizleyin." msgid "Choose which optional additional repositories to enable" -msgstr "" -"Hangi tercihi ek repositorylerin (depoların) aktifleştirileceğini seçin" +msgstr "Hangi tercihi ek repositorylerin (depoların) aktifleştirileceğini seçin" msgid "Add a user" msgstr "Kullanıcı ekle" @@ -628,9 +540,7 @@ msgid "Missing configurations:\n" msgstr "Eksik yapılandırmalar:\n" msgid "Either root-password or at least 1 superuser must be specified" -msgstr "" -"Root (kök) şifresi ya da en azından 1 adet süper-kullanıcı belirtilmek " -"zorunda" +msgstr "Root (kök) şifresi ya da en azından 1 adet süper-kullanıcı belirtilmek zorunda" msgid "Manage superuser accounts: " msgstr "Süper-kullanıcı hesaplarını yönet: " @@ -690,12 +600,8 @@ msgstr "BTRFS sıkıştırmasını kullanmak ister misiniz?" msgid "Would you like to create a separate partition for /home?" msgstr "/home dizini için ayrı bir disk bölümü oluşturmak ister misiniz?" -msgid "" -"The selected drives do not have the minimum capacity required for an " -"automatic suggestion\n" -msgstr "" -"Seçilmiş diskler otomatik öneriler için gerekli minimum kapasiteye sahip " -"değil\n" +msgid "The selected drives do not have the minimum capacity required for an automatic suggestion\n" +msgstr "Seçilmiş diskler otomatik öneriler için gerekli minimum kapasiteye sahip değil\n" msgid "Minimum capacity for /home partition: {}GB\n" msgstr "/home disk bölümü için minimum kapasite: {}GB\n" @@ -740,43 +646,26 @@ msgid "Manual configuration" msgstr "Manuel yapılandırma" msgid "Mark/Unmark a partition as compressed (btrfs only)" -msgstr "" -"Bir disk bölümünü sıkıştırılmış olarak işaretle/işareti kaldır (sadece btrfs)" +msgstr "Bir disk bölümünü sıkıştırılmış olarak işaretle/işareti kaldır (sadece btrfs)" -msgid "" -"The password you are using seems to be weak, are you sure you want to use it?" -msgstr "" -"Kullandığınız şifre zayıf gözüküyor, kullanmak istediğinize emin misiniz?" +msgid "The password you are using seems to be weak, are you sure you want to use it?" +msgstr "Kullandığınız şifre zayıf gözüküyor, kullanmak istediğinize emin misiniz?" -msgid "" -"Provides a selection of desktop environments and tiling window managers, e." -"g. gnome, kde, sway" -msgstr "" -"Masaüstü ortamları ve otomatik hizalamalı pencere yöneticilerine bir seçenek " -"sunar, örnek olarak gnome, kde, sway" +msgid "Provides a selection of desktop environments and tiling window managers, e.g. gnome, kde, sway" +msgstr "Masaüstü ortamları ve otomatik hizalamalı pencere yöneticilerine bir seçenek sunar, örnek olarak gnome, kde, sway" msgid "Select your desired desktop environment" msgstr "Arzu ettiğiniz masaüstü ortamını seçin" -msgid "" -"A very basic installation that allows you to customize Arch Linux as you see " -"fit." -msgstr "" -"Arch Linux'u istediğin gibi kişiselleştirmeni sağlayan çok basit bir kurulum." +msgid "A very basic installation that allows you to customize Arch Linux as you see fit." +msgstr "Arch Linux'u istediğin gibi kişiselleştirmeni sağlayan çok basit bir kurulum." -msgid "" -"Provides a selection of various server packages to install and enable, e.g. " -"httpd, nginx, mariadb" -msgstr "" -"Kurmak ve aktif etmek için bazı seçilmiş çeşitli sunucu paketleri sunar, " -"örnek olarak httpd, nginx, mariadb" +msgid "Provides a selection of various server packages to install and enable, e.g. httpd, nginx, mariadb" +msgstr "Kurmak ve aktif etmek için bazı seçilmiş çeşitli sunucu paketleri sunar, örnek olarak httpd, nginx, mariadb" -msgid "" -"Choose which servers to install, if none then a minimal installation wil be " -"done" -msgstr "" -"Hangi sunucuların kurulacağını seçin, eğer hiçbiri seçilmezse minimal bir " -"kurulum gerçekleştirilecektir" +#, fuzzy +msgid "Choose which servers to install, if none then a minimal installation will be done" +msgstr "Hangi sunucuların kurulacağını seçin, eğer hiçbiri seçilmezse minimal bir kurulum gerçekleştirilecektir" msgid "Installs a minimal system as well as xorg and graphics drivers." msgstr "Xorg ve grafik sürücüleri ile minimal bir sistem kurar." @@ -784,29 +673,20 @@ msgstr "Xorg ve grafik sürücüleri ile minimal bir sistem kurar." msgid "Press Enter to continue." msgstr "Devam etmek için Enter'a bas." -msgid "" -"Would you like to chroot into the newly created installation and perform " -"post-installation configuration?" -msgstr "" -"Yeni oluşturulmuş kuruluma chroot etmek ve kurulum sonrası konfigürasyon " -"gerçekleştirmek ister misiniz?" +msgid "Would you like to chroot into the newly created installation and perform post-installation configuration?" +msgstr "Yeni oluşturulmuş kuruluma chroot etmek ve kurulum sonrası konfigürasyon gerçekleştirmek ister misiniz?" msgid "Are you sure you want to reset this setting?" msgstr "Bu ayarı sıfırlamak istediğinize emin misiniz?" msgid "Select one or more hard drives to use and configure\n" -msgstr "" -"Kullanmak ve yapılandırmak için bir ya da daha fazla sabit disk seçin\n" +msgstr "Kullanmak ve yapılandırmak için bir ya da daha fazla sabit disk seçin\n" msgid "Any modifications to the existing setting will reset the disk layout!" msgstr "Mevcut ayara herhangi bir modifikasyon disk şemasını sıfırlayacaktır!" -msgid "" -"If you reset the harddrive selection this will also reset the current disk " -"layout. Are you sure?" -msgstr "" -"Eğer sabit disk seçimini sıfırlarsanız bu ayrıca mevcut disk şemasını da " -"sıfırlayacaktır. Emin misiniz?" +msgid "If you reset the harddrive selection this will also reset the current disk layout. Are you sure?" +msgstr "Eğer sabit disk seçimini sıfırlarsanız bu ayrıca mevcut disk şemasını da sıfırlayacaktır. Emin misiniz?" msgid "Save and exit" msgstr "Kaydet ve çık" @@ -816,8 +696,7 @@ msgid "" "contains queued partitions, this will remove those, are you sure?" msgstr "" "{}\n" -"işlem sırasında bekleyen disk bölümleri bulunduruyor, bu onları kaldıracak, " -"emin misiniz?" +"işlem sırasında bekleyen disk bölümleri bulunduruyor, bu onları kaldıracak, emin misiniz?" msgid "No audio server" msgstr "Ses sunucusu yok" @@ -853,17 +732,11 @@ msgstr "Ekle: " msgid "Value: " msgstr "Değer: " -msgid "" -"You can skip selecting a drive and partitioning and use whatever drive-setup " -"is mounted at /mnt (experimental)" -msgstr "" -"Disk seçmeyi ve disk bölümlendirmeyi geçebilir ve disk kurulumu /mnt " -"dizininde neye mount (monte) ediliyse onu kullanabilirsiniz (deneysel)" +msgid "You can skip selecting a drive and partitioning and use whatever drive-setup is mounted at /mnt (experimental)" +msgstr "Disk seçmeyi ve disk bölümlendirmeyi geçebilir ve disk kurulumu /mnt dizininde neye mount (monte) ediliyse onu kullanabilirsiniz (deneysel)" msgid "Select one of the disks or skip and use /mnt as default" -msgstr "" -"Disklerden birini seçin ya da geçin ve /mnt dizinini varsayılan olarak " -"kullanın" +msgstr "Disklerden birini seçin ya da geçin ve /mnt dizinini varsayılan olarak kullanın" msgid "Select which partitions to mark for formatting:" msgstr "Biçimlendirme için işaretlenecek disk bölümünü seçin:" @@ -882,3 +755,48 @@ msgstr "Boş alan" msgid "Bus-type" msgstr "Bus(veri yolu)-tipi" + +#, fuzzy +msgid "Either root-password or at least 1 user with sudo privileges must be specified" +msgstr "Root (kök) şifresi ya da en azından 1 adet süper-kullanıcı belirtilmek zorunda" + +#, fuzzy +msgid "Enter username (leave blank to skip): " +msgstr "Ek kullanıcı oluşturmak için bir kullanıcı adı girin (geçmek için boş bırakın): " + +msgid "The username you entered is invalid. Try again" +msgstr "" + +#, fuzzy +msgid "Should \"{}\" be a superuser (sudo)?" +msgstr "{} bir süper kullanıcı (sudoer) olmalı mı?" + +#, fuzzy +msgid "Select which partitions to encrypt:" +msgstr "" +"{}\n" +"\n" +"Hangi disk bölümünün şifrelenmiş olarak işaretleneceğini seçin" + +msgid "very weak" +msgstr "" + +msgid "weak" +msgstr "" + +msgid "moderate" +msgstr "" + +msgid "strong" +msgstr "" + +#, fuzzy +msgid "Add subvolume" +msgstr " alt disk bölümü :{:16}" + +msgid "Edit subvolume" +msgstr "" + +#, fuzzy +msgid "Delete subvolume" +msgstr "Kullanıcı Sil" diff --git a/archinstall/locales/ur/LC_MESSAGES/base.mo b/archinstall/locales/ur/LC_MESSAGES/base.mo index dad80f9d..44e38ad4 100644 Binary files a/archinstall/locales/ur/LC_MESSAGES/base.mo and b/archinstall/locales/ur/LC_MESSAGES/base.mo differ diff --git a/archinstall/locales/ur/LC_MESSAGES/base.po b/archinstall/locales/ur/LC_MESSAGES/base.po index 9baa850c..710c08d7 100644 --- a/archinstall/locales/ur/LC_MESSAGES/base.po +++ b/archinstall/locales/ur/LC_MESSAGES/base.po @@ -256,10 +256,12 @@ msgstr "مقامی انکوڈنگ" msgid "Drive(s)" msgstr "ہارڈ ڈرائیوز" -msgid "Select disk layout" -msgstr "ڈسک لے آؤٹ کو منتخب کریں" +#, fuzzy +msgid "Disk layout" +msgstr "ڈسک لے آؤٹ کو محفوظ کریں" -msgid "Set encryption password" +#, fuzzy +msgid "Encryption password" msgstr "انکرپشن پاس ورڈ سیٹ کریں" msgid "Swap" @@ -268,7 +270,8 @@ msgstr "سواپ" msgid "Bootloader" msgstr "بوٹ لوڈر" -msgid "root password" +#, fuzzy +msgid "Root password" msgstr "روٹ پاس ورڈ" msgid "Superuser account" @@ -424,8 +427,9 @@ msgstr "ترمیم" msgid "Delete" msgstr "حذف" -msgid "Select an action for < {} >" -msgstr "< {} > کے لیے ایک عمل منتخب کریں" +#, fuzzy +msgid "Select an action for '{}'" +msgstr "'{}' کے لیے ایک عمل منتخب کریں" msgid "Copy to new key:" msgstr "نئی کلید میں کاپی کریں:" @@ -672,7 +676,7 @@ msgstr "" msgid "Provides a selection of various server packages to install and enable, e.g. httpd, nginx, mariadb" msgstr "" -msgid "Choose which servers to install, if none then a minimal installation wil be done" +msgid "Choose which servers to install, if none then a minimal installation will be done" msgstr "" msgid "Installs a minimal system as well as xorg and graphics drivers." @@ -759,6 +763,68 @@ msgstr "" "\n" "فارمیٹنگ کے لیے کس پارٹیشن کو ماسک کرنا ہے" +msgid "Use HSM to unlock encrypted drive" +msgstr "" + +msgid "Device" +msgstr "" + +msgid "Size" +msgstr "" + +msgid "Free space" +msgstr "" + +msgid "Bus-type" +msgstr "" + +#, fuzzy +msgid "Either root-password or at least 1 user with sudo privileges must be specified" +msgstr "روٹ پاس ورڈ یا کم از کم ۱ سپر یوزر کی وضاحت ہونی چاہیے" + +#, fuzzy +msgid "Enter username (leave blank to skip): " +msgstr "ایک اضافی صارف بنانے کے لیے صارف نام درج کریں (چھوڑنے کے لیے خالی چھوڑیں):" + +msgid "The username you entered is invalid. Try again" +msgstr "" + +#, fuzzy +msgid "Should \"{}\" be a superuser (sudo)?" +msgstr "کیا {} کو سپر یوزر (sudoer) ہونا چاہیے؟" + +#, fuzzy +msgid "Select which partitions to encrypt:" +msgstr "" +"{}\n" +"\n" +"منتخب کریں کہ کس پارٹیشن کو انکرپٹڈ یا خفیہ رکھنا ہے" + +msgid "very weak" +msgstr "" + +msgid "weak" +msgstr "" + +msgid "moderate" +msgstr "" + +msgid "strong" +msgstr "" + +msgid "Add subvolume" +msgstr "" + +msgid "Edit subvolume" +msgstr "" + +#, fuzzy +msgid "Delete subvolume" +msgstr "صارف کو حذف کریں" + +#~ msgid "Select disk layout" +#~ msgstr "ڈسک لے آؤٹ کو منتخب کریں" + #~ msgid "Add :" #~ msgstr "شامل:" -- cgit v1.2.3-54-g00ecf From 5c3c1312a49e1c110d4c5825fbb8242868544900 Mon Sep 17 00:00:00 2001 From: Daniel Girtler Date: Tue, 14 Jun 2022 22:38:39 +1000 Subject: Update list manager (#1331) * Rework partition management * Update * Update list manager * Update * Update Co-authored-by: Daniel Girtler --- archinstall/lib/disk/partition.py | 35 ++- archinstall/lib/menu/list_manager.py | 262 +++------------------ .../lib/user_interaction/manage_users_conf.py | 22 +- archinstall/lib/user_interaction/network_conf.py | 20 +- .../lib/user_interaction/partitioning_conf.py | 14 +- .../lib/user_interaction/subvolume_config.py | 32 ++- 6 files changed, 109 insertions(+), 276 deletions(-) (limited to 'archinstall') diff --git a/archinstall/lib/disk/partition.py b/archinstall/lib/disk/partition.py index 062c79ab..17c24d57 100644 --- a/archinstall/lib/disk/partition.py +++ b/archinstall/lib/disk/partition.py @@ -17,14 +17,16 @@ from .btrfs.btrfs_helpers import subvolume_info_from_path from .btrfs.btrfssubvolumeinfo import BtrfsSubvolumeInfo class Partition: - def __init__(self, + def __init__( + self, path: str, block_device: BlockDevice, part_id :Optional[str] = None, filesystem :Optional[str] = None, mountpoint :Optional[str] = None, encrypted :bool = False, - autodetect_filesystem :bool = True): + autodetect_filesystem :bool = True + ): if not part_id: part_id = os.path.basename(path) @@ -76,7 +78,30 @@ class Partition: else: return f'Partition(path={self.path}, size={self.size}, PARTUUID={self._safe_uuid}, fs={self.filesystem}{mount_repr})' + def as_json(self) -> Dict[str, Any]: + """ + this is used for the table representation of the partition (see FormattedOutput) + """ + partition_info = { + 'type': 'primary', + 'PARTUUID': self._safe_uuid, + 'wipe': self.allow_formatting, + 'boot': self.boot, + 'ESP': self.boot, + 'mountpoint': self.target_mountpoint, + 'encrypted': self._encrypted, + 'start': self.start, + 'size': self.end, + 'filesystem': self.filesystem_type + } + + return partition_info + def __dump__(self) -> Dict[str, Any]: + # TODO remove this in favour of as_json + + log(get_filesystem_type(self.path)) + return { 'type': 'primary', 'PARTUUID': self._safe_uuid, @@ -88,10 +113,14 @@ class Partition: 'start': self.start, 'size': self.end, 'filesystem': { - 'format': get_filesystem_type(self.path) + 'format': self.filesystem_type } } + @property + def filesystem_type(self) -> Optional[str]: + return get_filesystem_type(self.path) + @property def mountpoint(self) -> Optional[str]: try: diff --git a/archinstall/lib/menu/list_manager.py b/archinstall/lib/menu/list_manager.py index fe491caa..e7a9c2ac 100644 --- a/archinstall/lib/menu/list_manager.py +++ b/archinstall/lib/menu/list_manager.py @@ -1,94 +1,7 @@ -#!/usr/bin/python -""" -# Purpose -ListManager is a widget based on `menu` which allows the handling of repetitive operations in a list. -Imagine you have a list and want to add/copy/edit/delete their elements. With this widget you will be shown the list -``` -Vamos alla - -Use ESC to skip - - -> uno : 1 -dos : 2 -tres : 3 -cuatro : 4 -==> -Confirm and exit -Cancel -(Press "/" to search) -``` -Once you select one of the elements of the list, you will be promted with the action to be done to the selected element -``` - -uno : 1 -dos : 2 -> tres : 3 -cuatro : 4 -==> -Confirm and exit -Cancel -(Press "/" to search) - -Select an action for < {'tres': 3} > - - -Add -Copy -Edit -Delete -> Cancel -``` -You execute the action for this element (which might or not involve user interaction) and return to the list main page -till you call one of the options `confirm and exit` which returns the modified list or `cancel` which returns the original list unchanged. -If the list is empty one action can be defined as default (usually Add). We call it **null_action** -YOu can also define a **default_action** which will appear below the separator, not tied to any element of the list. Barring explicit definition, default_action will be the null_action -``` -==> -Add -Confirm and exit -Cancel -(Press "/" to search) -``` -The default implementation can handle simple lists and a key:value dictionary. The default actions are the shown above. -A sample of basic usage is included at the end of the source. - -More sophisticaded uses can be achieved by -* changing the action list and the null_action during initialization -``` - opciones = ListManager('Vamos alla',opciones,[str(_('Add')),str(_('Delete'))],_('Add')).run() -``` -* And using following methods to overwrite/define user actions and other details: -* * `reformat`. To change the appearance of the list elements -* * `action_list`. To modify the content of the action list once an element is defined. F.i. to avoid Delete to appear for certain elements, or to add/modify action based in the value of the element. -* * `exec_action` which contains the actual code to be executed when an action is selected - -The contents in the base class of this methods serve for a very basic usage, and are to be taken as samples. Thus the best use of this class would be to subclass in your code - -``` - class ObjectList(archinstall.ListManager): - def __init__(prompt,list): - self.ObjectAction = [... list of actions ...] - self.ObjectNullAction = one ObjectAction - super().__init__(prompt,list,ObjectActions,ObjectNullAction) - def reformat(self): - ... beautfy the output of the list - def action_list(self): - ... if you need some changes to the action list based on self.target - def exec_action(self): - if self.action == self.ObjectAction[0]: - performFirstAction(self.target, ...) - - ... - resultList = ObjectList(prompt,originallist).run() -``` - -""" import copy from os import system -from typing import Union, Any, TYPE_CHECKING, Dict, Optional, Tuple, List +from typing import Any, TYPE_CHECKING, Dict, Optional, Tuple, List -from .text_input import TextInput from .menu import Menu if TYPE_CHECKING: @@ -98,58 +11,38 @@ if TYPE_CHECKING: class ListManager: def __init__( self, - prompt :str, - base_list :Union[list,dict] , - base_actions :list = None, - null_action :str = None, - default_action :Union[str,list] = None, - header :Union[str,list] = None): + prompt: str, + entries: List[Any], + base_actions: List[str], + sub_menu_actions: List[str] + ): """ - param :prompt Text which will appear at the header + :param prompt: Text which will appear at the header type param: string | DeferredTranslation - param :base:_list list/dict of option to be shown / mainpulated - type param: list | dict - - param base_actions an alternate list of actions to the items of the object + :param entries: list/dict of option to be shown / manipulated type param: list - param: null_action action which will be taken (if any) when base_list is empty - type param: string - - param: default_action action which will be presented at the bottom of the list. Shouldn't need a target. If not present, null_action is set there. - Both Null and Default actions can be defined outside the base_actions list, as long as they are launched in exec_action - type param: string or list + :param base_actions: list of actions that is displayed in the main list manager, + usually global actions such as 'Add...' + type param: list - param: header one or more header lines for the list - type param: string or list + :param sub_menu_actions: list of actions available for a chosen entry + type param: list """ + self._original_data = copy.deepcopy(entries) + self._data = copy.deepcopy(entries) explainer = str(_('\n Choose an object from the list, and select one of the available actions for it to execute')) self._prompt = prompt + explainer if prompt else explainer - self._null_action = str(null_action) if null_action else None - - if not default_action: - self._default_action = [self._null_action] - elif isinstance(default_action,(list,tuple)): - self._default_action = default_action - else: - self._default_action = [str(default_action)] - - self._header = header if header else '' - self._cancel_action = str(_('Cancel')) - self._confirm_action = str(_('Confirm and exit')) self._separator = '' - self._bottom_list = [self._confirm_action, self._cancel_action] - self._bottom_item = [self._cancel_action] - self._base_actions = base_actions if base_actions else [str(_('Add')), str(_('Copy')), str(_('Edit')), str(_('Delete'))] - self._original_data = copy.deepcopy(base_list) - self._data = copy.deepcopy(base_list) # as refs, changes are immediate + self._confirm_action = str(_('Confirm and exit')) + self._cancel_action = str(_('Cancel')) - # default values for the null case - self.target: Optional[Any] = None - self.action = self._null_action + self._terminate_actions = [self._confirm_action, self._cancel_action] + self._base_actions = base_actions + self._sub_menu_actions = sub_menu_actions def run(self): while True: @@ -158,11 +51,6 @@ class ListManager: data_formatted = self.reformat(self._data) options, header = self._prepare_selection(data_formatted) - menu_header = self._header - - if header: - menu_header += header - system('clear') choice = Menu( @@ -177,27 +65,13 @@ class ListManager: show_search_hint=False ).run() - if not choice.value or choice.value in self._bottom_list: - self.action = choice + if choice.value in self._base_actions: + self._data = self.handle_action(choice.value, None, self._data) + elif choice.value in self._terminate_actions: break - - if choice.value and choice.value in self._default_action: - self.action = choice.value - self.target = None - self._data = self.exec_action(self._data) - continue - - if isinstance(self._data, dict): - data_key = data_formatted[choice.value] - key = self._data[data_key] - self.target = {data_key: key} - elif isinstance(self._data, list): - self.target = [d for d in self._data if d == data_formatted[choice.value]][0] - else: - self.target = self._data[data_formatted[choice.value]] - - # Possible enhancement. If run_actions returns false a message line indicating the failure - self.run_actions(choice.value) + else: # an entry of the existing selection was choosen + selected_entry = data_formatted[choice.value] + self._run_actions_on_entry(selected_entry) if choice.value == self._cancel_action: return self._original_data # return the original list @@ -217,16 +91,14 @@ class ListManager: if len(options) > 0: options.append(self._separator) - if self._default_action: - # done only for mypy -> todo fix the self._default_action declaration - options += [action for action in self._default_action if action] + options += self._base_actions + options += self._terminate_actions - options += self._bottom_list return options, header - def run_actions(self,prompt_data=''): - options = self.action_list() + self._bottom_item - display_value = self.selected_action_display(self.target) if self.target else prompt_data + def _run_actions_on_entry(self, entry: Any): + options = self._sub_menu_actions + [self._cancel_action] + display_value = self.selected_action_display(entry) prompt = _("Select an action for '{}'").format(display_value) @@ -236,14 +108,11 @@ class ListManager: sort=False, clear_screen=False, clear_menu_on_exit=False, - preset_values=self._bottom_item, show_search_hint=False ).run() - self.action = choice.value - - if self.action and self.action != self._cancel_action: - self._data = self.exec_action(self._data) + if choice.value and choice.value != self._cancel_action: + self._data = self.handle_action(choice.value, entry, self._data) def selected_action_display(self, selection: Any) -> str: # this will return the value to be displayed in the @@ -256,64 +125,7 @@ class ListManager: # in the header value (useful when displaying tables) raise NotImplementedError('Please implement me in the child class') - def action_list(self): - """ - can define alternate action list or customize the list for each item. - Executed after any item is selected, contained in self.target - """ - active_entry = self.target if self.target else None - - if active_entry is None: - return [self._base_actions[0]] - else: - return self._base_actions[1:] - - def exec_action(self, data: Any): - """ - what's executed one an item (self.target) and one action (self.action) is selected. - Should be overwritten by the user - The result is expected to update self._data in this routine, else it is ignored - The basic code is useful for simple lists and dictionaries (key:value pairs, both strings) - """ - # TODO guarantee unicity - if isinstance(self._data,list): - if self.action == str(_('Add')): - self.target = TextInput(_('Add: '),None).run() - self._data.append(self.target) - if self.action == str(_('Copy')): - while True: - target = TextInput(_('Copy to: '),self.target).run() - if target != self.target: - self._data.append(self.target) - break - elif self.action == str(_('Edit')): - tgt = self.target - idx = self._data.index(self.target) - result = TextInput(_('Edit: '),tgt).run() - self._data[idx] = result - elif self.action == str(_('Delete')): - del self._data[self._data.index(self.target)] - elif isinstance(self._data,dict): - # allows overwrites - if self.target: - origkey,origval = list(self.target.items())[0] - else: - origkey = None - origval = None - if self.action == str(_('Add')): - key = TextInput(_('Key: '),None).run() - value = TextInput(_('Value: '),None).run() - self._data[key] = value - if self.action == str(_('Copy')): - while True: - key = TextInput(_('Copy to new key:'),origkey).run() - if key != origkey: - self._data[key] = origval - break - elif self.action == str(_('Edit')): - value = TextInput(_('Edit {}: ').format(origkey), origval).run() - self._data[origkey] = value - elif self.action == str(_('Delete')): - del self._data[origkey] - - return self._data + def handle_action(self, action: Any, entry: Optional[Any], data: List[Any]) -> List[Any]: + # this function is called when a base action or + # a specific action for an entry is triggered + raise NotImplementedError('Please implement me in the child class') diff --git a/archinstall/lib/user_interaction/manage_users_conf.py b/archinstall/lib/user_interaction/manage_users_conf.py index 33c31342..a97328c2 100644 --- a/archinstall/lib/user_interaction/manage_users_conf.py +++ b/archinstall/lib/user_interaction/manage_users_conf.py @@ -25,7 +25,7 @@ class UserList(ListManager): str(_('Promote/Demote user')), str(_('Delete User')) ] - super().__init__(prompt, lusers, self._actions, self._actions[0]) + super().__init__(prompt, lusers, [self._actions[0]], self._actions[1:]) def reformat(self, data: List[User]) -> Dict[str, User]: table = FormattedOutput.as_table(data) @@ -45,27 +45,25 @@ class UserList(ListManager): def selected_action_display(self, user: User) -> str: return user.username - def exec_action(self, data: List[User]) -> List[User]: - active_user = self.target if self.target else None - - if self.action == self._actions[0]: # add + def handle_action(self, action: str, entry: Optional[User], data: List[User]) -> List[User]: + if action == self._actions[0]: # add new_user = self._add_user() if new_user is not None: # in case a user with the same username as an existing user # was created we'll replace the existing one data = [d for d in data if d.username != new_user.username] data += [new_user] - elif self.action == self._actions[1]: # change password - prompt = str(_('Password for user "{}": ').format(active_user.username)) + elif action == self._actions[1]: # change password + prompt = str(_('Password for user "{}": ').format(entry.username)) new_password = get_password(prompt=prompt) if new_password: - user = next(filter(lambda x: x == active_user, data), 1) + user = next(filter(lambda x: x == entry, data), 1) user.password = new_password - elif self.action == self._actions[2]: # promote/demote - user = next(filter(lambda x: x == active_user, data), 1) + elif action == self._actions[2]: # promote/demote + user = next(filter(lambda x: x == entry, data), 1) user.sudo = False if user.sudo else True - elif self.action == self._actions[3]: # delete - data = [d for d in data if d != active_user] + elif action == self._actions[3]: # delete + data = [d for d in data if d != entry] return data diff --git a/archinstall/lib/user_interaction/network_conf.py b/archinstall/lib/user_interaction/network_conf.py index 4f22b790..1908603e 100644 --- a/archinstall/lib/user_interaction/network_conf.py +++ b/archinstall/lib/user_interaction/network_conf.py @@ -29,7 +29,7 @@ class ManualNetworkConfig(ListManager): str(_('Delete interface')) ] - super().__init__(prompt, ifaces, self._actions, self._actions[0]) + super().__init__(prompt, ifaces, [self._actions[0]], self._actions[1:]) def reformat(self, data: List[NetworkConfiguration]) -> Dict[str, Optional[NetworkConfiguration]]: table = FormattedOutput.as_table(data) @@ -49,21 +49,19 @@ class ManualNetworkConfig(ListManager): def selected_action_display(self, iface: NetworkConfiguration) -> str: return iface.iface if iface.iface else '' - def exec_action(self, data: List[NetworkConfiguration]): - active_iface: Optional[NetworkConfiguration] = self.target if self.target else None - - if self.action == self._actions[0]: # add + def handle_action(self, action: str, entry: Optional[NetworkConfiguration], data: List[NetworkConfiguration]): + if action == self._actions[0]: # add iface_name = self._select_iface(data) if iface_name: iface = NetworkConfiguration(NicType.MANUAL, iface=iface_name) iface = self._edit_iface(iface) data += [iface] - elif active_iface: - if self.action == self._actions[1]: # edit interface - data = [d for d in data if d.iface != active_iface.iface] - data.append(self._edit_iface(active_iface)) - elif self.action == self._actions[2]: # delete - data = [d for d in data if d != active_iface] + elif entry: + if action == self._actions[1]: # edit interface + data = [d for d in data if d.iface != entry.iface] + data.append(self._edit_iface(entry)) + elif action == self._actions[2]: # delete + data = [d for d in data if d != entry] return data diff --git a/archinstall/lib/user_interaction/partitioning_conf.py b/archinstall/lib/user_interaction/partitioning_conf.py index 0f4784b6..8bf76121 100644 --- a/archinstall/lib/user_interaction/partitioning_conf.py +++ b/archinstall/lib/user_interaction/partitioning_conf.py @@ -154,9 +154,6 @@ def manage_new_and_existing_partitions(block_device: 'BlockDevice') -> Dict[str, block_device_struct = {"partitions": [partition.__dump__() for partition in block_device.partitions.values()]} original_layout = copy.deepcopy(block_device_struct) - # Test code: [part.__dump__() for part in block_device.partitions.values()] - # TODO: Squeeze in BTRFS subvolumes here - new_partition = str(_('Create a new partition')) suggest_partition_layout = str(_('Suggest partition layout')) delete_partition = str(_('Delete a partition')) @@ -209,6 +206,7 @@ def manage_new_and_existing_partitions(block_device: 'BlockDevice') -> Dict[str, return original_layout elif task == save_and_exit: break + if task == new_partition: from ..disk import valid_parted_position @@ -222,8 +220,9 @@ def manage_new_and_existing_partitions(block_device: 'BlockDevice') -> Dict[str, if fs_choice.type_ == MenuSelectionType.Esc: continue - prompt = _('Enter the start sector (percentage or block number, default: {}): ').format( - block_device.first_free_sector) + prompt = str(_('Enter the start sector (percentage or block number, default: {}): ')).format( + block_device.first_free_sector + ) start = input(prompt).strip() if not start.strip(): @@ -232,8 +231,9 @@ def manage_new_and_existing_partitions(block_device: 'BlockDevice') -> Dict[str, else: end_suggested = '100%' - prompt = _('Enter the end sector of the partition (percentage or block number, ex: {}): ').format( - end_suggested) + prompt = str(_('Enter the end sector of the partition (percentage or block number, ex: {}): ')).format( + end_suggested + ) end = input(prompt).strip() if not end.strip(): diff --git a/archinstall/lib/user_interaction/subvolume_config.py b/archinstall/lib/user_interaction/subvolume_config.py index e2797bba..94150dee 100644 --- a/archinstall/lib/user_interaction/subvolume_config.py +++ b/archinstall/lib/user_interaction/subvolume_config.py @@ -12,13 +12,13 @@ if TYPE_CHECKING: class SubvolumeList(ListManager): - def __init__(self, prompt: str, current_volumes: List[Subvolume]): + def __init__(self, prompt: str, subvolumes: List[Subvolume]): self._actions = [ str(_('Add subvolume')), str(_('Edit subvolume')), str(_('Delete subvolume')) ] - super().__init__(prompt, current_volumes, self._actions, self._actions[0]) + super().__init__(prompt, subvolumes, [self._actions[0]], self._actions[1:]) def reformat(self, data: List[Subvolume]) -> Dict[str, Optional[Subvolume]]: table = FormattedOutput.as_table(data) @@ -75,13 +75,8 @@ class SubvolumeList(ListManager): return subvolume - def exec_action(self, data: List[Subvolume]) -> List[Subvolume]: - if self.target: - active_subvolume = self.target - else: - active_subvolume = None - - if self.action == self._actions[0]: # add + def handle_action(self, action: str, entry: Optional[Subvolume], data: List[Subvolume]) -> List[Subvolume]: + if action == self._actions[0]: # add new_subvolume = self._add_subvolume() if new_subvolume is not None: @@ -89,14 +84,15 @@ class SubvolumeList(ListManager): # was created we'll replace the existing one data = [d for d in data if d.name != new_subvolume.name] data += [new_subvolume] - elif self.action == self._actions[1]: # edit subvolume - new_subvolume = self._add_subvolume(active_subvolume) - - if new_subvolume is not None: - # we'll remove the original subvolume and add the modified version - data = [d for d in data if d.name != active_subvolume.name and d.name != new_subvolume.name] - data += [new_subvolume] - elif self.action == self._actions[2]: # delete - data = [d for d in data if d != active_subvolume] + elif entry is not None: + if action == self._actions[1]: # edit subvolume + new_subvolume = self._add_subvolume(entry) + + if new_subvolume is not None: + # we'll remove the original subvolume and add the modified version + data = [d for d in data if d.name != entry.name and d.name != new_subvolume.name] + data += [new_subvolume] + elif action == self._actions[2]: # delete + data = [d for d in data if d != entry] return data -- cgit v1.2.3-54-g00ecf From 9194f6d85965f435f8d0ae44ba20e73cc761eb44 Mon Sep 17 00:00:00 2001 From: Daniel Girtler Date: Tue, 26 Jul 2022 18:46:50 +1000 Subject: Cleanup partition (#1333) * Cleanup partition * Update * Remove unused method * Update partitioning * Update * Update * Fix mypy Co-authored-by: Daniel Girtler --- archinstall/lib/disk/blockdevice.py | 10 +- archinstall/lib/disk/btrfs/btrfspartition.py | 19 +- archinstall/lib/disk/filesystem.py | 26 +- archinstall/lib/disk/helpers.py | 10 +- archinstall/lib/disk/partition.py | 429 +++++++++------------ archinstall/lib/luks.py | 6 +- .../lib/user_interaction/partitioning_conf.py | 10 - 7 files changed, 227 insertions(+), 283 deletions(-) (limited to 'archinstall') diff --git a/archinstall/lib/disk/blockdevice.py b/archinstall/lib/disk/blockdevice.py index 4e207bf4..736bacbc 100644 --- a/archinstall/lib/disk/blockdevice.py +++ b/archinstall/lib/disk/blockdevice.py @@ -88,9 +88,6 @@ class BlockDevice: raise KeyError(f'{self.info} does not contain information: "{key}"') - def __len__(self) -> int: - return len(self.partitions) - def __lt__(self, left_comparitor :'BlockDevice') -> bool: return self._path < left_comparitor.path @@ -121,6 +118,8 @@ class BlockDevice: def _load_partitions(self): from .partition import Partition + self._partitions.clear() + lsblk_info = self._call_lsblk(self._path) device = lsblk_info['blockdevices'][0] self._partitions.clear() @@ -233,8 +232,6 @@ class BlockDevice: @property def partitions(self) -> Dict[str, 'Partition']: - self._partprobe() - self._load_partitions() return OrderedDict(sorted(self._partitions.items())) @property @@ -282,7 +279,7 @@ class BlockDevice: try: if uuid and partition.uuid and partition.uuid.lower() == uuid.lower(): return partition - elif partuuid and partition.part_uuid.lower() == partuuid.lower(): + elif partuuid and partition.part_uuid and partition.part_uuid.lower() == partuuid.lower(): return partition except DiskError as error: # Most likely a blockdevice that doesn't support or use UUID's @@ -291,6 +288,7 @@ class BlockDevice: pass log(f"uuid {uuid} or {partuuid} not found. Waiting {storage.get('DISK_TIMEOUTS', 1) * count}s for next attempt",level=logging.DEBUG) + self.flush_cache() time.sleep(storage.get('DISK_TIMEOUTS', 1) * count) log(f"Could not find {uuid}/{partuuid} in disk after 5 retries", level=logging.INFO) diff --git a/archinstall/lib/disk/btrfs/btrfspartition.py b/archinstall/lib/disk/btrfs/btrfspartition.py index a05f1527..d04c9b98 100644 --- a/archinstall/lib/disk/btrfs/btrfspartition.py +++ b/archinstall/lib/disk/btrfs/btrfspartition.py @@ -17,22 +17,11 @@ if TYPE_CHECKING: from ...installer import Installer from .btrfssubvolumeinfo import BtrfsSubvolumeInfo + class BTRFSPartition(Partition): def __init__(self, *args, **kwargs): Partition.__init__(self, *args, **kwargs) - def __repr__(self, *args :str, **kwargs :str) -> str: - mount_repr = '' - if self.mountpoint: - mount_repr = f", mounted={self.mountpoint}" - elif self.target_mountpoint: - mount_repr = f", rel_mountpoint={self.target_mountpoint}" - - if self._encrypted: - return f'BTRFSPartition(path={self.path}, size={self.size}, PARTUUID={self._safe_uuid}, parent={self.real_device}, fs={self.filesystem}{mount_repr})' - else: - return f'BTRFSPartition(path={self.path}, size={self.size}, PARTUUID={self._safe_uuid}, fs={self.filesystem}{mount_repr})' - @property def subvolumes(self): for filesystem in findmnt(pathlib.Path(self.path), recurse=True).get('filesystems', []): @@ -40,11 +29,11 @@ class BTRFSPartition(Partition): yield subvolume_info_from_path(filesystem['target']) def iterate_children(struct): - for child in struct.get('children', []): + for c in struct.get('children', []): if '[' in child.get('source', ''): - yield subvolume_info_from_path(child['target']) + yield subvolume_info_from_path(c['target']) - for sub_child in iterate_children(child): + for sub_child in iterate_children(c): yield sub_child for child in iterate_children(filesystem): diff --git a/archinstall/lib/disk/filesystem.py b/archinstall/lib/disk/filesystem.py index 1c7a801b..90656308 100644 --- a/archinstall/lib/disk/filesystem.py +++ b/archinstall/lib/disk/filesystem.py @@ -210,7 +210,14 @@ class Filesystem: # TODO: Implement this with declarative profiles instead. raise ValueError("Installation().use_entire_disk() has to be re-worked.") - def add_partition(self, partition_type :str, start :str, end :str, partition_format :Optional[str] = None, skip_mklabel :bool = False) -> Partition: + def add_partition( + self, + partition_type :str, + start :str, + end :str, + partition_format :Optional[str] = None, + skip_mklabel :bool = False + ) -> Partition: log(f'Adding partition to {self.blockdevice}, {start}->{end}', level=logging.INFO) if len(self.blockdevice.partitions) == 0 and skip_mklabel is False: @@ -232,6 +239,7 @@ class Filesystem: except DiskError: pass + # TODO this check should probably run in the setup process rather than during the installation if self.mode == MBR: if len(self.blockdevice.partitions) > 3: DiskError("Too many partitions on disk, MBR disks can only have 3 primary partitions") @@ -246,14 +254,9 @@ class Filesystem: if self.parted(parted_string): for count in range(storage.get('DISK_RETRY_ATTEMPTS', 3)): self.partprobe() + self.blockdevice.flush_cache() - new_partition_uuids = [] - for partition in self.blockdevice.partitions.values(): - try: - new_partition_uuids.append(partition.part_uuid) - except DiskError: - pass - + new_partition_uuids = [partition.part_uuid for partition in self.blockdevice.partitions.values()] new_partuuid_set = (set(previous_partuuids) ^ set(new_partition_uuids)) if len(new_partuuid_set) and (new_partuuid := new_partuuid_set.pop()): @@ -263,17 +266,20 @@ class Filesystem: log(f'Blockdevice: {self.blockdevice}', level=logging.ERROR, fg="red") log(f'Partitions: {self.blockdevice.partitions}', level=logging.ERROR, fg="red") log(f'Partition set: {new_partuuid_set}', level=logging.ERROR, fg="red") - log(f'New UUID: {[new_partuuid]}', level=logging.ERROR, fg="red") + log(f'New PARTUUID: {[new_partuuid]}', level=logging.ERROR, fg="red") log(f'get_partition(): {self.blockdevice.get_partition}', level=logging.ERROR, fg="red") raise err else: log(f"Could not get UUID for partition. Waiting {storage.get('DISK_TIMEOUTS', 1) * count}s before retrying.",level=logging.DEBUG) time.sleep(storage.get('DISK_TIMEOUTS', 1) * count) + total_partitions = set([partition.part_uuid for partition in self.blockdevice.partitions.values()]) + total_partitions.update(previous_partuuids) + # TODO: This should never be able to happen log(f"Could not find the new PARTUUID after adding the partition.", level=logging.ERROR, fg="red") log(f"Previous partitions: {previous_partuuids}", level=logging.ERROR, fg="red") - log(f"New partitions: {(previous_partuuids ^ {partition.part_uuid for partition in self.blockdevice.partitions.values()})}", level=logging.ERROR, fg="red") + log(f"New partitions: {total_partitions}", level=logging.ERROR, fg="red") raise DiskError(f"Could not add partition using: {parted_string}") def set_name(self, partition: int, name: str) -> bool: diff --git a/archinstall/lib/disk/helpers.py b/archinstall/lib/disk/helpers.py index 660594ed..c8ac564e 100644 --- a/archinstall/lib/disk/helpers.py +++ b/archinstall/lib/disk/helpers.py @@ -370,7 +370,7 @@ def get_all_targets(data :Dict[str, Any], filters :Dict[str, None] = {}) -> Dict return filters -def get_partitions_in_use(mountpoint :str) -> List[Partition]: +def get_partitions_in_use(mountpoint :str) -> Dict[str, Any]: from .partition import Partition try: @@ -393,8 +393,12 @@ def get_partitions_in_use(mountpoint :str) -> List[Partition]: if not type(blockdev) in (Partition, MapperDev): continue - for blockdev_mountpoint in blockdev.mount_information: - block_devices_mountpoints[blockdev_mountpoint['target']] = blockdev + if isinstance(blockdev, Partition): + for blockdev_mountpoint in blockdev.mountpoints: + block_devices_mountpoints[blockdev_mountpoint] = blockdev + else: + for blockdev_mountpoint in blockdev.mount_information: + block_devices_mountpoints[blockdev_mountpoint['target']] = blockdev log(f'Filtering available mounts {block_devices_mountpoints} to those under {mountpoint}', level=logging.DEBUG) diff --git a/archinstall/lib/disk/partition.py b/archinstall/lib/disk/partition.py index 17c24d57..4028f114 100644 --- a/archinstall/lib/disk/partition.py +++ b/archinstall/lib/disk/partition.py @@ -1,14 +1,16 @@ import glob -import pathlib import time import logging import json import os import hashlib +import typing +from dataclasses import dataclass +from pathlib import Path from typing import Optional, Dict, Any, List, Union, Iterator from .blockdevice import BlockDevice -from .helpers import find_mountpoint, get_filesystem_type, convert_size_to_gb, split_bind_name +from .helpers import get_filesystem_type, convert_size_to_gb, split_bind_name from ..storage import storage from ..exceptions import DiskError, SysCallError, UnknownFilesystemFormat from ..output import log @@ -16,6 +18,26 @@ from ..general import SysCommand from .btrfs.btrfs_helpers import subvolume_info_from_path from .btrfs.btrfssubvolumeinfo import BtrfsSubvolumeInfo + +@dataclass +class PartitionInfo: + pttype: str + partuuid: str + uuid: str + start: Optional[int] + end: Optional[int] + bootable: bool + size: float + sector_size: int + filesystem_type: str + mountpoints: List[Path] + + def get_first_mountpoint(self) -> Optional[Path]: + if len(self.mountpoints) > 0: + return self.mountpoints[0] + return None + + class Partition: def __init__( self, @@ -25,38 +47,37 @@ class Partition: filesystem :Optional[str] = None, mountpoint :Optional[str] = None, encrypted :bool = False, - autodetect_filesystem :bool = True + autodetect_filesystem :bool = True, ): - if not part_id: part_id = os.path.basename(path) - self.block_device = block_device - if type(self.block_device) is str: + if type(block_device) is str: raise ValueError(f"Partition()'s 'block_device' parameter has to be a archinstall.BlockDevice() instance!") - self.path = path - self.part_id = part_id - self.target_mountpoint = mountpoint - self.filesystem = filesystem + self.block_device = block_device + self._path = path + self._part_id = part_id + self._target_mountpoint = mountpoint self._encrypted = None - self.encrypted = encrypted - self.allow_formatting = False + self._encrypted = encrypted + self._wipe = False + self._type = 'primary' if mountpoint: self.mount(mountpoint) - try: - self.mount_information = list(find_mountpoint(self.path)) - except DiskError: - self.mount_information = [{}] + self._partition_info = self._fetch_information() - if not self.filesystem and autodetect_filesystem: - self.filesystem = get_filesystem_type(path) + if not autodetect_filesystem and filesystem: + self._partition_info.filesystem_type = filesystem - if self.filesystem == 'crypto_LUKS': - self.encrypted = True + if self._partition_info.filesystem_type == 'crypto_LUKS': + self._encrypted = True + # I hate doint this but I'm currently unsure where this + # is acutally used to be able to fix the typing issues properly + @typing.no_type_check def __lt__(self, left_comparitor :BlockDevice) -> bool: if type(left_comparitor) == Partition: left_comparitor = left_comparitor.path @@ -64,254 +85,191 @@ class Partition: left_comparitor = str(left_comparitor) # The goal is to check if /dev/nvme0n1p1 comes before /dev/nvme0n1p5 - return self.path < left_comparitor + return self._path < left_comparitor def __repr__(self, *args :str, **kwargs :str) -> str: mount_repr = '' - if self.mountpoint: - mount_repr = f", mounted={self.mountpoint}" - elif self.target_mountpoint: - mount_repr = f", rel_mountpoint={self.target_mountpoint}" + if mountpoint := self._partition_info.get_first_mountpoint(): + mount_repr = f", mounted={mountpoint}" + elif self._target_mountpoint: + mount_repr = f", rel_mountpoint={self._target_mountpoint}" + + classname = self.__class__.__name__ if self._encrypted: - return f'Partition(path={self.path}, size={self.size}, PARTUUID={self._safe_uuid}, parent={self.real_device}, fs={self.filesystem}{mount_repr})' + return f'{classname}(path={self._path}, size={self.size}, PARTUUID={self.part_uuid}, parent={self.real_device}, fs={self._partition_info.filesystem_type}{mount_repr})' else: - return f'Partition(path={self.path}, size={self.size}, PARTUUID={self._safe_uuid}, fs={self.filesystem}{mount_repr})' + return f'{classname}(path={self._path}, size={self.size}, PARTUUID={self.part_uuid}, fs={self._partition_info.filesystem_type}{mount_repr})' def as_json(self) -> Dict[str, Any]: """ this is used for the table representation of the partition (see FormattedOutput) """ partition_info = { - 'type': 'primary', - 'PARTUUID': self._safe_uuid, - 'wipe': self.allow_formatting, + 'type': self._type, + 'PARTUUID': self.part_uuid, + 'wipe': self._wipe, 'boot': self.boot, 'ESP': self.boot, - 'mountpoint': self.target_mountpoint, + 'mountpoint': self._target_mountpoint, 'encrypted': self._encrypted, 'start': self.start, 'size': self.end, - 'filesystem': self.filesystem_type + 'filesystem': self._partition_info.filesystem_type } return partition_info def __dump__(self) -> Dict[str, Any]: # TODO remove this in favour of as_json - - log(get_filesystem_type(self.path)) - return { - 'type': 'primary', - 'PARTUUID': self._safe_uuid, - 'wipe': self.allow_formatting, + 'type': self._type, + 'PARTUUID': self.part_uuid, + 'wipe': self._wipe, 'boot': self.boot, 'ESP': self.boot, - 'mountpoint': self.target_mountpoint, + 'mountpoint': self._target_mountpoint, 'encrypted': self._encrypted, 'start': self.start, 'size': self.end, 'filesystem': { - 'format': self.filesystem_type + 'format': self._partition_info.filesystem_type } } - @property - def filesystem_type(self) -> Optional[str]: - return get_filesystem_type(self.path) + def _call_lsblk(self) -> Dict[str, Any]: + self.partprobe() + output = SysCommand(f"lsblk --json -b -o+LOG-SEC,SIZE,PTTYPE,PARTUUID,UUID,FSTYPE {self.device_path}").decode('UTF-8') - @property - def mountpoint(self) -> Optional[str]: - try: - data = json.loads(SysCommand(f"findmnt --json -R {self.path}").decode()) - for filesystem in data['filesystems']: - return pathlib.Path(filesystem.get('target')) + if output: + lsblk_info = json.loads(output) + return lsblk_info - except SysCallError as error: - # Not mounted anywhere most likely - log(f"Could not locate mount information for {self.path}: {error}", level=logging.DEBUG, fg="grey") - pass - - return None + raise DiskError(f'Failed to read disk "{self.device_path}" with lsblk') - @property - def sector_size(self) -> Optional[int]: - output = json.loads(SysCommand(f"lsblk --json -o+LOG-SEC {self.device_path}").decode('UTF-8')) + def _call_sfdisk(self) -> Dict[str, Any]: + output = SysCommand(f"sfdisk --json {self.block_device.path}").decode('UTF-8') - for device in output['blockdevices']: - return device.get('log-sec', None) + if output: + sfdisk_info = json.loads(output) + partitions = sfdisk_info.get('partitiontable', {}).get('partitions', []) + node = list(filter(lambda x: x['node'] == self._path, partitions)) - @property - def start(self) -> Optional[str]: - output = json.loads(SysCommand(f"sfdisk --json {self.block_device.path}").decode('UTF-8')) + if len(node) > 0: + return node[0] - for partition in output.get('partitiontable', {}).get('partitions', []): - if partition['node'] == self.path: - return partition['start'] # * self.sector_size + return {} - @property - def end(self) -> Optional[str]: - # TODO: actually this is size in sectors unit - # TODO: Verify that the logic holds up, that 'size' is the size without 'start' added to it. - output = json.loads(SysCommand(f"sfdisk --json {self.block_device.path}").decode('UTF-8')) + raise DiskError(f'Failed to read disk "{self.block_device.path}" with sfdisk') - for partition in output.get('partitiontable', {}).get('partitions', []): - if partition['node'] == self.path: - return partition['size'] # * self.sector_size + def _fetch_information(self) -> PartitionInfo: + lsblk_info = self._call_lsblk() + sfdisk_info = self._call_sfdisk() + device = lsblk_info['blockdevices'][0] - @property - def end_sectors(self) -> Optional[str]: - output = json.loads(SysCommand(f"sfdisk --json {self.block_device.path}").decode('UTF-8')) + mountpoints = [Path(mountpoint) for mountpoint in device['mountpoints'] if mountpoint] + bootable = sfdisk_info.get('bootable', False) or sfdisk_info.get('type', '') == 'C12A7328-F81F-11D2-BA4B-00A0C93EC93B' - for partition in output.get('partitiontable', {}).get('partitions', []): - if partition['node'] == self.path: - return partition['start'] + partition['size'] + return PartitionInfo( + pttype=device['pttype'], + partuuid=device['partuuid'], + uuid=device['uuid'], + sector_size=device['log-sec'], + size=convert_size_to_gb(device['size']), + start=sfdisk_info.get('start', None), + end=sfdisk_info.get('size', None), + bootable=bootable, + filesystem_type=device['fstype'], + mountpoints=mountpoints + ) @property - def size(self) -> Optional[float]: - for i in range(storage['DISK_RETRY_ATTEMPTS']): - self.partprobe() - time.sleep(max(0.1, storage['DISK_TIMEOUTS'] * i)) - - try: - lsblk = json.loads(SysCommand(f"lsblk --json -b -o+SIZE {self.device_path}").decode()) - - for device in lsblk['blockdevices']: - return convert_size_to_gb(device['size']) - except SysCallError as error: - if error.exit_code == 8192: - return None - else: - raise error + def target_mountpoint(self) -> Optional[str]: + return self._target_mountpoint @property - def boot(self) -> bool: - output = json.loads(SysCommand(f"sfdisk --json {self.block_device.path}").decode('UTF-8')) - - for partition in output.get('partitiontable', {}).get('partitions', []): - if partition['node'] == self.path: - # first condition is for MBR disks, second for GPT disks - return partition.get('bootable', False) or partition.get('type','') == 'C12A7328-F81F-11D2-BA4B-00A0C93EC93B' - - return False + def path(self) -> str: + return self._path @property - def partition_type(self) -> Optional[str]: - lsblk = json.loads(SysCommand(f"lsblk --json -o+PTTYPE {self.device_path}").decode('UTF-8')) - - for device in lsblk['blockdevices']: - return device['pttype'] + def filesystem(self) -> str: + return self._partition_info.filesystem_type @property - def part_uuid(self) -> str: - """ - Returns the PARTUUID as returned by lsblk. - This is more reliable than relying on /dev/disk/by-partuuid as - it doesn't seam to be able to detect md raid partitions. - For bind mounts all the subvolumes share the same uuid - """ - for i in range(storage['DISK_RETRY_ATTEMPTS']): - if not self.partprobe(): - raise DiskError(f"Could not perform partprobe on {self.device_path}") - - time.sleep(max(0.1, storage['DISK_TIMEOUTS'] * i)) - - partuuid = self._safe_part_uuid - if partuuid: - return partuuid - - raise DiskError(f"Could not get PARTUUID for {self.path} using 'blkid -s PARTUUID -o value {self.path}'") + def mountpoint(self) -> Optional[Path]: + if len(self.mountpoints) > 0: + return self.mountpoints[0] + return None @property - def uuid(self) -> Optional[str]: - """ - Returns the UUID as returned by lsblk for the **partition**. - This is more reliable than relying on /dev/disk/by-uuid as - it doesn't seam to be able to detect md raid partitions. - For bind mounts all the subvolumes share the same uuid - """ - for i in range(storage['DISK_RETRY_ATTEMPTS']): - if not self.partprobe(): - raise DiskError(f"Could not perform partprobe on {self.device_path}") + def mountpoints(self) -> List[Path]: + return self._partition_info.mountpoints - time.sleep(storage.get('DISK_TIMEOUTS', 1) * i) - - partuuid = self._safe_uuid - if partuuid: - return partuuid - - raise DiskError(f"Could not get PARTUUID for {self.path} using 'blkid -s PARTUUID -o value {self.path}'") + @property + def sector_size(self) -> int: + return self._partition_info.sector_size @property - def _safe_uuid(self) -> Optional[str]: - """ - A near copy of self.uuid but without any delays. - This function should only be used where uuid is not crucial. - For instance when you want to get a __repr__ of the class. - """ - if not self.partprobe(): - if self.block_device.partition_type == 'iso9660': - return None + def start(self) -> Optional[int]: + return self._partition_info.start - log(f"Could not reliably refresh PARTUUID of partition {self.device_path} due to partprobe error.", level=logging.DEBUG) + @property + def end(self) -> Optional[int]: + return self._partition_info.end - try: - return SysCommand(f'blkid -s UUID -o value {self.device_path}').decode('UTF-8').strip() - except SysCallError as error: - if self.block_device.partition_type == 'iso9660': - # Parent device is a Optical Disk (.iso dd'ed onto a device for instance) - return None + @property + def end_sectors(self) -> Optional[int]: + start = self._partition_info.start + end = self._partition_info.end + if start and end: + return start + end + return None - log(f"Could not get PARTUUID of partition using 'blkid -s UUID -o value {self.device_path}': {error}") + @property + def size(self) -> Optional[float]: + return self._partition_info.size @property - def _safe_part_uuid(self) -> Optional[str]: - """ - A near copy of self.uuid but without any delays. - This function should only be used where uuid is not crucial. - For instance when you want to get a __repr__ of the class. - """ - if not self.partprobe(): - if self.block_device.partition_type == 'iso9660': - return None + def boot(self) -> bool: + return self._partition_info.bootable - log(f"Could not reliably refresh PARTUUID of partition {self.device_path} due to partprobe error.", level=logging.DEBUG) + @property + def partition_type(self) -> Optional[str]: + return self._partition_info.pttype - try: - return self.block_device.uuid - except SysCallError as error: - if self.block_device.partition_type == 'iso9660': - # Parent device is a Optical Disk (.iso dd'ed onto a device for instance) - return None + @property + def part_uuid(self) -> str: + return self._partition_info.partuuid - log(f"Could not get PARTUUID of partition using 'blkid -s PARTUUID -o value {self.device_path}': {error}") + @property + def uuid(self) -> Optional[str]: + return self._partition_info.uuid @property def encrypted(self) -> Union[bool, None]: return self._encrypted - @encrypted.setter - def encrypted(self, value: bool) -> None: - self._encrypted = value - @property def parent(self) -> str: return self.real_device @property def real_device(self) -> str: - for blockdevice in json.loads(SysCommand('lsblk -J').decode('UTF-8'))['blockdevices']: - if parent := self.find_parent_of(blockdevice, os.path.basename(self.device_path)): - return f"/dev/{parent}" - # raise DiskError(f'Could not find appropriate parent for encrypted partition {self}') - return self.path + output = SysCommand('lsblk -J').decode('UTF-8') + + if output: + for blockdevice in json.loads(output)['blockdevices']: + if parent := self.find_parent_of(blockdevice, os.path.basename(self.device_path)): + return f"/dev/{parent}" + return self._path + + raise DiskError('Unable to get disk information for command "lsblk -J"') @property def device_path(self) -> str: - """ for bind mounts returns the phisical path of the partition + """ for bind mounts returns the physical path of the partition """ - device_path, bind_name = split_bind_name(self.path) + device_path, bind_name = split_bind_name(self._path) return device_path @property @@ -319,7 +277,7 @@ class Partition: """ for bind mounts returns the bind name (subvolume path). Returns none if this property does not exist """ - device_path, bind_name = split_bind_name(self.path) + device_path, bind_name = split_bind_name(self._path) return bind_name @property @@ -330,29 +288,29 @@ class Partition: for child in information.get('children', []): if target := child.get('target'): if child.get('fstype') == 'btrfs': - if subvolume := subvolume_info_from_path(pathlib.Path(target)): + if subvolume := subvolume_info_from_path(Path(target)): yield subvolume if child.get('children'): for subchild in iterate_children_recursively(child): yield subchild - for mountpoint in self.mount_information: - if result := findmnt(pathlib.Path(mountpoint['target'])): - for filesystem in result.get('filesystems', []): - if mountpoint.get('fstype') == 'btrfs': - if subvolume := subvolume_info_from_path(pathlib.Path(mountpoint['target'])): + if self._partition_info.filesystem_type == 'btrfs': + for mountpoint in self._partition_info.mountpoints: + if result := findmnt(mountpoint): + for filesystem in result.get('filesystems', []): + if subvolume := subvolume_info_from_path(mountpoint): yield subvolume - for child in iterate_children_recursively(filesystem): - yield child + for child in iterate_children_recursively(filesystem): + yield child def partprobe(self) -> bool: try: if self.block_device: return 0 == SysCommand(f'partprobe {self.block_device.device}').exit_code except SysCallError as error: - log(f"Unreliable results might be given for {self.path} due to partprobe error: {error}", level=logging.DEBUG) + log(f"Unreliable results might be given for {self._path} due to partprobe error: {error}", level=logging.DEBUG) return False @@ -364,19 +322,20 @@ class Partition: with luks2(self, storage.get('ENC_IDENTIFIER', 'ai') + 'loop', password, auto_unmount=True) as unlocked_device: return unlocked_device.filesystem except SysCallError: - return None + pass + return None def has_content(self) -> bool: - fs_type = get_filesystem_type(self.path) + fs_type = self._partition_info.filesystem_type if not fs_type or "swap" in fs_type: return False temporary_mountpoint = '/tmp/' + hashlib.md5(bytes(f"{time.time()}", 'UTF-8') + os.urandom(12)).hexdigest() - temporary_path = pathlib.Path(temporary_mountpoint) + temporary_path = Path(temporary_mountpoint) temporary_path.mkdir(parents=True, exist_ok=True) - if (handle := SysCommand(f'/usr/bin/mount {self.path} {temporary_mountpoint}')).exit_code != 0: - raise DiskError(f'Could not mount and check for content on {self.path} because: {b"".join(handle)}') + if (handle := SysCommand(f'/usr/bin/mount {self._path} {temporary_mountpoint}')).exit_code != 0: + raise DiskError(f'Could not mount and check for content on {self._path} because: {handle}') files = len(glob.glob(f"{temporary_mountpoint}/*")) iterations = 0 @@ -387,14 +346,14 @@ class Partition: return True if files > 0 else False - def encrypt(self, *args :str, **kwargs :str) -> str: + def encrypt(self, password: Optional[str] = None) -> str: """ A wrapper function for luks2() instances and the .encrypt() method of that instance. """ from ..luks import luks2 handle = luks2(self, None, None) - return handle.encrypt(self, *args, **kwargs) + return handle.encrypt(self, password=password) def format(self, filesystem :Optional[str] = None, path :Optional[str] = None, log_formatting :bool = True, options :List[str] = [], retry :bool = True) -> bool: """ @@ -402,17 +361,17 @@ class Partition: the formatting functionality and in essence the support for the given filesystem. """ if filesystem is None: - filesystem = self.filesystem + filesystem = self._partition_info.filesystem_type if path is None: - path = self.path + path = self._path # This converts from fat32 -> vfat to unify filesystem names filesystem = get_mount_fs_type(filesystem) # To avoid "unable to open /dev/x: No such file or directory" start_wait = time.time() - while pathlib.Path(path).exists() is False and time.time() - start_wait < 10: + while Path(path).exists() is False and time.time() - start_wait < 10: time.sleep(0.025) if log_formatting: @@ -422,57 +381,57 @@ class Partition: if filesystem == 'btrfs': options = ['-f'] + options - if 'UUID:' not in (mkfs := SysCommand(f"/usr/bin/mkfs.btrfs {' '.join(options)} {path}").decode('UTF-8')): + mkfs = SysCommand(f"/usr/bin/mkfs.btrfs {' '.join(options)} {path}").decode('UTF-8') + if mkfs and 'UUID:' not in mkfs: raise DiskError(f'Could not format {path} with {filesystem} because: {mkfs}') - self.filesystem = filesystem + self._partition_info.filesystem_type = filesystem elif filesystem == 'vfat': options = ['-F32'] + options log(f"/usr/bin/mkfs.vfat {' '.join(options)} {path}") if (handle := SysCommand(f"/usr/bin/mkfs.vfat {' '.join(options)} {path}")).exit_code != 0: raise DiskError(f"Could not format {path} with {filesystem} because: {handle.decode('UTF-8')}") - self.filesystem = filesystem + self._partition_info.filesystem_type = filesystem elif filesystem == 'ext4': options = ['-F'] + options if (handle := SysCommand(f"/usr/bin/mkfs.ext4 {' '.join(options)} {path}")).exit_code != 0: raise DiskError(f"Could not format {path} with {filesystem} because: {handle.decode('UTF-8')}") - self.filesystem = filesystem + self._partition_info.filesystem_type = filesystem elif filesystem == 'ext2': options = ['-F'] + options if (handle := SysCommand(f"/usr/bin/mkfs.ext2 {' '.join(options)} {path}")).exit_code != 0: - raise DiskError(f'Could not format {path} with {filesystem} because: {b"".join(handle)}') - self.filesystem = 'ext2' - + raise DiskError(f"Could not format {path} with {filesystem} because: {handle.decode('UTF-8')}") + self._partition_info.filesystem_type = 'ext2' elif filesystem == 'xfs': options = ['-f'] + options if (handle := SysCommand(f"/usr/bin/mkfs.xfs {' '.join(options)} {path}")).exit_code != 0: raise DiskError(f"Could not format {path} with {filesystem} because: {handle.decode('UTF-8')}") - self.filesystem = filesystem + self._partition_info.filesystem_type = filesystem elif filesystem == 'f2fs': options = ['-f'] + options if (handle := SysCommand(f"/usr/bin/mkfs.f2fs {' '.join(options)} {path}")).exit_code != 0: raise DiskError(f"Could not format {path} with {filesystem} because: {handle.decode('UTF-8')}") - self.filesystem = filesystem + self._partition_info.filesystem_type = filesystem elif filesystem == 'ntfs3': options = ['-f'] + options if (handle := SysCommand(f"/usr/bin/mkfs.ntfs -Q {' '.join(options)} {path}")).exit_code != 0: raise DiskError(f"Could not format {path} with {filesystem} because: {handle.decode('UTF-8')}") - self.filesystem = filesystem + self._partition_info.filesystem_type = filesystem elif filesystem == 'crypto_LUKS': # from ..luks import luks2 # encrypted_partition = luks2(self, None, None) # encrypted_partition.format(path) - self.filesystem = filesystem + self._partition_info.filesystem_type = filesystem else: raise UnknownFilesystemFormat(f"Fileformat '{filesystem}' is not yet implemented.") @@ -485,9 +444,9 @@ class Partition: return self.format(filesystem, path, log_formatting, options, retry=False) if get_filesystem_type(path) == 'crypto_LUKS' or get_filesystem_type(self.real_device) == 'crypto_LUKS': - self.encrypted = True + self._encrypted = True else: - self.encrypted = False + self._encrypted = False return True @@ -499,18 +458,18 @@ class Partition: if parent := self.find_parent_of(child, name, parent=data['name']): return parent + return None + def mount(self, target :str, fs :Optional[str] = None, options :str = '') -> bool: - if not self.mountpoint: + if not self._partition_info.get_first_mountpoint(): log(f'Mounting {self} to {target}', level=logging.INFO) if not fs: - if not self.filesystem: - raise DiskError(f'Need to format (or define) the filesystem on {self} before mounting.') - fs = self.filesystem + fs = self._partition_info.filesystem_type fs_type = get_mount_fs_type(fs) - pathlib.Path(target).mkdir(parents=True, exist_ok=True) + Path(target).mkdir(parents=True, exist_ok=True) if self.bind_name: device_path = self.device_path @@ -520,7 +479,7 @@ class Partition: else: options = f"subvol={self.bind_name}" else: - device_path = self.path + device_path = self._path try: if options: mnt_handle = SysCommand(f"/usr/bin/mount -t {fs_type} -o {options} {device_path} {target}") @@ -529,7 +488,7 @@ class Partition: # TODO: Should be redundant to check for exit_code if mnt_handle.exit_code != 0: - raise DiskError(f"Could not mount {self.path} to {target} using options {options}") + raise DiskError(f"Could not mount {self._path} to {target} using options {options}") except SysCallError as err: raise err @@ -538,19 +497,17 @@ class Partition: return False def unmount(self) -> bool: - worker = SysCommand(f"/usr/bin/umount {self.path}") + worker = SysCommand(f"/usr/bin/umount {self._path}") + exit_code = worker.exit_code # Without to much research, it seams that low error codes are errors. # And above 8k is indicators such as "/dev/x not mounted.". # So anything in between 0 and 8k are errors (?). - if 0 < worker.exit_code < 8000: - raise SysCallError(f"Could not unmount {self.path} properly: {worker}", exit_code=worker.exit_code) + if exit_code and 0 < exit_code < 8000: + raise SysCallError(f"Could not unmount {self._path} properly: {worker}", exit_code=exit_code) return True - def umount(self) -> bool: - return self.unmount() - def filesystem_supported(self) -> bool: """ The support for a filesystem (this partition) is tested by calling @@ -559,7 +516,7 @@ class Partition: 2. UnknownFilesystemFormat that indicates that we don't support the given filesystem type """ try: - self.format(self.filesystem, '/dev/null', log_formatting=False, allow_formatting=True) + self.format(self._partition_info.filesystem_type, '/dev/null', log_formatting=False) except (SysCallError, DiskError): pass # We supported it, but /dev/null is not formattable as expected so the mkfs call exited with an error code except UnknownFilesystemFormat as err: diff --git a/archinstall/lib/luks.py b/archinstall/lib/luks.py index ac480b11..7e4534d8 100644 --- a/archinstall/lib/luks.py +++ b/archinstall/lib/luks.py @@ -22,9 +22,9 @@ from .disk.btrfs import BTRFSPartition class luks2: def __init__(self, - partition :Partition, - mountpoint :str, - password :str, + partition: Partition, + mountpoint: Optional[str], + password: Optional[str], key_file :Optional[str] = None, auto_unmount :bool = False, *args :str, diff --git a/archinstall/lib/user_interaction/partitioning_conf.py b/archinstall/lib/user_interaction/partitioning_conf.py index 8bf76121..f2e6b881 100644 --- a/archinstall/lib/user_interaction/partitioning_conf.py +++ b/archinstall/lib/user_interaction/partitioning_conf.py @@ -140,16 +140,6 @@ def get_default_partition_layout( return suggest_multi_disk_layout(block_devices, advanced_options=advanced_options) -def select_individual_blockdevice_usage(block_devices: list) -> Dict[str, Any]: - result = {} - - for device in block_devices: - layout = manage_new_and_existing_partitions(device) - result[device.path] = layout - - return result - - def manage_new_and_existing_partitions(block_device: 'BlockDevice') -> Dict[str, Any]: # noqa: max-complexity: 50 block_device_struct = {"partitions": [partition.__dump__() for partition in block_device.partitions.values()]} original_layout = copy.deepcopy(block_device_struct) -- cgit v1.2.3-54-g00ecf From d2f58362c9035be57670784584a666eea8c09e60 Mon Sep 17 00:00:00 2001 From: Fabian Bornschein <18744080+fabiscafe@users.noreply.github.com> Date: Mon, 1 Aug 2022 09:42:58 +0200 Subject: Remove the hash/number sign at the line-start (#1345) Currently the helper remove the first character of each line, this can lead to cases, where important characters are removed. For example if the locale is already set up. (hash is already removed) in that case the helper would remove the first character of the locale and lead to a broken attempt to set the locale later on. This change should avoid that and only remove the hash. Co-authored-by: Fabian Bornschein <2440175-fabiscafe@users.noreply.gitlab.com> --- archinstall/lib/locale_helpers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'archinstall') diff --git a/archinstall/lib/locale_helpers.py b/archinstall/lib/locale_helpers.py index b48c3bc4..5580fa91 100644 --- a/archinstall/lib/locale_helpers.py +++ b/archinstall/lib/locale_helpers.py @@ -20,7 +20,7 @@ def list_locales() -> List[str]: entries.reverse() for entry in entries: - text = entry[1:].strip() + text = entry.replace('#', '').strip() if text == '': break locales.append(text) -- cgit v1.2.3-54-g00ecf From 3bc39225458b32fcd43b8a5b76dbb6797723a86c Mon Sep 17 00:00:00 2001 From: Werner Llácer Date: Mon, 1 Aug 2022 09:44:26 +0200 Subject: Enhacements to list_manager: (#1346) * Enhacements to list_manager: method filter_option. To filter options based on selected entry attrib. last_choice. Which is the last action executed before exiting the loop * last_choice is now a calculated attribute, therefore readonly * Added last_choice to selection_menu * bug at selection_menu handling. Translations can be a problem --- archinstall/lib/menu/list_manager.py | 13 ++++++++++++- archinstall/lib/menu/selection_menu.py | 9 +++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) (limited to 'archinstall') diff --git a/archinstall/lib/menu/list_manager.py b/archinstall/lib/menu/list_manager.py index e7a9c2ac..ae3a6eb5 100644 --- a/archinstall/lib/menu/list_manager.py +++ b/archinstall/lib/menu/list_manager.py @@ -44,6 +44,12 @@ class ListManager: self._base_actions = base_actions self._sub_menu_actions = sub_menu_actions + self._last_choice = None + + @property + def last_choice(self): + return self._last_choice + def run(self): while True: # this will return a dictionary with the key as the menu entry to be displayed @@ -73,6 +79,7 @@ class ListManager: selected_entry = data_formatted[choice.value] self._run_actions_on_entry(selected_entry) + self._last_choice = choice if choice.value == self._cancel_action: return self._original_data # return the original list else: @@ -97,7 +104,7 @@ class ListManager: return options, header def _run_actions_on_entry(self, entry: Any): - options = self._sub_menu_actions + [self._cancel_action] + options = self.filter_options(entry,self._sub_menu_actions) + [self._cancel_action] display_value = self.selected_action_display(entry) prompt = _("Select an action for '{}'").format(display_value) @@ -129,3 +136,7 @@ class ListManager: # this function is called when a base action or # a specific action for an entry is triggered raise NotImplementedError('Please implement me in the child class') + + def filter_options(self, selection :Any, options :List[str]) -> List[str]: + # filter which actions to show for an specific selection + return options diff --git a/archinstall/lib/menu/selection_menu.py b/archinstall/lib/menu/selection_menu.py index 8dd6fcce..c6ac5852 100644 --- a/archinstall/lib/menu/selection_menu.py +++ b/archinstall/lib/menu/selection_menu.py @@ -188,6 +188,11 @@ class GeneralMenu: self._menu_options: Dict[str, Selector] = {} self._setup_selection_menu_options() self.preview_size = preview_size + self._last_choice = None + + @property + def last_choice(self): + return self._last_choice def __enter__(self, *args :Any, **kwargs :Any) -> GeneralMenu: self.is_context_mgr = True @@ -325,6 +330,10 @@ class GeneralMenu: if not self._process_selection(value): break + # we get the last action key + actions = {str(v.description):k for k,v in self._menu_options.items()} + self._last_choice = actions[selection.value.strip()] + if not self.is_context_mgr: self.__exit__() -- cgit v1.2.3-54-g00ecf From cfea0d6d1a6f6b82fd4b65abd2124c8fc0530949 Mon Sep 17 00:00:00 2001 From: Daniel Girtler Date: Mon, 1 Aug 2022 17:44:57 +1000 Subject: Update translations (#1348) * Show translations in own tongue * Fix flake8 * Update * Update * Update * Update * fix mypy * Update * Update Co-authored-by: Daniel Girtler --- .github/workflows/mypy.yaml | 2 +- README.md | 24 +++ archinstall/__init__.py | 2 +- archinstall/lib/menu/global_menu.py | 3 +- archinstall/lib/menu/selection_menu.py | 22 +-- archinstall/lib/translation.py | 144 ------------------ archinstall/lib/translationhandler.py | 165 +++++++++++++++++++++ archinstall/lib/user_interaction/general_conf.py | 21 ++- .../lib/user_interaction/manage_users_conf.py | 4 +- archinstall/locales/README.md | 9 +- archinstall/locales/cyrillic.json | 19 --- archinstall/locales/languages.json | 28 ++-- examples/swiss.py | 34 +++-- 13 files changed, 267 insertions(+), 210 deletions(-) delete mode 100644 archinstall/lib/translation.py create mode 100644 archinstall/lib/translationhandler.py delete mode 100644 archinstall/locales/cyrillic.json (limited to 'archinstall') diff --git a/.github/workflows/mypy.yaml b/.github/workflows/mypy.yaml index 01d4741f..c03cd3cf 100644 --- a/.github/workflows/mypy.yaml +++ b/.github/workflows/mypy.yaml @@ -15,4 +15,4 @@ jobs: # one day this will be enabled # run: mypy --strict --module archinstall || exit 0 - name: run mypy - run: mypy --follow-imports=silent archinstall/lib/menu/selection_menu.py archinstall/lib/menu/global_menu.py archinstall/lib/models/network_configuration.py archinstall/lib/menu/list_manager.py archinstall/lib/user_interaction/network_conf.py archinstall/lib/models/users.py archinstall/lib/disk/blockdevice.py archinstall/lib/user_interaction/subvolume_config.py archinstall/lib/disk/btrfs/btrfs_helpers.py archinstall/lib/translation.py + run: mypy --follow-imports=silent archinstall/lib/menu/selection_menu.py archinstall/lib/menu/global_menu.py archinstall/lib/models/network_configuration.py archinstall/lib/menu/list_manager.py archinstall/lib/user_interaction/network_conf.py archinstall/lib/models/users.py archinstall/lib/disk/blockdevice.py archinstall/lib/user_interaction/subvolume_config.py archinstall/lib/disk/btrfs/btrfs_helpers.py archinstall/lib/translationhandler.py diff --git a/README.md b/README.md index 20224eea..b1df757a 100644 --- a/README.md +++ b/README.md @@ -37,6 +37,29 @@ Assuming you are on a Arch Linux live-ISO and booted into EFI mode. # archinstall --config --disk-layout --creds +# Available Languages + +Archinstall is available in different languages which have been contributed and are maintained by the community. +Current translations are listed below and vary in the amount of translations per language +``` +English +Deutsch +Española +Française +Italiano +Nederlands +Polskie +Portugues do Brasil +Português +Svenska +Türk +čeština +русский +اردو +``` + +Any contributions to the translations are more than welcome, and to get started please follow [the guide](https://github.com/archlinux/archinstall/blob/master/archinstall/locales/README.md) + # Help? Submit an issue here on GitHub, or submit a post in the discord help channel.
@@ -57,6 +80,7 @@ This library is in turn used by the provided guided installer but is also for an Therefore, Archinstall will try its best to not introduce any breaking changes except for major releases which may break backwards compatibility after notifying about such changes. + # Scripting your own installation You could just copy [guided.py](https://github.com/archlinux/archinstall/blob/master/examples/guided.py) as a starting point. diff --git a/archinstall/__init__.py b/archinstall/__init__.py index 1a360c67..f607a922 100644 --- a/archinstall/__init__.py +++ b/archinstall/__init__.py @@ -40,7 +40,7 @@ from .lib.menu.selection_menu import ( Selector, GeneralMenu ) -from .lib.translation import Translation, DeferredTranslation +from .lib.translationhandler import TranslationHandler, DeferredTranslation from .lib.plugins import plugins, load_plugin # This initiates the plugin loading ceremony from .lib.configuration import * from .lib.udev import udevadm_info diff --git a/archinstall/lib/menu/global_menu.py b/archinstall/lib/menu/global_menu.py index 1a292476..1badc052 100644 --- a/archinstall/lib/menu/global_menu.py +++ b/archinstall/lib/menu/global_menu.py @@ -50,7 +50,8 @@ class GlobalMenu(GeneralMenu): Selector( _('Archinstall language'), lambda x: self._select_archinstall_language(x), - default='English') + display_func=lambda x: x.display_name, + default=self.translation_handler.get_language('en')) self._menu_options['keyboard-layout'] = \ Selector( _('Keyboard layout'), diff --git a/archinstall/lib/menu/selection_menu.py b/archinstall/lib/menu/selection_menu.py index c6ac5852..8a08812c 100644 --- a/archinstall/lib/menu/selection_menu.py +++ b/archinstall/lib/menu/selection_menu.py @@ -8,9 +8,11 @@ from typing import Callable, Any, List, Iterator, Tuple, Optional, Dict, TYPE_CH from .menu import Menu, MenuSelectionType from ..locale_helpers import set_keyboard_language from ..output import log -from ..translation import Translation +from ..translationhandler import TranslationHandler, Language from ..hsm.fido import get_fido2_devices +from ..user_interaction.general_conf import select_archinstall_language + if TYPE_CHECKING: _: Any @@ -181,7 +183,7 @@ class GeneralMenu: """ self._enabled_order :List[str] = [] - self._translation = Translation.load_nationalization() + self._translation_handler = TranslationHandler() self.is_context_mgr = False self._data_store = data_store if data_store is not None else {} self.auto_cursor = auto_cursor @@ -213,6 +215,10 @@ class GeneralMenu: self.exit_callback() + @property + def translation_handler(self) -> TranslationHandler: + return self._translation_handler + def _setup_selection_menu_options(self): """ Define the menu options. Menu options can be defined here in a subclass or done per program calling self.set_option() @@ -461,14 +467,10 @@ class GeneralMenu: mandatory_waiting += 1 return mandatory_fields, mandatory_waiting - def _select_archinstall_language(self, preset_value: str) -> str: - from ... import select_archinstall_language - language = select_archinstall_language(preset_value) - if language is not None: - self._translation.activate(language) - return language - - return preset_value + def _select_archinstall_language(self, preset_value: Language) -> Language: + language = select_archinstall_language(self.translation_handler.translated_languages, preset_value) + self._translation_handler.activate(language) + return language def _select_hsm(self, preset :Optional[pathlib.Path] = None) -> Optional[pathlib.Path]: title = _('Select which partitions to mark for formatting:') diff --git a/archinstall/lib/translation.py b/archinstall/lib/translation.py deleted file mode 100644 index c20a4285..00000000 --- a/archinstall/lib/translation.py +++ /dev/null @@ -1,144 +0,0 @@ -from __future__ import annotations - -import json -import logging -import os -import gettext - -from pathlib import Path -from typing import List, Dict, Any, TYPE_CHECKING, Tuple -from .exceptions import TranslationError - -if TYPE_CHECKING: - _: Any - - -class LanguageDefinitions: - _languages = 'languages.json' - _cyrillic = 'cyrillic.json' - - def __init__(self): - self._mappings = self._get_language_mappings() - self._cyrillic_languages = self._get_cyrillic_languages() - - def is_cyrillic(self, language: str) -> bool: - return language in self._cyrillic_languages - - def _get_language_mappings(self) -> List[Dict[str, str]]: - locales_dir = Translation.get_locales_dir() - languages = Path.joinpath(locales_dir, self._languages) - - with open(languages, 'r') as fp: - return json.load(fp) - - def get_language(self, abbr: str) -> str: - for entry in self._mappings: - if entry['abbr'] == abbr: - return entry['lang'] - - raise ValueError(f'No language with abbreviation "{abbr}" found') - - def _get_cyrillic_languages(self) -> List[str]: - locales_dir = Translation.get_locales_dir() - languages = Path.joinpath(locales_dir, self._cyrillic) - - with open(languages, 'r') as fp: - data = json.load(fp) - return data['languages'] - - -class DeferredTranslation: - def __init__(self, message: str): - self.message = message - - def __len__(self) -> int: - return len(self.message) - - def __str__(self) -> str: - translate = _ - if translate is DeferredTranslation: - return self.message - return translate(self.message) - - def __lt__(self, other) -> bool: - return self.message < other - - def __gt__(self, other) -> bool: - return self.message > other - - def __add__(self, other) -> DeferredTranslation: - if isinstance(other, str): - other = DeferredTranslation(other) - - concat = self.message + other.message - return DeferredTranslation(concat) - - def format(self, *args) -> str: - return self.message.format(*args) - - @classmethod - def install(cls): - import builtins - builtins._ = cls - - -class Translation: - def __init__(self, locales_dir): - self._languages = {} - - for names in self._get_translation_lang(): - try: - self._languages[names[0]] = gettext.translation('base', localedir=locales_dir, languages=names) - except FileNotFoundError as error: - raise TranslationError(f"Could not locate language file for '{names}': {error}") - - def activate(self, name): - if language := self._languages.get(name, None): - languages = LanguageDefinitions() - - if languages.is_cyrillic(name): - self._set_font('UniCyr_8x16') - else: - # this will reset a possible previously set font to a default font - self._set_font('') - - language.install() - else: - raise ValueError(f'Language not supported: {name}') - - def _set_font(self, font: str): - from archinstall import SysCommand, log - try: - log(f'Setting new font: {font}', level=logging.DEBUG) - SysCommand(f'setfont {font}') - except Exception: - log(f'Unable to set font {font}', level=logging.ERROR) - - @classmethod - def load_nationalization(cls) -> Translation: - locales_dir = cls.get_locales_dir() - return Translation(locales_dir) - - @classmethod - def get_locales_dir(cls) -> Path: - cur_path = Path(__file__).parent.parent - locales_dir = Path.joinpath(cur_path, 'locales') - return locales_dir - - @classmethod - def _defined_languages(cls) -> List[str]: - locales_dir = cls.get_locales_dir() - filenames = os.listdir(locales_dir) - return list(filter(lambda x: len(x) == 2, filenames)) - - @classmethod - def _get_translation_lang(cls) -> List[Tuple[str, str]]: - def_languages = cls._defined_languages() - languages = LanguageDefinitions() - return [(languages.get_language(lang), lang) for lang in def_languages] - - @classmethod - def get_available_lang(cls) -> List[str]: - def_languages = cls._defined_languages() - languages = LanguageDefinitions() - return [languages.get_language(lang) for lang in def_languages] diff --git a/archinstall/lib/translationhandler.py b/archinstall/lib/translationhandler.py new file mode 100644 index 00000000..12c8da4a --- /dev/null +++ b/archinstall/lib/translationhandler.py @@ -0,0 +1,165 @@ +from __future__ import annotations + +import json +import logging +import os +import gettext +from dataclasses import dataclass + +from pathlib import Path +from typing import List, Dict, Any, TYPE_CHECKING, Optional +from .exceptions import TranslationError + +if TYPE_CHECKING: + _: Any + + +@dataclass +class Language: + abbr: str + lang: str + translation: gettext.NullTranslations + translation_percent: int + translated_lang: Optional[str] + + @property + def display_name(self) -> str: + if self.translated_lang: + name = self.translated_lang + else: + name = self.lang + return f'{name} ({self.translation_percent}%)' + + def is_match(self, lang_or_translated_lang: str) -> bool: + if self.lang == lang_or_translated_lang: + return True + elif self.translated_lang == lang_or_translated_lang: + return True + return False + + +class TranslationHandler: + _base_pot = 'base.pot' + _languages = 'languages.json' + + def __init__(self): + # to display cyrillic languages correctly + self._set_font('UniCyr_8x16') + + self._total_messages = self._get_total_messages() + self._translated_languages = self._get_translations() + + @property + def translated_languages(self) -> List[Language]: + return self._translated_languages + + def _get_translations(self) -> List[Language]: + mappings = self._load_language_mappings() + defined_languages = self._defined_languages() + + languages = [] + + for short_form in defined_languages: + mapping_entry: Dict[str, Any] = next(filter(lambda x: x['abbr'] == short_form, mappings)) + abbr = mapping_entry['abbr'] + lang = mapping_entry['lang'] + translated_lang = mapping_entry.get('translated_lang', None) + + try: + translation = gettext.translation('base', localedir=self._get_locales_dir(), languages=(abbr, lang)) + + if abbr == 'en': + percent = 100 + else: + num_translations = self._get_catalog_size(translation) + percent = int((num_translations / self._total_messages) * 100) + + language = Language(abbr, lang, translation, percent, translated_lang) + languages.append(language) + except FileNotFoundError as error: + raise TranslationError(f"Could not locate language file for '{lang}': {error}") + + return languages + + def _set_font(self, font: str): + from archinstall import SysCommand, log + try: + log(f'Setting font: {font}', level=logging.DEBUG) + SysCommand(f'setfont {font}') + except Exception: + log(f'Unable to set font {font}', level=logging.ERROR) + + def _load_language_mappings(self) -> List[Dict[str, Any]]: + locales_dir = self._get_locales_dir() + languages = Path.joinpath(locales_dir, self._languages) + + with open(languages, 'r') as fp: + return json.load(fp) + + def _get_catalog_size(self, translation: gettext.NullTranslations) -> int: + # this is a ery naughty way of retrieving the data but + # there's no alternative method exposed unfortunately + catalog = translation._catalog # type: ignore + messages = {k: v for k, v in catalog.items() if k and v} + return len(messages) + + def _get_total_messages(self) -> int: + locales = self._get_locales_dir() + with open(f'{locales}/{self._base_pot}', 'r') as fp: + lines = fp.readlines() + msgid_lines = [line for line in lines if 'msgid' in line] + return len(msgid_lines) - 1 # don't count the first line which contains the metadata + + def get_language(self, abbr: str) -> Language: + try: + return next(filter(lambda x: x.abbr == abbr, self._translated_languages)) + except Exception: + raise ValueError(f'No language with abbreviation "{abbr}" found') + + def activate(self, language: Language): + language.translation.install() + + def _get_locales_dir(self) -> Path: + cur_path = Path(__file__).parent.parent + locales_dir = Path.joinpath(cur_path, 'locales') + return locales_dir + + def _defined_languages(self) -> List[str]: + locales_dir = self._get_locales_dir() + filenames = os.listdir(locales_dir) + return list(filter(lambda x: len(x) == 2 or x == 'pt_BR', filenames)) + + +class DeferredTranslation: + def __init__(self, message: str): + self.message = message + + def __len__(self) -> int: + return len(self.message) + + def __str__(self) -> str: + translate = _ + if translate is DeferredTranslation: + return self.message + return translate(self.message) + + def __lt__(self, other) -> bool: + return self.message < other + + def __gt__(self, other) -> bool: + return self.message > other + + def __add__(self, other) -> DeferredTranslation: + if isinstance(other, str): + other = DeferredTranslation(other) + + concat = self.message + other.message + return DeferredTranslation(concat) + + def format(self, *args) -> str: + return self.message.format(*args) + + @classmethod + def install(cls): + import builtins + builtins._ = cls diff --git a/archinstall/lib/user_interaction/general_conf.py b/archinstall/lib/user_interaction/general_conf.py index 15c42b86..bdc602b3 100644 --- a/archinstall/lib/user_interaction/general_conf.py +++ b/archinstall/lib/user_interaction/general_conf.py @@ -12,7 +12,7 @@ from ..output import log from ..profiles import Profile, list_profiles from ..mirrors import list_mirrors -from ..translation import Translation +from ..translationhandler import Language from ..packages.packages import validate_package_list from ..storage import storage @@ -118,13 +118,22 @@ def select_mirror_regions(preset_values: Dict[str, Any] = {}) -> Dict[str, Any]: case _: return {selected: mirrors[selected] for selected in selected_mirror.value} -def select_archinstall_language(preset_values: str): - languages = Translation.get_available_lang() - choice = Menu(_('Archinstall language'), languages, default_option=preset_values).run() +def select_archinstall_language(languages: List[Language], preset_value: Language) -> Language: + # these are the displayed language names which can either be + # the english name of a language or, if present, the + # name of the language in its own language + options = {lang.display_name: lang for lang in languages} + + choice = Menu( + _('Archinstall language'), + list(options.keys()), + default_option=preset_value.display_name + ).run() match choice.type_: - case MenuSelectionType.Esc: return preset_values - case MenuSelectionType.Selection: return choice.value + case MenuSelectionType.Esc: return preset_value + case MenuSelectionType.Selection: + return options[choice.value] def select_profile(preset) -> Optional[Profile]: diff --git a/archinstall/lib/user_interaction/manage_users_conf.py b/archinstall/lib/user_interaction/manage_users_conf.py index a97328c2..84ce3556 100644 --- a/archinstall/lib/user_interaction/manage_users_conf.py +++ b/archinstall/lib/user_interaction/manage_users_conf.py @@ -57,10 +57,10 @@ class UserList(ListManager): prompt = str(_('Password for user "{}": ').format(entry.username)) new_password = get_password(prompt=prompt) if new_password: - user = next(filter(lambda x: x == entry, data), 1) + user = next(filter(lambda x: x == entry, data)) user.password = new_password elif action == self._actions[2]: # promote/demote - user = next(filter(lambda x: x == entry, data), 1) + user = next(filter(lambda x: x == entry, data)) user.sudo = False if user.sudo else True elif action == self._actions[3]: # delete data = [d for d in data if d != entry] diff --git a/archinstall/locales/README.md b/archinstall/locales/README.md index 70822c05..51662702 100644 --- a/archinstall/locales/README.md +++ b/archinstall/locales/README.md @@ -5,7 +5,7 @@ Archinstall supports multiple languages, which depend on translations coming fro New languages can be added simply by creating a new folder with the proper language abbrevation (see list `languages.json` if unsure). Run the following command to create a new template for a language ``` - mkdir -p /LC_MESSAGES/ && touch /LC_MESSAGES/base.po +mkdir -p /LC_MESSAGES/ && touch /LC_MESSAGES/base.po ``` After that run the script `./locales_generator.sh` it will automatically populate the new `base.po` file with the strings that @@ -31,3 +31,10 @@ msgstr "Wollen sie wirklich abbrechen?" After the translations have been written, run the script once more `./locales_generator.sh` and it will auto-generate the `base.mo` file with the included translations. After that you're all ready to go and enjoy Archinstall in the new language :) + +To display the language inside Archinstall in your own tongue, please edit the file `languages.json` and +add a `translated_lang` entry to the respective language, e.g. + +``` + {"abbr": "pl", "lang": "Polish", "translated_lang": "Polskie"} +``` diff --git a/archinstall/locales/cyrillic.json b/archinstall/locales/cyrillic.json deleted file mode 100644 index 13f11ad0..00000000 --- a/archinstall/locales/cyrillic.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "languages": [ - "Abkhazian", - "Azerbaijani", - "Bashkir", - "Belarusian", - "Bulgarian", - "Chuvash", - "Komi", - "Macedonian", - "Mongolian", - "Russian", - "Serbo-Croatian", - "Tajik", - "Tatar", - "Ukrainian", - "Uzbek" - ] -} diff --git a/archinstall/locales/languages.json b/archinstall/locales/languages.json index c3c9d2c2..883042e8 100644 --- a/archinstall/locales/languages.json +++ b/archinstall/locales/languages.json @@ -20,7 +20,7 @@ {"abbr": "br", "lang": "Breton"}, {"abbr": "bg", "lang": "Bulgarian"}, {"abbr": "ca", "lang": "Catalan"}, - {"abbr": "cs", "lang": "Czech"}, + {"abbr": "cs", "lang": "Czech", "translated_lang": "čeština"}, {"abbr": "ch", "lang": "Chamorro"}, {"abbr": "ce", "lang": "Chechen"}, {"abbr": "cu", "lang": "Church Slavic"}, @@ -29,8 +29,8 @@ {"abbr": "co", "lang": "Corsican"}, {"abbr": "cr", "lang": "Cree"}, {"abbr": "cy", "lang": "Welsh"}, - {"abbr": "da", "lang": "Danish"}, - {"abbr": "de", "lang": "German"}, + {"abbr": "da", "lang": "Danish", "translated_lang": "Dansk"}, + {"abbr": "de", "lang": "German", "translated_lang": "Deutsch"}, {"abbr": "dv", "lang": "Dhivehi"}, {"abbr": "dz", "lang": "Dzongkha"}, {"abbr": "el", "lang": "Modern Greek (1453-)"}, @@ -43,7 +43,7 @@ {"abbr": "fa", "lang": "Persian"}, {"abbr": "fj", "lang": "Fijian"}, {"abbr": "fi", "lang": "Finnish"}, - {"abbr": "fr", "lang": "French"}, + {"abbr": "fr", "lang": "French", "translated_lang": "Française"}, {"abbr": "fy", "lang": "Western Frisian"}, {"abbr": "ff", "lang": "Fulah"}, {"abbr": "gd", "lang": "Scottish Gaelic"}, @@ -71,7 +71,7 @@ {"abbr": "id", "lang": "Indonesian"}, {"abbr": "ik", "lang": "Inupiaq"}, {"abbr": "is", "lang": "Icelandic"}, - {"abbr": "it", "lang": "Italian"}, + {"abbr": "it", "lang": "Italian", "translated_lang": "Italiano"}, {"abbr": "jv", "lang": "Javanese"}, {"abbr": "ja", "lang": "Japanese"}, {"abbr": "kl", "lang": "Kalaallisut"}, @@ -114,7 +114,7 @@ {"abbr": "nd", "lang": "North Ndebele"}, {"abbr": "ng", "lang": "Ndonga"}, {"abbr": "ne", "lang": "Nepali (macrolanguage)"}, - {"abbr": "nl", "lang": "Dutch"}, + {"abbr": "nl", "lang": "Dutch", "translated_lang": "Nederlands"}, {"abbr": "nn", "lang": "Norwegian Nynorsk"}, {"abbr": "nb", "lang": "Norwegian Bokmål"}, {"abbr": "no", "lang": "Norwegian"}, @@ -126,15 +126,15 @@ {"abbr": "os", "lang": "Ossetian"}, {"abbr": "pa", "lang": "Panjabi"}, {"abbr": "pi", "lang": "Pali"}, - {"abbr": "pl", "lang": "Polish"}, - {"abbr": "pt", "lang": "Portuguese"}, - {"abbr": "pt_BR", "lang": "Brazilian Portuguese"}, + {"abbr": "pl", "lang": "Polish", "translated_lang": "Polskie"}, + {"abbr": "pt", "lang": "Portuguese", "translated_lang": "Português"}, + {"abbr": "pt_BR", "lang": "Brazilian Portuguese", "translated_lang": "Portugues do Brasil"}, {"abbr": "ps", "lang": "Pushto"}, {"abbr": "qu", "lang": "Quechua"}, {"abbr": "rm", "lang": "Romansh"}, {"abbr": "ro", "lang": "Romanian"}, {"abbr": "rn", "lang": "Rundi"}, - {"abbr": "ru", "lang": "Russian"}, + {"abbr": "ru", "lang": "Russian", "translated_lang": "русский"}, {"abbr": "sg", "lang": "Sango"}, {"abbr": "sa", "lang": "Sanskrit"}, {"abbr": "si", "lang": "Sinhala"}, @@ -146,14 +146,14 @@ {"abbr": "sd", "lang": "Sindhi"}, {"abbr": "so", "lang": "Somali"}, {"abbr": "st", "lang": "Southern Sotho"}, - {"abbr": "es", "lang": "Spanish"}, + {"abbr": "es", "lang": "Spanish", "translated_lang": "Española"}, {"abbr": "sq", "lang": "Albanian"}, {"abbr": "sc", "lang": "Sardinian"}, {"abbr": "sr", "lang": "Serbian"}, {"abbr": "ss", "lang": "Swati"}, {"abbr": "su", "lang": "Sundanese"}, {"abbr": "sw", "lang": "Swahili (macrolanguage)"}, - {"abbr": "sv", "lang": "Swedish"}, + {"abbr": "sv", "lang": "Swedish", "translated_lang": "Svenska"}, {"abbr": "ty", "lang": "Tahitian"}, {"abbr": "ta", "lang": "Tamil"}, {"abbr": "tt", "lang": "Tatar"}, @@ -166,11 +166,11 @@ {"abbr": "tn", "lang": "Tswana"}, {"abbr": "ts", "lang": "Tsonga"}, {"abbr": "tk", "lang": "Turkmen"}, - {"abbr": "tr", "lang": "Turkish"}, + {"abbr": "tr", "lang": "Turkish", "translated_lang" : "Türk"}, {"abbr": "tw", "lang": "Twi"}, {"abbr": "ug", "lang": "Uighur"}, {"abbr": "uk", "lang": "Ukrainian"}, - {"abbr": "ur", "lang": "Urdu"}, + {"abbr": "ur", "lang": "Urdu", "translated_lang": "اردو"}, {"abbr": "uz", "lang": "Uzbek"}, {"abbr": "ve", "lang": "Venda"}, {"abbr": "vi", "lang": "Vietnamese"}, diff --git a/examples/swiss.py b/examples/swiss.py index 83b79c09..5d40dc68 100644 --- a/examples/swiss.py +++ b/examples/swiss.py @@ -158,24 +158,36 @@ class SetupMenu(archinstall.GeneralMenu): super().__init__(data_store=storage_area) def _setup_selection_menu_options(self): - self.set_option('archinstall-language', + self.set_option( + 'archinstall-language', archinstall.Selector( _('Archinstall language'), lambda x: self._select_archinstall_language(x), - default='English', - enabled=True)) - self.set_option('ntp', - archinstall.Selector( - 'Activate NTP', - lambda x: select_activate_NTP(), - default='Y', - enabled=True)) - self.set_option('mode', + display_func=lambda x: x.display_name, + default=self.translation_handler.get_language('en'), + enabled=True + ) + ) + + self.set_option( + 'ntp', + archinstall.Selector( + 'Activate NTP', + lambda x: select_activate_NTP(), + default='Y', + enabled=True + ) + ) + + self.set_option( + 'mode', archinstall.Selector( 'Excution mode', lambda x : select_mode(), default='full', - enabled=True)) + enabled=True) + ) + for item in ['LC_ALL','LC_CTYPE','LC_NUMERIC','LC_TIME','LC_MESSAGES','LC_COLLATE']: self.set_option(item, archinstall.Selector( -- cgit v1.2.3-54-g00ecf From 956b34905b730d32eab839b7a4627ca0bb9e5b06 Mon Sep 17 00:00:00 2001 From: virtual-meme-machine <46010615+virtual-meme-machine@users.noreply.github.com> Date: Mon, 1 Aug 2022 07:56:08 +0000 Subject: - Fix KeyError exceptions (#1354) --- archinstall/lib/installer.py | 8 ++++---- examples/guided.py | 11 ++++++----- 2 files changed, 10 insertions(+), 9 deletions(-) (limited to 'archinstall') diff --git a/archinstall/lib/installer.py b/archinstall/lib/installer.py index 97c2492d..f874c7fa 100644 --- a/archinstall/lib/installer.py +++ b/archinstall/lib/installer.py @@ -631,7 +631,7 @@ class Installer: mkinit.write(f"BINARIES=({' '.join(self.BINARIES)})\n") mkinit.write(f"FILES=({' '.join(self.FILES)})\n") - if not storage['arguments']['HSM']: + if not storage['arguments'].get('HSM'): # For now, if we don't use HSM we revert to the old # way of setting up encryption hooks for mkinitcpio. # This is purely for stability reasons, we're going away from this. @@ -673,7 +673,7 @@ class Installer: self.HOOKS.remove('fsck') if self.detect_encryption(partition): - if storage['arguments']['HSM']: + if storage['arguments'].get('HSM'): # Required bby mkinitcpio to add support for fido2-device options self.pacstrap('libfido2') @@ -737,7 +737,7 @@ class Installer: # TODO: Use python functions for this SysCommand(f'/usr/bin/arch-chroot {self.target} chmod 700 /root') - if storage['arguments']['HSM']: + if storage['arguments'].get('HSM'): # TODO: # A bit of a hack, but we need to get vconsole.conf in there # before running `mkinitcpio` because it expects it in HSM mode. @@ -865,7 +865,7 @@ class Installer: kernel_options = f"options" - if storage['arguments']['HSM']: + if storage['arguments'].get('HSM'): # Note: lsblk UUID must be used, not PARTUUID for sd-encrypt to work kernel_options += f" rd.luks.name={real_device.uuid}=luksdev" # Note: tpm2-device and fido2-device don't play along very well: diff --git a/examples/guided.py b/examples/guided.py index 8693b98f..0bb377a4 100644 --- a/examples/guided.py +++ b/examples/guided.py @@ -187,11 +187,12 @@ def perform_installation(mountpoint): if installation.minimal_installation(testing=enable_testing, multilib=enable_multilib): installation.set_locale(archinstall.arguments['sys-language'], archinstall.arguments['sys-encoding'].upper()) installation.set_hostname(archinstall.arguments['hostname']) - if archinstall.arguments['mirror-region'].get("mirrors", None) is not None: - installation.set_mirrors(archinstall.arguments['mirror-region']) # Set the mirrors in the installation medium - if archinstall.arguments['swap']: + if archinstall.arguments.get('mirror-region') is not None: + if archinstall.arguments.get("mirrors", None) is not None: + installation.set_mirrors(archinstall.arguments['mirror-region']) # Set the mirrors in the installation medium + if archinstall.arguments.get('swap'): installation.setup_swap('zram') - if archinstall.arguments["bootloader"] == "grub-install" and archinstall.has_uefi(): + if archinstall.arguments.get("bootloader") == "grub-install" and archinstall.has_uefi(): installation.add_additional_packages("grub") installation.add_bootloader(archinstall.arguments["bootloader"]) @@ -274,7 +275,7 @@ if not (archinstall.check_mirror_reachable() or archinstall.arguments.get('skip- archinstall.log(f"Arch Linux mirrors are not reachable. Please check your internet connection and the log file '{log_file}'.", level=logging.INFO, fg="red") exit(1) -if not archinstall.arguments['offline']: +if not archinstall.arguments.get('offline'): latest_version_archlinux_keyring = max([k.pkg_version for k in archinstall.find_package('archlinux-keyring')]) # If we want to check for keyring updates -- cgit v1.2.3-54-g00ecf From 3da03a192e3dc47c0e0c08302d28e9f3a62bcd0f Mon Sep 17 00:00:00 2001 From: Werner Llácer Date: Mon, 1 Aug 2022 10:26:51 +0200 Subject: Solves issue 1343. Could not locate partition after creation (#1355) * Solves issue 1343. Could not locate partition after creation * Added some flake fixes. Co-authored-by: Anton Hvornum --- archinstall/lib/disk/partition.py | 62 +++++++++++++++++++++++++++++++++++++++ archinstall/lib/general.py | 2 +- archinstall/lib/plugins.py | 2 +- 3 files changed, 64 insertions(+), 2 deletions(-) (limited to 'archinstall') diff --git a/archinstall/lib/disk/partition.py b/archinstall/lib/disk/partition.py index 4028f114..f70bf907 100644 --- a/archinstall/lib/disk/partition.py +++ b/archinstall/lib/disk/partition.py @@ -243,6 +243,68 @@ class Partition: @property def uuid(self) -> Optional[str]: + """ + Returns the UUID as returned by lsblk for the **partition**. + This is more reliable than relying on /dev/disk/by-uuid as + it doesn't seam to be able to detect md raid partitions. + For bind mounts all the subvolumes share the same uuid + """ + for i in range(storage['DISK_RETRY_ATTEMPTS']): + if not self.partprobe(): + raise DiskError(f"Could not perform partprobe on {self.device_path}") + + time.sleep(storage.get('DISK_TIMEOUTS', 1) * i) + + partuuid = self._safe_uuid + if partuuid: + return partuuid + + raise DiskError(f"Could not get PARTUUID for {self.path} using 'blkid -s PARTUUID -o value {self.path}'") + + @property + def _safe_uuid(self) -> Optional[str]: + """ + A near copy of self.uuid but without any delays. + This function should only be used where uuid is not crucial. + For instance when you want to get a __repr__ of the class. + """ + if not self.partprobe(): + if self.block_device.partition_type == 'iso9660': + return None + + log(f"Could not reliably refresh PARTUUID of partition {self.device_path} due to partprobe error.", level=logging.DEBUG) + + try: + return SysCommand(f'blkid -s UUID -o value {self.device_path}').decode('UTF-8').strip() + except SysCallError as error: + if self.block_device.partition_type == 'iso9660': + # Parent device is a Optical Disk (.iso dd'ed onto a device for instance) + return None + + log(f"Could not get PARTUUID of partition using 'blkid -s UUID -o value {self.device_path}': {error}") + + @property + def _safe_part_uuid(self) -> Optional[str]: + """ + A near copy of self.uuid but without any delays. + This function should only be used where uuid is not crucial. + For instance when you want to get a __repr__ of the class. + """ + if not self.partprobe(): + if self.block_device.partition_type == 'iso9660': + return None + + log(f"Could not reliably refresh PARTUUID of partition {self.device_path} due to partprobe error.", level=logging.DEBUG) + + try: + return SysCommand(f'blkid -s PARTUUID -o value {self.device_path}').decode('UTF-8').strip() + except SysCallError as error: + if self.block_device.partition_type == 'iso9660': + # Parent device is a Optical Disk (.iso dd'ed onto a device for instance) + return None + + log(f"Could not get PARTUUID of partition using 'blkid -s PARTUUID -o value {self.device_path}': {error}") + return self._partition_info.uuid @property diff --git a/archinstall/lib/general.py b/archinstall/lib/general.py index 3ec1d685..27f444e8 100644 --- a/archinstall/lib/general.py +++ b/archinstall/lib/general.py @@ -37,7 +37,7 @@ else: def unregister(self, fileno :int, *args :List[Any], **kwargs :Dict[str, Any]) -> None: try: - del(self.monitoring[fileno]) + del(self.monitoring[fileno]) # noqa: E275 except: pass diff --git a/archinstall/lib/plugins.py b/archinstall/lib/plugins.py index 99e3811c..f771aacb 100644 --- a/archinstall/lib/plugins.py +++ b/archinstall/lib/plugins.py @@ -60,7 +60,7 @@ def import_via_path(path :str, namespace :Optional[str] = None) -> ModuleType: log(f"The above error was detected when loading the plugin: {path}", fg="red", level=logging.ERROR) try: - del(sys.modules[namespace]) + del(sys.modules[namespace]) # noqa: E275 except: pass -- cgit v1.2.3-54-g00ecf From 1bd2210e5f100ed96411c65a25c7f89dd854b35b Mon Sep 17 00:00:00 2001 From: Daniel Girtler Date: Mon, 1 Aug 2022 18:28:41 +1000 Subject: Downstream merged simple menu changes (#1356) Co-authored-by: Daniel Girtler --- archinstall/lib/menu/menu.py | 20 +++++++++---------- archinstall/lib/menu/simple_menu.py | 25 +++++++++++------------- archinstall/lib/user_interaction/disk_conf.py | 4 ++-- archinstall/lib/user_interaction/general_conf.py | 8 ++++---- archinstall/lib/user_interaction/network_conf.py | 4 ++-- archinstall/lib/user_interaction/system_conf.py | 8 ++++---- 6 files changed, 33 insertions(+), 36 deletions(-) (limited to 'archinstall') diff --git a/archinstall/lib/menu/menu.py b/archinstall/lib/menu/menu.py index 80982db0..1e6f0110 100644 --- a/archinstall/lib/menu/menu.py +++ b/archinstall/lib/menu/menu.py @@ -56,8 +56,8 @@ class Menu(TerminalMenu): preview_size=0.75, preview_title='Info', header :Union[List[str],str] = None, - explode_on_interrupt :bool = False, - explode_warning :str = '', + raise_error_on_interrupt :bool = False, + raise_error_warning_msg :str = '', clear_screen: bool = True, show_search_hint: bool = True, cycle_cursor: bool = True, @@ -104,10 +104,10 @@ class Menu(TerminalMenu): param header: one or more header lines for the menu type param: string or list - param explode_on_interrupt: This will explicitly handle a ctrl+c instead and return that specific state + param raise_error_on_interrupt: This will explicitly handle a ctrl+c instead and return that specific state type param: bool - param explode_warning: If explode_on_interrupt is True and this is non-empty, there will be a warning with a user confirmation displayed + param raise_error_warning_msg: If raise_error_on_interrupt is True and this is non-empty, there will be a warning with a user confirmation displayed type param: str :param kwargs : any SimpleTerminal parameter @@ -150,8 +150,8 @@ class Menu(TerminalMenu): self._skip = skip self._default_option = default_option self._multi = multi - self._explode_on_interrupt = explode_on_interrupt - self._explode_warning = explode_warning + self._raise_error_on_interrupt = raise_error_on_interrupt + self._raise_error_warning_msg = raise_error_warning_msg menu_title = f'\n{title}\n\n' @@ -164,7 +164,7 @@ class Menu(TerminalMenu): if skip: action_info += str(_("Use ESC to skip")) - if self._explode_on_interrupt: + if self._raise_error_on_interrupt: if len(action_info) > 0: action_info += '\n' action_info += str(_('Use CTRL+C to reset current selection\n\n')) @@ -198,7 +198,7 @@ class Menu(TerminalMenu): preview_command=preview_command, preview_size=preview_size, preview_title=preview_title, - explode_on_interrupt=self._explode_on_interrupt, + raise_error_on_interrupt=self._raise_error_on_interrupt, multi_select_select_on_accept=False, clear_screen=clear_screen, show_search_hint=show_search_hint, @@ -236,8 +236,8 @@ class Menu(TerminalMenu): ret = self._show() if ret.type_ == MenuSelectionType.Ctrl_c: - if self._explode_on_interrupt and len(self._explode_warning) > 0: - response = Menu(self._explode_warning, Menu.yes_no(), skip=False).run() + if self._raise_error_on_interrupt and len(self._raise_error_warning_msg) > 0: + response = Menu(self._raise_error_warning_msg, Menu.yes_no(), skip=False).run() if response.value == Menu.no(): return self.run() diff --git a/archinstall/lib/menu/simple_menu.py b/archinstall/lib/menu/simple_menu.py index f7a2cf23..1980e2ce 100644 --- a/archinstall/lib/menu/simple_menu.py +++ b/archinstall/lib/menu/simple_menu.py @@ -65,7 +65,7 @@ __author__ = "Ingo Meyer" __email__ = "i.meyer@fz-juelich.de" __copyright__ = "Copyright © 2021 Forschungszentrum Jülich GmbH. All rights reserved." __license__ = "MIT" -__version_info__ = (1, 4, 1) +__version_info__ = (1, 5, 0) __version__ = ".".join(map(str, __version_info__)) @@ -86,6 +86,7 @@ DEFAULT_MULTI_SELECT_SELECT_ON_ACCEPT = True DEFAULT_PREVIEW_BORDER = True DEFAULT_PREVIEW_SIZE = 0.25 DEFAULT_PREVIEW_TITLE = "preview" +DEFAULT_QUIT_KEYS = ("escape", "q") DEFAULT_SEARCH_CASE_SENSITIVE = False DEFAULT_SEARCH_HIGHLIGHT_STYLE = ("fg_black", "bg_yellow", "bold") DEFAULT_SEARCH_KEY = "/" @@ -581,6 +582,8 @@ class TerminalMenu: preview_command: Optional[Union[str, Callable[[str], str]]] = None, preview_size: float = DEFAULT_PREVIEW_SIZE, preview_title: str = DEFAULT_PREVIEW_TITLE, + quit_keys: Iterable[str] = DEFAULT_QUIT_KEYS, + raise_error_on_interrupt: bool = False, search_case_sensitive: bool = DEFAULT_SEARCH_CASE_SENSITIVE, search_highlight_style: Optional[Iterable[str]] = DEFAULT_SEARCH_HIGHLIGHT_STYLE, search_key: Optional[str] = DEFAULT_SEARCH_KEY, @@ -596,8 +599,7 @@ class TerminalMenu: status_bar: Optional[Union[str, Iterable[str], Callable[[str], str]]] = None, status_bar_below_preview: bool = DEFAULT_STATUS_BAR_BELOW_PREVIEW, status_bar_style: Optional[Iterable[str]] = DEFAULT_STATUS_BAR_STYLE, - title: Optional[Union[str, Iterable[str]]] = None, - explode_on_interrupt: bool = False + title: Optional[Union[str, Iterable[str]]] = None ): def extract_shortcuts_menu_entries_and_preview_arguments( entries: Iterable[str], @@ -619,7 +621,7 @@ class TerminalMenu: else: unit_separated_entry = escaped_separator_pattern.sub("|", separator_pattern.sub("\\1\x1F", entry)) match_obj = menu_entry_pattern.match(unit_separated_entry) - # this is none in case the entry was an empty string which + # this is none in case the entry was an emtpy string which # will be interpreted as a separator assert match_obj is not None shortcut_key = match_obj.group(1) @@ -716,10 +718,11 @@ class TerminalMenu: self._preview_command = preview_command self._preview_size = preview_size self._preview_title = preview_title + self._quit_keys = tuple(quit_keys) + self._raise_error_on_interrupt = raise_error_on_interrupt self._search_case_sensitive = search_case_sensitive self._search_highlight_style = tuple(search_highlight_style) if search_highlight_style is not None else () self._search_key = search_key - self._explode_on_interrupt = explode_on_interrupt self._shortcut_brackets_highlight_style = ( tuple(shortcut_brackets_highlight_style) if shortcut_brackets_highlight_style is not None else () ) @@ -787,6 +790,7 @@ class TerminalMenu: # backspace can be queried from the terminal database but is unreliable, query the terminal directly instead self._init_backspace_control_character() self._add_missing_control_characters_for_keys(self._accept_keys) + self._add_missing_control_characters_for_keys(self._quit_keys) self._init_terminal_codes() @staticmethod @@ -1477,7 +1481,7 @@ class TerminalMenu: "menu_down": set(("down", "ctrl-j", "j")), "accept": set(self._accept_keys), "multi_select": set(self._multi_select_keys), - "quit": set(("escape", "q")), + "quit": set(self._quit_keys), "search_start": set((self._search_key,)), "backspace": set(("backspace",)), } # type: Dict[str, Set[Optional[str]]] @@ -1541,7 +1545,7 @@ class TerminalMenu: # `search_start` key self._search.search_text += next_key except KeyboardInterrupt as e: - if self._explode_on_interrupt: + if self._raise_error_on_interrupt: raise e menu_was_interrupted = True finally: @@ -1845,12 +1849,6 @@ def get_argumentparser() -> argparse.ArgumentParser: ), ) parser.add_argument("-t", "--title", action="store", dest="title", help="menu title") - parser.add_argument( - "--explode-on-interrupt", - action="store_true", - dest="explode_on_interrupt", - help="Instead of quitting the menu, this will raise the KeyboardInterrupt Exception", - ) parser.add_argument( "-V", "--version", action="store_true", dest="print_version", help="print the version number and exit" ) @@ -1981,7 +1979,6 @@ def main() -> None: status_bar_below_preview=args.status_bar_below_preview, status_bar_style=args.status_bar_style, title=args.title, - explode_on_interrupt=args.explode_on_interrupt, ) except (InvalidParameterCombinationError, InvalidStyleError, UnknownMenuEntryError) as e: print(str(e), file=sys.stderr) diff --git a/archinstall/lib/user_interaction/disk_conf.py b/archinstall/lib/user_interaction/disk_conf.py index 371d052f..b5ed6967 100644 --- a/archinstall/lib/user_interaction/disk_conf.py +++ b/archinstall/lib/user_interaction/disk_conf.py @@ -45,8 +45,8 @@ def select_disk_layout(preset: Optional[Dict[str, Any]], block_devices: list, ad choice = Menu( _('Select what you wish to do with the selected block devices'), modes, - explode_on_interrupt=True, - explode_warning=warning + raise_error_on_interrupt=True, + raise_error_warning_msg=warning ).run() match choice.type_: diff --git a/archinstall/lib/user_interaction/general_conf.py b/archinstall/lib/user_interaction/general_conf.py index bdc602b3..754ffa29 100644 --- a/archinstall/lib/user_interaction/general_conf.py +++ b/archinstall/lib/user_interaction/general_conf.py @@ -109,7 +109,7 @@ def select_mirror_regions(preset_values: Dict[str, Any] = {}) -> Dict[str, Any]: list(mirrors.keys()), preset_values=preselected, multi=True, - explode_on_interrupt=True + raise_error_on_interrupt=True ).run() match selected_mirror.type_: @@ -159,8 +159,8 @@ def select_profile(preset) -> Optional[Profile]: selection = Menu( title=title, p_options=list(options.keys()), - explode_on_interrupt=True, - explode_warning=warning + raise_error_on_interrupt=True, + raise_error_warning_msg=warning ).run() match selection.type_: @@ -222,7 +222,7 @@ def select_additional_repositories(preset: List[str]) -> List[str]: sort=False, multi=True, preset_values=preset, - explode_on_interrupt=True + raise_error_on_interrupt=True ).run() match choice.type_: diff --git a/archinstall/lib/user_interaction/network_conf.py b/archinstall/lib/user_interaction/network_conf.py index 1908603e..557e8ed8 100644 --- a/archinstall/lib/user_interaction/network_conf.py +++ b/archinstall/lib/user_interaction/network_conf.py @@ -154,8 +154,8 @@ def ask_to_configure_network( list(network_options.values()), cursor_index=cursor_idx, sort=False, - explode_on_interrupt=True, - explode_warning=warning + raise_error_on_interrupt=True, + raise_error_warning_msg=warning ).run() match choice.type_: diff --git a/archinstall/lib/user_interaction/system_conf.py b/archinstall/lib/user_interaction/system_conf.py index f4ada14b..0416e91f 100644 --- a/archinstall/lib/user_interaction/system_conf.py +++ b/archinstall/lib/user_interaction/system_conf.py @@ -32,8 +32,8 @@ def select_kernel(preset: List[str] = None) -> List[str]: sort=True, multi=True, preset_values=preset, - explode_on_interrupt=True, - explode_warning=warning + raise_error_on_interrupt=True, + raise_error_warning_msg=warning ).run() match choice.type_: @@ -67,8 +67,8 @@ def select_harddrives(preset: List[str] = []) -> List[str]: list(options.keys()), preset_values=list(preset_disks.keys()), multi=True, - explode_on_interrupt=True, - explode_warning=warning + raise_error_on_interrupt=True, + raise_error_warning_msg=warning ).run() match selected_harddrive.type_: -- cgit v1.2.3-54-g00ecf From 31e6eca3af607bbfa79cda30c9e0ff16bb2b66c3 Mon Sep 17 00:00:00 2001 From: Daniel Girtler Date: Mon, 1 Aug 2022 18:29:58 +1000 Subject: Handle no internet connection gracefully (#1361) * Handle no internet connection gracefully * Update * flake8 * Update * Update Co-authored-by: Daniel Girtler --- archinstall/lib/networking.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'archinstall') diff --git a/archinstall/lib/networking.py b/archinstall/lib/networking.py index 3e883a7b..96e8f3a1 100644 --- a/archinstall/lib/networking.py +++ b/archinstall/lib/networking.py @@ -4,7 +4,7 @@ import socket import struct from typing import Union, Dict, Any, List -from .exceptions import HardwareIncompatibilityError +from .exceptions import HardwareIncompatibilityError, SysCallError from .general import SysCommand from .output import log from .pacman import run_pacman @@ -33,14 +33,17 @@ def list_interfaces(skip_loopback :bool = True) -> Dict[str, str]: def check_mirror_reachable() -> bool: log("Testing connectivity to the Arch Linux mirrors ...", level=logging.INFO) - if run_pacman("-Sy").exit_code == 0: - return True - - elif os.geteuid() != 0: - log("check_mirror_reachable() uses 'pacman -Sy' which requires root.", level=logging.ERROR, fg="red") + try: + if run_pacman("-Sy").exit_code == 0: + return True + elif os.geteuid() != 0: + log("check_mirror_reachable() uses 'pacman -Sy' which requires root.", level=logging.ERROR, fg="red") + except SysCallError as err: + log(err, level=logging.DEBUG) return False + def update_keyring() -> bool: log("Updating archlinux-keyring ...", level=logging.INFO) if run_pacman("-Sy --noconfirm archlinux-keyring").exit_code == 0: -- cgit v1.2.3-54-g00ecf From 94d611d22f178474d1f3a491cfe60e99bd3293b3 Mon Sep 17 00:00:00 2001 From: 0xShree <49250702+0xShree@users.noreply.github.com> Date: Mon, 1 Aug 2022 08:33:38 +0000 Subject: Change regex expression only to match #[multilib] string (#1364) * Changed regex expression only to match [multilib] string * Update multilib regex expression * Update regex expression Add raw string format --- archinstall/lib/installer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'archinstall') diff --git a/archinstall/lib/installer.py b/archinstall/lib/installer.py index f874c7fa..42f71678 100644 --- a/archinstall/lib/installer.py +++ b/archinstall/lib/installer.py @@ -325,7 +325,7 @@ class Installer: def enable_multilib_repository(self): # Set up a regular expression pattern of a commented line containing 'multilib' within [] - pattern = re.compile("^#\\[.*multilib.*\\]$") + pattern = re.compile(r"^#\s*\[multilib\]$") # This is used to track if the previous line is a match, so we end up uncommenting the line after the block. matched = False -- cgit v1.2.3-54-g00ecf From 7bf0fe3c56ed1e8ca9a55ab3dbf6943f94e2a1af Mon Sep 17 00:00:00 2001 From: Werner Llácer Date: Mon, 1 Aug 2022 10:38:22 +0200 Subject: restoring ability to use a predefined installation directory (#1373) --- archinstall/lib/menu/global_menu.py | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) (limited to 'archinstall') diff --git a/archinstall/lib/menu/global_menu.py b/archinstall/lib/menu/global_menu.py index 1badc052..d9943945 100644 --- a/archinstall/lib/menu/global_menu.py +++ b/archinstall/lib/menu/global_menu.py @@ -42,6 +42,7 @@ if TYPE_CHECKING: class GlobalMenu(GeneralMenu): def __init__(self,data_store): + self._disk_check = True super().__init__(data_store=data_store, auto_cursor=True, preview_size=0.3) def _setup_selection_menu_options(self): @@ -304,11 +305,12 @@ class GlobalMenu(GeneralMenu): missing += ['Hostname'] if not check('!root-password') and not has_superuser(): missing += [str(_('Either root-password or at least 1 user with sudo privileges must be specified'))] - if not check('harddrives'): - missing += [str(_('Drive(s)'))] - if check('harddrives'): - if not self._menu_options['harddrives'].is_empty() and not check('disk_layouts'): - missing += [str(_('Disk layout'))] + if self._disk_check: + if not check('harddrives'): + missing += [str(_('Drive(s)'))] + if check('harddrives'): + if not self._menu_options['harddrives'].is_empty() and not check('disk_layouts'): + missing += [str(_('Disk layout'))] return missing @@ -334,7 +336,7 @@ class GlobalMenu(GeneralMenu): def _select_harddrives(self, old_harddrives : list) -> List: harddrives = select_harddrives(old_harddrives) - if harddrives: + if harddrives is not None: if len(harddrives) == 0: prompt = _( "You decided to skip harddrive selection\nand will use whatever drive-setup is mounted at {} (experimental)\n" @@ -345,7 +347,10 @@ class GlobalMenu(GeneralMenu): choice = Menu(prompt, Menu.yes_no(), default_option=Menu.yes(), skip=False).run() if choice.value == Menu.no(): + self._disk_check = True return self._select_harddrives(old_harddrives) + else: + self._disk_check = False # in case the harddrives got changed we have to reset the disk layout as well if old_harddrives != harddrives: -- cgit v1.2.3-54-g00ecf From 68d89a07dfbf298918dc5575bec00976f3ae5dd6 Mon Sep 17 00:00:00 2001 From: Werner Llácer Date: Mon, 1 Aug 2022 10:41:44 +0200 Subject: enhacements to FormattedOutput (#1376) * enhacements to FormattedOutput * flake8 complain --- archinstall/lib/output.py | 78 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 58 insertions(+), 20 deletions(-) (limited to 'archinstall') diff --git a/archinstall/lib/output.py b/archinstall/lib/output.py index e2b38ce6..709a7382 100644 --- a/archinstall/lib/output.py +++ b/archinstall/lib/output.py @@ -2,45 +2,83 @@ import logging import os import sys from pathlib import Path -from typing import Dict, Union, List, Any +from typing import Dict, Union, List, Any, Callable from .storage import storage +from dataclasses import asdict, is_dataclass class FormattedOutput: @classmethod - def values(cls, o: Any) -> Dict[str, Any]: - if hasattr(o, 'as_json'): + def values(cls, o: Any, class_formatter: str = None, filter_list: List[str] = None) -> Dict[str, Any]: + """ the original values returned a dataclass as dict thru the call to some specific methods + this version allows thru the parameter class_formatter to call a dynamicly selected formatting method. + Can transmit a filter list to the class_formatter, + """ + if class_formatter: + # if invoked per reference it has to be a standard function or a classmethod. + # A method of an instance does not make sense + if callable(class_formatter): + return class_formatter(o, filter_list) + # if is invoked by name we restrict it to a method of the class. No need to mess more + elif hasattr(o, class_formatter) and callable(getattr(o, class_formatter)): + func = getattr(o, class_formatter) + return func(filter_list) + # kept as to make it backward compatible + elif hasattr(o, 'as_json'): return o.as_json() elif hasattr(o, 'json'): return o.json() + elif is_dataclass(o): + return asdict(o) else: return o.__dict__ @classmethod - def as_table(cls, obj: List[Any]) -> str: + def as_table(cls, obj: List[Any], class_formatter: Union[str, Callable] = None, filter_list: List[str] = None) -> str: + """ variant of as_table (subtly different code) which has two additional parameters + filter which is a list of fields which will be shon + class_formatter a special method to format the outgoing data + + A general comment, the format selected for the output (a string where every data record is separated by newline) + is for compatibility with a print statement + As_table_filter can be a drop in replacement for as_table + """ + raw_data = [cls.values(o, class_formatter, filter_list) for o in obj] + # determine the maximum column size column_width: Dict[str, int] = {} - for o in obj: - for k, v in cls.values(o).items(): - column_width.setdefault(k, 0) - column_width[k] = max([column_width[k], len(str(v)), len(k)]) - + for o in raw_data: + for k, v in o.items(): + if not filter_list or k in filter_list: + column_width.setdefault(k, 0) + column_width[k] = max([column_width[k], len(str(v)), len(k)]) + + if not filter_list: + filter_list = (column_width.keys()) + # create the header lines output = '' - for key, width in column_width.items(): + key_list = [] + for key in filter_list: + width = column_width[key] key = key.replace('!', '') - output += key.ljust(width) + ' | ' - - output = output[:-3] + '\n' + key_list.append(key.ljust(width)) + output += ' | '.join(key_list) + '\n' output += '-' * len(output) + '\n' - for o in obj: - for k, v in cls.values(o).items(): - if '!' in k: - v = '*' * len(str(v)) - output += str(v).ljust(column_width[k]) + ' | ' - output = output[:-3] - output += '\n' + # create the data lines + for record in raw_data: + obj_data = [] + for key in filter_list: + width = column_width.get(key, len(key)) + value = record.get(key, '') + if '!' in key: + value = '*' * width + if isinstance(value,(int, float)) or (isinstance(value, str) and value.isnumeric()): + obj_data.append(str(value).rjust(width)) + else: + obj_data.append(str(value).ljust(width)) + output += ' | '.join(obj_data) + '\n' return output -- cgit v1.2.3-54-g00ecf From 5626c109272b7d34d25facbd2b22f466bf1f4ce2 Mon Sep 17 00:00:00 2001 From: Samaoo Date: Mon, 1 Aug 2022 14:07:04 +0200 Subject: fix `valid_parted_position()` (#1382) * fix `valid_parted_position()` * make lines shorter * change `pos` to `pos.lower()` * revert changing `if not len(pos):` to `if not pos:` * `b` can not have decimal places * add `.lower()` --- archinstall/lib/disk/validators.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'archinstall') diff --git a/archinstall/lib/disk/validators.py b/archinstall/lib/disk/validators.py index fd1b7f33..54808886 100644 --- a/archinstall/lib/disk/validators.py +++ b/archinstall/lib/disk/validators.py @@ -7,13 +7,11 @@ def valid_parted_position(pos :str) -> bool: if pos.isdigit(): return True - if pos[-1] == '%' and pos[:-1].isdigit(): + if pos.lower().endswith('b') and pos[:-1].isdigit(): return True - if pos[-3:].lower() in ['mib', 'kib', 'b', 'tib'] and pos[:-3].replace(".", "", 1).isdigit(): - return True - - if pos[-2:].lower() in ['kb', 'mb', 'gb', 'tb'] and pos[:-2].replace(".", "", 1).isdigit(): + if any(pos.lower().endswith(size) and pos[:-len(size)].replace(".", "", 1).isdigit() + for size in ['%', 'kb', 'mb', 'gb', 'tb', 'kib', 'mib', 'gib', 'tib']): return True return False -- cgit v1.2.3-54-g00ecf From 463114356cd195b5402fc7f280508fea6566a7df Mon Sep 17 00:00:00 2001 From: Abhay Mohandas <80393938+abhay-mohandas@users.noreply.github.com> Date: Mon, 1 Aug 2022 19:09:39 +0530 Subject: Option for Parallel Downloads (#1397) * Adding menu * Working on parallel downloads * error updates * updates * update * Few more updates * bug fixes * More bug fixes * Minor bug fixes * Few changes * Minor changes * Cleaned up add_number_of_parrallel_downloads() and hid it behind --advanced * Forgot one import * Fixed flake8 Co-authored-by: Anton Hvornum --- archinstall/lib/menu/global_menu.py | 10 ++++++++++ archinstall/lib/user_interaction/__init__.py | 2 +- archinstall/lib/user_interaction/general_conf.py | 24 ++++++++++++++++++++++++ examples/guided.py | 4 ++++ 4 files changed, 39 insertions(+), 1 deletion(-) (limited to 'archinstall') diff --git a/archinstall/lib/menu/global_menu.py b/archinstall/lib/menu/global_menu.py index d9943945..b518ac22 100644 --- a/archinstall/lib/menu/global_menu.py +++ b/archinstall/lib/menu/global_menu.py @@ -32,6 +32,7 @@ from ..user_interaction import select_encrypted_partitions from ..user_interaction import select_harddrives from ..user_interaction import select_profile from ..user_interaction import select_additional_repositories +from ..user_interaction import add_number_of_parrallel_downloads from ..models.users import User from ..user_interaction.partitioning_conf import current_partition_layout from ..output import FormattedOutput @@ -145,6 +146,15 @@ class GlobalMenu(GeneralMenu): display_func=lambda x: x if x else 'None', default=None ) + + self._menu_options['parallel downloads'] = \ + Selector( + _('Parallel Downloads'), + add_number_of_parrallel_downloads, + display_func=lambda x: x if x else '0', + default=None + ) + self._menu_options['kernels'] = \ Selector( _('Kernels'), diff --git a/archinstall/lib/user_interaction/__init__.py b/archinstall/lib/user_interaction/__init__.py index 8aba4b4d..a1ca2652 100644 --- a/archinstall/lib/user_interaction/__init__.py +++ b/archinstall/lib/user_interaction/__init__.py @@ -7,6 +7,6 @@ from .network_conf import ask_to_configure_network from .partitioning_conf import select_partition, select_encrypted_partitions from .general_conf import (ask_ntp, ask_for_a_timezone, ask_for_audio_selection, select_language, select_mirror_regions, select_profile, select_archinstall_language, ask_additional_packages_to_install, - select_additional_repositories, ask_hostname) + select_additional_repositories, ask_hostname, add_number_of_parrallel_downloads) from .disk_conf import ask_for_main_filesystem_format, select_individual_blockdevice_usage, select_disk_layout, select_disk from .utils import get_password, do_countdown diff --git a/archinstall/lib/user_interaction/general_conf.py b/archinstall/lib/user_interaction/general_conf.py index 754ffa29..44147afa 100644 --- a/archinstall/lib/user_interaction/general_conf.py +++ b/archinstall/lib/user_interaction/general_conf.py @@ -1,6 +1,7 @@ from __future__ import annotations import logging +import pathlib from typing import List, Any, Optional, Dict, TYPE_CHECKING from ..menu.menu import MenuSelectionType @@ -205,6 +206,29 @@ def ask_additional_packages_to_install(pre_set_packages: List[str] = []) -> List return packages +def add_number_of_parrallel_downloads(input_number :Optional[int] = None) -> Optional[int]: + print(_("Enter the number of parallel downloads to be enabled.\n [Default value is 0]")) + + while input_number is None: + try: + input_number = int(TextInput("> ").run().strip() or 0) + break + except: + print(_("Invalid input! Try again with a valid input")) + + pacman_conf_path = pathlib.Path("/etc/pacman.conf") + with pacman_conf_path.open() as f: + pacman_conf = f.read().split("\n") + + with pacman_conf_path.open("w") as fwrite: + for line in pacman_conf: + if "ParallelDownloads" in line: + fwrite.write(f"ParallelDownloads = {input_number}\n") + else: + fwrite.write(f"{line}\n") + + return input_number + def select_additional_repositories(preset: List[str]) -> List[str]: """ diff --git a/examples/guided.py b/examples/guided.py index 0bb377a4..bbf19bf9 100644 --- a/examples/guided.py +++ b/examples/guided.py @@ -85,6 +85,10 @@ def ask_user_questions(): global_menu.enable('packages') + if archinstall.arguments.get('advanced', False): + # Enable parallel downloads + global_menu.enable('parallel downloads') + # Ask or Call the helper function that asks the user to optionally configure a network. global_menu.enable('nic') -- cgit v1.2.3-54-g00ecf From a31bf94fa3727ef2c13e37d33560f6acf1141902 Mon Sep 17 00:00:00 2001 From: Anton Hvornum Date: Tue, 9 Aug 2022 14:58:09 +0200 Subject: Adding a .json() call for our JSON serializer for the Language class (#1410) * Adding a .json() call for our JSON serializer * Update translationhandler.py --- archinstall/lib/translationhandler.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'archinstall') diff --git a/archinstall/lib/translationhandler.py b/archinstall/lib/translationhandler.py index 12c8da4a..58b7ebd4 100644 --- a/archinstall/lib/translationhandler.py +++ b/archinstall/lib/translationhandler.py @@ -37,6 +37,8 @@ class Language: return True return False + def json(self) -> str: + return self.lang class TranslationHandler: _base_pot = 'base.pot' -- cgit v1.2.3-54-g00ecf From 437ac124c6f02bc4f1c7e319a8ad407acffe9d8f Mon Sep 17 00:00:00 2001 From: Anton Hvornum Date: Tue, 9 Aug 2022 20:05:05 +0200 Subject: Converted paths to pathlib.Path and mount points to detect properly (#1412) * Converted a path to pathlib.Path * Using Partition.mountpoints instead of Partition.mountpoint * Update mapperdev.py * Added .mountpoints to MapperDev * Spelling error --- archinstall/lib/disk/helpers.py | 4 ++++ archinstall/lib/disk/mapperdev.py | 6 +++++- archinstall/lib/installer.py | 4 ++-- 3 files changed, 11 insertions(+), 3 deletions(-) (limited to 'archinstall') diff --git a/archinstall/lib/disk/helpers.py b/archinstall/lib/disk/helpers.py index c8ac564e..60efe724 100644 --- a/archinstall/lib/disk/helpers.py +++ b/archinstall/lib/disk/helpers.py @@ -403,6 +403,10 @@ def get_partitions_in_use(mountpoint :str) -> Dict[str, Any]: log(f'Filtering available mounts {block_devices_mountpoints} to those under {mountpoint}', level=logging.DEBUG) for mountpoint in list(get_all_targets(output['filesystems']).keys()): + # Since all_blockdevices() returns PosixPath objects, we need to convert + # findmnt paths to pathlib.Path() first: + mountpoint = pathlib.Path(mountpoint) + if mountpoint in block_devices_mountpoints: if mountpoint not in mounts: mounts[mountpoint] = block_devices_mountpoints[mountpoint] diff --git a/archinstall/lib/disk/mapperdev.py b/archinstall/lib/disk/mapperdev.py index 49137ae9..71ef2a79 100644 --- a/archinstall/lib/disk/mapperdev.py +++ b/archinstall/lib/disk/mapperdev.py @@ -64,10 +64,14 @@ class MapperDev: return None + @property + def mountpoints(self) -> List[Dict[str, Any]]: + return [obj['target'] for obj in self.mount_information] + @property def mount_information(self) -> List[Dict[str, Any]]: from .helpers import find_mountpoint - return list(find_mountpoint(self.path)) + return [{**obj, 'target' : pathlib.Path(obj.get('target', '/dev/null'))} for obj in find_mountpoint(self.path)] @property def filesystem(self) -> Optional[str]: diff --git a/archinstall/lib/installer.py b/archinstall/lib/installer.py index 42f71678..a0bcc2a6 100644 --- a/archinstall/lib/installer.py +++ b/archinstall/lib/installer.py @@ -1000,9 +1000,9 @@ class Installer: root_partition = None for partition in self.partitions: print(partition, [partition.mountpoint], [self.target]) - if partition.mountpoint == self.target / 'boot': + if self.target / 'boot' in partition.mountpoints: boot_partition = partition - elif partition.mountpoint == self.target: + elif self.target in partition.mountpoints: root_partition = partition if boot_partition is None or root_partition is None: -- cgit v1.2.3-54-g00ecf From 3e10fc106b27c70593147b1c8aef1be221106d75 Mon Sep 17 00:00:00 2001 From: Metin Yazici Date: Tue, 9 Aug 2022 20:14:28 +0200 Subject: Add command line option to get the program version (#1406) --- archinstall/__init__.py | 1 + 1 file changed, 1 insertion(+) (limited to 'archinstall') diff --git a/archinstall/__init__.py b/archinstall/__init__.py index f607a922..3e9f8391 100644 --- a/archinstall/__init__.py +++ b/archinstall/__init__.py @@ -66,6 +66,7 @@ def define_arguments(): Remember that the property/entry name python assigns to the parameters is the first string defined as argument and dashes inside it '-' are changed to '_' """ + parser.add_argument("-v", "--version", action="version", version="%(prog)s " + __version__) parser.add_argument("--config", nargs="?", help="JSON configuration file or URL") parser.add_argument("--creds", nargs="?", help="JSON credentials configuration file") parser.add_argument("--disk_layouts","--disk_layout","--disk-layouts","--disk-layout",nargs="?", -- cgit v1.2.3-54-g00ecf From 6213560a0543b11eb007020b044255edaf009d4b Mon Sep 17 00:00:00 2001 From: Abhay Mohandas <80393938+abhay-mohandas@users.noreply.github.com> Date: Tue, 9 Aug 2022 23:45:49 +0530 Subject: Fixes for known issues in the Parallel Download option (#1403) * Adding menu * Working on parallel downloads * error updates * updates * update * Few more updates * bug fixes * More bug fixes * Minor bug fixes * Few changes * Minor changes * Cleaned up add_number_of_parrallel_downloads() and hid it behind --advanced * Forgot one import * Fixed flake8 * Bug fixes * I'm trying... * trying again * trying even more * Bug fixes * Fixed known issues * Code improvements * Few fixes * Minor changes * Minor changes * Trying to fix flake8 Co-authored-by: Anton Hvornum --- archinstall/lib/menu/global_menu.py | 2 +- archinstall/lib/user_interaction/general_conf.py | 22 ++++++++++++++++------ 2 files changed, 17 insertions(+), 7 deletions(-) (limited to 'archinstall') diff --git a/archinstall/lib/menu/global_menu.py b/archinstall/lib/menu/global_menu.py index b518ac22..f631c086 100644 --- a/archinstall/lib/menu/global_menu.py +++ b/archinstall/lib/menu/global_menu.py @@ -152,7 +152,7 @@ class GlobalMenu(GeneralMenu): _('Parallel Downloads'), add_number_of_parrallel_downloads, display_func=lambda x: x if x else '0', - default=None + default=0 ) self._menu_options['kernels'] = \ diff --git a/archinstall/lib/user_interaction/general_conf.py b/archinstall/lib/user_interaction/general_conf.py index 44147afa..a121f368 100644 --- a/archinstall/lib/user_interaction/general_conf.py +++ b/archinstall/lib/user_interaction/general_conf.py @@ -206,15 +206,25 @@ def ask_additional_packages_to_install(pre_set_packages: List[str] = []) -> List return packages -def add_number_of_parrallel_downloads(input_number :Optional[int] = None) -> Optional[int]: - print(_("Enter the number of parallel downloads to be enabled.\n [Default value is 0]")) - while input_number is None: +def add_number_of_parrallel_downloads(input_number :Optional[int] = None) -> Optional[int]: + max_downloads = 5 + print(_(f"This option enables the number of parallel downloads that can occur during installation")) + print(_(f"Enter the number of parallel downloads to be enabled.\n (Enter a value between 1 to {max_downloads})\nNote:")) + print(_(f" - Maximum value : {max_downloads} ( Allows {max_downloads} parallel downloads, allows {max_downloads+1} downloads at a time )")) + print(_(f" - Minimum value : 1 ( Allows 1 parallel download, allows 2 downloads at a time )")) + print(_(f" - Disable/Default : 0 ( Disables parallel downloading, allows only 1 download at a time )")) + + while True: try: - input_number = int(TextInput("> ").run().strip() or 0) + input_number = int(TextInput("[Default value: 0] > ").run().strip() or 0) + if input_number <= 0: + input_number = 0 + elif input_number > max_downloads: + input_number = max_downloads break except: - print(_("Invalid input! Try again with a valid input")) + print(_(f"Invalid input! Try again with a valid input [1 to {max_downloads}, or 0 to disable]")) pacman_conf_path = pathlib.Path("/etc/pacman.conf") with pacman_conf_path.open() as f: @@ -223,7 +233,7 @@ def add_number_of_parrallel_downloads(input_number :Optional[int] = None) -> Opt with pacman_conf_path.open("w") as fwrite: for line in pacman_conf: if "ParallelDownloads" in line: - fwrite.write(f"ParallelDownloads = {input_number}\n") + fwrite.write(f"ParallelDownloads = {input_number+1}\n") if not input_number == 0 else fwrite.write("#ParallelDownloads = 0\n") else: fwrite.write(f"{line}\n") -- cgit v1.2.3-54-g00ecf From 242f8076bb7679a565433e30c61662c70f37b06f Mon Sep 17 00:00:00 2001 From: Anton Hvornum Date: Wed, 10 Aug 2022 11:02:24 +0200 Subject: Adding better error output for when loading remote configurations goes wrong. (#1415) --- archinstall/lib/general.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'archinstall') diff --git a/archinstall/lib/general.py b/archinstall/lib/general.py index 27f444e8..9edbaea8 100644 --- a/archinstall/lib/general.py +++ b/archinstall/lib/general.py @@ -12,6 +12,7 @@ import time import re import urllib.parse import urllib.request +import urllib.error import pathlib from datetime import datetime, date from typing import Callable, Optional, Dict, Any, List, Union, Iterator, TYPE_CHECKING @@ -548,8 +549,12 @@ def json_stream_to_structure(configuration_identifier : str, stream :str, target parsed_url = urllib.parse.urlparse(stream) if parsed_url.scheme: # The stream is in fact a URL that should be grabbed - with urllib.request.urlopen(urllib.request.Request(stream, headers={'User-Agent': 'ArchInstall'})) as response: - target.update(json.loads(response.read())) + try: + with urllib.request.urlopen(urllib.request.Request(stream, headers={'User-Agent': 'ArchInstall'})) as response: + target.update(json.loads(response.read())) + except urllib.error.HTTPError as error: + log(f"Could not load {configuration_identifier} via {parsed_url} due to: {error}", level=logging.ERROR, fg="red") + return False else: if pathlib.Path(stream).exists(): try: -- cgit v1.2.3-54-g00ecf From 259aaa488428aa5647d27ebb8e4678829e793dc2 Mon Sep 17 00:00:00 2001 From: Anton Hvornum Date: Wed, 10 Aug 2022 12:57:32 +0200 Subject: Fixing a list access issue (#1416) --- archinstall/lib/installer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'archinstall') diff --git a/archinstall/lib/installer.py b/archinstall/lib/installer.py index a0bcc2a6..798801aa 100644 --- a/archinstall/lib/installer.py +++ b/archinstall/lib/installer.py @@ -219,7 +219,7 @@ class Installer: """ if partition.get("mountpoint") is None: if (sub_list := partition.get("btrfs",{}).get('subvolumes',{})): - for mountpoint in [sub_list[subvolume] if isinstance(sub_list[subvolume],str) else sub_list[subvolume].get("mountpoint") for subvolume in sub_list if sub_list[subvolume]]: + for mountpoint in [sub_list[subvolume].get("mountpoint") if isinstance(subvolume, dict) else subvolume.mountpoint for subvolume in sub_list]: if mountpoint == '/': return True return False -- cgit v1.2.3-54-g00ecf From 397cceca90592ec39a594cd8fa5215b64d7238ae Mon Sep 17 00:00:00 2001 From: codefiles <11915375+codefiles@users.noreply.github.com> Date: Thu, 11 Aug 2022 05:32:33 -0400 Subject: Fix check for additional repositories (#1391) * Fix typos * Fix check for additional repositories --- archinstall/lib/installer.py | 2 +- examples/guided.py | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) (limited to 'archinstall') diff --git a/archinstall/lib/installer.py b/archinstall/lib/installer.py index 798801aa..8b87b072 100644 --- a/archinstall/lib/installer.py +++ b/archinstall/lib/installer.py @@ -705,7 +705,7 @@ class Installer: self.log("The multilib flag is set. This system will be installed with the multilib repository enabled.") self.enable_multilib_repository() else: - self.log("The testing flag is not set. This system will be installed without testing repositories enabled.") + self.log("The multilib flag is not set. This system will be installed without multilib repositories enabled.") if testing: self.log("The testing flag is set. This system will be installed with testing repositories enabled.") diff --git a/examples/guided.py b/examples/guided.py index bbf19bf9..ffbc6226 100644 --- a/examples/guided.py +++ b/examples/guided.py @@ -185,8 +185,12 @@ def perform_installation(mountpoint): archinstall.use_mirrors(archinstall.arguments['mirror-region']) # Set the mirrors for the live medium # Retrieve list of additional repositories and set boolean values appropriately - enable_testing = 'testing' in archinstall.arguments.get('additional-repositories', None) - enable_multilib = 'multilib' in archinstall.arguments.get('additional-repositories', None) + if archinstall.arguments.get('additional-repositories', None) is not None: + enable_testing = 'testing' in archinstall.arguments.get('additional-repositories', None) + enable_multilib = 'multilib' in archinstall.arguments.get('additional-repositories', None) + else: + enable_testing = False + enable_multilib = False if installation.minimal_installation(testing=enable_testing, multilib=enable_multilib): installation.set_locale(archinstall.arguments['sys-language'], archinstall.arguments['sys-encoding'].upper()) -- cgit v1.2.3-54-g00ecf From 1086fd686d28317851c7f09eb00898648ecaaad7 Mon Sep 17 00:00:00 2001 From: Anton Hvornum Date: Thu, 11 Aug 2022 18:06:02 +0200 Subject: Cleaned up argument loading slighly. (#1419) * Cleaned up argument loading slighly. Also flipped some --silent logic to avoid double negatives. --plugin and --conf {'plugin': ...} should now both work. * Tweaked xorg profile to use list instead of strings. Because strings causes some issues through add_additional_packages() as it ends up as [(xorg, xorg-xinit), nano] instead of a flat list of packages or string. * Tweaked xorg profile to use list instead of strings. Because strings causes some issues through add_additional_packages() as it ends up as [(xorg, xorg-xinit), nano] instead of a flat list of packages or string. --- archinstall/__init__.py | 30 +++++++++++++++++++++++++----- archinstall/lib/plugins.py | 2 ++ profiles/xorg.py | 10 +++++----- 3 files changed, 32 insertions(+), 10 deletions(-) (limited to 'archinstall') diff --git a/archinstall/__init__.py b/archinstall/__init__.py index 3e9f8391..090ad7de 100644 --- a/archinstall/__init__.py +++ b/archinstall/__init__.py @@ -1,5 +1,6 @@ """Arch Linux installer - guided, templates etc.""" -from argparse import ArgumentParser +import typing +from argparse import ArgumentParser, Namespace from .lib.disk import * from .lib.exceptions import * @@ -132,6 +133,24 @@ def parse_unspecified_argument_list(unknowns :list, multiple :bool = False, erro print(f" We ignore the entry {element} as it isn't related to any argument") return config +def cleanup_empty_args(args :typing.Union[Namespace, dict]) -> dict: + """ + Takes arguments (dictionary or argparse Namespace) and removes any + None values. This ensures clean mergers during dict.update(args) + """ + if type(args) == Namespace: + args = vars(args) + + clean_args = {} + for key, val in args.items(): + if type(val) == dict: + val = cleanup_empty_args(val) + + if val is not None: + clean_args[key] = val + + return clean_args + def get_arguments() -> Dict[str, Any]: """ The handling of parameters from the command line Is done on following steps: @@ -159,14 +178,15 @@ def get_arguments() -> Dict[str, Any]: exit(1) # load the parameters. first the known, then the unknowns - config.update(vars(args)) + args = cleanup_empty_args(args) + config.update(args) config.update(parse_unspecified_argument_list(unknowns)) # amend the parameters (check internal consistency) # Installation can't be silent if config is not passed - if args.config is not None : - config["silent"] = args.silent - else: + if args.get('config') is None: config["silent"] = False + else: + config["silent"] = args.get('silent') # avoiding a compatibility issue if 'dry-run' in config: diff --git a/archinstall/lib/plugins.py b/archinstall/lib/plugins.py index f771aacb..0ff63610 100644 --- a/archinstall/lib/plugins.py +++ b/archinstall/lib/plugins.py @@ -73,6 +73,7 @@ def find_nth(haystack :List[str], needle :str, n :int) -> int: def load_plugin(path :str) -> ModuleType: parsed_url = urllib.parse.urlparse(path) + log(f"Loading plugin {parsed_url}.", fg="gray", level=logging.INFO) # The Profile was not a direct match on a remote URL if not parsed_url.scheme: @@ -96,6 +97,7 @@ def load_plugin(path :str) -> ModuleType: if hasattr(sys.modules[namespace], 'Plugin'): try: plugins[namespace] = sys.modules[namespace].Plugin() + log(f"Plugin {plugins[namespace]} has been loaded.", fg="gray", level=logging.INFO) except Exception as err: log(err, level=logging.ERROR) log(f"The above error was detected when initiating the plugin: {path}", fg="red", level=logging.ERROR) diff --git a/profiles/xorg.py b/profiles/xorg.py index 2ce8dcc2..de45acd3 100644 --- a/profiles/xorg.py +++ b/profiles/xorg.py @@ -47,9 +47,9 @@ if __name__ == 'xorg': for kernel in archinstall.storage['installation_session'].kernels: archinstall.storage['installation_session'].add_additional_packages(f"{kernel}-headers") # Fixes https://github.com/archlinux/archinstall/issues/585 archinstall.storage['installation_session'].add_additional_packages("dkms") # I've had kernel regen fail if it wasn't installed before nvidia-dkms - archinstall.storage['installation_session'].add_additional_packages("xorg-server xorg-xinit nvidia-dkms") + archinstall.storage['installation_session'].add_additional_packages("xorg-server", "xorg-xinit", "nvidia-dkms") else: - archinstall.storage['installation_session'].add_additional_packages(f"xorg-server xorg-xinit {' '.join(archinstall.storage.get('gfx_driver_packages', []))}") + archinstall.storage['installation_session'].add_additional_packages(f"xorg-server", "xorg-xinit", *archinstall.storage.get('gfx_driver_packages', [])) elif 'amdgpu' in archinstall.storage.get("gfx_driver_packages", []): # The order of these two are important if amdgpu is installed #808 if 'amdgpu' in archinstall.storage['installation_session'].MODULES: @@ -60,9 +60,9 @@ if __name__ == 'xorg': archinstall.storage['installation_session'].MODULES.remove('radeon') archinstall.storage['installation_session'].MODULES.append('radeon') - archinstall.storage['installation_session'].add_additional_packages(f"xorg-server xorg-xinit {' '.join(archinstall.storage.get('gfx_driver_packages', []))}") + archinstall.storage['installation_session'].add_additional_packages(f"xorg-server", "xorg-xinit", *archinstall.storage.get('gfx_driver_packages', [])) else: - archinstall.storage['installation_session'].add_additional_packages(f"xorg-server xorg-xinit {' '.join(archinstall.storage.get('gfx_driver_packages', []))}") + archinstall.storage['installation_session'].add_additional_packages(f"xorg-server", "xorg-xinit", *archinstall.storage.get('gfx_driver_packages', [])) except Exception as err: archinstall.log(f"Could not handle nvidia and linuz-zen specific situations during xorg installation: {err}", level=logging.WARNING, fg="yellow") - archinstall.storage['installation_session'].add_additional_packages("xorg-server xorg-xinit") # Prep didn't run, so there's no driver to install + archinstall.storage['installation_session'].add_additional_packages("xorg-server", "xorg-xinit") # Prep didn't run, so there's no driver to install -- cgit v1.2.3-54-g00ecf From a78f7d193b4681ee5a4532982387844a749353d3 Mon Sep 17 00:00:00 2001 From: Anton Hvornum Date: Fri, 12 Aug 2022 16:58:41 +0200 Subject: Fixed small issues with how Installation.chown() was called. --- archinstall/lib/installer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'archinstall') diff --git a/archinstall/lib/installer.py b/archinstall/lib/installer.py index 8b87b072..5b6177bb 100644 --- a/archinstall/lib/installer.py +++ b/archinstall/lib/installer.py @@ -1131,7 +1131,7 @@ class Installer: return SysCommand(f"/usr/bin/arch-chroot {self.target} sh -c \"chsh -s {shell} {user}\"").exit_code == 0 def chown(self, owner :str, path :str, options :List[str] = []) -> bool: - return SysCommand(f"/usr/bin/arch-chroot {self.target} sh -c 'chown {' '.join(options)} {owner} {path}").exit_code == 0 + return SysCommand(f"/usr/bin/arch-chroot {self.target} sh -c 'chown {' '.join(options)} {owner} {path.repalce('\'', '\\\'')}'").exit_code == 0 def create_file(self, filename :str, owner :Optional[str] = None) -> InstallationFile: return InstallationFile(self, filename, owner) -- cgit v1.2.3-54-g00ecf From 7b06da280dd90421b233f1403b7bfe344bc11037 Mon Sep 17 00:00:00 2001 From: Anton Hvornum Date: Fri, 12 Aug 2022 18:11:27 +0200 Subject: Fix flake8 issue that slinked in. --- archinstall/lib/installer.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'archinstall') diff --git a/archinstall/lib/installer.py b/archinstall/lib/installer.py index 5b6177bb..05a74e14 100644 --- a/archinstall/lib/installer.py +++ b/archinstall/lib/installer.py @@ -1131,7 +1131,8 @@ class Installer: return SysCommand(f"/usr/bin/arch-chroot {self.target} sh -c \"chsh -s {shell} {user}\"").exit_code == 0 def chown(self, owner :str, path :str, options :List[str] = []) -> bool: - return SysCommand(f"/usr/bin/arch-chroot {self.target} sh -c 'chown {' '.join(options)} {owner} {path.repalce('\'', '\\\'')}'").exit_code == 0 + cleaned_path = path.repalce('\'', '\\\'') + return SysCommand(f"/usr/bin/arch-chroot {self.target} sh -c 'chown {' '.join(options)} {owner} {cleaned_path}'").exit_code == 0 def create_file(self, filename :str, owner :Optional[str] = None) -> InstallationFile: return InstallationFile(self, filename, owner) -- cgit v1.2.3-54-g00ecf From 7b4940ef6d2ec7631e948cffe55518e75609dcf3 Mon Sep 17 00:00:00 2001 From: Anton Hvornum Date: Fri, 12 Aug 2022 19:32:42 +0200 Subject: Spelling error on .replace() --- archinstall/lib/installer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'archinstall') diff --git a/archinstall/lib/installer.py b/archinstall/lib/installer.py index 05a74e14..62257642 100644 --- a/archinstall/lib/installer.py +++ b/archinstall/lib/installer.py @@ -1131,7 +1131,7 @@ class Installer: return SysCommand(f"/usr/bin/arch-chroot {self.target} sh -c \"chsh -s {shell} {user}\"").exit_code == 0 def chown(self, owner :str, path :str, options :List[str] = []) -> bool: - cleaned_path = path.repalce('\'', '\\\'') + cleaned_path = path.replace('\'', '\\\'') return SysCommand(f"/usr/bin/arch-chroot {self.target} sh -c 'chown {' '.join(options)} {owner} {cleaned_path}'").exit_code == 0 def create_file(self, filename :str, owner :Optional[str] = None) -> InstallationFile: -- cgit v1.2.3-54-g00ecf From b1ab5ba3723ef0d7c04b061189d5ad74cba0de8b Mon Sep 17 00:00:00 2001 From: Anton Hvornum Date: Fri, 12 Aug 2022 22:36:06 +0200 Subject: Fixing double insertion of encoding in locale.gen/locale.conf (#1421) * A temporary fix for #1200, in the long run we need something like what was mentioned in the issue comments: https://github.com/archlinux/archinstall/issues/1200#issuecomment-1212754806 * Enabled the use of modifier detection and getting it in right * Mistaken a split * Adding less strict decoding of output log, this in order to handle the more correct locale generation introduced in this PR. --- archinstall/lib/general.py | 2 +- archinstall/lib/installer.py | 21 +++++++++++++++++++-- 2 files changed, 20 insertions(+), 3 deletions(-) (limited to 'archinstall') diff --git a/archinstall/lib/general.py b/archinstall/lib/general.py index 9edbaea8..1dc37994 100644 --- a/archinstall/lib/general.py +++ b/archinstall/lib/general.py @@ -444,7 +444,7 @@ class SysCommand: def __repr__(self, *args :List[Any], **kwargs :Dict[str, Any]) -> str: if self.session: - return self.session._trace_log.decode('UTF-8') + return self.session._trace_log.decode('UTF-8', errors='backslashreplace') return '' def __json__(self) -> Dict[str, Union[str, bool, List[str], Dict[str, Any], Optional[bool], Optional[Dict[str, Any]]]]: diff --git a/archinstall/lib/installer.py b/archinstall/lib/installer.py index 62257642..08896289 100644 --- a/archinstall/lib/installer.py +++ b/archinstall/lib/installer.py @@ -443,10 +443,27 @@ class Installer: if not len(locale): return True + modifier = '' + + # This is a temporary patch to fix #1200 + if '.' in locale: + locale, potential_encoding = locale.split('.', 1) + + # Override encoding if encoding is set to the default parameter + # and the "found" encoding differs. + if encoding == 'UTF-8' and encoding != potential_encoding: + encoding = potential_encoding + + # Make sure we extract the modifier, that way we can put it in if needed. + if '@' in locale: + locale, modifier = locale.split('@', 1) + modifier = f"@{modifier}" + # - End patch + with open(f'{self.target}/etc/locale.gen', 'a') as fh: - fh.write(f'{locale}.{encoding} {encoding}\n') + fh.write(f'{locale}.{encoding}{modifier} {encoding}\n') with open(f'{self.target}/etc/locale.conf', 'w') as fh: - fh.write(f'LANG={locale}.{encoding}\n') + fh.write(f'LANG={locale}.{encoding}{modifier}\n') return True if SysCommand(f'/usr/bin/arch-chroot {self.target} locale-gen').exit_code == 0 else False -- cgit v1.2.3-54-g00ecf From 65212a46aa43fadb2b0ee88b46b573765d7be9f9 Mon Sep 17 00:00:00 2001 From: Anton Hvornum Date: Sun, 14 Aug 2022 11:56:24 +0200 Subject: Fix boot entry containing subvolume definition when no subvolumes were selected (#1424) * Attempting fix by looking at the subvolume 'name', should indicate it's a root block and not a root subvolume --- archinstall/lib/installer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'archinstall') diff --git a/archinstall/lib/installer.py b/archinstall/lib/installer.py index 08896289..0f298eba 100644 --- a/archinstall/lib/installer.py +++ b/archinstall/lib/installer.py @@ -866,7 +866,7 @@ class Installer: options_entry = f'rw intel_pstate=no_hwp {" ".join(self.KERNEL_PARAMS)}\n' for subvolume in root_partition.subvolumes: - if subvolume.root is True: + if subvolume.root is True and subvolume.name != '': options_entry = f"rootflags=subvol={subvolume.name} " + options_entry # Zswap should be disabled when using zram. -- cgit v1.2.3-54-g00ecf From 13703fbb04d7bc7975368b035342e104c26e3f35 Mon Sep 17 00:00:00 2001 From: Anton Hvornum Date: Sun, 28 Aug 2022 22:04:25 +0200 Subject: Fix permission flags on all the log files created (#1440) * Changed permissions on the logs stored in /var/log/archinstall. Also cleaned up one of the saves to have the same syntax as the others * Tweaked secondary encryption password detection logic, as it wouldn't take it from the main arguments[] otherwise. * Changed permission on cmd_output.txt * Changed permission on cmd_history.txt --- archinstall/lib/configuration.py | 14 +++++++++++++- archinstall/lib/general.py | 22 ++++++++++++++++++++-- archinstall/lib/installer.py | 11 ++++++----- 3 files changed, 39 insertions(+), 8 deletions(-) (limited to 'archinstall') diff --git a/archinstall/lib/configuration.py b/archinstall/lib/configuration.py index 510f7103..2a43174d 100644 --- a/archinstall/lib/configuration.py +++ b/archinstall/lib/configuration.py @@ -1,4 +1,6 @@ +import os import json +import stat import logging import pathlib from typing import Optional, Dict @@ -106,23 +108,33 @@ class ConfigurationOutput: def save_user_config(self, dest_path :pathlib.Path = None): if self._is_valid_path(dest_path): - with open(dest_path / self._user_config_file, 'w') as config_file: + target = dest_path / self._user_config_file + + with open(target, 'w') as config_file: config_file.write(self.user_config_to_json()) + os.chmod(str(dest_path / self._user_config_file), stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP) + def save_user_creds(self, dest_path :pathlib.Path = None): if self._is_valid_path(dest_path): if user_creds := self.user_credentials_to_json(): target = dest_path / self._user_creds_file + with open(target, 'w') as config_file: config_file.write(user_creds) + os.chmod(str(target), stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP) + def save_disk_layout(self, dest_path :pathlib.Path = None): if self._is_valid_path(dest_path): if disk_layout := self.disk_layout_to_json(): target = dest_path / self._disk_layout_file + with target.open('w') as config_file: config_file.write(disk_layout) + os.chmod(str(target), stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP) + def save(self, dest_path :pathlib.Path = None): if not dest_path: dest_path = self._default_save_path diff --git a/archinstall/lib/general.py b/archinstall/lib/general.py index 1dc37994..61c4358e 100644 --- a/archinstall/lib/general.py +++ b/archinstall/lib/general.py @@ -6,6 +6,7 @@ import os import secrets import shlex import subprocess +import stat import string import sys import time @@ -313,9 +314,18 @@ class SysCommandWorker: except UnicodeDecodeError: return False - with open(f"{storage['LOG_PATH']}/cmd_output.txt", "a") as peak_output_log: + peak_logfile = pathlib.Path(f"{storage['LOG_PATH']}/cmd_output.txt") + + change_perm = False + if peak_logfile.exists() is False: + change_perm = True + + with peak_logfile.open("a") as peak_output_log: peak_output_log.write(output) + if change_perm: + os.chmod(str(peak_logfile), stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP) + sys.stdout.write(str(output)) sys.stdout.flush() @@ -361,10 +371,18 @@ class SysCommandWorker: # https://stackoverflow.com/questions/4022600/python-pty-fork-how-does-it-work if not self.pid: + history_logfile = pathlib.Path(f"{storage['LOG_PATH']}/cmd_history.txt") try: + change_perm = False + if history_logfile.exists() is False: + change_perm = True + try: - with open(f"{storage['LOG_PATH']}/cmd_history.txt", "a") as cmd_log: + with history_logfile.open("a") as cmd_log: cmd_log.write(f"{self.cmd}\n") + + if change_perm: + os.chmod(str(history_logfile), stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP) except PermissionError: pass diff --git a/archinstall/lib/installer.py b/archinstall/lib/installer.py index 0f298eba..a8346cb6 100644 --- a/archinstall/lib/installer.py +++ b/archinstall/lib/installer.py @@ -246,11 +246,12 @@ class Installer: # we manage the encrypted partititons for partition in [entry for entry in list_part if entry.get('encrypted', False)]: # open the luks device and all associate stuff - if not (password := partition.get('!password', None)): - raise RequirementError(f"Missing partition {partition['device_instance'].path} encryption password in layout: {partition}") - loopdev = f"{storage.get('ENC_IDENTIFIER', 'ai')}{pathlib.Path(partition['mountpoint']).name}loop" - else: - loopdev = f"{storage.get('ENC_IDENTIFIER', 'ai')}{pathlib.Path(partition['device_instance'].path).name}" + if not (password := partition.get('!password', None)) and storage['arguments'].get('!encryption-password'): + password = storage['arguments'].get('!encryption-password') + elif not password: + raise RequirementError(f"Missing partition encryption password in layout: {partition}") + + loopdev = f"{storage.get('ENC_IDENTIFIER', 'ai')}{pathlib.Path(partition['device_instance'].path).name}" # note that we DON'T auto_unmount (i.e. close the encrypted device so it can be used with (luks_handle := luks2(partition['device_instance'], loopdev, password, auto_unmount=False)) as unlocked_device: -- cgit v1.2.3-54-g00ecf From 6f412622292f64587848e0f03e65eab7eb4cd0e3 Mon Sep 17 00:00:00 2001 From: Anton Hvornum Date: Sun, 28 Aug 2022 22:30:19 +0200 Subject: Removed debugging --- archinstall/lib/installer.py | 1 - 1 file changed, 1 deletion(-) (limited to 'archinstall') diff --git a/archinstall/lib/installer.py b/archinstall/lib/installer.py index a8346cb6..c7682655 100644 --- a/archinstall/lib/installer.py +++ b/archinstall/lib/installer.py @@ -1017,7 +1017,6 @@ class Installer: boot_partition = None root_partition = None for partition in self.partitions: - print(partition, [partition.mountpoint], [self.target]) if self.target / 'boot' in partition.mountpoints: boot_partition = partition elif self.target in partition.mountpoints: -- cgit v1.2.3-54-g00ecf From f6e695871cdf55dd5277a955ff63a1ee1fd14348 Mon Sep 17 00:00:00 2001 From: Anton Hvornum Date: Tue, 30 Aug 2022 19:34:25 +0200 Subject: Homogenize language option during handling (#1446) * Adding a more elaborate fix * Added recovery function to selecting language too * Tweaked return value of display_language() to return the Language() object. --- archinstall/lib/menu/global_menu.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'archinstall') diff --git a/archinstall/lib/menu/global_menu.py b/archinstall/lib/menu/global_menu.py index f631c086..fc7c90bc 100644 --- a/archinstall/lib/menu/global_menu.py +++ b/archinstall/lib/menu/global_menu.py @@ -36,10 +36,21 @@ from ..user_interaction import add_number_of_parrallel_downloads from ..models.users import User from ..user_interaction.partitioning_conf import current_partition_layout from ..output import FormattedOutput +from ..translationhandler import Language if TYPE_CHECKING: _: Any +def display_language(global_menu, x): + if type(x) == Language: + return x + elif type(x) == str: + translation_handler = global_menu._translation_handler + for language in translation_handler._get_translations(): + if language.lang == x: + return language + else: + raise ValueError(f"Language entry needs to Language() object or string of full language like 'English'.") class GlobalMenu(GeneralMenu): def __init__(self,data_store): @@ -51,8 +62,8 @@ class GlobalMenu(GeneralMenu): self._menu_options['archinstall-language'] = \ Selector( _('Archinstall language'), - lambda x: self._select_archinstall_language(x), - display_func=lambda x: x.display_name, + lambda x: self._select_archinstall_language(display_language(self, x)), + display_func=lambda x: display_language(self, x).display_name, default=self.translation_handler.get_language('en')) self._menu_options['keyboard-layout'] = \ Selector( -- cgit v1.2.3-54-g00ecf From 0f5b91c7d733e94ffcad2fd8dd01774631b0c15a Mon Sep 17 00:00:00 2001 From: Anton Hvornum Date: Tue, 30 Aug 2022 22:59:23 +0200 Subject: Fixing issue where blkid causes SysCallException (#1445) * Moving a partprobe() call to better allow for cache updates * Trying to improve Partition()._fetch_information() * Removed a sleep() for debugging purposes * Tweaked a sleep --- archinstall/lib/disk/filesystem.py | 6 ++++-- archinstall/lib/disk/helpers.py | 5 +++++ archinstall/lib/disk/partition.py | 18 ++++++++++++++++-- archinstall/lib/exceptions.py | 8 ++++++-- archinstall/lib/general.py | 2 +- 5 files changed, 32 insertions(+), 7 deletions(-) (limited to 'archinstall') diff --git a/archinstall/lib/disk/filesystem.py b/archinstall/lib/disk/filesystem.py index 90656308..5d5952a0 100644 --- a/archinstall/lib/disk/filesystem.py +++ b/archinstall/lib/disk/filesystem.py @@ -253,7 +253,6 @@ class Filesystem: if self.parted(parted_string): for count in range(storage.get('DISK_RETRY_ATTEMPTS', 3)): - self.partprobe() self.blockdevice.flush_cache() new_partition_uuids = [partition.part_uuid for partition in self.blockdevice.partitions.values()] @@ -271,7 +270,10 @@ class Filesystem: raise err else: log(f"Could not get UUID for partition. Waiting {storage.get('DISK_TIMEOUTS', 1) * count}s before retrying.",level=logging.DEBUG) - time.sleep(storage.get('DISK_TIMEOUTS', 1) * count) + self.partprobe() + time.sleep(max(0.1, storage.get('DISK_TIMEOUTS', 1))) + else: + print("Parted did not return True during partition creation") total_partitions = set([partition.part_uuid for partition in self.blockdevice.partitions.values()]) total_partitions.update(previous_partuuids) diff --git a/archinstall/lib/disk/helpers.py b/archinstall/lib/disk/helpers.py index 60efe724..a148a5db 100644 --- a/archinstall/lib/disk/helpers.py +++ b/archinstall/lib/disk/helpers.py @@ -229,12 +229,17 @@ def all_blockdevices(mappers=False, partitions=False, error=False) -> Dict[str, try: information = get_loop_info(device_path) if not information: + print("Exit code for blkid -p -o export was:", ex.exit_code) raise SysCallError("Could not get loop information", exit_code=1) except SysCallError: + print("Not a loop device, trying uevent rules.") information = get_blockdevice_uevent(pathlib.Path(block_device).readlink().name) else: + # We could not reliably get any information, perhaps the disk is clean of information? + print("Raising ex because:", ex.exit_code) raise ex + # return instances information = enrich_blockdevice_information(information) diff --git a/archinstall/lib/disk/partition.py b/archinstall/lib/disk/partition.py index f70bf907..56a7d436 100644 --- a/archinstall/lib/disk/partition.py +++ b/archinstall/lib/disk/partition.py @@ -139,7 +139,19 @@ class Partition: def _call_lsblk(self) -> Dict[str, Any]: self.partprobe() - output = SysCommand(f"lsblk --json -b -o+LOG-SEC,SIZE,PTTYPE,PARTUUID,UUID,FSTYPE {self.device_path}").decode('UTF-8') + # This sleep might be overkill, but lsblk is known to + # work against a chaotic cache that can change during call + # causing no information to be returned (blkid is better) + # time.sleep(1) + + # TODO: Maybe incorporate a re-try system here based on time.sleep(max(0.1, storage.get('DISK_TIMEOUTS', 1))) + + try: + output = SysCommand(f"lsblk --json -b -o+LOG-SEC,SIZE,PTTYPE,PARTUUID,UUID,FSTYPE {self.device_path}").decode('UTF-8') + except SysCallError as error: + # It appears as if lsblk can return exit codes like 8192 to indicate something. + # But it does return output so we'll try to catch it. + output = error.worker.decode('UTF-8') if output: lsblk_info = json.loads(output) @@ -165,7 +177,9 @@ class Partition: def _fetch_information(self) -> PartitionInfo: lsblk_info = self._call_lsblk() sfdisk_info = self._call_sfdisk() - device = lsblk_info['blockdevices'][0] + + if not (device := lsblk_info.get('blockdevices', [None])[0]): + raise DiskError(f'Failed to retrieve information for "{self.device_path}" with lsblk') mountpoints = [Path(mountpoint) for mountpoint in device['mountpoints'] if mountpoint] bootable = sfdisk_info.get('bootable', False) or sfdisk_info.get('type', '') == 'C12A7328-F81F-11D2-BA4B-00A0C93EC93B' diff --git a/archinstall/lib/exceptions.py b/archinstall/lib/exceptions.py index a16faa3f..a66e4e04 100644 --- a/archinstall/lib/exceptions.py +++ b/archinstall/lib/exceptions.py @@ -1,4 +1,7 @@ -from typing import Optional +from typing import Optional, TYPE_CHECKING + +if TYPE_CHECKING: + from .general import SysCommandWorker class RequirementError(BaseException): pass @@ -17,10 +20,11 @@ class ProfileError(BaseException): class SysCallError(BaseException): - def __init__(self, message :str, exit_code :Optional[int] = None) -> None: + def __init__(self, message :str, exit_code :Optional[int] = None, worker :Optional['SysCommandWorker'] = None) -> None: super(SysCallError, self).__init__(message) self.message = message self.exit_code = exit_code + self.worker = worker class PermissionError(BaseException): diff --git a/archinstall/lib/general.py b/archinstall/lib/general.py index 61c4358e..d76b7036 100644 --- a/archinstall/lib/general.py +++ b/archinstall/lib/general.py @@ -272,7 +272,7 @@ class SysCommandWorker: log(args[1], level=logging.DEBUG, fg='red') if self.exit_code != 0: - raise SysCallError(f"{self.cmd} exited with abnormal exit code [{self.exit_code}]: {self._trace_log[-500:]}", self.exit_code) + raise SysCallError(f"{self.cmd} exited with abnormal exit code [{self.exit_code}]: {self._trace_log[-500:]}", self.exit_code, worker=self) def is_alive(self) -> bool: self.poll() -- cgit v1.2.3-54-g00ecf From ea407f5c9de2966ee741198e55fcfa8f29760295 Mon Sep 17 00:00:00 2001 From: Anton Hvornum Date: Tue, 30 Aug 2022 23:57:44 +0200 Subject: Version bump to v2.5.1rc1 in prep for release --- archinstall/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'archinstall') diff --git a/archinstall/__init__.py b/archinstall/__init__.py index 090ad7de..184097b1 100644 --- a/archinstall/__init__.py +++ b/archinstall/__init__.py @@ -51,7 +51,7 @@ from .lib.hsm import ( ) parser = ArgumentParser() -__version__ = "2.5.0" +__version__ = "2.5.1rc1" storage['__version__'] = __version__ # add the custome _ as a builtin, it can now be used anywhere in the -- cgit v1.2.3-54-g00ecf From bc97bbabb75e8b60395c5ddb948370e1c95ea4a7 Mon Sep 17 00:00:00 2001 From: Oskar Date: Fri, 2 Sep 2022 12:31:34 +0200 Subject: Update polish locale (#1385) --- archinstall/locales/pl/LC_MESSAGES/base.mo | Bin 22346 -> 23368 bytes archinstall/locales/pl/LC_MESSAGES/base.po | 52 +++++++++++++---------------- 2 files changed, 24 insertions(+), 28 deletions(-) (limited to 'archinstall') diff --git a/archinstall/locales/pl/LC_MESSAGES/base.mo b/archinstall/locales/pl/LC_MESSAGES/base.mo index d60d939a..05fbedaf 100644 Binary files a/archinstall/locales/pl/LC_MESSAGES/base.mo and b/archinstall/locales/pl/LC_MESSAGES/base.mo differ diff --git a/archinstall/locales/pl/LC_MESSAGES/base.po b/archinstall/locales/pl/LC_MESSAGES/base.po index f6730462..6a9d7ef4 100644 --- a/archinstall/locales/pl/LC_MESSAGES/base.po +++ b/archinstall/locales/pl/LC_MESSAGES/base.po @@ -1,21 +1,17 @@ msgid "" msgstr "" -"Project-Id-Version: \n" -"POT-Creation-Date: \n" -"PO-Revision-Date: \n" -"Last-Translator: Aleksandr Melman \n" +"Last-Translator: MedzikUser \n" "Language-Team: \n" "Language: pl\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Generator: Poedit 3.0.1\n" msgid "[!] A log file has been created here: {} {}" -msgstr "Plik dziennika został stworzony tutaj: {} {}" +msgstr "[!] Plik dziennika został stworzony tutaj: {} {}" msgid " Please submit this issue (and file) to https://github.com/archlinux/archinstall/issues" -msgstr " Proszę zgłosić ten błąd (i plik) pod adresem https://github.com/archlinux/archinstall/issues" +msgstr " Proszę zgłosić ten błąd (i dołączyć plik) pod adresem https://github.com/archlinux/archinstall/issues" msgid "Do you really want to abort?" msgstr "Czy napewno chcesz przerwać proces?" @@ -33,7 +29,7 @@ msgid "Username for required superuser with sudo privileges: " msgstr "Nazwa użytkownika dla wymaganego superużytkownika z uprawnieniami sudo: " msgid "Any additional users to install (leave blank for no users): " -msgstr "Ewentualni użytkownicy do instalacji (pozostaw puste jeśli nie chcesz tworzyć użytkowników): " +msgstr "Ewentualni użytkownicy do instalacji (pozostaw puste jeśli nie chcesz tworzyć użytkowników): " msgid "Should this user be a superuser (sudoer)?" msgstr "Czy użytkownik powinien superużytkownikiem (sudoer)?" @@ -42,7 +38,7 @@ msgid "Select a timezone" msgstr "Wybierz strefę czasową" msgid "Would you like to use GRUB as a bootloader instead of systemd-boot?" -msgstr "Czy chcesz użyć GRUB-a jako programu rozruchowego zamiast systemd-boot?" +msgstr "Czy chcesz użyć GRUB-a jako programu rozruchowego zamiast systemd-boot?" msgid "Choose a bootloader" msgstr "Wybierz program rozruchowy" @@ -217,10 +213,10 @@ msgid "Choose which kernels to use or leave blank for default \"{}\"" msgstr "Wybierz które jądra mają być używane, lub pozostaw puste dla ustawień domyślnych \"{}\"" msgid "Choose which locale language to use" -msgstr "Wybierz które locale języka mają zostać użyte" +msgstr "Wybierz które locale języka mają zostać użyte" msgid "Choose which locale encoding to use" -msgstr "Wybierz które locale kodowania mają zostać użyte" +msgstr "Wybierz które locale kodowania mają zostać użyte" msgid "Select one of the values shown below: " msgstr "Wybierz jedną z wartości przedstawionych poniżej: " @@ -492,7 +488,7 @@ msgid "" "{}\n" "\n" "Select which partition to set subvolumes on" -msgstr "Wybierz partycję, na której mają być ustawione subwoluminów" +msgstr "Wybierz partycję, na której mają być ustawione subwoluminy" msgid "Manage btrfs subvolumes for current partition" msgstr "Zarządzaj subwoluminami btrfs dla bieżącej partycji" @@ -701,7 +697,7 @@ msgstr "" "zawiera partycje oczekujące w kolejce, to spowoduje ich usunięcie, czy jesteś pewien?" msgid "No audio server" -msgstr "" +msgstr "Brak serwera dźwięku" msgid "(default)" msgstr "(domyslne)" @@ -725,7 +721,7 @@ msgid "Edit: " msgstr "Edytuj: " msgid "Key: " -msgstr "" +msgstr "Klucz: " msgid "Edit {}: " msgstr "Edytuj {}: " @@ -738,28 +734,28 @@ msgid "Value: " msgstr "Wartość: " msgid "You can skip selecting a drive and partitioning and use whatever drive-setup is mounted at /mnt (experimental)" -msgstr "" +msgstr "Możesz pominąć wybów dysków i partycji i użyć dowolnego zestawu dysku zamontowanego w /mnt (eksperymentalne)" msgid "Select one of the disks or skip and use /mnt as default" -msgstr "" +msgstr "Wybierz jeden z dysków lub pomiń i użyj /mnt jako domyślnego" msgid "Select which partitions to mark for formatting:" msgstr "Wybierz partycja która ma zostać sformatowana:" msgid "Use HSM to unlock encrypted drive" -msgstr "" +msgstr "Użyj HSM do odblokowania zaszyfrowanego dysku" msgid "Device" -msgstr "" +msgstr "Urządzenie" msgid "Size" -msgstr "" +msgstr "Rozmiar" msgid "Free space" -msgstr "" +msgstr "Wolne miejsce" msgid "Bus-type" -msgstr "" +msgstr "Typ magistrali" #, fuzzy msgid "Either root-password or at least 1 user with sudo privileges must be specified" @@ -770,7 +766,7 @@ msgid "Enter username (leave blank to skip): " msgstr "Wprowadź nazwę użytkownika, aby utworzyć dodatkowego użytkownika (pozostaw puste, aby pominąć): " msgid "The username you entered is invalid. Try again" -msgstr "" +msgstr "Wprowadzona nazwa użytkownika jest nieprawidłowa. Spróbuj ponownie" #, fuzzy msgid "Should \"{}\" be a superuser (sudo)?" @@ -784,23 +780,23 @@ msgstr "" "Wybierz partycja która ma zostać zaszyfrowana" msgid "very weak" -msgstr "" +msgstr "bardzo słabe" msgid "weak" -msgstr "" +msgstr "słabe" msgid "moderate" -msgstr "" +msgstr "umiarkowane" msgid "strong" -msgstr "" +msgstr "mocne" #, fuzzy msgid "Add subvolume" -msgstr " Subwolumin :{:16}" +msgstr "Subwolumin :{:16}" msgid "Edit subvolume" -msgstr "" +msgstr "Edytuj wolumen" #, fuzzy msgid "Delete subvolume" -- cgit v1.2.3-54-g00ecf From e12a0e6b7a1203327099e082a422d7119795bfde Mon Sep 17 00:00:00 2001 From: Rafael Fontenelle Date: Fri, 2 Sep 2022 07:32:17 -0300 Subject: Update pt br (#1396) * Update locales * Update pt_BR --- archinstall/locales/base.pot | 3 + archinstall/locales/cs/LC_MESSAGES/base.po | 3 + archinstall/locales/de/LC_MESSAGES/base.po | 3 + archinstall/locales/en/LC_MESSAGES/base.po | 3 + archinstall/locales/es/LC_MESSAGES/base.po | 3 + archinstall/locales/fr/LC_MESSAGES/base.po | 3 + archinstall/locales/it/LC_MESSAGES/base.po | 3 + archinstall/locales/nl/LC_MESSAGES/base.po | 3 + archinstall/locales/pl/LC_MESSAGES/base.po | 3 + archinstall/locales/pt/LC_MESSAGES/base.po | 3 + archinstall/locales/pt_BR/LC_MESSAGES/base.mo | Bin 23362 -> 24896 bytes archinstall/locales/pt_BR/LC_MESSAGES/base.po | 89 ++++---- archinstall/locales/ru/LC_MESSAGES/base.po | 300 ++++++++------------------ archinstall/locales/sv/LC_MESSAGES/base.po | 3 + archinstall/locales/tr/LC_MESSAGES/base.po | 3 + archinstall/locales/ur/LC_MESSAGES/base.po | 3 + 16 files changed, 166 insertions(+), 262 deletions(-) (limited to 'archinstall') diff --git a/archinstall/locales/base.pot b/archinstall/locales/base.pot index baaf622c..7a259336 100644 --- a/archinstall/locales/base.pot +++ b/archinstall/locales/base.pot @@ -784,3 +784,6 @@ msgstr "" msgid "Delete subvolume" msgstr "" + +msgid "Configured {} interfaces" +msgstr "" diff --git a/archinstall/locales/cs/LC_MESSAGES/base.po b/archinstall/locales/cs/LC_MESSAGES/base.po index 143e815c..7a2a197f 100644 --- a/archinstall/locales/cs/LC_MESSAGES/base.po +++ b/archinstall/locales/cs/LC_MESSAGES/base.po @@ -789,3 +789,6 @@ msgstr "" #, fuzzy msgid "Delete subvolume" msgstr "Smazat uživatele" + +msgid "Configured {} interfaces" +msgstr "" diff --git a/archinstall/locales/de/LC_MESSAGES/base.po b/archinstall/locales/de/LC_MESSAGES/base.po index ee40cea5..a601326e 100644 --- a/archinstall/locales/de/LC_MESSAGES/base.po +++ b/archinstall/locales/de/LC_MESSAGES/base.po @@ -805,6 +805,9 @@ msgstr "" msgid "Delete subvolume" msgstr "Benutzerkonto löschen" +msgid "Configured {} interfaces" +msgstr "" + #~ msgid "Select disk layout" #~ msgstr "Laufwerke-layout auswählen" diff --git a/archinstall/locales/en/LC_MESSAGES/base.po b/archinstall/locales/en/LC_MESSAGES/base.po index 63e9f804..1825d501 100644 --- a/archinstall/locales/en/LC_MESSAGES/base.po +++ b/archinstall/locales/en/LC_MESSAGES/base.po @@ -740,3 +740,6 @@ msgstr "" msgid "Delete subvolume" msgstr "" + +msgid "Configured {} interfaces" +msgstr "" diff --git a/archinstall/locales/es/LC_MESSAGES/base.po b/archinstall/locales/es/LC_MESSAGES/base.po index 6f18c5f8..47a64b0a 100644 --- a/archinstall/locales/es/LC_MESSAGES/base.po +++ b/archinstall/locales/es/LC_MESSAGES/base.po @@ -788,6 +788,9 @@ msgstr "" msgid "Delete subvolume" msgstr "Eliminar usuario" +msgid "Configured {} interfaces" +msgstr "" + #~ msgid "Select disk layout" #~ msgstr "Seleccione el diseño del disco" diff --git a/archinstall/locales/fr/LC_MESSAGES/base.po b/archinstall/locales/fr/LC_MESSAGES/base.po index 359dbdd7..877b793f 100644 --- a/archinstall/locales/fr/LC_MESSAGES/base.po +++ b/archinstall/locales/fr/LC_MESSAGES/base.po @@ -794,6 +794,9 @@ msgstr "" msgid "Delete subvolume" msgstr "Supprimer l'utilisateur" +msgid "Configured {} interfaces" +msgstr "" + #~ msgid "Select disk layout" #~ msgstr "Sélectionner la disposition du disque" diff --git a/archinstall/locales/it/LC_MESSAGES/base.po b/archinstall/locales/it/LC_MESSAGES/base.po index 529fb47b..baf55a28 100644 --- a/archinstall/locales/it/LC_MESSAGES/base.po +++ b/archinstall/locales/it/LC_MESSAGES/base.po @@ -796,3 +796,6 @@ msgstr "" #, fuzzy msgid "Delete subvolume" msgstr "Elimina utente" + +msgid "Configured {} interfaces" +msgstr "" diff --git a/archinstall/locales/nl/LC_MESSAGES/base.po b/archinstall/locales/nl/LC_MESSAGES/base.po index 72547f7a..8553595e 100644 --- a/archinstall/locales/nl/LC_MESSAGES/base.po +++ b/archinstall/locales/nl/LC_MESSAGES/base.po @@ -820,6 +820,9 @@ msgstr "" msgid "Delete subvolume" msgstr "Gebruiker verwijderen" +msgid "Configured {} interfaces" +msgstr "" + #~ msgid "Select disk layout" #~ msgstr "Kies een schijfindeling" diff --git a/archinstall/locales/pl/LC_MESSAGES/base.po b/archinstall/locales/pl/LC_MESSAGES/base.po index 6a9d7ef4..1bd4b47e 100644 --- a/archinstall/locales/pl/LC_MESSAGES/base.po +++ b/archinstall/locales/pl/LC_MESSAGES/base.po @@ -802,6 +802,9 @@ msgstr "Edytuj wolumen" msgid "Delete subvolume" msgstr "Usuń użytkownika" +msgid "Configured {} interfaces" +msgstr "" + #~ msgid "Select disk layout" #~ msgstr "Wybierz układ dysku" diff --git a/archinstall/locales/pt/LC_MESSAGES/base.po b/archinstall/locales/pt/LC_MESSAGES/base.po index e44a0133..2e9b461c 100644 --- a/archinstall/locales/pt/LC_MESSAGES/base.po +++ b/archinstall/locales/pt/LC_MESSAGES/base.po @@ -840,6 +840,9 @@ msgstr "" msgid "Delete subvolume" msgstr "Eliminar Utilizador" +msgid "Configured {} interfaces" +msgstr "" + #~ msgid "Select disk layout" #~ msgstr "Seleciona o esquema de disco" diff --git a/archinstall/locales/pt_BR/LC_MESSAGES/base.mo b/archinstall/locales/pt_BR/LC_MESSAGES/base.mo index bfc9645c..c66bae7f 100644 Binary files a/archinstall/locales/pt_BR/LC_MESSAGES/base.mo and b/archinstall/locales/pt_BR/LC_MESSAGES/base.mo differ diff --git a/archinstall/locales/pt_BR/LC_MESSAGES/base.po b/archinstall/locales/pt_BR/LC_MESSAGES/base.po index 004ad022..69f8c902 100644 --- a/archinstall/locales/pt_BR/LC_MESSAGES/base.po +++ b/archinstall/locales/pt_BR/LC_MESSAGES/base.po @@ -1,6 +1,10 @@ +# Translators: +# @Cain-dev (cain-dev.github.io) +# Rafael Fontenelle + msgid "" msgstr "" -"Last-Translator: @Cain-dev (cain-dev.github.io)\n" +"Last-Translator: Rafael Fontenelle \n" "Language: pt_BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -67,7 +71,7 @@ msgid "Select which mode to configure for \"{}\" or skip to use default mode \"{ msgstr "Selecione qual modo configurar para \"{}\" ou ignore para usar o modo padrão \"{}\"" msgid "Enter the IP and subnet for {} (example: 192.168.0.5/24): " -msgstr "Digite o IP e a subrede para {} (exemplo: 192.168.0.5/24): " +msgstr "Digite o IP e a sub-rede para {} (exemplo: 192.168.0.5/24): " msgid "Enter your gateway (router) IP address or leave blank for none: " msgstr "Digite o seu IP de gateway (router) ou deixe em branco para nenhum: " @@ -85,7 +89,7 @@ msgid "" "Select what to do with\n" "{}" msgstr "" -"Selecione o que fazer com \n" +"Selecione o que fazer com\n" "{}" msgid "Enter a desired filesystem type for the partition" @@ -95,7 +99,7 @@ msgid "Enter the start sector (percentage or block number, default: {}): " msgstr "Digite o setor de início (porcentagem ou número do bloco, padrão: {}): " msgid "Enter the end sector of the partition (percentage or block number, ex: {}): " -msgstr "Digite o setor final da partição (porcentagem ou número de bloco, ex: {}): " +msgstr "Digite o setor final da partição (porcentagem ou número de bloco, ex.: {}): " msgid "{} contains queued partitions, this will remove those, are you sure?" msgstr "{} contém partições em fila, isto irá removê-las, tem certeza?" @@ -149,7 +153,7 @@ msgid "" msgstr "" "{}\n" "\n" -"Selecione qual partição marcar como bootável" +"Selecione qual partição marcar como inicializável" msgid "" "{}\n" @@ -298,7 +302,7 @@ msgid "" "WARNING: Archinstall won't check the suitability of this setup\n" "Do you wish to continue?" msgstr "" -"Você decidiu ignorar a seleção de disco rídigo\n" +"Você decidiu ignorar a seleção de disco rígido\n" "e usar qualquer configuração de disco rígido montada em {} (experimental)\n" "ATENÇÃO: O Archinstall não verifica a viabilidade desta configuração\n" "Deseja continuar?" @@ -325,7 +329,7 @@ msgid "Mark/Unmark a partition as encrypted" msgstr "Marcar/Desmarcar uma partição como encriptada" msgid "Mark/Unmark a partition as bootable (automatic for /boot)" -msgstr "Marcar/Desmarcar uma partição como bootável (automática para /boot)" +msgstr "Marcar/Desmarcar uma partição como inicializável (automática para /boot)" msgid "Set desired filesystem for a partition" msgstr "Definir o sistema de arquivos desejado para uma partição" @@ -387,7 +391,7 @@ msgid "" "For more information, please check the Arch wiki" msgstr "" "A hora de hardware e outros passos de pós-configuração podem ser necessários para que o NTP funcione.\n" -"Para mais informações, por favor visite a Arch wiki" +"Para mais informações, por favor visite a wiki do Arch" msgid "Enter a username to create an additional user (leave blank to skip): " msgstr "Digite um nome de usuário para criar um usuário adicional (deixe em branco para pular): " @@ -437,10 +441,10 @@ msgstr "" "Esta é a configuração escolhida escolhida por você:" msgid "Pacman is already running, waiting maximum 10 minutes for it to terminate." -msgstr "O Pacman já está a rodando, aguarde no máximo até 10 minutos para terminar." +msgstr "O Pacman já está em execução, aguarde no máximo até 10 minutos para terminar." msgid "Pre-existing pacman lock never exited. Please clean up any existing pacman sessions before using archinstall." -msgstr "Pacman lock não terminou. Por favor, limpe as sessões de pacman existentes antes de usar o archinstall." +msgstr "A trava pré-existente do Pacman não terminou. Por favor, limpe as sessões de pacman existentes antes de usar o archinstall." msgid "Choose which optional additional repositories to enable" msgstr "Escolha quais repositórios adicionais opcionais ativar" @@ -452,7 +456,7 @@ msgid "Change password" msgstr "Mudar senha" msgid "Promote/Demote user" -msgstr "Promover/Demover usuário" +msgstr "Promover/Rebaixar usuário" msgid "Delete User" msgstr "Deletar usuário" @@ -465,7 +469,7 @@ msgstr "" "Definir um novo usuário\n" msgid "User Name : " -msgstr "Nome de Usuário : " +msgstr "Nome de usuário : " msgid "Should {} be a superuser (sudoer)?" msgstr "{} deve ser um superusuário (sudoer)?" @@ -513,7 +517,7 @@ msgid "Enter a directory for the configuration(s) to be saved: " msgstr "Digite um diretório para as configurações serem salvas: " msgid "Not a valid directory: {}" -msgstr "Não é um diretorio válido: {}" +msgstr "Não é um diretório válido: {}" msgid "The password you are using seems to be weak," msgstr "A senha que está usando parece ser fraca," @@ -616,7 +620,7 @@ msgid "Manual configuration setting must be a list" msgstr "O ajuste de configuração manual deve ser em lista" msgid "No iface specified for manual configuration" -msgstr "iface não especificado para configuração manual" +msgstr "iface não especificada para configuração manual" msgid "Manual nic configuration with no auto DHCP requires an IP address" msgstr "A configuração manual de NIC sem DHCP automático requer um endereço IP" @@ -654,7 +658,6 @@ msgstr "Uma instalação bem básica que permite a você customizar o Arch Linux msgid "Provides a selection of various server packages to install and enable, e.g. httpd, nginx, mariadb" msgstr "Proporciona uma seleção de diversos pacotes de servidor para instalar e habilitar como por exemplo httpd, nginx, mariadb" -#, fuzzy msgid "Choose which servers to install, if none then a minimal installation will be done" msgstr "Selecione quais servidores instalar, se há nenhum uma instalação mínima será feita" @@ -668,16 +671,16 @@ msgid "Would you like to chroot into the newly created installation and perform msgstr "Deseja fazer chroot para a nova instalação e realizar configurações pós-instalação?" msgid "Are you sure you want to reset this setting?" -msgstr "Tem certeza que desejar resetar essa configuração?" +msgstr "Tem certeza que desejar redefinir essa configuração?" msgid "Select one or more hard drives to use and configure\n" msgstr "Selecione uma ou mais unidades para usar e configurar\n" msgid "Any modifications to the existing setting will reset the disk layout!" -msgstr "Quaisquer modificações para configurações existentes vão resetar o layout de disco!" +msgstr "Quaisquer modificações para configurações existentes vão redefinir o layout de disco!" msgid "If you reset the harddrive selection this will also reset the current disk layout. Are you sure?" -msgstr "Se você resetar a seleção de unidades isso também resetará o layout da unidade atual. Tem certeza?" +msgstr "Se você redefinir a seleção de unidades isso também redefinirá o layout da unidade atual. Tem certeza?" msgid "Save and exit" msgstr "Salvar e sair" @@ -687,7 +690,7 @@ msgid "" "contains queued partitions, this will remove those, are you sure?" msgstr "" "{}\n" -"contém partições enfileiradas partitions, isso irá removê-las, tem certeza?" +"contém partições enfileiradas, isso irá removê-las, tem certeza?" msgid "No audio server" msgstr "Sem servidor de áudio" @@ -702,7 +705,7 @@ msgid "" "Use CTRL+C to reset current selection\n" "\n" msgstr "" -"Use CTRL+C para resetar a seleção atual\n" +"Use CTRL+C para redefinir a seleção atual\n" "\n" msgid "Copy to: " @@ -733,61 +736,55 @@ msgid "Select which partitions to mark for formatting:" msgstr "Selecione quais partições marcar para formatar:" msgid "Use HSM to unlock encrypted drive" -msgstr "" +msgstr "Usar HSM para desbloquear unidade encriptada" msgid "Device" -msgstr "" +msgstr "Dispositivo" msgid "Size" -msgstr "" +msgstr "Tamanho" msgid "Free space" -msgstr "" +msgstr "Espaço livre" msgid "Bus-type" -msgstr "" +msgstr "Tipo de barramento" -#, fuzzy msgid "Either root-password or at least 1 user with sudo privileges must be specified" -msgstr "Deve se especificar uma senha de root ou pelo menos 1 superusuário" +msgstr "Deve-se especificar uma senha de root ou pelo menos 1 usuário com privilégios de sudo" -#, fuzzy msgid "Enter username (leave blank to skip): " -msgstr "Digite um nome de usuário para criar um usuário adicional (deixe em branco para pular): " +msgstr "Digite um nome de usuário (deixe em branco para pular): " msgid "The username you entered is invalid. Try again" -msgstr "" +msgstr "O nome de usuário que você digitou é inválido. Tente novamente" -#, fuzzy msgid "Should \"{}\" be a superuser (sudo)?" -msgstr "{} deve ser um superusuário (sudoer)?" +msgstr "\"{}\" deve ser um superusuário (sudo)?" -#, fuzzy msgid "Select which partitions to encrypt:" -msgstr "" -"{}\n" -"\n" -"Selecione qual partição marcar como encriptada" +msgstr "Selecione quais partições encriptar:" msgid "very weak" -msgstr "" +msgstr "muito fraca" msgid "weak" -msgstr "" +msgstr "fraca" msgid "moderate" -msgstr "" +msgstr "moderada" msgid "strong" -msgstr "" +msgstr "forte" -#, fuzzy msgid "Add subvolume" -msgstr " Subvolume :{:16}" +msgstr "Adicionar subvolume" msgid "Edit subvolume" -msgstr "" +msgstr "Editar subvolume" -#, fuzzy msgid "Delete subvolume" -msgstr "Deletar usuário" +msgstr "Deletar subvolume" + +msgid "Configured {} interfaces" +msgstr "{} interfaces configuradas" diff --git a/archinstall/locales/ru/LC_MESSAGES/base.po b/archinstall/locales/ru/LC_MESSAGES/base.po index 2a88a85f..ad568e06 100644 --- a/archinstall/locales/ru/LC_MESSAGES/base.po +++ b/archinstall/locales/ru/LC_MESSAGES/base.po @@ -9,19 +9,14 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && " -"n%10<=4 && (n%100<12 || n%100>14) ? 1 : 2);\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : 2);\n" "X-Generator: Poedit 3.0.1\n" msgid "[!] A log file has been created here: {} {}" msgstr "[!] Здесь был создан файл журнала: {} {}" -msgid "" -" Please submit this issue (and file) to https://github.com/archlinux/" -"archinstall/issues" -msgstr "" -" Пожалуйста, отправьте эту проблему (и файл) по адресу https://github.com/" -"archlinux/archinstall/issues" +msgid " Please submit this issue (and file) to https://github.com/archlinux/archinstall/issues" +msgstr " Пожалуйста, отправьте эту проблему (и файл) по адресу https://github.com/archlinux/archinstall/issues" msgid "Do you really want to abort?" msgstr "Вы действительно хотите прекратить?" @@ -36,13 +31,10 @@ msgid "Desired hostname for the installation: " msgstr "Желаемое имя хоста для установки: " msgid "Username for required superuser with sudo privileges: " -msgstr "" -"Имя пользователя для требуемого суперпользователя с привилегиями sudo: " +msgstr "Имя пользователя для требуемого суперпользователя с привилегиями sudo: " msgid "Any additional users to install (leave blank for no users): " -msgstr "" -"Любые дополнительные пользователи для установки (оставьте пустым, если " -"пользователей нет): " +msgstr "Любые дополнительные пользователи для установки (оставьте пустым, если пользователей нет): " msgid "Should this user be a superuser (sudoer)?" msgstr "Должен ли этот пользователь быть суперпользователем (sudoer)?" @@ -59,59 +51,38 @@ msgstr "Выберите загрузчик" msgid "Choose an audio server" msgstr "Выберите звуковой сервер" -msgid "" -"Only packages such as base, base-devel, linux, linux-firmware, efibootmgr " -"and optional profile packages are installed." -msgstr "" -"Устанавливаются только такие пакеты, как base, base-devel, linux, linux-" -"firmware, efibootmgr и дополнительные пакеты профиля." +msgid "Only packages such as base, base-devel, linux, linux-firmware, efibootmgr and optional profile packages are installed." +msgstr "Устанавливаются только такие пакеты, как base, base-devel, linux, linux-firmware, efibootmgr и дополнительные пакеты профиля." -msgid "" -"If you desire a web browser, such as firefox or chromium, you may specify it " -"in the following prompt." -msgstr "" -"Если вы хотите использовать веб-браузер, например, firefox или chromium, вы " -"можете указать его в следующем запросе." +msgid "If you desire a web browser, such as firefox or chromium, you may specify it in the following prompt." +msgstr "Если вы хотите использовать веб-браузер, например, firefox или chromium, вы можете указать его в следующем запросе." -msgid "" -"Write additional packages to install (space separated, leave blank to skip): " -msgstr "" -"Напишите дополнительные пакеты для установки (разделите пробелами, оставьте " -"пустым, чтобы пропустить): " +msgid "Write additional packages to install (space separated, leave blank to skip): " +msgstr "Напишите дополнительные пакеты для установки (разделите пробелами, оставьте пустым, чтобы пропустить): " msgid "Copy ISO network configuration to installation" msgstr "Копировать сетевую конфигурацию ISO в установку" -msgid "" -"Use NetworkManager (necessary to configure internet graphically in GNOME and " -"KDE)" -msgstr "" -"Использовать NetworkManager (необходим для графической настройки интернета в " -"GNOME и KDE)" +msgid "Use NetworkManager (necessary to configure internet graphically in GNOME and KDE)" +msgstr "Использовать NetworkManager (необходим для графической настройки интернета в GNOME и KDE)" msgid "Select one network interface to configure" msgstr "Выберите один сетевой интерфейс для настройки" -msgid "" -"Select which mode to configure for \"{}\" or skip to use default mode \"{}\"" -msgstr "" -"Выберите режим для конфигурации \"{}\" или пропустите, чтобы использовать " -"режим по умолчанию \"{}\"." +msgid "Select which mode to configure for \"{}\" or skip to use default mode \"{}\"" +msgstr "Выберите режим для конфигурации \"{}\" или пропустите, чтобы использовать режим по умолчанию \"{}\"." msgid "Enter the IP and subnet for {} (example: 192.168.0.5/24): " msgstr "Введите IP-адрес и подсеть для {} (пример: 192.168.0.5/24): " msgid "Enter your gateway (router) IP address or leave blank for none: " -msgstr "" -"Введите IP-адрес вашего шлюза (маршрутизатора) или оставьте пустым, если его " -"нет: " +msgstr "Введите IP-адрес вашего шлюза (маршрутизатора) или оставьте пустым, если его нет: " msgid "Enter your DNS servers (space separated, blank for none): " msgstr "Введите ваши DNS-серверы (через пробел, пустой - нет): " msgid "Select which filesystem your main partition should use" -msgstr "" -"Выберите, какую файловую систему должен использовать ваш основной раздел" +msgstr "Выберите, какую файловую систему должен использовать ваш основной раздел" msgid "Current partition layout" msgstr "Текущая разметка разделов" @@ -129,10 +100,8 @@ msgstr "Введите желаемый тип файловой системы msgid "Enter the start sector (percentage or block number, default: {}): " msgstr "Введите начальный сектор (процент или номер блока, по умолчанию: {}): " -msgid "" -"Enter the end sector of the partition (percentage or block number, ex: {}): " -msgstr "" -"Введите конечный сектор раздела (процент или номер блока, например: {}): " +msgid "Enter the end sector of the partition (percentage or block number, ex: {}): " +msgstr "Введите конечный сектор раздела (процент или номер блока, например: {}): " msgid "{} contains queued partitions, this will remove those, are you sure?" msgstr "{} содержит разделы в очереди, это удалит их, вы уверены?" @@ -155,17 +124,11 @@ msgstr "" "\n" "Выберите по индексу, какой раздел куда монтировать" -msgid "" -" * Partition mount-points are relative to inside the installation, the boot " -"would be /boot as an example." -msgstr "" -" * Точки монтирования разделов являются относительными внутри установки, " -"например, загрузочный будет /boot." +msgid " * Partition mount-points are relative to inside the installation, the boot would be /boot as an example." +msgstr " * Точки монтирования разделов являются относительными внутри установки, например, загрузочный будет /boot." msgid "Select where to mount partition (leave blank to remove mountpoint): " -msgstr "" -"Выберите куда монтировать раздел (оставьте пустым, чтобы удалить точку " -"монтирования): " +msgstr "Выберите куда монтировать раздел (оставьте пустым, чтобы удалить точку монтирования): " msgid "" "{}\n" @@ -210,25 +173,16 @@ msgid "Archinstall language" msgstr "Язык Archinstall" msgid "Wipe all selected drives and use a best-effort default partition layout" -msgstr "" -"Стереть все выбранные диски и использовать оптимальную схему разделов по " -"умолчанию" +msgstr "Стереть все выбранные диски и использовать оптимальную схему разделов по умолчанию" -msgid "" -"Select what to do with each individual drive (followed by partition usage)" -msgstr "" -"Выберите, что делать с каждым отдельным диском (с последующим использованием " -"разделов)" +msgid "Select what to do with each individual drive (followed by partition usage)" +msgstr "Выберите, что делать с каждым отдельным диском (с последующим использованием разделов)" msgid "Select what you wish to do with the selected block devices" msgstr "Выберите, что вы хотите сделать с выбранными блочными устройствами" -msgid "" -"This is a list of pre-programmed profiles, they might make it easier to " -"install things like desktop environments" -msgstr "" -"Это список предварительно запрограммированных профилей, они могут облегчить " -"установку таких вещей, как окружения рабочего стола" +msgid "This is a list of pre-programmed profiles, they might make it easier to install things like desktop environments" +msgstr "Это список предварительно запрограммированных профилей, они могут облегчить установку таких вещей, как окружения рабочего стола" msgid "Select keyboard layout" msgstr "Выберите раскладку клавиатуры" @@ -237,29 +191,16 @@ msgid "Select one of the regions to download packages from" msgstr "Выберите один из регионов для загрузки пакетов" msgid "Select one or more hard drives to use and configure" -msgstr "" -"Выберите один или несколько жестких дисков для использования и настройте их" +msgstr "Выберите один или несколько жестких дисков для использования и настройте их" -msgid "" -"For the best compatibility with your AMD hardware, you may want to use " -"either the all open-source or AMD / ATI options." -msgstr "" -"Для наилучшей совместимости с оборудованием AMD вы можете использовать либо " -"все варианты с открытым исходным кодом, либо AMD / ATI." +msgid "For the best compatibility with your AMD hardware, you may want to use either the all open-source or AMD / ATI options." +msgstr "Для наилучшей совместимости с оборудованием AMD вы можете использовать либо все варианты с открытым исходным кодом, либо 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 "" -"Для лучшей совместимости с оборудованием Intel вы можете использовать либо " -"все варианты с открытым исходным кодом, либо Intel.\n" +msgid "For the best compatibility with your Intel hardware, you may want to use either the all open-source or Intel options.\n" +msgstr "Для лучшей совместимости с оборудованием Intel вы можете использовать либо все варианты с открытым исходным кодом, либо Intel.\n" -msgid "" -"For the best compatibility with your Nvidia hardware, you may want to use " -"the Nvidia proprietary driver.\n" -msgstr "" -"Для наилучшей совместимости с оборудованием Nvidia вы можете использовать " -"проприетарный драйвер Nvidia.\n" +msgid "For the best compatibility with your Nvidia hardware, you may want to use the Nvidia proprietary driver.\n" +msgstr "Для наилучшей совместимости с оборудованием Nvidia вы можете использовать проприетарный драйвер Nvidia.\n" msgid "" "\n" @@ -268,15 +209,13 @@ msgid "" msgstr "" "\n" "\n" -"Выберите графический драйвер или оставьте пустым, чтобы установить все " -"драйверы с открытым исходным кодом" +"Выберите графический драйвер или оставьте пустым, чтобы установить все драйверы с открытым исходным кодом" msgid "All open-source (default)" msgstr "Все с открытым исходным кодом (по умолчанию)" msgid "Choose which kernels to use or leave blank for default \"{}\"" -msgstr "" -"Выберите, какие ядра использовать, или оставьте пустым по умолчанию \"{}\"." +msgstr "Выберите, какие ядра использовать, или оставьте пустым по умолчанию \"{}\"." msgid "Choose which locale language to use" msgstr "Выберите, какой язык локали использовать" @@ -293,12 +232,8 @@ msgstr "Выберите один или несколько из приведе msgid "Adding partition...." msgstr "Добавление раздела...." -msgid "" -"You need to enter a valid fs-type in order to continue. See `man parted` for " -"valid fs-type's." -msgstr "" -"Чтобы продолжить, вам нужно ввести действительный fs-тип. Смотрите `man " -"parted` для правильных fs-типов." +msgid "You need to enter a valid fs-type in order to continue. See `man parted` for valid fs-type's." +msgstr "Чтобы продолжить, вам нужно ввести действительный fs-тип. Смотрите `man parted` для правильных fs-типов." msgid "Error: Listing profiles on URL \"{}\" resulted in:" msgstr "Ошибка: Перечисление профилей по URL \"{}\" привело к:" @@ -370,8 +305,7 @@ msgid "" "Do you wish to continue?" msgstr "" "Вы решили пропустить выбор жесткого диска\n" -"и будете использовать любой диск, смонтированный по адресу {} " -"(экспериментально)\n" +"и будете использовать любой диск, смонтированный по адресу {} (экспериментально)\n" "ПРЕДУПРЕЖДЕНИЕ: Archinstall не будет проверять пригодность этой установки.\n" "Вы хотите продолжить?" @@ -391,16 +325,13 @@ msgid "Assign mount-point for a partition" msgstr "Назначить точку монтирования для раздела" msgid "Mark/Unmark a partition to be formatted (wipes data)" -msgstr "" -"Пометить/снять отметку с раздела, который будет отформатирован (стирание " -"данных)" +msgstr "Пометить/снять отметку с раздела, который будет отформатирован (стирание данных)" msgid "Mark/Unmark a partition as encrypted" msgstr "Пометить/снять отметку с раздела как зашифрованный" msgid "Mark/Unmark a partition as bootable (automatic for /boot)" -msgstr "" -"Пометить/снять отметку с раздела как загрузочный (автоматически для /boot)" +msgstr "Пометить/снять отметку с раздела как загрузочный (автоматически для /boot)" msgid "Set desired filesystem for a partition" msgstr "Установите желаемую файловую систему для раздела" @@ -440,8 +371,7 @@ msgid "Enter a encryption password for {}" msgstr "Введите пароль шифрования для {}" msgid "Enter disk encryption password (leave blank for no encryption): " -msgstr "" -"Введите пароль шифрования диска (оставьте пустым для отсутствия шифрования): " +msgstr "Введите пароль шифрования диска (оставьте пустым для отсутствия шифрования): " msgid "Create a required super-user with sudo privileges: " msgstr "Создайте необходимого суперпользователя с привилегиями sudo: " @@ -452,43 +382,31 @@ msgstr "Введите пароль root (оставьте пустым, что msgid "Password for user \"{}\": " msgstr "Пароль для пользователя \"{}\": " -msgid "" -"Verifying that additional packages exist (this might take a few seconds)" -msgstr "" -"Проверка наличия дополнительных пакетов (это может занять несколько секунд)" +msgid "Verifying that additional packages exist (this might take a few seconds)" +msgstr "Проверка наличия дополнительных пакетов (это может занять несколько секунд)" -msgid "" -"Would you like to use automatic time synchronization (NTP) with the default " -"time servers?\n" -msgstr "" -"Вы хотите использовать автоматическую синхронизацию времени (NTP) с " -"серверами времени по умолчанию?\n" +msgid "Would you like to use automatic time synchronization (NTP) with the default time servers?\n" +msgstr "Вы хотите использовать автоматическую синхронизацию времени (NTP) с серверами времени по умолчанию?\n" msgid "" -"Hardware time and other post-configuration steps might be required in order " -"for NTP to work.\n" +"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 "" -"Для работы NTP может потребоваться аппаратное время и другие шаги после " -"конфигурации.\n" +"Для работы NTP может потребоваться аппаратное время и другие шаги после конфигурации.\n" "Для получения дополнительной информации, пожалуйста, ознакомьтесь с ArchWiki" msgid "Enter a username to create an additional user (leave blank to skip): " -msgstr "" -"Введите имя пользователя для создания дополнительного пользователя (оставьте " -"пустым, чтобы пропустить): " +msgstr "Введите имя пользователя для создания дополнительного пользователя (оставьте пустым, чтобы пропустить): " msgid "Use ESC to skip\n" msgstr "Используйте ESC, чтобы пропустить\n" msgid "" "\n" -" Choose an object from the list, and select one of the available actions for " -"it to execute" +" Choose an object from the list, and select one of the available actions for it to execute" msgstr "" "\n" -" Выберите объект из списка и выберите одно из доступных действий для его " -"выполнения" +" Выберите объект из списка и выберите одно из доступных действий для его выполнения" msgid "Cancel" msgstr "Отменить" @@ -524,17 +442,11 @@ msgstr "" "\n" "Это выбранная вами конфигурация:" -msgid "" -"Pacman is already running, waiting maximum 10 minutes for it to terminate." -msgstr "" -"Pacman уже запущен, ожидание его завершения составляет максимум 10 минут." +msgid "Pacman is already running, waiting maximum 10 minutes for it to terminate." +msgstr "Pacman уже запущен, ожидание его завершения составляет максимум 10 минут." -msgid "" -"Pre-existing pacman lock never exited. Please clean up any existing pacman " -"sessions before using archinstall." -msgstr "" -"Существовавшая ранее блокировка pacman не завершилась. Пожалуйста, очистите " -"все существующие сессии pacman перед использованием archinstall." +msgid "Pre-existing pacman lock never exited. Please clean up any existing pacman sessions before using archinstall." +msgstr "Существовавшая ранее блокировка pacman не завершилась. Пожалуйста, очистите все существующие сессии pacman перед использованием archinstall." msgid "Choose which optional additional repositories to enable" msgstr "Выберите, какие дополнительные репозитории следует включить" @@ -625,8 +537,7 @@ msgid "Missing configurations:\n" msgstr "Отсутствующие конфигурации:\n" msgid "Either root-password or at least 1 superuser must be specified" -msgstr "" -"Должен быть указан либо пароль root, либо как минимум 1 суперпользователь" +msgstr "Должен быть указан либо пароль root, либо как минимум 1 суперпользователь" msgid "Manage superuser accounts: " msgstr "Управление учетными записями суперпользователей: " @@ -686,12 +597,8 @@ msgstr "Хотите ли вы использовать сжатие BTRFS?" msgid "Would you like to create a separate partition for /home?" msgstr "Хотите ли вы создать отдельный раздел для /home?" -msgid "" -"The selected drives do not have the minimum capacity required for an " -"automatic suggestion\n" -msgstr "" -"Выбранные диски не имеют минимальной емкости, необходимой для " -"автоматического предложения\n" +msgid "The selected drives do not have the minimum capacity required for an automatic suggestion\n" +msgstr "Выбранные диски не имеют минимальной емкости, необходимой для автоматического предложения\n" msgid "Minimum capacity for /home partition: {}GB\n" msgstr "Минимальный размер раздела /home: {}GB\n" @@ -718,9 +625,7 @@ msgid "No iface specified for manual configuration" msgstr "Не указан iface для ручной настройки" msgid "Manual nic configuration with no auto DHCP requires an IP address" -msgstr "" -"Ручная конфигурация сетевого адаптера без автоматического DHCP требует IP-" -"адреса" +msgstr "Ручная конфигурация сетевого адаптера без автоматического DHCP требует IP-адреса" msgid "Add interface" msgstr "Добавить интерфейс" @@ -740,74 +645,44 @@ msgstr "Ручная конфигурация" msgid "Mark/Unmark a partition as compressed (btrfs only)" msgstr "Пометить/снять отметку с раздела как сжатый (только для btrfs)" -msgid "" -"The password you are using seems to be weak, are you sure you want to use it?" -msgstr "" -"Пароль, который вы используете, кажется слабым, вы уверены, что хотите его " -"использовать?" +msgid "The password you are using seems to be weak, are you sure you want to use it?" +msgstr "Пароль, который вы используете, кажется слабым, вы уверены, что хотите его использовать?" -msgid "" -"Provides a selection of desktop environments and tiling window managers, e." -"g. gnome, kde, sway" -msgstr "" -"Предоставляет выбор окружений рабочего стола и тайловых оконных менеджеров, " -"например, gnome, kde, sway" +msgid "Provides a selection of desktop environments and tiling window managers, e.g. gnome, kde, sway" +msgstr "Предоставляет выбор окружений рабочего стола и тайловых оконных менеджеров, например, gnome, kde, sway" msgid "Select your desired desktop environment" msgstr "Выберите желаемое окружение рабочего стола" -msgid "" -"A very basic installation that allows you to customize Arch Linux as you see " -"fit." -msgstr "" -"Очень базовая установка, позволяющая настроить Arch Linux по своему " -"усмотрению." +msgid "A very basic installation that allows you to customize Arch Linux as you see fit." +msgstr "Очень базовая установка, позволяющая настроить Arch Linux по своему усмотрению." -msgid "" -"Provides a selection of various server packages to install and enable, e.g. " -"httpd, nginx, mariadb" -msgstr "" -"Предоставляет выбор различных пакетов сервера для установки и включения, " -"например, httpd, nginx, mariadb" +msgid "Provides a selection of various server packages to install and enable, e.g. httpd, nginx, mariadb" +msgstr "Предоставляет выбор различных пакетов сервера для установки и включения, например, httpd, nginx, mariadb" -msgid "" -"Choose which servers to install, if none then a minimal installation will be " -"done" -msgstr "" -"Выберите серверы для установки, если их нет, то будет выполнена минимальная " -"установка" +msgid "Choose which servers to install, if none then a minimal installation will be done" +msgstr "Выберите серверы для установки, если их нет, то будет выполнена минимальная установка" msgid "Installs a minimal system as well as xorg and graphics drivers." -msgstr "" -"Устанавливает минимальную систему, а также xorg и графические драйверы." +msgstr "Устанавливает минимальную систему, а также xorg и графические драйверы." msgid "Press Enter to continue." msgstr "Нажмите Enter, чтобы продолжить." -msgid "" -"Would you like to chroot into the newly created installation and perform " -"post-installation configuration?" -msgstr "" -"Хотите ли вы использовать chroot в новой созданной установке и выполнить " -"настройку после установки?" +msgid "Would you like to chroot into the newly created installation and perform post-installation configuration?" +msgstr "Хотите ли вы использовать chroot в новой созданной установке и выполнить настройку после установки?" msgid "Are you sure you want to reset this setting?" msgstr "Вы уверены, что хотите сбросить эту настройку?" msgid "Select one or more hard drives to use and configure\n" -msgstr "" -"Выберите один или несколько жестких дисков для использования и настройки\n" +msgstr "Выберите один или несколько жестких дисков для использования и настройки\n" msgid "Any modifications to the existing setting will reset the disk layout!" -msgstr "" -"Любые изменения существующей настройки приведут к сбросу разметки диска!" +msgstr "Любые изменения существующей настройки приведут к сбросу разметки диска!" -msgid "" -"If you reset the harddrive selection this will also reset the current disk " -"layout. Are you sure?" -msgstr "" -"Если вы сбросите выбор жесткого диска, это также сбросит текущую разметку " -"диска. Вы уверены?" +msgid "If you reset the harddrive selection this will also reset the current disk layout. Are you sure?" +msgstr "Если вы сбросите выбор жесткого диска, это также сбросит текущую разметку диска. Вы уверены?" msgid "Save and exit" msgstr "Сохранить и выйти" @@ -853,12 +728,8 @@ msgstr "Добавить: " msgid "Value: " msgstr "Значение: " -msgid "" -"You can skip selecting a drive and partitioning and use whatever drive-setup " -"is mounted at /mnt (experimental)" -msgstr "" -"Вы можете не выбирать диск и разметку и использовать любой диск, " -"смонтированный в /mnt (экспериментально)" +msgid "You can skip selecting a drive and partitioning and use whatever drive-setup is mounted at /mnt (experimental)" +msgstr "Вы можете не выбирать диск и разметку и использовать любой диск, смонтированный в /mnt (экспериментально)" msgid "Select one of the disks or skip and use /mnt as default" msgstr "Выберите один из дисков или пропустите и используйте /mnt по умолчанию" @@ -881,12 +752,8 @@ msgstr "Свободное место" msgid "Bus-type" msgstr "Тип шины" -msgid "" -"Either root-password or at least 1 user with sudo privileges must be " -"specified" -msgstr "" -"Должен быть указан либо пароль root, либо хотя бы 1 пользователь с " -"привилегиями sudo" +msgid "Either root-password or at least 1 user with sudo privileges must be specified" +msgstr "Должен быть указан либо пароль root, либо хотя бы 1 пользователь с привилегиями sudo" msgid "Enter username (leave blank to skip): " msgstr "Введите имя пользователя (оставьте пустым, чтобы пропустить): " @@ -921,14 +788,15 @@ msgstr "Редактировать подтом" msgid "Delete subvolume" msgstr "Удалить подтом" +msgid "Configured {} interfaces" +msgstr "" + #, python-brace-format #~ msgid "Edit {origkey} :" #~ msgstr "Редактировать {origkey}:" #~ msgid "Archinstall requires root privileges to run. See --help for more." -#~ msgstr "" -#~ "Для запуска Archinstall требуются привилегии root. Для получения " -#~ "дополнительной информации смотрите --help." +#~ msgstr "Для запуска Archinstall требуются привилегии root. Для получения дополнительной информации смотрите --help." #~ msgid " ! Formatting {archinstall.arguments['harddrives']} in " #~ msgstr " ! Форматирование {archinstall.arguments['harddrives']} в " diff --git a/archinstall/locales/sv/LC_MESSAGES/base.po b/archinstall/locales/sv/LC_MESSAGES/base.po index 747e28a1..b3712972 100644 --- a/archinstall/locales/sv/LC_MESSAGES/base.po +++ b/archinstall/locales/sv/LC_MESSAGES/base.po @@ -801,5 +801,8 @@ msgstr "" msgid "Delete subvolume" msgstr "Ta bort användare" +msgid "Configured {} interfaces" +msgstr "" + #~ msgid "Select disk layout" #~ msgstr "Välj hårddisk-layout" diff --git a/archinstall/locales/tr/LC_MESSAGES/base.po b/archinstall/locales/tr/LC_MESSAGES/base.po index 60475156..4d978ee0 100644 --- a/archinstall/locales/tr/LC_MESSAGES/base.po +++ b/archinstall/locales/tr/LC_MESSAGES/base.po @@ -800,3 +800,6 @@ msgstr "" #, fuzzy msgid "Delete subvolume" msgstr "Kullanıcı Sil" + +msgid "Configured {} interfaces" +msgstr "" diff --git a/archinstall/locales/ur/LC_MESSAGES/base.po b/archinstall/locales/ur/LC_MESSAGES/base.po index 710c08d7..2927c3ea 100644 --- a/archinstall/locales/ur/LC_MESSAGES/base.po +++ b/archinstall/locales/ur/LC_MESSAGES/base.po @@ -822,6 +822,9 @@ msgstr "" msgid "Delete subvolume" msgstr "صارف کو حذف کریں" +msgid "Configured {} interfaces" +msgstr "" + #~ msgid "Select disk layout" #~ msgstr "ڈسک لے آؤٹ کو منتخب کریں" -- cgit v1.2.3-54-g00ecf From 8b33e53d256159aac3e7826672c570fd4660495f Mon Sep 17 00:00:00 2001 From: zer0-x <65136727+zer0-x@users.noreply.github.com> Date: Fri, 2 Sep 2022 13:36:26 +0300 Subject: Translate few strings to Arabic (#1442) * Translate few strings to Arabic * Compile the Arabic localization to `.mo` file --- archinstall/locales/ar/LC_MESSAGES/base.mo | Bin 0 -> 3799 bytes archinstall/locales/ar/LC_MESSAGES/base.po | 783 +++++++++++++++++++++++++++++ 2 files changed, 783 insertions(+) create mode 100644 archinstall/locales/ar/LC_MESSAGES/base.mo create mode 100644 archinstall/locales/ar/LC_MESSAGES/base.po (limited to 'archinstall') diff --git a/archinstall/locales/ar/LC_MESSAGES/base.mo b/archinstall/locales/ar/LC_MESSAGES/base.mo new file mode 100644 index 00000000..6218cc97 Binary files /dev/null and b/archinstall/locales/ar/LC_MESSAGES/base.mo differ diff --git a/archinstall/locales/ar/LC_MESSAGES/base.po b/archinstall/locales/ar/LC_MESSAGES/base.po new file mode 100644 index 00000000..aad0f928 --- /dev/null +++ b/archinstall/locales/ar/LC_MESSAGES/base.po @@ -0,0 +1,783 @@ +# Header entry was created by Lokalize. +# +# zer0-x, 2022. +msgid "" +msgstr "" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Last-Translator: zer0-x\n" +"PO-Revision-Date: 2022-06-16 03:35+0300\n" +"Project-Id-Version: \n" +"Language-Team: Arabic\n" +"Language: ar\n" +"MIME-Version: 1.0\n" +"X-Generator: Lokalize 22.04.2\n" +"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 ? 4 : 5;\n" + +msgid "[!] A log file has been created here: {} {}" +msgstr "[!] مِلَف سِجِل أُنشِأ هُنا: {} {}" + +msgid "" +" Please submit this issue (and file) to" +" https://github.com/archlinux/archinstall/issues" +msgstr "" +" يُرجى تسليم تقرير عن هذا الخلل (مع المِلَف) إلى" +" https://github.com/archlinux/archinstall/issues" + +msgid "Do you really want to abort?" +msgstr "هل تُريدُ حقًا إجهاضَ العَملِيَّة؟" + +msgid "And one more time for verification: " +msgstr "ومرة أخرى للتحقق:" + +msgid "Would you like to use swap on zram?" +msgstr "هل تريد استخدام swap أو zram؟" + +msgid "Desired hostname for the installation: " +msgstr "اسم المضيف المُراد للتثبيت:" + +msgid "Username for required superuser with sudo privileges: " +msgstr "اسم المتستخدم لأجل المستخدم الخارِق المطلوب مع امتيازات sudo:" + +msgid "Any additional users to install (leave blank for no users): " +msgstr "أي مستخدمين إضافيين للتثبيت (اتركه فارغًا لعدم وجود مستخدمين):" + +msgid "Should this user be a superuser (sudoer)?" +msgstr "هل يجب أن يكون هذا المستخدم خارق (sudoer)؟" + +msgid "Select a timezone" +msgstr "حدِّد منطقة زمنية" + +msgid "Would you like to use GRUB as a bootloader instead of systemd-boot?" +msgstr "هل ترغب في استخدام GRUB كمُحمّل إقلاع بدلاً من systemd-boot؟" + +msgid "Choose a bootloader" +msgstr "اختر مُحمّل الإقلاع" + +msgid "Choose an audio server" +msgstr "اختر خادِم صوتيات" + +msgid "" +"Only packages such as base, base-devel, linux, linux-firmware, efibootmgr and" +" optional profile packages are installed." +msgstr "" +"فقط الحزم مثل base وbase-devel وlinux وlinux-firmware وefibootmgr و" +" حِزم مِلف اختيارية سوف تُثَبَّت." + +msgid "" +"If you desire a web browser, such as firefox or chromium, you may specify it" +" in the following prompt." +msgstr "" +"إذا كنت ترغب في متصفح الويب ، مثل Firefox أو chromium، فيمكنك تحديده" +" في موضِع الكتابة التالي." + +msgid "" +"Write additional packages to install (space separated, leave blank to skip): " +msgstr "اكتب حزمًا إضافية لتثبيتها (تُفصَل بالمسافات، اتركها فارغة للتخطي):" + +msgid "Copy ISO network configuration to installation" +msgstr "انسخ إعداد شبكة الـISO للتثبيت" + +msgid "" +"Use NetworkManager (necessary to configure internet graphically in GNOME and" +" KDE)" +msgstr "" +"استخدم مُدير الشبكة (ضروري لإعداد الإنترنت باستخدام واجهة رسومية في جنوم و" +" كيدي)" + +msgid "Select one network interface to configure" +msgstr "حدِّد واجهة شبكة واحدة للإعداد" + +msgid "" +"Select which mode to configure for \"{}\" or skip to use default mode \"{}\"" +msgstr "" +"حدد الوضع المراد تهيئته لـ\"{}\" أو تخطى لاستخدام الوضع الافتراضي \"{}\"" + +msgid "Enter the IP and subnet for {} (example: 192.168.0.5/24): " +msgstr "أدخِل الIP مع تجزئة الشبكة لـ{} (على سبيل المثال: 192.168.0.5/24): " + +msgid "Enter your gateway (router) IP address or leave blank for none: " +msgstr "" + +msgid "Enter your DNS servers (space separated, blank for none): " +msgstr "" + +msgid "Select which filesystem your main partition should use" +msgstr "" + +msgid "Current partition layout" +msgstr "" + +msgid "" +"Select what to do with\n" +"{}" +msgstr "" + +msgid "Enter a desired filesystem type for the partition" +msgstr "" + +msgid "Enter the start sector (percentage or block number, default: {}): " +msgstr "" + +msgid "" +"Enter the end sector of the partition (percentage or block number, ex: {}): " +msgstr "" + +msgid "{} contains queued partitions, this will remove those, are you sure?" +msgstr "" + +msgid "" +"{}\n" +"\n" +"Select by index which partitions to delete" +msgstr "" + +msgid "" +"{}\n" +"\n" +"Select by index which partition to mount where" +msgstr "" + +msgid "" +" * Partition mount-points are relative to inside the installation, the boot" +" would be /boot as an example." +msgstr "" + +msgid "Select where to mount partition (leave blank to remove mountpoint): " +msgstr "" + +msgid "" +"{}\n" +"\n" +"Select which partition to mask for formatting" +msgstr "" + +msgid "" +"{}\n" +"\n" +"Select which partition to mark as encrypted" +msgstr "" + +msgid "" +"{}\n" +"\n" +"Select which partition to mark as bootable" +msgstr "" + +msgid "" +"{}\n" +"\n" +"Select which partition to set a filesystem on" +msgstr "" + +msgid "Enter a desired filesystem type for the partition: " +msgstr "" + +msgid "Archinstall language" +msgstr "" + +msgid "Wipe all selected drives and use a best-effort default partition layout" +msgstr "" + +msgid "" +"Select what to do with each individual drive (followed by partition usage)" +msgstr "" + +msgid "Select what you wish to do with the selected block devices" +msgstr "" + +msgid "" +"This is a list of pre-programmed profiles, they might make it easier to" +" install things like desktop environments" +msgstr "" + +msgid "Select keyboard layout" +msgstr "" + +msgid "Select one of the regions to download packages from" +msgstr "" + +msgid "Select one or more hard drives to use and configure" +msgstr "" + +msgid "" +"For the best compatibility with your AMD hardware, you may want to use either" +" the all open-source or AMD / ATI options." +msgstr "" + +msgid "" +"For the best compatibility with your Intel hardware, you may want to use" +" either the all open-source or Intel options.\n" +msgstr "" + +msgid "" +"For the best compatibility with your Nvidia hardware, you may want to use the" +" Nvidia proprietary driver.\n" +msgstr "" + +msgid "" +"\n" +"\n" +"Select a graphics driver or leave blank to install all open-source drivers" +msgstr "" + +msgid "All open-source (default)" +msgstr "" + +msgid "Choose which kernels to use or leave blank for default \"{}\"" +msgstr "" + +msgid "Choose which locale language to use" +msgstr "" + +msgid "Choose which locale encoding to use" +msgstr "" + +msgid "Select one of the values shown below: " +msgstr "" + +msgid "Select one or more of the options below: " +msgstr "" + +msgid "Adding partition...." +msgstr "" + +msgid "" +"You need to enter a valid fs-type in order to continue. See `man parted` for" +" valid fs-type's." +msgstr "" + +msgid "Error: Listing profiles on URL \"{}\" resulted in:" +msgstr "" + +msgid "Error: Could not decode \"{}\" result as JSON:" +msgstr "" + +msgid "Keyboard layout" +msgstr "" + +msgid "Mirror region" +msgstr "" + +msgid "Locale language" +msgstr "" + +msgid "Locale encoding" +msgstr "" + +msgid "Drive(s)" +msgstr "" + +msgid "Disk layout" +msgstr "" + +msgid "Encryption password" +msgstr "" + +msgid "Swap" +msgstr "" + +msgid "Bootloader" +msgstr "" + +msgid "Root password" +msgstr "" + +msgid "Superuser account" +msgstr "" + +msgid "User account" +msgstr "" + +msgid "Profile" +msgstr "" + +msgid "Audio" +msgstr "" + +msgid "Kernels" +msgstr "" + +msgid "Additional packages" +msgstr "" + +msgid "Network configuration" +msgstr "" + +msgid "Automatic time sync (NTP)" +msgstr "" + +msgid "Install ({} config(s) missing)" +msgstr "" + +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 "" + +msgid "Re-using partition instance: {}" +msgstr "" + +msgid "Create a new partition" +msgstr "" + +msgid "Delete a partition" +msgstr "" + +msgid "Clear/Delete all partitions" +msgstr "" + +msgid "Assign mount-point for a partition" +msgstr "" + +msgid "Mark/Unmark a partition to be formatted (wipes data)" +msgstr "" + +msgid "Mark/Unmark a partition as encrypted" +msgstr "" + +msgid "Mark/Unmark a partition as bootable (automatic for /boot)" +msgstr "" + +msgid "Set desired filesystem for a partition" +msgstr "" + +msgid "Abort" +msgstr "" + +msgid "Hostname" +msgstr "" + +msgid "Not configured, unavailable unless setup manually" +msgstr "" + +msgid "Timezone" +msgstr "" + +msgid "Set/Modify the below options" +msgstr "" + +msgid "Install" +msgstr "" + +msgid "" +"Use ESC to skip\n" +"\n" +msgstr "" + +msgid "Suggest partition layout" +msgstr "" + +msgid "Enter a password: " +msgstr "" + +msgid "Enter a encryption password for {}" +msgstr "" + +msgid "Enter disk encryption password (leave blank for no encryption): " +msgstr "" + +msgid "Create a required super-user with sudo privileges: " +msgstr "" + +msgid "Enter root password (leave blank to disable root): " +msgstr "" + +msgid "Password for user \"{}\": " +msgstr "" + +msgid "" +"Verifying that additional packages exist (this might take a few seconds)" +msgstr "" + +msgid "" +"Would you like to use automatic time synchronization (NTP) with the default" +" time servers?\n" +msgstr "" + +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 "" + +msgid "Enter a username to create an additional user (leave blank to skip): " +msgstr "" + +msgid "Use ESC to skip\n" +msgstr "" + +msgid "" +"\n" +" Choose an object from the list, and select one of the available actions for" +" it to execute" +msgstr "" + +msgid "Cancel" +msgstr "" + +msgid "Confirm and exit" +msgstr "" + +msgid "Add" +msgstr "" + +msgid "Copy" +msgstr "" + +msgid "Edit" +msgstr "" + +msgid "Delete" +msgstr "" + +msgid "Select an action for < {} >" +msgstr "" + +msgid "Copy to new key:" +msgstr "" + +msgid "Unknown nic type: {}. Possible values are {}" +msgstr "" + +msgid "" +"\n" +"This is your chosen configuration:" +msgstr "" + +msgid "" +"Pacman is already running, waiting maximum 10 minutes for it to terminate." +msgstr "" + +msgid "" +"Pre-existing pacman lock never exited. Please clean up any existing pacman" +" sessions before using archinstall." +msgstr "" + +msgid "Choose which optional additional repositories to enable" +msgstr "" + +msgid "Add a user" +msgstr "" + +msgid "Change password" +msgstr "" + +msgid "Promote/Demote user" +msgstr "" + +msgid "Delete User" +msgstr "" + +msgid "" +"\n" +"Define a new user\n" +msgstr "" + +msgid "User Name : " +msgstr "" + +msgid "Should {} be a superuser (sudoer)?" +msgstr "" + +msgid "Define users with sudo privilege: " +msgstr "" + +msgid "No network configuration" +msgstr "" + +msgid "Set desired subvolumes on a btrfs partition" +msgstr "" + +msgid "" +"{}\n" +"\n" +"Select which partition to set subvolumes on" +msgstr "" + +msgid "Manage btrfs subvolumes for current partition" +msgstr "" + +msgid "No configuration" +msgstr "" + +msgid "Save user configuration" +msgstr "" + +msgid "Save user credentials" +msgstr "" + +msgid "Save disk layout" +msgstr "" + +msgid "Save all" +msgstr "" + +msgid "Choose which configuration to save" +msgstr "" + +msgid "Enter a directory for the configuration(s) to be saved: " +msgstr "" + +msgid "Not a valid directory: {}" +msgstr "" + +msgid "The password you are using seems to be weak," +msgstr "" + +msgid "are you sure you want to use it?" +msgstr "" + +msgid "Optional repositories" +msgstr "" + +msgid "Save configuration" +msgstr "" + +msgid "Missing configurations:\n" +msgstr "" + +msgid "Either root-password or at least 1 superuser must be specified" +msgstr "" + +msgid "Manage superuser accounts: " +msgstr "" + +msgid "Manage ordinary user accounts: " +msgstr "" + +msgid " Subvolume :{:16}" +msgstr "" + +msgid " mounted at {:16}" +msgstr "" + +msgid " with option {}" +msgstr "" + +msgid "" +"\n" +" Fill the desired values for a new subvolume \n" +msgstr "" + +msgid "Subvolume name " +msgstr "" + +msgid "Subvolume mountpoint" +msgstr "" + +msgid "Subvolume options" +msgstr "" + +msgid "Save" +msgstr "" + +msgid "Subvolume name :" +msgstr "" + +msgid "Select a mount point :" +msgstr "" + +msgid "Select the desired subvolume options " +msgstr "" + +msgid "Define users with sudo privilege, by username: " +msgstr "" + +msgid "[!] A log file has been created here: {}" +msgstr "" + +msgid "Would you like to use BTRFS subvolumes with a default structure?" +msgstr "" + +msgid "Would you like to use BTRFS compression?" +msgstr "" + +msgid "Would you like to create a separate partition for /home?" +msgstr "" + +msgid "" +"The selected drives do not have the minimum capacity required for an" +" automatic suggestion\n" +msgstr "" + +msgid "Minimum capacity for /home partition: {}GB\n" +msgstr "" + +msgid "Minimum capacity for Arch Linux partition: {}GB" +msgstr "" + +msgid "Continue" +msgstr "" + +msgid "yes" +msgstr "" + +msgid "no" +msgstr "" + +msgid "set: {}" +msgstr "" + +msgid "Manual configuration setting must be a list" +msgstr "" + +msgid "No iface specified for manual configuration" +msgstr "" + +msgid "Manual nic configuration with no auto DHCP requires an IP address" +msgstr "" + +msgid "Add interface" +msgstr "" + +msgid "Edit interface" +msgstr "" + +msgid "Delete interface" +msgstr "" + +msgid "Select interface to add" +msgstr "" + +msgid "Manual configuration" +msgstr "" + +msgid "Mark/Unmark a partition as compressed (btrfs only)" +msgstr "" + +msgid "" +"The password you are using seems to be weak, are you sure you want to use it?" +msgstr "" + +msgid "" +"Provides a selection of desktop environments and tiling window managers, e.g." +" gnome, kde, sway" +msgstr "" + +msgid "Select your desired desktop environment" +msgstr "" + +msgid "" +"A very basic installation that allows you to customize Arch Linux as you see" +" fit." +msgstr "" + +msgid "" +"Provides a selection of various server packages to install and enable, e.g." +" httpd, nginx, mariadb" +msgstr "" + +msgid "" +"Choose which servers to install, if none then a minimal installation wil be" +" done" +msgstr "" + +msgid "Installs a minimal system as well as xorg and graphics drivers." +msgstr "" + +msgid "Press Enter to continue." +msgstr "" + +msgid "" +"Would you like to chroot into the newly created installation and perform" +" post-installation configuration?" +msgstr "" + +msgid "Are you sure you want to reset this setting?" +msgstr "" + +msgid "Select one or more hard drives to use and configure\n" +msgstr "" + +msgid "Any modifications to the existing setting will reset the disk layout!" +msgstr "" + +msgid "" +"If you reset the harddrive selection this will also reset the current disk" +" layout. Are you sure?" +msgstr "" + +msgid "Save and exit" +msgstr "" + +msgid "" +"{}\n" +"contains queued partitions, this will remove those, are you sure?" +msgstr "" + +msgid "No audio server" +msgstr "" + +msgid "(default)" +msgstr "" + +msgid "Use ESC to skip" +msgstr "" + +msgid "" +"Use CTRL+C to reset current selection\n" +"\n" +msgstr "" + +msgid "Copy to: " +msgstr "" + +msgid "Edit: " +msgstr "" + +msgid "Key: " +msgstr "" + +msgid "Edit {}: " +msgstr "" + +msgid "Add: " +msgstr "" + +msgid "Value: " +msgstr "" + +msgid "" +"You can skip selecting a drive and partitioning and use whatever drive-setup" +" is mounted at /mnt (experimental)" +msgstr "" + +msgid "Select one of the disks or skip and use /mnt as default" +msgstr "" + +msgid "Select which partitions to mark for formatting:" +msgstr "" + +msgid "Use HSM to unlock encrypted drive" +msgstr "" + +msgid "Device" +msgstr "" + +msgid "Size" +msgstr "" + +msgid "Free space" +msgstr "" + +msgid "Bus-type" +msgstr "" + +msgid "" +"Either root-password or at least 1 user with sudo privileges must be specified" +msgstr "" + +msgid "Enter username (leave blank to skip): " +msgstr "" + +msgid "The username you entered is invalid. Try again" +msgstr "" + +msgid "Should \"{}\" be a superuser (sudo)?" +msgstr "" + +msgid "Select which partitions to encrypt:" +msgstr "" -- cgit v1.2.3-54-g00ecf From 883a8b692e19a08dddeeeaa646bcd6c0a4505a68 Mon Sep 17 00:00:00 2001 From: Orestis Ousoultzoglou Date: Fri, 2 Sep 2022 13:36:53 +0300 Subject: Add Greek translation (#1427) * Add el translation: 50% * Add el translation: 50% * Add el translation: 100% * Add el translation: add .mo file * Add el translation: fixes * Add el translation: include Greek in README --- README.md | 1 + archinstall/locales/el/LC_MESSAGES/base.mo | Bin 0 -> 35979 bytes archinstall/locales/el/LC_MESSAGES/base.po | 820 +++++++++++++++++++++++++++++ archinstall/locales/languages.json | 2 +- 4 files changed, 822 insertions(+), 1 deletion(-) create mode 100644 archinstall/locales/el/LC_MESSAGES/base.mo create mode 100644 archinstall/locales/el/LC_MESSAGES/base.po (limited to 'archinstall') diff --git a/README.md b/README.md index b1df757a..3eb6d531 100644 --- a/README.md +++ b/README.md @@ -56,6 +56,7 @@ Türk čeština русский اردو +Ελληνικά ``` Any contributions to the translations are more than welcome, and to get started please follow [the guide](https://github.com/archlinux/archinstall/blob/master/archinstall/locales/README.md) diff --git a/archinstall/locales/el/LC_MESSAGES/base.mo b/archinstall/locales/el/LC_MESSAGES/base.mo new file mode 100644 index 00000000..beae2659 Binary files /dev/null and b/archinstall/locales/el/LC_MESSAGES/base.mo differ diff --git a/archinstall/locales/el/LC_MESSAGES/base.po b/archinstall/locales/el/LC_MESSAGES/base.po new file mode 100644 index 00000000..2561c9f2 --- /dev/null +++ b/archinstall/locales/el/LC_MESSAGES/base.po @@ -0,0 +1,820 @@ +msgid "" +msgstr "" +"Project-Id-Version: \n" +"POT-Creation-Date: \n" +"PO-Revision-Date: \n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: el\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 3.1\n" + +msgid "[!] A log file has been created here: {} {}" +msgstr "[!] Ένα αρχείο καταγραφής έχει δημιουργηθεί εδώ: {} {}" + +msgid " Please submit this issue (and file) to https://github.com/archlinux/archinstall/issues" +msgstr " Παρακαλώ επισυνάψτε αυτό το issue (και αρχείο) στο https://github.com/archlinux/archinstall/issues" + +msgid "Do you really want to abort?" +msgstr "Θέλετε σίγουρα να διακόψετε;" + +msgid "And one more time for verification: " +msgstr "Και άλλη μία φορά για επαλήθευση: " + +msgid "Would you like to use swap on zram?" +msgstr "Θα θέλατε να χρησιμοποιήσετε swap με zram;" + +msgid "Desired hostname for the installation: " +msgstr "Επιθυμητό όνομα υπολογιστή για την εγκατάσταση: " + +msgid "Username for required superuser with sudo privileges: " +msgstr "Όνομα χρήστη για τον απαιτούμενο υπερ-χρήστη με δικαιώματα sudo: " + +msgid "Any additional users to install (leave blank for no users): " +msgstr "Επιπρόσθετοι χρήστες για την εγκατάσταση (αφήστε κενό για κανέναν χρήστη): " + +msgid "Should this user be a superuser (sudoer)?" +msgstr "Θα έπρεπε αυτός ο χρήστης να είναι ένας υπερχρήστης (χρήστης sudo);" + +msgid "Select a timezone" +msgstr "Επιλέξτε μία ζώνη ώρας" + +msgid "Would you like to use GRUB as a bootloader instead of systemd-boot?" +msgstr "Θα θέλατε να χρησιμοποιήσετε το GRUB ως bootloader αντί του systemd-boot;" + +msgid "Choose a bootloader" +msgstr "Επιλέξτε έναν bootloader" + +msgid "Choose an audio server" +msgstr "Επιλέξτε έναν διακομιστή ήχου" + +msgid "Only packages such as base, base-devel, linux, linux-firmware, efibootmgr and optional profile packages are installed." +msgstr "Εγκαθίστανται μόνο πακέτα όπως το base, base-devel, linux, linux-firmware, efibootmgr και προαιρετικά πακέτα προφίλ." + +msgid "If you desire a web browser, such as firefox or chromium, you may specify it in the following prompt." +msgstr "Εάν επιθυμείτε έναν περιηγητή διαδικτύου, όπως ο firefox ή ο chromium, πρέπει να το καθορίσετε στο επακόλουθο prompt." + +msgid "Write additional packages to install (space separated, leave blank to skip): " +msgstr "Γράψτε περαιτέρω πακέτα προς εγκατάσταση (χωρισμένα με κενό, αφήστε άδειο για να παραληφθεί): " + +msgid "Copy ISO network configuration to installation" +msgstr "Αντιγραφή διαμόρφωση δικτύου ISO στην εγκατάσταση" + +msgid "Use NetworkManager (necessary to configure internet graphically in GNOME and KDE)" +msgstr "Χρήση NetworkManager (απαραίτητος για τη διαμόρφωση του δικτύου γραφικά σε GNOME και KDE)" + +msgid "Select one network interface to configure" +msgstr "Επιλέξτε μία διεπαφή δικτύου για διαμόρφωση" + +msgid "Select which mode to configure for \"{}\" or skip to use default mode \"{}\"" +msgstr "Επιλέξτε ποιο mode να διαμορφωθεί για το \"{}\" ή παραλείψτε για να χρησιμοποιηθεί το default mode \"{}\"" + +msgid "Enter the IP and subnet for {} (example: 192.168.0.5/24): " +msgstr "Εισάγετε την IP και το υποδίκτυο για το {} (παράδειγμα: 192.168.0.5/24): " + +msgid "Enter your gateway (router) IP address or leave blank for none: " +msgstr "Εισάγετε τη διεύθυνση IP του router σας ή αφήστε άδειο για καμία διεύθυνση: " + +msgid "Enter your DNS servers (space separated, blank for none): " +msgstr "Εισάγετε τους διακομιστές DNS σας (χωρισμένοι με κενό, αφήστε άδειο για κανέναν διακομιστή): " + +msgid "Select which filesystem your main partition should use" +msgstr "Επιλέξτε ποιο σύστημα αρχείων θέλετε να χρησιμοποιεί η κύρια διαμέριση" + +msgid "Current partition layout" +msgstr "Τρέχουσα διάταξη διαμέρισης" + +msgid "" +"Select what to do with\n" +"{}" +msgstr "" +"Επιλέξτε τι να γίνει με\n" +"{}" + +msgid "Enter a desired filesystem type for the partition" +msgstr "Εισάγετε ένα επιθυμητό τύπο συστήματος αρχείων για τη διαμέριση" + +msgid "Enter the start sector (percentage or block number, default: {}): " +msgstr "Εισάγετε τον start sector (ποσοστό ή αριθμό block, προκαθορισμένο {}): " + +msgid "Enter the end sector of the partition (percentage or block number, ex: {}): " +msgstr "Εισάγετε τον end sector της διαμέρισης (ποσοστό ή αριθμό block, πχ: {}) " + +msgid "{} contains queued partitions, this will remove those, are you sure?" +msgstr "{} περιέχει διαμερίσεις στην ουρά, αυτό θα τις διαγράψει, είστε σίγουρη/ος;" + +msgid "" +"{}\n" +"\n" +"Select by index which partitions to delete" +msgstr "" +"{}\n" +"\n" +"Επιλέξτε ποιες διαμερίσεις να διαγραφούν μέσω δείκτη" + +msgid "" +"{}\n" +"\n" +"Select by index which partition to mount where" +msgstr "" +"{}\n" +"\n" +"Επιλέξτε ποια διαμέριση να γίνει mount που, μέσω δείκτη" + +msgid " * Partition mount-points are relative to inside the installation, the boot would be /boot as an example." +msgstr " * Τα σημεία mount της διαμέρισης είναι σχετικά ως προς το εσωτερικό της εγκατάστασης, για παράδειγμα το boot θα ήταν /boot." + +msgid "Select where to mount partition (leave blank to remove mountpoint): " +msgstr "Επιλέξτε που να γίνει mount η διαμέρισιη (αφήστε άδειο για να διαγραφεί το σημείο mount): " + +msgid "" +"{}\n" +"\n" +"Select which partition to mask for formatting" +msgstr "" +"{}\n" +"\n" +"Επιλέξτε ποια διαμέριση να μεταμφιεστεί για μορφοποίηση" + +msgid "" +"{}\n" +"\n" +"Select which partition to mark as encrypted" +msgstr "" +"{}\n" +"\n" +"Επιλέξτε ποια διαμέριση να σημειωθεί ως κρυπτογραφημένη" + +msgid "" +"{}\n" +"\n" +"Select which partition to mark as bootable" +msgstr "" +"{}\n" +"\n" +"Επιλέξτε ποια διαμέριση να σημειωθεί ως bootable" + +msgid "" +"{}\n" +"\n" +"Select which partition to set a filesystem on" +msgstr "" +"{}\n" +"\n" +"Επιλέξτε σε ποια διαμέριση να δημιουργηθεί σύστημα αρχείων" + +msgid "Enter a desired filesystem type for the partition: " +msgstr "Εισάγετε τον επιθυμητό τύπο συστήματος αρχείων για αυτήν τη διαμέριση: " + +msgid "Archinstall language" +msgstr "Γλώσσα archinstall" + +msgid "Wipe all selected drives and use a best-effort default partition layout" +msgstr "Διαγραφή όλων των επιλεγμένων δίσκων και χρήση μίας προκαθορισμένης διάταξης βέλτιστης προσπάθειας" + +msgid "Select what to do with each individual drive (followed by partition usage)" +msgstr "Επιλέξτε τι να γίνει με κάθε ξεχωριστό δίσκο (με επακόλουθο τη χρήση διαμέρισης)" + +msgid "Select what you wish to do with the selected block devices" +msgstr "Επιλέξτε τι θέλετε να κάνετε με τις επιλεγμένες συσκευές block" + +msgid "This is a list of pre-programmed profiles, they might make it easier to install things like desktop environments" +msgstr "Αυτή είναι μία λίστα με προ-προγραμματισμένα προφίλ, που μπορεί να κάνουν την εγκατάσταση πραγμάτων όπως περιβάλλοντα επιφάνειας εργασίας πιο εύκολη" + +msgid "Select keyboard layout" +msgstr "Επιλέξτε διάταξη πληκτρολογίου" + +msgid "Select one of the regions to download packages from" +msgstr "Επιλέξτε μία από τις περιοχές από τις οποίες να γίνει λήψη πακέτων" + +msgid "Select one or more hard drives to use and configure" +msgstr "Επιλέξτε έναν ή περισσότερους σκληρούς δίσκους προς χρήση και διαμόρφωση" + +msgid "For the best compatibility with your AMD hardware, you may want to use either the all open-source or AMD / ATI options." +msgstr "Για την καλύτερη συμβατότητα με το AMD υλισμικό σας, ίσως θέλετε να χρησιμοποιήσετε είτε την \"όλα ανοιχτής πηγής\", είτε την 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 "Για την καλύτερη συμβατότητα με το Intel υλισμικό σας, ίσως θέλετε να χρησιμοποιήσετε είτε την \"όλα ανοιχτής πηγής\", είτε την Intel επιλογή.\n" + +msgid "For the best compatibility with your Nvidia hardware, you may want to use the Nvidia proprietary driver.\n" +msgstr "Για την καλύτερη συμβατότητα με το Nvidia υλισμικό σας, ίσως θέλετε να χρησιμοποιήσετε τον ιδιόκτητο οδηγό της Nvidia.\n" + +msgid "" +"\n" +"\n" +"Select a graphics driver or leave blank to install all open-source drivers" +msgstr "" +"\n" +"\n" +"Επιλέξτε έναν οδηγώ γραφικών ή αφήστε άδειο για να εγκατασταθούν όλοι οι οδηγοί ανοιχτής πηγής" + +msgid "All open-source (default)" +msgstr "Όλα ανοιχτής πηγής (προκαθορισμένο)" + +msgid "Choose which kernels to use or leave blank for default \"{}\"" +msgstr "Επιλέξτε ποια kernels να χρησιμοποιηθούν ή αφήστε άδειο για το προκαθορισμένο \"{}\"" + +msgid "Choose which locale language to use" +msgstr "Επιλέξτε ποια τοπική γλώσσα να χρησιμοποιηθεί" + +msgid "Choose which locale encoding to use" +msgstr "Επιλέξτε ποια τοπική κωδικοποίηση να χρησιμοποιηθεί" + +msgid "Select one of the values shown below: " +msgstr "Επιλέξτε μία από τις τιμές που φαίνονται παρακάτω: " + +msgid "Select one or more of the options below: " +msgstr "Επιλέξτε μία ή παραπάνω από τις επιλογές παρακάτω: " + +msgid "Adding partition...." +msgstr "Προσθέτωντας τη διαμέριση...." + +msgid "You need to enter a valid fs-type in order to continue. See `man parted` for valid fs-type's." +msgstr "Πρέπει να εισάγετε έναν έγκυρο fs-type ώστε να συνεχίσετε. Δείτε `man parted` για έγκυρους fs-type." + +msgid "Error: Listing profiles on URL \"{}\" resulted in:" +msgstr "Σφάλμα: Η καταγραφή προφίλ στο URL \"{}\" είχε ως αποτέλεσμα:" + +msgid "Error: Could not decode \"{}\" result as JSON:" +msgstr "Σφάλμα: Η αποκωδικοποίηση του αποτελέσματος \"{}\" ως JSON ήταν ανεπιτυχής:" + +msgid "Keyboard layout" +msgstr "Διάταξη πληκτρολογίου" + +msgid "Mirror region" +msgstr "Περιοχή mirror" + +msgid "Locale language" +msgstr "Τοπική γλώσσα" + +msgid "Locale encoding" +msgstr "Τοπική κωδικοποίηση" + +msgid "Drive(s)" +msgstr "Δίσκος(οι)" + +msgid "Disk layout" +msgstr "Διάταξη δίσκου" + +msgid "Encryption password" +msgstr "Κωδικός κρυπτογράφησης" + +msgid "Swap" +msgstr "Swap" + +msgid "Bootloader" +msgstr "Bootloader" + +msgid "Root password" +msgstr "Κωδικός root" + +msgid "Superuser account" +msgstr "Λογαριασμός υπερχρήστη" + +msgid "User account" +msgstr "Λογαριασμός χρήστη" + +msgid "Profile" +msgstr "Προφίλ" + +msgid "Audio" +msgstr "Ήχος" + +msgid "Kernels" +msgstr "Kernels" + +msgid "Additional packages" +msgstr "Περαιτέρω πακέτα" + +msgid "Network configuration" +msgstr "Διαμόρφωση δικτύου" + +msgid "Automatic time sync (NTP)" +msgstr "Αυτόματη ενημέρωση ώρας (NTP)" + +msgid "Install ({} config(s) missing)" +msgstr "Εγκατάσταση (η/οι {} διαμόρφωση/εις λείπει/ουν)" + +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 "" +"Επιλέξατε να παραλείψετε την επιλογή σκληρού δίσκου\n" +"και θα χρησιμοποιηθεί οποιαδήποτε εγκατάσταση δίσκου είναι mount στο {} (πειραματικό)\n" +"ΠΡΟΣΟΧΗ: Το archinstall δεν μπορεί να ελέγξει την καταλληλότητα αυτής της εγκατάστασης\n" +"Θέλετε να συνεχίσετε;" + +msgid "Re-using partition instance: {}" +msgstr "Επαναχρησιμοποιώντας την instance διαμέρισης: {}" + +msgid "Create a new partition" +msgstr "Δημιουργία καινούργιας διαμέρισης" + +msgid "Delete a partition" +msgstr "Διαγραφή διαμέρισης" + +msgid "Clear/Delete all partitions" +msgstr "Καθαρισμός/Διαγραφή όλων των διαμερίσεων" + +msgid "Assign mount-point for a partition" +msgstr "Εκχώρηση σημείου mount για μία διαμέριση" + +msgid "Mark/Unmark a partition to be formatted (wipes data)" +msgstr "Σημείωση/Ξεμαρκάρισμα διαμέρισης προς μορφοποίηση (διαγράφει τα δεδομένα)" + +msgid "Mark/Unmark a partition as encrypted" +msgstr "Σημείωση/Ξεμαρκάρισμα διαμέρισης ως κρυπτογραφημένη" + +msgid "Mark/Unmark a partition as bootable (automatic for /boot)" +msgstr "Σημείωση/Ξεμαρκάρισμα διαμέρισης ως ικανή για boot (αυτόματο για /boot)" + +msgid "Set desired filesystem for a partition" +msgstr "Θέση επιθυμητού συστήματος αρχείων για μία διαμέριση" + +msgid "Abort" +msgstr "Εγκατάλειψη" + +msgid "Hostname" +msgstr "Όνομα υπολογιστή" + +msgid "Not configured, unavailable unless setup manually" +msgstr "Δεν έχει διαμορφωθεί, μη διαθέσιμο εκτός εάν εγκατασταθεί χειροκίνητα" + +msgid "Timezone" +msgstr "Ζώνη ώρας" + +msgid "Set/Modify the below options" +msgstr "Θέση/Τροποποίηση των παρακάτω επιλογών" + +msgid "Install" +msgstr "Εγκατάσταση" + +msgid "" +"Use ESC to skip\n" +"\n" +msgstr "" +"Χρησιμοποιήστε ESC για παράλειψη\n" +"\n" + +msgid "Suggest partition layout" +msgstr "Πρόταση διάταξης διαμέρισης" + +msgid "Enter a password: " +msgstr "Εισάγετε κωδικό: " + +msgid "Enter a encryption password for {}" +msgstr "Εισάγετε έναν κωδικό κρυπτογράφησης για {}" + +msgid "Enter disk encryption password (leave blank for no encryption): " +msgstr "Εισάγετε κωδικό κρυπτογράφησης δίσκου (αφήστε άδειο για καμία κρυπτογράφηση): " + +msgid "Create a required super-user with sudo privileges: " +msgstr "Δημιουργήστε έναν απαιτούμενο υπερχρήστη με δικαιώματα sudo: " + +msgid "Enter root password (leave blank to disable root): " +msgstr "Εισάγετε τον κωδικό root (αφήστε άδειο για να απενεργοποιηθεί το root): " + +msgid "Password for user \"{}\": " +msgstr "Κωδικός για τον χρήστη \"{}\": " + +msgid "Verifying that additional packages exist (this might take a few seconds)" +msgstr "Επαληθεύοντας ότι υπάρχουν περαιτέρω πακέτα (μπορεί να πάρει μερικά δευτερόλεπτα)" + +msgid "Would you like to use automatic time synchronization (NTP) with the default time servers?\n" +msgstr "Θα θέλατε να χρησιμοποιήσετε αυτόματο συγχρονισμό χρόνου (NTP) με τους προκαθορισμένους διακομιστές χρόνου;\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 "" +"Ο χρόνος υλισμικού και άλλα βήματα μετά τη διαμόρφωση ενδέχεται να απαιτούνται ώστε να δουλέψει ο NTP.\n" +"Για περισσότερες πληροφορίες, παρακαλώ ελέγξτε το Arch wiki" + +msgid "Enter a username to create an additional user (leave blank to skip): " +msgstr "Εισάγετε ένα όνομα χρήστη για να δημιουργήσετε έναν ακόμα χρήστη (αφήστε άδειο για παράλειψη): " + +msgid "Use ESC to skip\n" +msgstr "Χρησιμοποιήστε ESC για παράλειψη\n" + +msgid "" +"\n" +" Choose an object from the list, and select one of the available actions for it to execute" +msgstr "" +"\n" +"Επιλέξτε ένα αντικείμενο από τη λίστα, και επιλέξτε μία από τις διαθέσιμες επιλογές προς εκτέλεση" + +msgid "Cancel" +msgstr "Ακύρωση" + +msgid "Confirm and exit" +msgstr "Επιβεβαίωση και έξοδος" + +msgid "Add" +msgstr "Προσθήκη" + +msgid "Copy" +msgstr "Αντιγραφή" + +msgid "Edit" +msgstr "Επεξεργασία" + +msgid "Delete" +msgstr "Διαγραφή" + +msgid "Select an action for '{}'" +msgstr "Επιλέξτε μία ενέργεια για '{}'" + +msgid "Copy to new key:" +msgstr "Αντιγραφή σε νέο κλειδί:" + +msgid "Unknown nic type: {}. Possible values are {}" +msgstr "Άγνωστος τύπος nic: {}. Πιθανές τιμές είναι οι {}" + +msgid "" +"\n" +"This is your chosen configuration:" +msgstr "" +"\n" +"Αυτή είναι η επιλεγμένη σας διαμόρφωση:" + +msgid "Pacman is already running, waiting maximum 10 minutes for it to terminate." +msgstr "Ο Pacman ήδη εκτελείται, αναμονή μέχρι 10 λεπτά ώστε να τερματίσει." + +msgid "Pre-existing pacman lock never exited. Please clean up any existing pacman sessions before using archinstall." +msgstr "Η προϋπάρχουσα pacman lock δεν εξήλθε. Παρακαλώ καθαρίστε τυχόν συνεδρίες pacman πριν τη χρήση του archinstall." + +msgid "Choose which optional additional repositories to enable" +msgstr "Επιλέξτε ποια προαιρετικά περαιτέρω αποθετήρια να ενεργοποιηθούν" + +msgid "Add a user" +msgstr "Προσθήκη χρήστη" + +msgid "Change password" +msgstr "Αλλαγή κωδικού" + +msgid "Promote/Demote user" +msgstr "Προαγωγή/Υποβιβασμός χρήστη" + +msgid "Delete User" +msgstr "Διαγραφή Χρήστη" + +msgid "" +"\n" +"Define a new user\n" +msgstr "" +"\n" +"Ορισμός νέου χρήστη\n" + +msgid "User Name : " +msgstr "Όνομα Χρήστη : " + +msgid "Should {} be a superuser (sudoer)?" +msgstr "Θα έπρεπε ο {} να είναι υπερχρήστης (χρήστης sudo);" + +msgid "Define users with sudo privilege: " +msgstr "Καθορίστε τους χρήστες με δικαιώματα sudo: " + +msgid "No network configuration" +msgstr "Καμία διαμόρφωση δικτύου" + +msgid "Set desired subvolumes on a btrfs partition" +msgstr "Θέση επιθυμητών υποόγκων σε μία διαμέριση btrfs" + +msgid "" +"{}\n" +"\n" +"Select which partition to set subvolumes on" +msgstr "" +"{}\n" +"\n" +"Επιλέξτε σε ποια διαμέριση να τεθούν υποόγκοι" + +msgid "Manage btrfs subvolumes for current partition" +msgstr "Διαχειριστείτε τους υποόγκους btrfs για την τρέχουσα διαμέριση" + +msgid "No configuration" +msgstr "Καμία διαμόρφωση" + +msgid "Save user configuration" +msgstr "Αποθήκευση διαμόρφωσης χρήστη" + +msgid "Save user credentials" +msgstr "Αποθήκευση στοιχείων χρήστη" + +msgid "Save disk layout" +msgstr "Αποθήκευση διάταξης δίσκου" + +msgid "Save all" +msgstr "Αποθήκευση όλων" + +msgid "Choose which configuration to save" +msgstr "Επιλέξτε ποια διαμόρφωση να αποθηκευτεί" + +msgid "Enter a directory for the configuration(s) to be saved: " +msgstr "Εισάγετε έναν φάκελο για την αποθήκευση της/ων διαμόρφωση/ων: " + +msgid "Not a valid directory: {}" +msgstr "Μη έγκυρος φάκελος: {}" + +msgid "The password you are using seems to be weak," +msgstr "Ο κωδικός που χρησιμοποιείτε φαίνεται να είναι αδύναμος," + +msgid "are you sure you want to use it?" +msgstr "είστε σίγουρη/ος ότι θέλετε να τον χρησιμοποιήσετε;" + +msgid "Optional repositories" +msgstr "Προαιρετικά αποθετήρια" + +msgid "Save configuration" +msgstr "Αποθήκευση διαμόρφωσης" + +msgid "Missing configurations:\n" +msgstr "Διαμορφώσεις που λείπουν:\n" + +msgid "Either root-password or at least 1 superuser must be specified" +msgstr "Πρέπει να καθοριστεί είτε ο κωδικός του root είτε τουλάχιστον 1 υπερχρήστης" + +msgid "Manage superuser accounts: " +msgstr "Διαχείριση λογαριασμών υπερχρήστη: " + +msgid "Manage ordinary user accounts: " +msgstr "Διαχείριση λογαριασμών κανονικών χρηστών: " + +msgid " Subvolume :{:16}" +msgstr " Υποόγκος :{:16}" + +msgid " mounted at {:16}" +msgstr " Έχει γίνει mount στο {:16}" + +msgid " with option {}" +msgstr " με επιλογή {}" + +msgid "" +"\n" +" Fill the desired values for a new subvolume \n" +msgstr "" +"\n" +" Συμπληρώστε τις επιθυμητές τιμές για έναν νέο υποόγκο \n" + +msgid "Subvolume name " +msgstr "Όνομα υποόγκου " + +msgid "Subvolume mountpoint" +msgstr "Σημείο mount υποόγκου" + +msgid "Subvolume options" +msgstr "Επιλογές υποόγκου" + +msgid "Save" +msgstr "Αποθήκευση" + +msgid "Subvolume name :" +msgstr "Όνομα υποόγκου :" + +msgid "Select a mount point :" +msgstr "Επιλέξτε ένα σημείο mount :" + +msgid "Select the desired subvolume options " +msgstr "Επιλέξτε τις επιθυμητές επιλογές υποόγκου " + +msgid "Define users with sudo privilege, by username: " +msgstr "Καθορίστε τους χρήστες με δικαιώματα sudo, μέσω όνομα χρήστη: " + +msgid "[!] A log file has been created here: {}" +msgstr "[!] Ένα αρχείο ιστορικού έχει δημιουργηθεί εδώ: {}" + +msgid "Would you like to use BTRFS subvolumes with a default structure?" +msgstr "Θα θέλατε να χρησιμοποιήσετε BTRFS υποόγκους με μία προκαθορισμένη δομή;" + +msgid "Would you like to use BTRFS compression?" +msgstr "Θα θέλατε να χρησιμοποιήσετε συμπίεση BTRFS;" + +msgid "Would you like to create a separate partition for /home?" +msgstr "Θα θέλατε να δημιουργήσετε μία ξεχωριστή διαμέριση για το /home;" + +msgid "The selected drives do not have the minimum capacity required for an automatic suggestion\n" +msgstr "Οι επιλεγμένοι δίσκοι δεν έχουν την ελάχιστη χωρητικότητα που απαιτείται για μία αυτόματη πρόταση\n" + +msgid "Minimum capacity for /home partition: {}GB\n" +msgstr "Ελάχιστη χωρητικότητα για τη διαμέριση /home: {}GB\n" + +msgid "Minimum capacity for Arch Linux partition: {}GB" +msgstr "Ελάχιστη χωρητικότητα για τη διαμέριση Arch Linux: {}GB" + +msgid "Continue" +msgstr "Συνέχεια" + +msgid "yes" +msgstr "ναι" + +msgid "no" +msgstr "οχι" + +msgid "set: {}" +msgstr "θέση {}" + +msgid "Manual configuration setting must be a list" +msgstr "Η ρύθμιση χειροκίνητης διαμόρφωσης πρέπει να είναι μία λίστα" + +msgid "No iface specified for manual configuration" +msgstr "Δεν έχει καθοριστεί iface για χειροκίνητη διαμόρφωση" + +msgid "Manual nic configuration with no auto DHCP requires an IP address" +msgstr "Η χειροκίνητη διαμόρφωση nic χωρίς αυτόματο DHCP απαιτεί μία διεύθυνση IP" + +msgid "Add interface" +msgstr "Προσθήκη διεπαφής" + +msgid "Edit interface" +msgstr "Επεξεργασία διεπαφής" + +msgid "Delete interface" +msgstr "Διαγραφή διεπαφής" + +msgid "Select interface to add" +msgstr "Επιλέξτε διεπαφή προς προσθήκη" + +msgid "Manual configuration" +msgstr "Χειροκίνητη διαμόρφωση" + +msgid "Mark/Unmark a partition as compressed (btrfs only)" +msgstr "Σημείωση/Ξεμαρκάρισμα μίας διαμέρισως ως συμπιεσμένη (μόνο για btrfs)" + +msgid "The password you are using seems to be weak, are you sure you want to use it?" +msgstr "Ο κωδικός που χρησιμοποιείτε φαίνεται να είναι αδύναμος, είστε σίγουρη/ος ότι θέλετε να τον χρησιμοποιήσετε;" + +msgid "Provides a selection of desktop environments and tiling window managers, e.g. gnome, kde, sway" +msgstr "Παρέχει μία επιλογή από περιβάλλοντα επιφάνειας εργασίας και διαχειριστές tiling παραθύρων, π.χ. gnome, kde, sway" + +msgid "Select your desired desktop environment" +msgstr "Επιλέξτε το επιθυμητό σας περιβάλλον επιφάνειας εργασίας" + +msgid "A very basic installation that allows you to customize Arch Linux as you see fit." +msgstr "Μία πολύ βασική εγκατάσταση που σας επιτρέπει να προσαρμόσετε τα Arch Linux όπως εσείς κρίνετε κατάλληλο." + +msgid "Provides a selection of various server packages to install and enable, e.g. httpd, nginx, mariadb" +msgstr "Παρέχει μία επιλογή από ποικίλα πακέτα διακομιστών προς εγκατάσταση και ενεργοποίηση, π.χ. httpd, nginx, mariadb" + +msgid "Choose which servers to install, if none then a minimal installation will be done" +msgstr "Επιλέξτε ποιους διακομιστές να εγκατασταθούν, αν δεν επιλεχθεί κανένας τότε θα γίνει μία minimal εγκατάσταση" + +msgid "Installs a minimal system as well as xorg and graphics drivers." +msgstr "Εγκαθιστά ένα minimal σύστημα καθώς και το xorg και οδηγούς γραφικών." + +msgid "Press Enter to continue." +msgstr "Πατήστε Enter για να συνεχίσετε." + +msgid "Would you like to chroot into the newly created installation and perform post-installation configuration?" +msgstr "Θα θέλατε να κάνετε chroot εντός της καινούργιας εγκατάστασης για περαιτέρω διαμόρφωση;" + +msgid "Are you sure you want to reset this setting?" +msgstr "Είστε σίγουρη/ος ότι θέλετε να επαναφέρετε αυτήν τη ρύθμιση;" + +msgid "Select one or more hard drives to use and configure\n" +msgstr "Επιλέξτε έναν ή περισσότερους σκληρούς δίσκους προς χρήση και διαμόρφωση\n" + +msgid "Any modifications to the existing setting will reset the disk layout!" +msgstr "Τυχόν τροποποιήσεις στην ήδη υπάρχουσα ρύθμιση θα επαναφέρουν τη διάταξη δίσκου!" + +msgid "If you reset the harddrive selection this will also reset the current disk layout. Are you sure?" +msgstr "Αν επαναφέρετε την επιλογή σκληρού δίσκου αυτό επίσης θα επαναφέρει την τρέχουσα διάταξη δίσκου. Είστε σίγουρη/ος;" + +msgid "Save and exit" +msgstr "Αποθήκευση και έξοδος" + +msgid "" +"{}\n" +"contains queued partitions, this will remove those, are you sure?" +msgstr "" +"{}\n" +"περιέχει διαμερίσεις στην ουρά, αυτό θα τις διαγράψει, είστε σίγουρη/ος;" + +msgid "No audio server" +msgstr "Κανένας διακομιστής ήχου" + +msgid "(default)" +msgstr "(προκαθορισμένο)" + +msgid "Use ESC to skip" +msgstr "Χρησιμοποιήστε ESC για παράλειψη" + +msgid "" +"Use CTRL+C to reset current selection\n" +"\n" +msgstr "" +"Χρησιμοποιήστε CTRL+C για να επαναφέρετε την τρέχουσα επιλογή\n" +"\n" + +msgid "Copy to: " +msgstr "Αντιγραφή σε: " + +msgid "Edit: " +msgstr "Επεξεργασία " + +msgid "Key: " +msgstr "Κλειδί: " + +msgid "Edit {}: " +msgstr "Επεξεργασία {}: " + +msgid "Add: " +msgstr "Προσθήκη: " + +msgid "Value: " +msgstr "Τιμή: " + +msgid "You can skip selecting a drive and partitioning and use whatever drive-setup is mounted at /mnt (experimental)" +msgstr "Μπορείτε να παραλείψετε την επιλογή δίσκου και διαμερισμού και να χρησιμοποιήσετε οποιαδήποτε εγκατάσαση δίσκου είναι mount στο /mnt (πειραματικό)" + +msgid "Select one of the disks or skip and use /mnt as default" +msgstr "Επιλέξτε έναν από τους δίσκους ή παραλείψτε και χρησιμοποιήστε το /mnt ως προκαθορισμένο" + +msgid "Select which partitions to mark for formatting:" +msgstr "Επιλέξτε ποιες διαμερίσεις να σημειωθούν για μορφοποίηση:" + +msgid "Use HSM to unlock encrypted drive" +msgstr "Χρήση HSM για ξεκλείδωμα κρυπτογραφημένου δίσκου" + +msgid "Device" +msgstr "Συσκευή" + +msgid "Size" +msgstr "Μέγεθος" + +msgid "Free space" +msgstr "Ελεύθερος χώρος" + +msgid "Bus-type" +msgstr "Τύπος bus" + +msgid "Either root-password or at least 1 user with sudo privileges must be specified" +msgstr "Πρέπει να καθοριστεί είτε ο κωδικός root ή τουλάχιστον 1 χρήστης με δικαιώματα sudo" + +msgid "Enter username (leave blank to skip): " +msgstr "Εισάγετε όνομα χρήστη (αφήστε κενό για παράλειψη): " + +msgid "The username you entered is invalid. Try again" +msgstr "Το όνομα χρήστη που εισάγατε δεν είναι έγκυρο. Προσπαθήστε ξανά" + +msgid "Should \"{}\" be a superuser (sudo)?" +msgstr "Θα έπρεπε ο \"{}\" να είναι υπερχρήστης (sudo);" + +msgid "Select which partitions to encrypt:" +msgstr "Επιλέξτε ποιες διαμερίσεις να κρυπτογραφηθούν." + +msgid "very weak" +msgstr "πολύ αδύναμος" + +msgid "weak" +msgstr "αδύναμος" + +msgid "moderate" +msgstr "μέτριος" + +msgid "strong" +msgstr "ισχυρός" + +msgid "Add subvolume" +msgstr "Προσθήκη υποόγκου" + +msgid "Edit subvolume" +msgstr "Επεξεργασία υποόγκου" + +msgid "Delete subvolume" +msgstr "Διαγραφή υποόγκου" + +msgid "This option enables the number of parallel downloads that can occur during installation" +msgstr "Αυτή η επιλογή θέτει τον αριθμό των παράλληλων λήψεων που μπορούν να συμβούν κατά την εγκατάσταση" + +#, python-brace-format +msgid "" +"Enter the number of parallel downloads to be enabled.\n" +" (Enter a value between 1 to {max_downloads})\n" +"Note:" +msgstr "" +"Εισάγετε τον αριθμό των παράλληλων λήψεων προς ενεργοποίηση.\n" +" (Εισάγετε μία τιμή από 1 μέχρι {max_downloads})\n" +"Σημείωση:" + +msgid " - Maximum value : {max_downloads} ( Allows {max_downloads} parallel downloads, allows {max_downloads+1} downloads at a time )" +msgstr " - Μέγιστη τιμή : {max_downloads} ( Επιτρέπει {max_downloads} παράλληλες λήψεις, επιτρέπει {max_downloads+1} λήψεις σε μία στιγμή )" + +msgid " - Minimum value : 1 ( Allows 1 parallel download, allows 2 downloads at a time )" +msgstr " - Ελάχιστη τιμή : 1 ( Επιτρέπει 1 παράλληλη λήψη, επιτρέπει 2 λήψεις σε μία στιγμή )" + +msgid " - Disable/Default : 0 ( Disables parallel downloading, allows only 1 download at a time )" +msgstr " - Απενεργοποίηση/Προκαθορισμένο : 0 ( Απενεργοποιεί τις παράλληλες λήψεις, επιτρέπει μόνο 1 λήψη σε μία στιγμή )" + +#, python-brace-format +msgid "Invalid input! Try again with a valid input [1 to {max_downloads}, or 0 to disable]" +msgstr "Μη έγκυρη είσοδος! Προσπαθήστε ξανά με μία έγκυρη είσοδο [1 μέχρι {max_downloads}, ή 0 για απενεργοποίηση]" + +msgid "Parallel Downloads" +msgstr "Παράλληλες Λήψεις" + +msgid "Configured {} interfaces" +msgstr "Διαμορφωμένες {} διεπαφές" diff --git a/archinstall/locales/languages.json b/archinstall/locales/languages.json index 883042e8..decebadf 100644 --- a/archinstall/locales/languages.json +++ b/archinstall/locales/languages.json @@ -33,7 +33,7 @@ {"abbr": "de", "lang": "German", "translated_lang": "Deutsch"}, {"abbr": "dv", "lang": "Dhivehi"}, {"abbr": "dz", "lang": "Dzongkha"}, - {"abbr": "el", "lang": "Modern Greek (1453-)"}, + {"abbr": "el", "lang": "Modern Greek (1453-)", "translated_lang": "Ελληνικά"}, {"abbr": "en", "lang": "English"}, {"abbr": "eo", "lang": "Esperanto"}, {"abbr": "et", "lang": "Estonian"}, -- cgit v1.2.3-54-g00ecf From dba30fdcf0e4e0cf3ef66d26a182c3852f3ee8f0 Mon Sep 17 00:00:00 2001 From: "K.B.Dharun Krishna" Date: Mon, 5 Sep 2022 15:50:08 +0530 Subject: locales: AddTamil translation (#1454) --- README.md | 1 + archinstall/locales/languages.json | 2 +- archinstall/locales/ta/LC_MESSAGES/base.mo | Bin 0 -> 47919 bytes archinstall/locales/ta/LC_MESSAGES/base.po | 820 +++++++++++++++++++++++++++++ 4 files changed, 822 insertions(+), 1 deletion(-) create mode 100644 archinstall/locales/ta/LC_MESSAGES/base.mo create mode 100644 archinstall/locales/ta/LC_MESSAGES/base.po (limited to 'archinstall') diff --git a/README.md b/README.md index 3eb6d531..7a087dcb 100644 --- a/README.md +++ b/README.md @@ -57,6 +57,7 @@ Türk русский اردو Ελληνικά +தமிழ் ``` Any contributions to the translations are more than welcome, and to get started please follow [the guide](https://github.com/archlinux/archinstall/blob/master/archinstall/locales/README.md) diff --git a/archinstall/locales/languages.json b/archinstall/locales/languages.json index decebadf..0f8fe34c 100644 --- a/archinstall/locales/languages.json +++ b/archinstall/locales/languages.json @@ -155,7 +155,7 @@ {"abbr": "sw", "lang": "Swahili (macrolanguage)"}, {"abbr": "sv", "lang": "Swedish", "translated_lang": "Svenska"}, {"abbr": "ty", "lang": "Tahitian"}, - {"abbr": "ta", "lang": "Tamil"}, + {"abbr": "ta", "lang": "Tamil", "translated_lang": "தமிழ்"}, {"abbr": "tt", "lang": "Tatar"}, {"abbr": "te", "lang": "Telugu"}, {"abbr": "tg", "lang": "Tajik"}, diff --git a/archinstall/locales/ta/LC_MESSAGES/base.mo b/archinstall/locales/ta/LC_MESSAGES/base.mo new file mode 100644 index 00000000..2129b1fb Binary files /dev/null and b/archinstall/locales/ta/LC_MESSAGES/base.mo differ diff --git a/archinstall/locales/ta/LC_MESSAGES/base.po b/archinstall/locales/ta/LC_MESSAGES/base.po new file mode 100644 index 00000000..9cf261f2 --- /dev/null +++ b/archinstall/locales/ta/LC_MESSAGES/base.po @@ -0,0 +1,820 @@ +msgid "" +msgstr "" +"Project-Id-Version: \n" +"POT-Creation-Date: \n" +"PO-Revision-Date: \n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: ta\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 3.1.1\n" + +msgid "[!] A log file has been created here: {} {}" +msgstr "[!] ஒரு பதிவு கோப்பு இங்கே உருவாக்கப்பட்டது: {} {}" + +msgid " Please submit this issue (and file) to https://github.com/archlinux/archinstall/issues" +msgstr " இந்த சிக்கல் (மற்றும் கோப்பை) https://github.com/archlinux/archinstall/issues க்கு சமர்ப்பிக்கவும்" + +msgid "Do you really want to abort?" +msgstr "நீங்கள் உண்மையிலேயே கைவிட விரும்புகிறீர்களா?" + +msgid "And one more time for verification: " +msgstr "மற்றும் மேலும் ஒரு முறை சரிபார்த்தல்: " + +msgid "Would you like to use swap on zram?" +msgstr "நீங்கள் zram இல் swap ஐப் பயன்படுத்த விரும்புகிறீர்களா?" + +msgid "Desired hostname for the installation: " +msgstr "நிறுவலுக்கு விரும்பிய ஹோஸ்ட்பெயர்: " + +msgid "Username for required superuser with sudo privileges: " +msgstr "சூடோ சிறப்புரிமைகளுடன் தேவைப்படும் சூப்பர் யூசருக்கான பயனர் பெயர்: " + +msgid "Any additional users to install (leave blank for no users): " +msgstr "நிறுவ வேண்டிய கூடுதல் பயனர்கள் (பயனர்கள் யாரும் இல்லாத நிலையில் காலியாக விடவும்): " + +msgid "Should this user be a superuser (sudoer)?" +msgstr "இந்தப் பயனர் ஒரு சூப்பர் யூசராக (sudoer) இருக்க வேண்டுமா?" + +msgid "Select a timezone" +msgstr "நேர மண்டலத்தைத் தேர்ந்தெடுக்கவும்" + +msgid "Would you like to use GRUB as a bootloader instead of systemd-boot?" +msgstr "நீங்கள் systemd-boot க்குப் பதிலாக GRUB ஐ துவக்க ஏற்றியாகப் பயன்படுத்த விரும்புகிறீர்களா?" + +msgid "Choose a bootloader" +msgstr "துவக்க ஏற்றியைத் தேர்ந்தெடுக்கவும்" + +msgid "Choose an audio server" +msgstr "ஆடியோ சர்வரை தேர்வு செய்யவும்" + +msgid "Only packages such as base, base-devel, linux, linux-firmware, efibootmgr and optional profile packages are installed." +msgstr "தொகுப்பு Base, base-devel, linux, linux-firmware, efibootmgr மற்றும் விருப்ப சுயவிவர தொகுப்புகள் போன்ற தொகுப்புகள் மட்டுமே நிறுவப்பட்டுள்ளன." + +msgid "If you desire a web browser, such as firefox or chromium, you may specify it in the following prompt." +msgstr "நீங்கள் பயர்பாக்ஸ் அல்லது குரோமியம் போன்ற இணைய உலாவியை விரும்பினால், அதை பின்வரும் வரியில் குறிப்பிடலாம்." + +msgid "Write additional packages to install (space separated, leave blank to skip): " +msgstr "நிறுவ கூடுதல் தொகுப்புகளை எழுதவும் (இடம் பிரிக்கப்பட்டது, தவிர்க்க காலியாக விடவும்): " + +msgid "Copy ISO network configuration to installation" +msgstr "நிறுவலுக்கு ISO பிணைய கட்டமைப்பு நகலெடுக்கவும்" + +msgid "Use NetworkManager (necessary to configure internet graphically in GNOME and KDE)" +msgstr "பயன்படுத்துங்கள் NetworkManager ஐப்(GNOME மற்றும் KDE இல் இணையத்தை வரைகலை முறையில் கட்டமைக்க அவசியம்)" + +msgid "Select one network interface to configure" +msgstr "கட்டமைக்க ஒரு பிணைய இடைமுகத்தைத் தேர்ந்தெடுக்கவும்" + +msgid "Select which mode to configure for \"{}\" or skip to use default mode \"{}\"" +msgstr "எந்த பயன்முறையை \"{}\" உள்ளமைக்க வேண்டும் என்பதைத் தேர்ந்தெடுக்கவும் அல்லது இயல்புநிலை பயன்முறை \"{}\" ஐப் பயன்படுத்த தவிர்க்கவும்" + +msgid "Enter the IP and subnet for {} (example: 192.168.0.5/24): " +msgstr "உள்ளிடுங்கள் IP மற்றும் சப்நெட்டை {}(எடுத்துக்காட்டு: 192.168.0.5/24): " + +msgid "Enter your gateway (router) IP address or leave blank for none: " +msgstr "உங்கள் நுழைவாயில் (திசைவி) IP முகவரியை உள்ளிடவும் அல்லது எதற்கும் காலியாக விடவும்: " + +msgid "Enter your DNS servers (space separated, blank for none): " +msgstr "உங்கள் DNS சேவையகங்களை உள்ளிடவும் (இடம் பிரிக்கப்பட்டது, எதற்கும் காலியாக இல்லை): " + +msgid "Select which filesystem your main partition should use" +msgstr "உங்கள் பிரதான பகிர்வு எந்த கோப்பு முறைமையைப் பயன்படுத்த வேண்டும் என்பதைத் தேர்ந்தெடுக்கவும்" + +msgid "Current partition layout" +msgstr "தற்போதைய பகிர்வு தளவமைப்பு" + +msgid "" +"Select what to do with\n" +"{}" +msgstr "" +"என்ன செய்ய வேண்டும் என்பதைத் தேர்ந்தெடுக்கவும்\n" +"{}" + +msgid "Enter a desired filesystem type for the partition" +msgstr "பகிர்வுக்கு தேவையான கோப்பு முறைமை வகையை உள்ளிடவும்" + +msgid "Enter the start sector (percentage or block number, default: {}): " +msgstr "தொடக்கப் பிரிவை உள்ளிடவும் (சதவீதம் அல்லது தொகுதி எண், இயல்புநிலை: {}): " + +msgid "Enter the end sector of the partition (percentage or block number, ex: {}): " +msgstr "பகிர்வின் இறுதிப் பகுதியை உள்ளிடவும் (சதவீதம் அல்லது தொகுதி எண், எ.கா: {}): " + +msgid "{} contains queued partitions, this will remove those, are you sure?" +msgstr "{} வரிசைப்படுத்தப்பட்ட பகிர்வுகளைக் கொண்டுள்ளது, இது அவற்றை அகற்றும், நீங்கள் உறுதியாக இருக்கிறீர்களா?" + +msgid "" +"{}\n" +"\n" +"Select by index which partitions to delete" +msgstr "" +"{}\n" +"\n" +"எந்த பகிர்வுகளை நீக்க வேண்டும் என்பதை குறியீட்டின் மூலம் தேர்ந்தெடுக்கவும்" + +msgid "" +"{}\n" +"\n" +"Select by index which partition to mount where" +msgstr "" +"{}\n" +"\n" +"எந்த பகிர்வை எங்கு ஏற்ற வேண்டும் என்பதை குறியீட்டு மூலம் தேர்ந்தெடுக்கவும்" + +msgid " * Partition mount-points are relative to inside the installation, the boot would be /boot as an example." +msgstr " * பகிர்வு மவுண்ட்-பாயிண்ட்கள் நிறுவலின் உள்ளே தொடர்புடையவை, துவக்கம் /boot எடுத்துக்காட்டாக இருக்கும்." + +msgid "Select where to mount partition (leave blank to remove mountpoint): " +msgstr "பகிர்வை எங்கு ஏற்ற வேண்டும் என்பதைத் தேர்ந்தெடுக்கவும் (மவுண்ட்பாயிண்டை அகற்ற காலியாக விடவும்): " + +msgid "" +"{}\n" +"\n" +"Select which partition to mask for formatting" +msgstr "" +"{}\n" +"\n" +"வடிவமைப்பிற்கு எந்த பகிர்வை மறைக்க வேண்டும் என்பதைத் தேர்ந்தெடுக்கவும்" + +msgid "" +"{}\n" +"\n" +"Select which partition to mark as encrypted" +msgstr "" +"{}\n" +"\n" +"எந்தப் பிரிவை மறைகுறியாக்கப்பட்டதாகக் குறிக்க வேண்டும் என்பதைத் தேர்ந்தெடுக்கவும்" + +msgid "" +"{}\n" +"\n" +"Select which partition to mark as bootable" +msgstr "" +"{}\n" +"\n" +"துவக்கக்கூடியதாகக் குறிக்கும் பகிர்வைத் தேர்ந்தெடுக்கவும்" + +msgid "" +"{}\n" +"\n" +"Select which partition to set a filesystem on" +msgstr "" +"{}\n" +"\n" +"கோப்பு முறைமையை எந்த பகிர்வில் அமைக்க வேண்டும் என்பதைத் தேர்ந்தெடுக்கவும்" + +msgid "Enter a desired filesystem type for the partition: " +msgstr "பகிர்வுக்கு தேவையான கோப்பு முறைமை வகையை உள்ளிடவும்: " + +msgid "Archinstall language" +msgstr "Archinstall மொழி" + +msgid "Wipe all selected drives and use a best-effort default partition layout" +msgstr "தேர்ந்தெடுக்கப்பட்ட அனைத்து இயக்கிகளையும் துடைத்து, சிறந்த முயற்சி இயல்புநிலை பகிர்வு அமைப்பைப் பயன்படுத்தவும்" + +msgid "Select what to do with each individual drive (followed by partition usage)" +msgstr "ஒவ்வொரு தனி இயக்ககத்தையும் என்ன செய்ய வேண்டும் என்பதைத் தேர்ந்தெடுக்கவும் (பகிர்வு உபயோகத்தைத் தொடர்ந்து)" + +msgid "Select what you wish to do with the selected block devices" +msgstr "தேர்ந்தெடுக்கப்பட்ட தொகுதி சாதனங்களில் நீங்கள் என்ன செய்ய விரும்புகிறீர்கள் என்பதைத் தேர்ந்தெடுக்கவும்" + +msgid "This is a list of pre-programmed profiles, they might make it easier to install things like desktop environments" +msgstr "இது முன்-திட்டமிடப்பட்ட சுயவிவரங்களின் பட்டியல், அவை டெஸ்க்டாப் சூழல்கள் போன்றவற்றை நிறுவுவதை எளிதாக்கலாம்" + +msgid "Select keyboard layout" +msgstr "விசைப்பலகை அமைப்பைத் தேர்ந்தெடுக்கவும்" + +msgid "Select one of the regions to download packages from" +msgstr "தொகுப்புகளை பதிவிறக்கம் செய்ய வேண்டிய பகுதிகளில் ஒன்றைத் தேர்ந்தெடுக்கவும்" + +msgid "Select one or more hard drives to use and configure" +msgstr "பயன்படுத்த மற்றும் கட்டமைக்க ஒன்று அல்லது அதற்கு மேற்பட்ட ஹார்டு டிரைவ்களைத் தேர்ந்தெடுக்கவும்" + +msgid "For the best compatibility with your AMD hardware, you may want to use either the all open-source or AMD / ATI options." +msgstr "உங்கள் AMD வன்பொருளுடன் சிறந்த இணக்கத்தன்மைக்கு, நீங்கள் அனைத்து திறந்த மூல அல்லது 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 "உங்கள் இன்டெல் வன்பொருளுடன் சிறந்த இணக்கத்தன்மைக்கு, நீங்கள் அனைத்து ஓப்பன் சோர்ஸ் அல்லது இன்டெல் விருப்பங்களையும் பயன்படுத்த விரும்பலாம்.\n" + +msgid "For the best compatibility with your Nvidia hardware, you may want to use the Nvidia proprietary driver.\n" +msgstr "உங்கள் Nvidia வன்பொருளுடன் சிறந்த இணக்கத்தன்மைக்கு, நீங்கள் Nvidia தனியுரிம இயக்கியைப் பயன்படுத்த விரும்பலாம்.\n" + +msgid "" +"\n" +"\n" +"Select a graphics driver or leave blank to install all open-source drivers" +msgstr "" +"\n" +"\n" +"கிராபிக்ஸ் இயக்கியைத் தேர்ந்தெடுக்கவும் அல்லது அனைத்து திறந்த மூல இயக்கிகளையும் நிறுவ காலியாக விடவும்" + +msgid "All open-source (default)" +msgstr "அனைத்தும் திறந்த-மூலம் (இயல்புநிலை)" + +msgid "Choose which kernels to use or leave blank for default \"{}\"" +msgstr "எந்த கர்னல்களைப் பயன்படுத்த வேண்டும் என்பதைத் தேர்வு செய்யவும் அல்லது இயல்புநிலைக்கு காலியாக விடவும் \"{}\"" + +msgid "Choose which locale language to use" +msgstr "எந்த லோகேல் மொழியைப் பயன்படுத்த வேண்டும் என்பதைத் தேர்ந்தெடுக்கவும்" + +msgid "Choose which locale encoding to use" +msgstr "எந்த லோகேல் என்கோடிங்கைப் பயன்படுத்த வேண்டும் என்பதைத் தேர்வுசெய்யவும்" + +msgid "Select one of the values shown below: " +msgstr "கீழே காட்டப்பட்டுள்ள மதிப்புகளில் ஒன்றைத் தேர்ந்தெடுக்கவும்: " + +msgid "Select one or more of the options below: " +msgstr "கீழே உள்ள விருப்பங்களில் ஒன்று அல்லது அதற்கு மேற்பட்டவற்றைத் தேர்ந்தெடுக்கவும்: " + +msgid "Adding partition...." +msgstr "பகிர்வை சேர்க்கிறது...." + +msgid "You need to enter a valid fs-type in order to continue. See `man parted` for valid fs-type's." +msgstr "தொடர, நீங்கள் செல்லுபடியாகும் fs-type உள்ளிட வேண்டும். செல்லுபடியாகும் fs-type'sக்கு `man parted` என்பதைப் பார்க்கவும்." + +msgid "Error: Listing profiles on URL \"{}\" resulted in:" +msgstr "பிழை: URL \"{}\" இல் சுயவிவரங்களை பட்டியலிடுவதால் விளைவித்தது:" + +msgid "Error: Could not decode \"{}\" result as JSON:" +msgstr "பிழை: \"{}\" முடிவை JSON ஆக டிகோட் செய்ய முடியவில்லை:" + +msgid "Keyboard layout" +msgstr "விசைப்பலகை அமைப்பு" + +msgid "Mirror region" +msgstr "மிரர் பிராந்தியம்" + +msgid "Locale language" +msgstr "லோகேல் மொழி" + +msgid "Locale encoding" +msgstr "லோகேல் என்கோடிங்" + +msgid "Drive(s)" +msgstr "இயக்கி(கள்)" + +msgid "Disk layout" +msgstr "வட்டு தளவமைப்பு" + +msgid "Encryption password" +msgstr "குறியாக்கம் கடவுச்சொல்" + +msgid "Swap" +msgstr "இடமாற்று" + +msgid "Bootloader" +msgstr "துவக்க ஏற்றி" + +msgid "Root password" +msgstr "ரூட் கடவுச்சொல்" + +msgid "Superuser account" +msgstr "சூப்பர் யூசர் கணக்கு" + +msgid "User account" +msgstr "பயனர் கணக்கு" + +msgid "Profile" +msgstr "சுயவிவரம்" + +msgid "Audio" +msgstr "ஆடியோ" + +msgid "Kernels" +msgstr "கர்னல்கள்" + +msgid "Additional packages" +msgstr "கூடுதல் தொகுப்புகள்" + +msgid "Network configuration" +msgstr "பிணைய கட்டமைப்பு" + +msgid "Automatic time sync (NTP)" +msgstr "தானியங்கி நேர ஒத்திசைவு (NTP)" + +msgid "Install ({} config(s) missing)" +msgstr "நிறுவு ({} config(கள்) இல்லை)" + +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 "" +"ஹார்ட் டிரைவ் தேர்வைத் தவிர்க்க முடிவு செய்துள்ளீர்கள்\n" +"மற்றும் {} (சோதனை) இல் ஏற்றப்பட்ட எந்த இயக்கி அமைப்பையும் பயன்படுத்தும்\n" +"எச்சரிக்கை: இந்த அமைப்பின் பொருத்தத்தை Archinstall சரிபார்க்காது\n" +"நீங்கள் தொடர விரும்புகிறீர்களா?" + +msgid "Re-using partition instance: {}" +msgstr "பகிர்வு நிகழ்வை மீண்டும் பயன்படுத்துதல்: {}" + +msgid "Create a new partition" +msgstr "புதிய பகிர்வை உருவாக்கவும்" + +msgid "Delete a partition" +msgstr "ஒரு பகிர்வை நீக்கவும்" + +msgid "Clear/Delete all partitions" +msgstr "அழிக்கவும்/நீக்கவும் அனைத்து பகிர்வுகளை" + +msgid "Assign mount-point for a partition" +msgstr "ஒரு பகிர்வுக்கு ஏற்ற-புள்ளியை ஒதுக்கவும்" + +msgid "Mark/Unmark a partition to be formatted (wipes data)" +msgstr "குறி/குறிநீக்கு வடிவமைக்கப்பட வேண்டிய பகிர்வை (தரவை அழிக்கிறது)" + +msgid "Mark/Unmark a partition as encrypted" +msgstr "குறி/குறி நீக்கு ஒரு பகிர்வு மறைகுறியாக்கப்பட்டது" + +msgid "Mark/Unmark a partition as bootable (automatic for /boot)" +msgstr "குறி/குறிநீக்கு ஒரு பகிர்வை துவக்கக்கூடியதாக(/boot க்கு தானியங்கு)" + +msgid "Set desired filesystem for a partition" +msgstr "ஒரு பகிர்வுக்கு தேவையான கோப்பு முறைமையை அமைக்கவும்" + +msgid "Abort" +msgstr "கைவிடு" + +msgid "Hostname" +msgstr "ஹோஸ்ட் பெயர்" + +msgid "Not configured, unavailable unless setup manually" +msgstr "உள்ளமைக்கப்படவில்லை, கைமுறையாக அமைக்கும் வரை கிடைக்காது" + +msgid "Timezone" +msgstr "நேரம் மண்டலம்" + +msgid "Set/Modify the below options" +msgstr "கீழே உள்ள விருப்பங்களை அமைக்கவும்/மாற்றவும்" + +msgid "Install" +msgstr "நிறுவு" + +msgid "" +"Use ESC to skip\n" +"\n" +msgstr "" +"தவிர்க்க ESC ஐப் பயன்படுத்தவும்\n" +"\n" + +msgid "Suggest partition layout" +msgstr "பகிர்வு தளவமைப்பை பரிந்துரைக்கவும்" + +msgid "Enter a password: " +msgstr "கடவுச்சொல்லை உள்ளிடவும்: " + +msgid "Enter a encryption password for {}" +msgstr "{}க்கான என்க்ரிப்ஷன் கடவுச்சொல்லை உள்ளிடவும்" + +msgid "Enter disk encryption password (leave blank for no encryption): " +msgstr "வட்டு குறியாக்க கடவுச்சொல்லை உள்ளிடவும் (குறியாக்கம் இல்லாமல் இருப்பதற்கு காலியாக விடவும்): " + +msgid "Create a required super-user with sudo privileges: " +msgstr "சூடோ சலுகைகளுடன் தேவையான சூப்பர் பயனரை உருவாக்கவும்: " + +msgid "Enter root password (leave blank to disable root): " +msgstr "ரூட் கடவுச்சொல்லை உள்ளிடவும் (ரூட்டை முடக்க காலியாக விடவும்): " + +msgid "Password for user \"{}\": " +msgstr "\"{}\" பயனருக்கான கடவுச்சொல்: " + +msgid "Verifying that additional packages exist (this might take a few seconds)" +msgstr "கூடுதல் தொகுப்புகள் உள்ளனவா என்று சரிபார்க்கிறது (இதற்கு சில வினாடிகள் ஆகலாம்)" + +msgid "Would you like to use automatic time synchronization (NTP) with the default time servers?\n" +msgstr "இயல்புநிலை நேர சேவையகங்களுடன் தானியங்கி நேர ஒத்திசைவை (NTP) பயன்படுத்த விரும்புகிறீர்களா?\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 "" +"NTP வேலை செய்ய வன்பொருள் நேரம் மற்றும் பிற பிந்தைய கட்டமைப்பு படிகள் தேவைப்படலாம்.\n" +"மேலும் தகவலுக்கு, ஆர்ச் விக்கியைப் பார்க்கவும்" + +msgid "Enter a username to create an additional user (leave blank to skip): " +msgstr "கூடுதல் பயனரை உருவாக்க பயனர்பெயரை உள்ளிடவும் (தவிர்க்க காலியாக விடவும்): " + +msgid "Use ESC to skip\n" +msgstr "தவிர்க்க ESC ஐப் பயன்படுத்தவும்\n" + +msgid "" +"\n" +" Choose an object from the list, and select one of the available actions for it to execute" +msgstr "" +"\n" +"பட்டியலிலிருந்து ஒரு பொருளைத் தேர்வுசெய்து, அதைச் செயல்படுத்த கிடைக்கக்கூடிய செயல்களில் ஒன்றைத் தேர்ந்தெடுக்கவும்" + +msgid "Cancel" +msgstr "ரத்து செய்" + +msgid "Confirm and exit" +msgstr "உறுதி செய்து வெளியேறவும்" + +msgid "Add" +msgstr "சேர்" + +msgid "Copy" +msgstr "நகல்" + +msgid "Edit" +msgstr "தொகு" + +msgid "Delete" +msgstr "அழி" + +msgid "Select an action for '{}'" +msgstr "'{}'க்கான செயலைத் தேர்ந்தெடுக்கவும்" + +msgid "Copy to new key:" +msgstr "புதிய விசைக்கு நகலெடு:" + +msgid "Unknown nic type: {}. Possible values are {}" +msgstr "அறியப்படாத nic வகை: {}. சாத்தியமான மதிப்புகள் {} ஆகும்" + +msgid "" +"\n" +"This is your chosen configuration:" +msgstr "" +"\n" +"இது நீங்கள் தேர்ந்தெடுத்த கட்டமைப்பு:" + +msgid "Pacman is already running, waiting maximum 10 minutes for it to terminate." +msgstr "பேக்மேன் ஏற்கனவே இயங்கி வருகிறது, அது முடிவடைவதற்கு அதிகபட்சம் 10 நிமிடங்கள் காத்திருக்கிறது." + +msgid "Pre-existing pacman lock never exited. Please clean up any existing pacman sessions before using archinstall." +msgstr "முன்பே இருக்கும் பேக்மேன் பூட்டு ஒருபோதும் வெளியேறவில்லை. archinstall ஐப் பயன்படுத்துவதற்கு முன், ஏற்கனவே உள்ள பேக்மேன் அமர்வுகளை சுத்தம் செய்யவும்." + +msgid "Choose which optional additional repositories to enable" +msgstr "எந்த விருப்ப கூடுதல் களஞ்சியங்களை இயக்க வேண்டும் என்பதை தேர்வு செய்யவும்" + +msgid "Add a user" +msgstr "ஒரு பயனரைச் சேர்க்கவும்" + +msgid "Change password" +msgstr "கடவுச்சொல்லை மாற்று" + +msgid "Promote/Demote user" +msgstr "பயனரை உயர்த்து/பதவி இறக்கு" + +msgid "Delete User" +msgstr "பயனரை நீக்கு" + +msgid "" +"\n" +"Define a new user\n" +msgstr "" +"\n" +"புதிய பயனரை வரையறுக்கவும்\n" + +msgid "User Name : " +msgstr "பயனர் பெயர்: " + +msgid "Should {} be a superuser (sudoer)?" +msgstr "{} ஒரு சூப்பர் யூசராக (sudoer) இருக்க வேண்டுமா?" + +msgid "Define users with sudo privilege: " +msgstr "சூடோ சிறப்புரிமை கொண்ட பயனர்களை வரையறுக்கவும்: " + +msgid "No network configuration" +msgstr "பிணைய கட்டமைப்பு இல்லை" + +msgid "Set desired subvolumes on a btrfs partition" +msgstr "ஒரு btrfs பகிர்வில் விரும்பிய துணை தொகுதிகளை அமைக்கவும்" + +msgid "" +"{}\n" +"\n" +"Select which partition to set subvolumes on" +msgstr "" +"{}\n" +"\n" +"எந்த பகிர்வில் துணைத்தொகுதிகளை அமைக்க வேண்டும் என்பதைத் தேர்ந்தெடுக்கவும்" + +msgid "Manage btrfs subvolumes for current partition" +msgstr "தற்போதைய பகிர்வுக்கு btrfs துணை தொகுதிகளை நிர்வகிக்கவும்" + +msgid "No configuration" +msgstr "கட்டமைப்பு இல்லை" + +msgid "Save user configuration" +msgstr "பயனர் உள்ளமைவைச் சேமிக்கவும்" + +msgid "Save user credentials" +msgstr "பயனர் நற்சான்றிதழ்களைச் சேமிக்கவும்" + +msgid "Save disk layout" +msgstr "வட்டு அமைப்பைச் சேமிக்கவும்" + +msgid "Save all" +msgstr "அனைத்தையும் சேமிக்கவும்" + +msgid "Choose which configuration to save" +msgstr "எந்த அமைப்பைச் சேமிக்க வேண்டும் என்பதைத் தேர்ந்தெடுக்கவும்" + +msgid "Enter a directory for the configuration(s) to be saved: " +msgstr "உள்ளமைவு(களை) சேமிக்க ஒரு கோப்பகத்தை உள்ளிடவும்: " + +msgid "Not a valid directory: {}" +msgstr "சரியான கோப்பகம் இல்லை: {}" + +msgid "The password you are using seems to be weak," +msgstr "நீங்கள் பயன்படுத்தும் கடவுச்சொல் பலவீனமாக உள்ளது," + +msgid "are you sure you want to use it?" +msgstr "நீங்கள் நிச்சயமாக அதைப் பயன்படுத்த விரும்புகிறீர்களா?" + +msgid "Optional repositories" +msgstr "விருப்ப களஞ்சியங்கள்" + +msgid "Save configuration" +msgstr "உள்ளமைவைச் சேமிக்கவும்" + +msgid "Missing configurations:\n" +msgstr "விடுபட்ட கட்டமைப்புகள்:\n" + +msgid "Either root-password or at least 1 superuser must be specified" +msgstr "ரூட்-கடவுச்சொல் அல்லது குறைந்தபட்சம் 1 சூப்பர் யூசர் குறிப்பிடப்பட வேண்டும்" + +msgid "Manage superuser accounts: " +msgstr "சூப்பர் யூசர் கணக்குகளை நிர்வகிக்கவும்: " + +msgid "Manage ordinary user accounts: " +msgstr "சாதாரண பயனர் கணக்குகளை நிர்வகிக்கவும்: " + +msgid " Subvolume :{:16}" +msgstr " துணைத் தொகுதி :{:16}" + +msgid " mounted at {:16}" +msgstr " {:16} இல் ஏற்றப்பட்டது" + +msgid " with option {}" +msgstr " விருப்பம் உடன் {}" + +msgid "" +"\n" +" Fill the desired values for a new subvolume \n" +msgstr "" +"\n" +"புதிய துணைத்தொகுதிக்கு தேவையான மதிப்புகளை நிரப்பவும்\n" + +msgid "Subvolume name " +msgstr "துணைத்தொகுதி பெயர் " + +msgid "Subvolume mountpoint" +msgstr "துணை தொகுதி மவுண்ட்பாயிண்ட்" + +msgid "Subvolume options" +msgstr "துணை தொகுதி விருப்பங்கள்" + +msgid "Save" +msgstr "சேமிக்கவும்" + +msgid "Subvolume name :" +msgstr "துணைத்தொகுதி பெயர்:" + +msgid "Select a mount point :" +msgstr "மவுண்ட் பாயிண்ட்டைத் தேர்ந்தெடுக்கவும்:" + +msgid "Select the desired subvolume options " +msgstr "தேவையான துணை தொகுதி விருப்பங்களைத் தேர்ந்தெடுக்கவும் " + +msgid "Define users with sudo privilege, by username: " +msgstr "சூடோ சிறப்புரிமை கொண்ட பயனர்களை, பயனர் பெயரால் வரையறுக்கவும்: " + +msgid "[!] A log file has been created here: {}" +msgstr "[!] ஒரு பதிவு கோப்பு இங்கே உருவாக்கப்பட்டது: {}" + +msgid "Would you like to use BTRFS subvolumes with a default structure?" +msgstr "இயல்புநிலை கட்டமைப்புடன் BTRFS துணைத்தொகுதிகளைப் பயன்படுத்த விரும்புகிறீர்களா?" + +msgid "Would you like to use BTRFS compression?" +msgstr "BTRFS சுருக்கத்தைப் பயன்படுத்த விரும்புகிறீர்களா?" + +msgid "Would you like to create a separate partition for /home?" +msgstr "/home க்கு தனி பகிர்வை உருவாக்க விரும்புகிறீர்களா?" + +msgid "The selected drives do not have the minimum capacity required for an automatic suggestion\n" +msgstr "தேர்ந்தெடுக்கப்பட்ட டிரைவ்களில் தானியங்கி பரிந்துரைக்குத் தேவையான குறைந்தபட்ச திறன் இல்லை\n" + +msgid "Minimum capacity for /home partition: {}GB\n" +msgstr "/home பகிர்வுக்கான குறைந்த பட்ச கொள்ளளவு: {}GB\n" + +msgid "Minimum capacity for Arch Linux partition: {}GB" +msgstr "ஆர்ச் லினக்ஸ் பகிர்வுக்கான குறைந்தபட்ச கொள்ளளவு: {}GB" + +msgid "Continue" +msgstr "தொடரவும்" + +msgid "yes" +msgstr "ஆமாம்" + +msgid "no" +msgstr "இல்லை" + +msgid "set: {}" +msgstr "அமை: {}" + +msgid "Manual configuration setting must be a list" +msgstr "கைமுறை உள்ளமைவு அமைப்பு கண்டிப்பாக ஒரு பட்டியலாக இருக்க வேண்டும்" + +msgid "No iface specified for manual configuration" +msgstr "கைமுறை உள்ளமைவுக்கு iface எதுவும் குறிப்பிடப்படவில்லை" + +msgid "Manual nic configuration with no auto DHCP requires an IP address" +msgstr "தானியங்கு DHCP இல்லாத கைமுறையான nic கட்டமைப்பிற்கு IP முகவரி தேவை" + +msgid "Add interface" +msgstr "இடைமுகத்தைச் சேர்க்கவும்" + +msgid "Edit interface" +msgstr "இடைமுகத்தை திருத்தவும்" + +msgid "Delete interface" +msgstr "இடைமுகத்தை நீக்கு" + +msgid "Select interface to add" +msgstr "சேர்க்க இடைமுகத்தைத் தேர்ந்தெடுக்கவும்" + +msgid "Manual configuration" +msgstr "கைமுறை கட்டமைப்பு" + +msgid "Mark/Unmark a partition as compressed (btrfs only)" +msgstr "ஒரு பகிர்வை சுருக்கப்பட்டதாகக் குறிக்கவும்/குறி நீக்கவும் (btrfs மட்டும்)" + +msgid "The password you are using seems to be weak, are you sure you want to use it?" +msgstr "நீங்கள் பயன்படுத்தும் கடவுச்சொல் பலவீனமாக இருப்பதாகத் தெரிகிறது, நிச்சயமாக அதைப் பயன்படுத்த விரும்புகிறீர்களா?" + +msgid "Provides a selection of desktop environments and tiling window managers, e.g. gnome, kde, sway" +msgstr "டெஸ்க்டாப் சூழல்கள் மற்றும் டைலிங் சாளர மேலாளர்களின் தேர்வை வழங்குகிறது, எ.கா. gnome, kde, sway" + +msgid "Select your desired desktop environment" +msgstr "நீங்கள் விரும்பும் டெஸ்க்டாப் சூழலைத் தேர்ந்தெடுக்கவும்" + +msgid "A very basic installation that allows you to customize Arch Linux as you see fit." +msgstr "ஆர்ச் லினக்ஸை நீங்கள் பொருத்தமாகத் தனிப்பயனாக்க அனுமதிக்கும் மிக அடிப்படையான நிறுவல்." + +msgid "Provides a selection of various server packages to install and enable, e.g. httpd, nginx, mariadb" +msgstr "நிறுவவும் இயக்கவும் பல்வேறு சர்வர் தொகுப்புகளின் தேர்வை வழங்குகிறது, எ.கா. httpd, nginx, mariadb" + +msgid "Choose which servers to install, if none then a minimal installation will be done" +msgstr "எந்த சேவையகங்களை நிறுவ வேண்டும் என்பதைத் தேர்வுசெய்யவும், எதுவும் இல்லை என்றால், குறைந்தபட்ச நிறுவல் செய்யப்படும்" + +msgid "Installs a minimal system as well as xorg and graphics drivers." +msgstr "குறைந்தபட்ச அமைப்பு மற்றும் xorg மற்றும் கிராபிக்ஸ் இயக்கிகளை நிறுவுகிறது." + +msgid "Press Enter to continue." +msgstr "தொடர Enter ஐ அழுத்தவும்." + +msgid "Would you like to chroot into the newly created installation and perform post-installation configuration?" +msgstr "புதிதாக உருவாக்கப்பட்ட நிறுவலில் chroot செய்து, நிறுவலுக்குப் பிந்தைய உள்ளமைவைச் செய்ய விரும்புகிறீர்களா?" + +msgid "Are you sure you want to reset this setting?" +msgstr "இஇந்த அமைப்பை நிச்சயமாக மீட்டமைக்க வேண்டுமா?" + +msgid "Select one or more hard drives to use and configure\n" +msgstr "பயன்படுத்த மற்றும் கட்டமைக்க ஒன்று அல்லது அதற்கு மேற்பட்ட ஹார்டு டிரைவ்களைத் தேர்ந்தெடுக்கவும்\n" + +msgid "Any modifications to the existing setting will reset the disk layout!" +msgstr "ஏற்கனவே உள்ள அமைப்பில் ஏதேனும் மாற்றங்கள் செய்தால் வட்டு தளவமைப்பை மீட்டமைக்கும்!" + +msgid "If you reset the harddrive selection this will also reset the current disk layout. Are you sure?" +msgstr "நீங்கள் ஹார்ட் டிரைவ் தேர்வை மீட்டமைத்தால், இது தற்போதைய வட்டு அமைப்பையும் மீட்டமைக்கும். நீங்கள் உறுதியாக இருக்கிறீர்களா?" + +msgid "Save and exit" +msgstr "சேமித்து விட்டு வெளியேறவும்" + +msgid "" +"{}\n" +"contains queued partitions, this will remove those, are you sure?" +msgstr "" +"{}\n" +"வரிசைப்படுத்தப்பட்ட பகிர்வுகளைக் கொண்டுள்ளது, இது அவற்றை அகற்றும், நீங்கள் உறுதியாக இருக்கிறீர்களா?" + +msgid "No audio server" +msgstr "ஆடியோ சர்வர் இல்லை" + +msgid "(default)" +msgstr "(இயல்புநிலை)" + +msgid "Use ESC to skip" +msgstr "தவிர்க்க ESC ஐப் பயன்படுத்தவும்" + +msgid "" +"Use CTRL+C to reset current selection\n" +"\n" +msgstr "" +"தற்போதைய தேர்வை மீட்டமைக்க CTRL+C ஐப் பயன்படுத்தவும்\n" +"\n" + +msgid "Copy to: " +msgstr "இதற்கு நகலெடுக்கவும்: " + +msgid "Edit: " +msgstr "தொகு: " + +msgid "Key: " +msgstr "சாவி: " + +msgid "Edit {}: " +msgstr "தொகு {}: " + +msgid "Add: " +msgstr "சேர்: " + +msgid "Value: " +msgstr "மதிப்பு: " + +msgid "You can skip selecting a drive and partitioning and use whatever drive-setup is mounted at /mnt (experimental)" +msgstr "நீங்கள் ஒரு இயக்கி மற்றும் பகிர்வைத் தேர்ந்தெடுப்பதைத் தவிர்க்கலாம் மற்றும் /mnt (பரிசோதனை) இல் ஏற்றப்பட்ட எந்த இயக்கி அமைப்பையும் பயன்படுத்தலாம்" + +msgid "Select one of the disks or skip and use /mnt as default" +msgstr "வட்டுகளில் ஒன்றைத் தேர்ந்தெடுக்கவும் அல்லது தவிர்க்கவும் மற்றும் /mnt ஐ இயல்புநிலையாகப் பயன்படுத்தவும்" + +msgid "Select which partitions to mark for formatting:" +msgstr "வடிவமைப்பிற்காக எந்தப் பகிர்வுகளைக் குறிக்க வேண்டும் என்பதைத் தேர்ந்தெடுக்கவும்:" + +msgid "Use HSM to unlock encrypted drive" +msgstr "மறைகுறியாக்கப்பட்ட இயக்ககத்தைத் திறக்க HSM ஐப் பயன்படுத்தவும்" + +msgid "Device" +msgstr "சாதனம்" + +msgid "Size" +msgstr "அளவு" + +msgid "Free space" +msgstr "பயன்படுத்தாத இடம்" + +msgid "Bus-type" +msgstr "பேருந்து-வகை" + +msgid "Either root-password or at least 1 user with sudo privileges must be specified" +msgstr "ரூட்-கடவுச்சொல் அல்லது குறைந்தபட்சம் 1 பயனர் சூடோ சிறப்புரிமைகளைக் குறிப்பிட வேண்டும்" + +msgid "Enter username (leave blank to skip): " +msgstr "பயனர்பெயரை உள்ளிடவும் (தவிர்க்க காலியாக விடவும்): " + +msgid "The username you entered is invalid. Try again" +msgstr "நீங்கள் உள்ளிட்ட பயனர்பெயர் தவறானது. மீண்டும் முயற்சிக்கவும்" + +msgid "Should \"{}\" be a superuser (sudo)?" +msgstr "\"{}\" ஒரு சூப்பர் யூசராக (sudo) இருக்க வேண்டுமா?" + +msgid "Select which partitions to encrypt:" +msgstr "குறியாக்கம் செய்ய வேண்டிய பகிர்வுகளைத் தேர்ந்தெடுக்கவும்:" + +msgid "very weak" +msgstr "மிகவும் பலவீனமானது" + +msgid "weak" +msgstr "பலவீனமான" + +msgid "moderate" +msgstr "மிதமான" + +msgid "strong" +msgstr "வலுவான" + +msgid "Add subvolume" +msgstr "துணைத்தொகுதியைச் சேர்க்கவும்" + +msgid "Edit subvolume" +msgstr "துணைத்தொகுதியைத் திருத்தவும்" + +msgid "Delete subvolume" +msgstr "துணைத்தொகுதியை நீக்கவும்" + +msgid "Configured {} interfaces" +msgstr "கட்டமைக்கப்பட்ட {} இடைமுகங்கள்" + +msgid "Parallel Downloads" +msgstr "இணையான பதிவிறக்கங்கள்" + +msgid "This option enables the number of parallel downloads that can occur during installation" +msgstr "இந்த விருப்பம் நிறுவலின் போது நிகழக்கூடிய இணையான பதிவிறக்கங்களின் எண்ணிக்கையை செயல்படுத்துகிறது" + +#, python-brace-format +msgid "" +"Enter the number of parallel downloads to be enabled.\n" +" (Enter a value between 1 to {max_downloads})\n" +"Note:" +msgstr "" +"இயக்கப்பட வேண்டிய இணையான பதிவிறக்கங்களின் எண்ணிக்கையை உள்ளிடவும்.\n" +" (1 முதல் {max_downloads} வரையிலான மதிப்பை உள்ளிடவும்)\n" +"குறிப்பு:" + +msgid " - Maximum value : {max_downloads} ( Allows {max_downloads} parallel downloads, allows {max_downloads+1} downloads at a time )" +msgstr " - அதிகபட்ச மதிப்பு : {max_downloads} ( {max_downloads} இணையான பதிவிறக்கங்களை அனுமதிக்கிறது, ஒரே நேரத்தில் {max_downloads+1} பதிவிறக்கங்களை அனுமதிக்கிறது )" + +msgid " - Minimum value : 1 ( Allows 1 parallel download, allows 2 downloads at a time )" +msgstr " - குறைந்தபட்ச மதிப்பு : 1 (1 இணை பதிவிறக்கத்தை அனுமதிக்கிறது, ஒரு நேரத்தில் 2 பதிவிறக்கங்களை அனுமதிக்கிறது )" + +msgid " - Disable/Default : 0 ( Disables parallel downloading, allows only 1 download at a time )" +msgstr " - முடக்கு/இயல்புநிலை: 0 (இணை பதிவிறக்கத்தை முடக்குகிறது, ஒரு நேரத்தில் 1 பதிவிறக்கத்தை மட்டுமே அனுமதிக்கிறது )" + +#, python-brace-format +msgid "Invalid input! Try again with a valid input [1 to {max_downloads}, or 0 to disable]" +msgstr "தவறான உள்ளீடு! சரியான உள்ளீட்டில் [1 முதல் {max_downloads} வரை அல்லது முடக்க 0 வரை] மீண்டும் முயற்சிக்கவும்" -- cgit v1.2.3-54-g00ecf From fa53ce9ab8a8525d5db1971a0fe83ac098440135 Mon Sep 17 00:00:00 2001 From: Alexmelman88 <99257010+Alexmelman88@users.noreply.github.com> Date: Mon, 5 Sep 2022 14:32:29 +0300 Subject: Update ru locale (#1455) * Update languages.json * Update base.po * Add files via upload * Update README.md --- README.md | 2 +- archinstall/locales/languages.json | 2 +- archinstall/locales/ru/LC_MESSAGES/base.mo | Bin 33398 -> 33483 bytes archinstall/locales/ru/LC_MESSAGES/base.po | 2 +- 4 files changed, 3 insertions(+), 3 deletions(-) (limited to 'archinstall') diff --git a/README.md b/README.md index 7a087dcb..e4d368cc 100644 --- a/README.md +++ b/README.md @@ -54,7 +54,7 @@ Português Svenska Türk čeština -русский +Русский اردو Ελληνικά தமிழ் diff --git a/archinstall/locales/languages.json b/archinstall/locales/languages.json index 0f8fe34c..090590cb 100644 --- a/archinstall/locales/languages.json +++ b/archinstall/locales/languages.json @@ -134,7 +134,7 @@ {"abbr": "rm", "lang": "Romansh"}, {"abbr": "ro", "lang": "Romanian"}, {"abbr": "rn", "lang": "Rundi"}, - {"abbr": "ru", "lang": "Russian", "translated_lang": "русский"}, + {"abbr": "ru", "lang": "Russian", "translated_lang": "Русский"}, {"abbr": "sg", "lang": "Sango"}, {"abbr": "sa", "lang": "Sanskrit"}, {"abbr": "si", "lang": "Sinhala"}, diff --git a/archinstall/locales/ru/LC_MESSAGES/base.mo b/archinstall/locales/ru/LC_MESSAGES/base.mo index 0930b800..6c0f8450 100644 Binary files a/archinstall/locales/ru/LC_MESSAGES/base.mo and b/archinstall/locales/ru/LC_MESSAGES/base.mo differ diff --git a/archinstall/locales/ru/LC_MESSAGES/base.po b/archinstall/locales/ru/LC_MESSAGES/base.po index ad568e06..a88c58a1 100644 --- a/archinstall/locales/ru/LC_MESSAGES/base.po +++ b/archinstall/locales/ru/LC_MESSAGES/base.po @@ -789,7 +789,7 @@ msgid "Delete subvolume" msgstr "Удалить подтом" msgid "Configured {} interfaces" -msgstr "" +msgstr "Настроено интерфейсов: {}" #, python-brace-format #~ msgid "Edit {origkey} :" -- cgit v1.2.3-54-g00ecf From 24d478d037dd24dd8e05f580e8ee5e4f5f53ad03 Mon Sep 17 00:00:00 2001 From: Wise Date: Tue, 6 Sep 2022 08:28:46 +0200 Subject: Fix Turkish local typos (#1459) * Update languages.json Little typo fix * Update README.md Little typo fix --- README.md | 2 +- archinstall/locales/languages.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'archinstall') diff --git a/README.md b/README.md index e4d368cc..0027991d 100644 --- a/README.md +++ b/README.md @@ -52,7 +52,7 @@ Polskie Portugues do Brasil Português Svenska -Türk +Türkçe čeština Русский اردو diff --git a/archinstall/locales/languages.json b/archinstall/locales/languages.json index 090590cb..55ddf57e 100644 --- a/archinstall/locales/languages.json +++ b/archinstall/locales/languages.json @@ -166,7 +166,7 @@ {"abbr": "tn", "lang": "Tswana"}, {"abbr": "ts", "lang": "Tsonga"}, {"abbr": "tk", "lang": "Turkmen"}, - {"abbr": "tr", "lang": "Turkish", "translated_lang" : "Türk"}, + {"abbr": "tr", "lang": "Turkish", "translated_lang" : "Türkçe"}, {"abbr": "tw", "lang": "Twi"}, {"abbr": "ug", "lang": "Uighur"}, {"abbr": "uk", "lang": "Ukrainian"}, -- cgit v1.2.3-54-g00ecf From 4dcd5e684f9461145c5b8656b1a91f99ace26b27 Mon Sep 17 00:00:00 2001 From: Daniel Girtler Date: Tue, 6 Sep 2022 16:31:08 +1000 Subject: Move deserialization into init (#1456) Co-authored-by: Daniel Girtler --- archinstall/__init__.py | 15 +- archinstall/lib/menu/global_menu.py | 57 +++----- archinstall/lib/translationhandler.py | 50 ++++++- archinstall/locales/ar/LC_MESSAGES/base.po | 192 ++++++++++++-------------- archinstall/locales/base.pot | 36 +++++ archinstall/locales/cs/LC_MESSAGES/base.po | 26 ++++ archinstall/locales/de/LC_MESSAGES/base.po | 26 ++++ archinstall/locales/el/LC_MESSAGES/base.po | 6 +- archinstall/locales/en/LC_MESSAGES/base.po | 26 ++++ archinstall/locales/es/LC_MESSAGES/base.po | 26 ++++ archinstall/locales/fr/LC_MESSAGES/base.po | 26 ++++ archinstall/locales/it/LC_MESSAGES/base.po | 26 ++++ archinstall/locales/nl/LC_MESSAGES/base.po | 26 ++++ archinstall/locales/pl/LC_MESSAGES/base.po | 26 ++++ archinstall/locales/pt/LC_MESSAGES/base.po | 26 ++++ archinstall/locales/pt_BR/LC_MESSAGES/base.po | 27 +++- archinstall/locales/ru/LC_MESSAGES/base.po | 26 ++++ archinstall/locales/sv/LC_MESSAGES/base.po | 26 ++++ archinstall/locales/ta/LC_MESSAGES/base.po | 6 +- archinstall/locales/tr/LC_MESSAGES/base.po | 26 ++++ archinstall/locales/ur/LC_MESSAGES/base.po | 26 ++++ examples/swiss.py | 2 +- 22 files changed, 581 insertions(+), 148 deletions(-) (limited to 'archinstall') diff --git a/archinstall/__init__.py b/archinstall/__init__.py index 184097b1..4e1e6d6d 100644 --- a/archinstall/__init__.py +++ b/archinstall/__init__.py @@ -195,40 +195,53 @@ def get_arguments() -> Dict[str, Any]: return config def load_config(): - from .lib.models import NetworkConfiguration """ refine and set some arguments. Formerly at the scripts """ + from .lib.models import NetworkConfiguration + + if (archinstall_lang := arguments.get('archinstall-language', None)) is not None: + arguments['archinstall-language'] = TranslationHandler().get_language_by_name(archinstall_lang) + if arguments.get('harddrives', None) is not None: if type(arguments['harddrives']) is str: arguments['harddrives'] = arguments['harddrives'].split(',') arguments['harddrives'] = [BlockDevice(BlockDev) for BlockDev in arguments['harddrives']] # Temporarily disabling keep_partitions if config file is loaded # Temporary workaround to make Desktop Environments work + if arguments.get('profile', None) is not None: if type(arguments.get('profile', None)) is dict: arguments['profile'] = Profile(None, arguments.get('profile', None)['path']) else: arguments['profile'] = Profile(None, arguments.get('profile', None)) + storage['_desktop_profile'] = arguments.get('desktop-environment', None) + if arguments.get('mirror-region', None) is not None: if type(arguments.get('mirror-region', None)) is dict: arguments['mirror-region'] = arguments.get('mirror-region', None) else: selected_region = arguments.get('mirror-region', None) arguments['mirror-region'] = {selected_region: list_mirrors()[selected_region]} + if arguments.get('sys-language', None) is not None: arguments['sys-language'] = arguments.get('sys-language', 'en_US') + if arguments.get('sys-encoding', None) is not None: arguments['sys-encoding'] = arguments.get('sys-encoding', 'utf-8') + if arguments.get('gfx_driver', None) is not None: storage['gfx_driver_packages'] = AVAILABLE_GFX_DRIVERS.get(arguments.get('gfx_driver', None), None) + if arguments.get('servers', None) is not None: storage['_selected_servers'] = arguments.get('servers', None) + if arguments.get('nic', None) is not None: handler = NetworkConfigurationHandler() handler.parse_arguments(arguments.get('nic')) arguments['nic'] = handler.configuration + if arguments.get('!users', None) is not None or arguments.get('!superusers', None) is not None: users = arguments.get('!users', None) superusers = arguments.get('!superusers', None) diff --git a/archinstall/lib/menu/global_menu.py b/archinstall/lib/menu/global_menu.py index fc7c90bc..d1bec189 100644 --- a/archinstall/lib/menu/global_menu.py +++ b/archinstall/lib/menu/global_menu.py @@ -3,54 +3,41 @@ from __future__ import annotations from typing import Any, List, Optional, Union, Dict, TYPE_CHECKING import archinstall - -from ..menu import Menu -from ..menu.selection_menu import Selector, GeneralMenu +from ..disk import encrypted_partitions from ..general import SysCommand, secret from ..hardware import has_uefi +from ..menu import Menu +from ..menu.selection_menu import Selector, GeneralMenu from ..models import NetworkConfiguration -from ..storage import storage +from ..models.users import User +from ..output import FormattedOutput from ..profiles import is_desktop_profile, Profile -from ..disk import encrypted_partitions - -from ..user_interaction import get_password, ask_for_a_timezone, save_config -from ..user_interaction import ask_ntp -from ..user_interaction import ask_for_swap +from ..storage import storage +from ..user_interaction import add_number_of_parrallel_downloads +from ..user_interaction import ask_additional_packages_to_install +from ..user_interaction import ask_for_additional_users +from ..user_interaction import ask_for_audio_selection from ..user_interaction import ask_for_bootloader +from ..user_interaction import ask_for_swap from ..user_interaction import ask_hostname -from ..user_interaction import ask_for_audio_selection -from ..user_interaction import ask_additional_packages_to_install +from ..user_interaction import ask_ntp from ..user_interaction import ask_to_configure_network -from ..user_interaction import ask_for_additional_users -from ..user_interaction import select_language -from ..user_interaction import select_mirror_regions -from ..user_interaction import select_locale_lang -from ..user_interaction import select_locale_enc +from ..user_interaction import get_password, ask_for_a_timezone, save_config +from ..user_interaction import select_additional_repositories from ..user_interaction import select_disk_layout -from ..user_interaction import select_kernel from ..user_interaction import select_encrypted_partitions from ..user_interaction import select_harddrives +from ..user_interaction import select_kernel +from ..user_interaction import select_language +from ..user_interaction import select_locale_enc +from ..user_interaction import select_locale_lang +from ..user_interaction import select_mirror_regions from ..user_interaction import select_profile -from ..user_interaction import select_additional_repositories -from ..user_interaction import add_number_of_parrallel_downloads -from ..models.users import User from ..user_interaction.partitioning_conf import current_partition_layout -from ..output import FormattedOutput -from ..translationhandler import Language if TYPE_CHECKING: _: Any -def display_language(global_menu, x): - if type(x) == Language: - return x - elif type(x) == str: - translation_handler = global_menu._translation_handler - for language in translation_handler._get_translations(): - if language.lang == x: - return language - else: - raise ValueError(f"Language entry needs to Language() object or string of full language like 'English'.") class GlobalMenu(GeneralMenu): def __init__(self,data_store): @@ -62,9 +49,9 @@ class GlobalMenu(GeneralMenu): self._menu_options['archinstall-language'] = \ Selector( _('Archinstall language'), - lambda x: self._select_archinstall_language(display_language(self, x)), - display_func=lambda x: display_language(self, x).display_name, - default=self.translation_handler.get_language('en')) + lambda x: self._select_archinstall_language(x), + display_func=lambda x: x.display_name, + default=self.translation_handler.get_language_by_abbr('en')) self._menu_options['keyboard-layout'] = \ Selector( _('Keyboard layout'), diff --git a/archinstall/lib/translationhandler.py b/archinstall/lib/translationhandler.py index 58b7ebd4..d6b3ccb6 100644 --- a/archinstall/lib/translationhandler.py +++ b/archinstall/lib/translationhandler.py @@ -40,6 +40,7 @@ class Language: def json(self) -> str: return self.lang + class TranslationHandler: _base_pot = 'base.pot' _languages = 'languages.json' @@ -48,7 +49,7 @@ class TranslationHandler: # to display cyrillic languages correctly self._set_font('UniCyr_8x16') - self._total_messages = self._get_total_messages() + self._total_messages = self._get_total_active_messages() self._translated_languages = self._get_translations() @property @@ -56,6 +57,9 @@ class TranslationHandler: return self._translated_languages def _get_translations(self) -> List[Language]: + """ + Load all translated languages and return a list of such + """ mappings = self._load_language_mappings() defined_languages = self._defined_languages() @@ -68,13 +72,17 @@ class TranslationHandler: translated_lang = mapping_entry.get('translated_lang', None) try: + # get a translation for a specific language translation = gettext.translation('base', localedir=self._get_locales_dir(), languages=(abbr, lang)) + # calculate the percentage of total translated text to total number of messages if abbr == 'en': percent = 100 else: num_translations = self._get_catalog_size(translation) percent = int((num_translations / self._total_messages) * 100) + # prevent cases where the .pot file is out of date and the percentage is above 100 + percent = min(100, percent) language = Language(abbr, lang, translation, percent, translated_lang) languages.append(language) @@ -84,6 +92,9 @@ class TranslationHandler: return languages def _set_font(self, font: str): + """ + Set the provided font as the new terminal font + """ from archinstall import SysCommand, log try: log(f'Setting font: {font}', level=logging.DEBUG) @@ -92,6 +103,9 @@ class TranslationHandler: log(f'Unable to set font {font}', level=logging.ERROR) def _load_language_mappings(self) -> List[Dict[str, Any]]: + """ + Load the mapping table of all known languages + """ locales_dir = self._get_locales_dir() languages = Path.joinpath(locales_dir, self._languages) @@ -99,34 +113,62 @@ class TranslationHandler: return json.load(fp) def _get_catalog_size(self, translation: gettext.NullTranslations) -> int: - # this is a ery naughty way of retrieving the data but + """ + Get the number of translated messages for a translations + """ + # this is a very naughty way of retrieving the data but # there's no alternative method exposed unfortunately catalog = translation._catalog # type: ignore messages = {k: v for k, v in catalog.items() if k and v} return len(messages) - def _get_total_messages(self) -> int: + def _get_total_active_messages(self) -> int: + """ + Get total messages that could be translated + """ locales = self._get_locales_dir() with open(f'{locales}/{self._base_pot}', 'r') as fp: lines = fp.readlines() msgid_lines = [line for line in lines if 'msgid' in line] + return len(msgid_lines) - 1 # don't count the first line which contains the metadata - def get_language(self, abbr: str) -> Language: + def get_language_by_name(self, name: str) -> Language: + """ + Get a language object by it's name, e.g. English + """ + try: + return next(filter(lambda x: x.lang == name, self._translated_languages)) + except Exception: + raise ValueError(f'No language with name found: {name}') + + def get_language_by_abbr(self, abbr: str) -> Language: + """ + Get a language object by its abbrevation, e.g. en + """ try: return next(filter(lambda x: x.abbr == abbr, self._translated_languages)) except Exception: raise ValueError(f'No language with abbreviation "{abbr}" found') def activate(self, language: Language): + """ + Set the provided language as the current translation + """ language.translation.install() def _get_locales_dir(self) -> Path: + """ + Get the locales directory path + """ cur_path = Path(__file__).parent.parent locales_dir = Path.joinpath(cur_path, 'locales') return locales_dir def _defined_languages(self) -> List[str]: + """ + Get a list of all known languages + """ locales_dir = self._get_locales_dir() filenames = os.listdir(locales_dir) return list(filter(lambda x: len(x) == 2 or x == 'pt_BR', filenames)) diff --git a/archinstall/locales/ar/LC_MESSAGES/base.po b/archinstall/locales/ar/LC_MESSAGES/base.po index aad0f928..ac14f102 100644 --- a/archinstall/locales/ar/LC_MESSAGES/base.po +++ b/archinstall/locales/ar/LC_MESSAGES/base.po @@ -3,26 +3,22 @@ # zer0-x, 2022. msgid "" msgstr "" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Last-Translator: zer0-x\n" -"PO-Revision-Date: 2022-06-16 03:35+0300\n" "Project-Id-Version: \n" +"PO-Revision-Date: 2022-06-16 03:35+0300\n" +"Last-Translator: zer0-x\n" "Language-Team: Arabic\n" "Language: ar\n" "MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" "X-Generator: Lokalize 22.04.2\n" "Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 ? 4 : 5;\n" msgid "[!] A log file has been created here: {} {}" msgstr "[!] مِلَف سِجِل أُنشِأ هُنا: {} {}" -msgid "" -" Please submit this issue (and file) to" -" https://github.com/archlinux/archinstall/issues" -msgstr "" -" يُرجى تسليم تقرير عن هذا الخلل (مع المِلَف) إلى" -" https://github.com/archlinux/archinstall/issues" +msgid " Please submit this issue (and file) to https://github.com/archlinux/archinstall/issues" +msgstr " يُرجى تسليم تقرير عن هذا الخلل (مع المِلَف) إلى https://github.com/archlinux/archinstall/issues" msgid "Do you really want to abort?" msgstr "هل تُريدُ حقًا إجهاضَ العَملِيَّة؟" @@ -57,41 +53,26 @@ msgstr "اختر مُحمّل الإقلاع" msgid "Choose an audio server" msgstr "اختر خادِم صوتيات" -msgid "" -"Only packages such as base, base-devel, linux, linux-firmware, efibootmgr and" -" optional profile packages are installed." -msgstr "" -"فقط الحزم مثل base وbase-devel وlinux وlinux-firmware وefibootmgr و" -" حِزم مِلف اختيارية سوف تُثَبَّت." +msgid "Only packages such as base, base-devel, linux, linux-firmware, efibootmgr and optional profile packages are installed." +msgstr "فقط الحزم مثل base وbase-devel وlinux وlinux-firmware وefibootmgr و حِزم مِلف اختيارية سوف تُثَبَّت." -msgid "" -"If you desire a web browser, such as firefox or chromium, you may specify it" -" in the following prompt." -msgstr "" -"إذا كنت ترغب في متصفح الويب ، مثل Firefox أو chromium، فيمكنك تحديده" -" في موضِع الكتابة التالي." +msgid "If you desire a web browser, such as firefox or chromium, you may specify it in the following prompt." +msgstr "إذا كنت ترغب في متصفح الويب ، مثل Firefox أو chromium، فيمكنك تحديده في موضِع الكتابة التالي." -msgid "" -"Write additional packages to install (space separated, leave blank to skip): " +msgid "Write additional packages to install (space separated, leave blank to skip): " msgstr "اكتب حزمًا إضافية لتثبيتها (تُفصَل بالمسافات، اتركها فارغة للتخطي):" msgid "Copy ISO network configuration to installation" msgstr "انسخ إعداد شبكة الـISO للتثبيت" -msgid "" -"Use NetworkManager (necessary to configure internet graphically in GNOME and" -" KDE)" -msgstr "" -"استخدم مُدير الشبكة (ضروري لإعداد الإنترنت باستخدام واجهة رسومية في جنوم و" -" كيدي)" +msgid "Use NetworkManager (necessary to configure internet graphically in GNOME and KDE)" +msgstr "استخدم مُدير الشبكة (ضروري لإعداد الإنترنت باستخدام واجهة رسومية في جنوم و كيدي)" msgid "Select one network interface to configure" msgstr "حدِّد واجهة شبكة واحدة للإعداد" -msgid "" -"Select which mode to configure for \"{}\" or skip to use default mode \"{}\"" -msgstr "" -"حدد الوضع المراد تهيئته لـ\"{}\" أو تخطى لاستخدام الوضع الافتراضي \"{}\"" +msgid "Select which mode to configure for \"{}\" or skip to use default mode \"{}\"" +msgstr "حدد الوضع المراد تهيئته لـ\"{}\" أو تخطى لاستخدام الوضع الافتراضي \"{}\"" msgid "Enter the IP and subnet for {} (example: 192.168.0.5/24): " msgstr "أدخِل الIP مع تجزئة الشبكة لـ{} (على سبيل المثال: 192.168.0.5/24): " @@ -119,8 +100,7 @@ msgstr "" msgid "Enter the start sector (percentage or block number, default: {}): " msgstr "" -msgid "" -"Enter the end sector of the partition (percentage or block number, ex: {}): " +msgid "Enter the end sector of the partition (percentage or block number, ex: {}): " msgstr "" msgid "{} contains queued partitions, this will remove those, are you sure?" @@ -138,9 +118,7 @@ msgid "" "Select by index which partition to mount where" msgstr "" -msgid "" -" * Partition mount-points are relative to inside the installation, the boot" -" would be /boot as an example." +msgid " * Partition mount-points are relative to inside the installation, the boot would be /boot as an example." msgstr "" msgid "Select where to mount partition (leave blank to remove mountpoint): " @@ -179,16 +157,13 @@ msgstr "" msgid "Wipe all selected drives and use a best-effort default partition layout" msgstr "" -msgid "" -"Select what to do with each individual drive (followed by partition usage)" +msgid "Select what to do with each individual drive (followed by partition usage)" msgstr "" msgid "Select what you wish to do with the selected block devices" msgstr "" -msgid "" -"This is a list of pre-programmed profiles, they might make it easier to" -" install things like desktop environments" +msgid "This is a list of pre-programmed profiles, they might make it easier to install things like desktop environments" msgstr "" msgid "Select keyboard layout" @@ -200,19 +175,13 @@ msgstr "" msgid "Select one or more hard drives to use and configure" msgstr "" -msgid "" -"For the best compatibility with your AMD hardware, you may want to use either" -" the all open-source or AMD / ATI options." +msgid "For the best compatibility with your AMD hardware, you may want to use either the all open-source or AMD / ATI options." msgstr "" -msgid "" -"For the best compatibility with your Intel hardware, you may want to use" -" either the all open-source or Intel options.\n" +msgid "For the best compatibility with your Intel hardware, you may want to use either the all open-source or Intel options.\n" msgstr "" -msgid "" -"For the best compatibility with your Nvidia hardware, you may want to use the" -" Nvidia proprietary driver.\n" +msgid "For the best compatibility with your Nvidia hardware, you may want to use the Nvidia proprietary driver.\n" msgstr "" msgid "" @@ -242,9 +211,7 @@ msgstr "" msgid "Adding partition...." msgstr "" -msgid "" -"You need to enter a valid fs-type in order to continue. See `man parted` for" -" valid fs-type's." +msgid "You need to enter a valid fs-type in order to continue. See `man parted` for valid fs-type's." msgstr "" msgid "Error: Listing profiles on URL \"{}\" resulted in:" @@ -388,18 +355,14 @@ msgstr "" msgid "Password for user \"{}\": " msgstr "" -msgid "" -"Verifying that additional packages exist (this might take a few seconds)" +msgid "Verifying that additional packages exist (this might take a few seconds)" msgstr "" -msgid "" -"Would you like to use automatic time synchronization (NTP) with the default" -" time servers?\n" +msgid "Would you like to use automatic time synchronization (NTP) with the default time servers?\n" msgstr "" msgid "" -"Hardware time and other post-configuration steps might be required in order" -" for NTP to work.\n" +"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 "" @@ -411,8 +374,7 @@ msgstr "" msgid "" "\n" -" Choose an object from the list, and select one of the available actions for" -" it to execute" +" Choose an object from the list, and select one of the available actions for it to execute" msgstr "" msgid "Cancel" @@ -433,8 +395,9 @@ msgstr "" msgid "Delete" msgstr "" -msgid "Select an action for < {} >" -msgstr "" +#, fuzzy +msgid "Select an action for '{}'" +msgstr "حدِّد منطقة زمنية" msgid "Copy to new key:" msgstr "" @@ -447,13 +410,10 @@ msgid "" "This is your chosen configuration:" msgstr "" -msgid "" -"Pacman is already running, waiting maximum 10 minutes for it to terminate." +msgid "Pacman is already running, waiting maximum 10 minutes for it to terminate." msgstr "" -msgid "" -"Pre-existing pacman lock never exited. Please clean up any existing pacman" -" sessions before using archinstall." +msgid "Pre-existing pacman lock never exited. Please clean up any existing pacman sessions before using archinstall." msgstr "" msgid "Choose which optional additional repositories to enable" @@ -598,9 +558,7 @@ msgstr "" msgid "Would you like to create a separate partition for /home?" msgstr "" -msgid "" -"The selected drives do not have the minimum capacity required for an" -" automatic suggestion\n" +msgid "The selected drives do not have the minimum capacity required for an automatic suggestion\n" msgstr "" msgid "Minimum capacity for /home partition: {}GB\n" @@ -648,31 +606,22 @@ msgstr "" msgid "Mark/Unmark a partition as compressed (btrfs only)" msgstr "" -msgid "" -"The password you are using seems to be weak, are you sure you want to use it?" +msgid "The password you are using seems to be weak, are you sure you want to use it?" msgstr "" -msgid "" -"Provides a selection of desktop environments and tiling window managers, e.g." -" gnome, kde, sway" +msgid "Provides a selection of desktop environments and tiling window managers, e.g. gnome, kde, sway" msgstr "" msgid "Select your desired desktop environment" msgstr "" -msgid "" -"A very basic installation that allows you to customize Arch Linux as you see" -" fit." +msgid "A very basic installation that allows you to customize Arch Linux as you see fit." msgstr "" -msgid "" -"Provides a selection of various server packages to install and enable, e.g." -" httpd, nginx, mariadb" +msgid "Provides a selection of various server packages to install and enable, e.g. httpd, nginx, mariadb" msgstr "" -msgid "" -"Choose which servers to install, if none then a minimal installation wil be" -" done" +msgid "Choose which servers to install, if none then a minimal installation will be done" msgstr "" msgid "Installs a minimal system as well as xorg and graphics drivers." @@ -681,9 +630,7 @@ msgstr "" msgid "Press Enter to continue." msgstr "" -msgid "" -"Would you like to chroot into the newly created installation and perform" -" post-installation configuration?" +msgid "Would you like to chroot into the newly created installation and perform post-installation configuration?" msgstr "" msgid "Are you sure you want to reset this setting?" @@ -695,9 +642,7 @@ msgstr "" msgid "Any modifications to the existing setting will reset the disk layout!" msgstr "" -msgid "" -"If you reset the harddrive selection this will also reset the current disk" -" layout. Are you sure?" +msgid "If you reset the harddrive selection this will also reset the current disk layout. Are you sure?" msgstr "" msgid "Save and exit" @@ -740,9 +685,7 @@ msgstr "" msgid "Value: " msgstr "" -msgid "" -"You can skip selecting a drive and partitioning and use whatever drive-setup" -" is mounted at /mnt (experimental)" +msgid "You can skip selecting a drive and partitioning and use whatever drive-setup is mounted at /mnt (experimental)" msgstr "" msgid "Select one of the disks or skip and use /mnt as default" @@ -766,8 +709,7 @@ msgstr "" msgid "Bus-type" msgstr "" -msgid "" -"Either root-password or at least 1 user with sudo privileges must be specified" +msgid "Either root-password or at least 1 user with sudo privileges must be specified" msgstr "" msgid "Enter username (leave blank to skip): " @@ -781,3 +723,53 @@ msgstr "" msgid "Select which partitions to encrypt:" msgstr "" + +msgid "very weak" +msgstr "" + +msgid "weak" +msgstr "" + +msgid "moderate" +msgstr "" + +msgid "strong" +msgstr "" + +msgid "Add subvolume" +msgstr "" + +msgid "Edit subvolume" +msgstr "" + +msgid "Delete subvolume" +msgstr "" + +msgid "Configured {} interfaces" +msgstr "" + +msgid "This option enables the number of parallel downloads that can occur during installation" +msgstr "" + +#, python-brace-format +msgid "" +"Enter the number of parallel downloads to be enabled.\n" +" (Enter a value between 1 to {max_downloads})\n" +"Note:" +msgstr "" + +msgid " - Maximum value : {max_downloads} ( Allows {max_downloads} parallel downloads, allows {max_downloads+1} downloads at a time )" +msgstr "" + +msgid " - Minimum value : 1 ( Allows 1 parallel download, allows 2 downloads at a time )" +msgstr "" + +msgid " - Disable/Default : 0 ( Disables parallel downloading, allows only 1 download at a time )" +msgstr "" + +#, python-brace-format +msgid "Invalid input! Try again with a valid input [1 to {max_downloads}, or 0 to disable]" +msgstr "" + +msgid "Parallel Downloads" +msgstr "" diff --git a/archinstall/locales/base.pot b/archinstall/locales/base.pot index 7a259336..b2be65f8 100644 --- a/archinstall/locales/base.pot +++ b/archinstall/locales/base.pot @@ -787,3 +787,39 @@ msgstr "" msgid "Configured {} interfaces" msgstr "" + +msgid "" +"This option enables the number of parallel downloads that can occur during " +"installation" +msgstr "" + +#, python-brace-format +msgid "" +"Enter the number of parallel downloads to be enabled.\n" +" (Enter a value between 1 to {max_downloads})\n" +"Note:" +msgstr "" + +msgid "" +" - Maximum value : {max_downloads} ( Allows {max_downloads} parallel " +"downloads, allows {max_downloads+1} downloads at a time )" +msgstr "" + +msgid "" +" - Minimum value : 1 ( Allows 1 parallel download, allows 2 downloads at a " +"time )" +msgstr "" + +msgid "" +" - Disable/Default : 0 ( Disables parallel downloading, allows only 1 " +"download at a time )" +msgstr "" + +#, python-brace-format +msgid "" +"Invalid input! Try again with a valid input [1 to {max_downloads}, or 0 to " +"disable]" +msgstr "" + +msgid "Parallel Downloads" +msgstr "" diff --git a/archinstall/locales/cs/LC_MESSAGES/base.po b/archinstall/locales/cs/LC_MESSAGES/base.po index 7a2a197f..194bbf78 100644 --- a/archinstall/locales/cs/LC_MESSAGES/base.po +++ b/archinstall/locales/cs/LC_MESSAGES/base.po @@ -792,3 +792,29 @@ msgstr "Smazat uživatele" msgid "Configured {} interfaces" msgstr "" + +msgid "This option enables the number of parallel downloads that can occur during installation" +msgstr "" + +#, python-brace-format +msgid "" +"Enter the number of parallel downloads to be enabled.\n" +" (Enter a value between 1 to {max_downloads})\n" +"Note:" +msgstr "" + +msgid " - Maximum value : {max_downloads} ( Allows {max_downloads} parallel downloads, allows {max_downloads+1} downloads at a time )" +msgstr "" + +msgid " - Minimum value : 1 ( Allows 1 parallel download, allows 2 downloads at a time )" +msgstr "" + +msgid " - Disable/Default : 0 ( Disables parallel downloading, allows only 1 download at a time )" +msgstr "" + +#, python-brace-format +msgid "Invalid input! Try again with a valid input [1 to {max_downloads}, or 0 to disable]" +msgstr "" + +msgid "Parallel Downloads" +msgstr "" diff --git a/archinstall/locales/de/LC_MESSAGES/base.po b/archinstall/locales/de/LC_MESSAGES/base.po index a601326e..11fc821d 100644 --- a/archinstall/locales/de/LC_MESSAGES/base.po +++ b/archinstall/locales/de/LC_MESSAGES/base.po @@ -808,6 +808,32 @@ msgstr "Benutzerkonto löschen" msgid "Configured {} interfaces" msgstr "" +msgid "This option enables the number of parallel downloads that can occur during installation" +msgstr "" + +#, python-brace-format +msgid "" +"Enter the number of parallel downloads to be enabled.\n" +" (Enter a value between 1 to {max_downloads})\n" +"Note:" +msgstr "" + +msgid " - Maximum value : {max_downloads} ( Allows {max_downloads} parallel downloads, allows {max_downloads+1} downloads at a time )" +msgstr "" + +msgid " - Minimum value : 1 ( Allows 1 parallel download, allows 2 downloads at a time )" +msgstr "" + +msgid " - Disable/Default : 0 ( Disables parallel downloading, allows only 1 download at a time )" +msgstr "" + +#, python-brace-format +msgid "Invalid input! Try again with a valid input [1 to {max_downloads}, or 0 to disable]" +msgstr "" + +msgid "Parallel Downloads" +msgstr "" + #~ msgid "Select disk layout" #~ msgstr "Laufwerke-layout auswählen" diff --git a/archinstall/locales/el/LC_MESSAGES/base.po b/archinstall/locales/el/LC_MESSAGES/base.po index 2561c9f2..9b342ac9 100644 --- a/archinstall/locales/el/LC_MESSAGES/base.po +++ b/archinstall/locales/el/LC_MESSAGES/base.po @@ -787,6 +787,9 @@ msgstr "Επεξεργασία υποόγκου" msgid "Delete subvolume" msgstr "Διαγραφή υποόγκου" +msgid "Configured {} interfaces" +msgstr "Διαμορφωμένες {} διεπαφές" + msgid "This option enables the number of parallel downloads that can occur during installation" msgstr "Αυτή η επιλογή θέτει τον αριθμό των παράλληλων λήψεων που μπορούν να συμβούν κατά την εγκατάσταση" @@ -815,6 +818,3 @@ msgstr "Μη έγκυρη είσοδος! Προσπαθήστε ξανά με msgid "Parallel Downloads" msgstr "Παράλληλες Λήψεις" - -msgid "Configured {} interfaces" -msgstr "Διαμορφωμένες {} διεπαφές" diff --git a/archinstall/locales/en/LC_MESSAGES/base.po b/archinstall/locales/en/LC_MESSAGES/base.po index 1825d501..01d4414f 100644 --- a/archinstall/locales/en/LC_MESSAGES/base.po +++ b/archinstall/locales/en/LC_MESSAGES/base.po @@ -743,3 +743,29 @@ msgstr "" msgid "Configured {} interfaces" msgstr "" + +msgid "This option enables the number of parallel downloads that can occur during installation" +msgstr "" + +#, python-brace-format +msgid "" +"Enter the number of parallel downloads to be enabled.\n" +" (Enter a value between 1 to {max_downloads})\n" +"Note:" +msgstr "" + +msgid " - Maximum value : {max_downloads} ( Allows {max_downloads} parallel downloads, allows {max_downloads+1} downloads at a time )" +msgstr "" + +msgid " - Minimum value : 1 ( Allows 1 parallel download, allows 2 downloads at a time )" +msgstr "" + +msgid " - Disable/Default : 0 ( Disables parallel downloading, allows only 1 download at a time )" +msgstr "" + +#, python-brace-format +msgid "Invalid input! Try again with a valid input [1 to {max_downloads}, or 0 to disable]" +msgstr "" + +msgid "Parallel Downloads" +msgstr "" diff --git a/archinstall/locales/es/LC_MESSAGES/base.po b/archinstall/locales/es/LC_MESSAGES/base.po index 47a64b0a..6186b6d8 100644 --- a/archinstall/locales/es/LC_MESSAGES/base.po +++ b/archinstall/locales/es/LC_MESSAGES/base.po @@ -791,6 +791,32 @@ msgstr "Eliminar usuario" msgid "Configured {} interfaces" msgstr "" +msgid "This option enables the number of parallel downloads that can occur during installation" +msgstr "" + +#, python-brace-format +msgid "" +"Enter the number of parallel downloads to be enabled.\n" +" (Enter a value between 1 to {max_downloads})\n" +"Note:" +msgstr "" + +msgid " - Maximum value : {max_downloads} ( Allows {max_downloads} parallel downloads, allows {max_downloads+1} downloads at a time )" +msgstr "" + +msgid " - Minimum value : 1 ( Allows 1 parallel download, allows 2 downloads at a time )" +msgstr "" + +msgid " - Disable/Default : 0 ( Disables parallel downloading, allows only 1 download at a time )" +msgstr "" + +#, python-brace-format +msgid "Invalid input! Try again with a valid input [1 to {max_downloads}, or 0 to disable]" +msgstr "" + +msgid "Parallel Downloads" +msgstr "" + #~ msgid "Select disk layout" #~ msgstr "Seleccione el diseño del disco" diff --git a/archinstall/locales/fr/LC_MESSAGES/base.po b/archinstall/locales/fr/LC_MESSAGES/base.po index 877b793f..2d7de615 100644 --- a/archinstall/locales/fr/LC_MESSAGES/base.po +++ b/archinstall/locales/fr/LC_MESSAGES/base.po @@ -797,6 +797,32 @@ msgstr "Supprimer l'utilisateur" msgid "Configured {} interfaces" msgstr "" +msgid "This option enables the number of parallel downloads that can occur during installation" +msgstr "" + +#, python-brace-format +msgid "" +"Enter the number of parallel downloads to be enabled.\n" +" (Enter a value between 1 to {max_downloads})\n" +"Note:" +msgstr "" + +msgid " - Maximum value : {max_downloads} ( Allows {max_downloads} parallel downloads, allows {max_downloads+1} downloads at a time )" +msgstr "" + +msgid " - Minimum value : 1 ( Allows 1 parallel download, allows 2 downloads at a time )" +msgstr "" + +msgid " - Disable/Default : 0 ( Disables parallel downloading, allows only 1 download at a time )" +msgstr "" + +#, python-brace-format +msgid "Invalid input! Try again with a valid input [1 to {max_downloads}, or 0 to disable]" +msgstr "" + +msgid "Parallel Downloads" +msgstr "" + #~ msgid "Select disk layout" #~ msgstr "Sélectionner la disposition du disque" diff --git a/archinstall/locales/it/LC_MESSAGES/base.po b/archinstall/locales/it/LC_MESSAGES/base.po index baf55a28..893fe292 100644 --- a/archinstall/locales/it/LC_MESSAGES/base.po +++ b/archinstall/locales/it/LC_MESSAGES/base.po @@ -799,3 +799,29 @@ msgstr "Elimina utente" msgid "Configured {} interfaces" msgstr "" + +msgid "This option enables the number of parallel downloads that can occur during installation" +msgstr "" + +#, python-brace-format +msgid "" +"Enter the number of parallel downloads to be enabled.\n" +" (Enter a value between 1 to {max_downloads})\n" +"Note:" +msgstr "" + +msgid " - Maximum value : {max_downloads} ( Allows {max_downloads} parallel downloads, allows {max_downloads+1} downloads at a time )" +msgstr "" + +msgid " - Minimum value : 1 ( Allows 1 parallel download, allows 2 downloads at a time )" +msgstr "" + +msgid " - Disable/Default : 0 ( Disables parallel downloading, allows only 1 download at a time )" +msgstr "" + +#, python-brace-format +msgid "Invalid input! Try again with a valid input [1 to {max_downloads}, or 0 to disable]" +msgstr "" + +msgid "Parallel Downloads" +msgstr "" diff --git a/archinstall/locales/nl/LC_MESSAGES/base.po b/archinstall/locales/nl/LC_MESSAGES/base.po index 8553595e..aa7754d2 100644 --- a/archinstall/locales/nl/LC_MESSAGES/base.po +++ b/archinstall/locales/nl/LC_MESSAGES/base.po @@ -823,6 +823,32 @@ msgstr "Gebruiker verwijderen" msgid "Configured {} interfaces" msgstr "" +msgid "This option enables the number of parallel downloads that can occur during installation" +msgstr "" + +#, python-brace-format +msgid "" +"Enter the number of parallel downloads to be enabled.\n" +" (Enter a value between 1 to {max_downloads})\n" +"Note:" +msgstr "" + +msgid " - Maximum value : {max_downloads} ( Allows {max_downloads} parallel downloads, allows {max_downloads+1} downloads at a time )" +msgstr "" + +msgid " - Minimum value : 1 ( Allows 1 parallel download, allows 2 downloads at a time )" +msgstr "" + +msgid " - Disable/Default : 0 ( Disables parallel downloading, allows only 1 download at a time )" +msgstr "" + +#, python-brace-format +msgid "Invalid input! Try again with a valid input [1 to {max_downloads}, or 0 to disable]" +msgstr "" + +msgid "Parallel Downloads" +msgstr "" + #~ msgid "Select disk layout" #~ msgstr "Kies een schijfindeling" diff --git a/archinstall/locales/pl/LC_MESSAGES/base.po b/archinstall/locales/pl/LC_MESSAGES/base.po index 1bd4b47e..c65126ea 100644 --- a/archinstall/locales/pl/LC_MESSAGES/base.po +++ b/archinstall/locales/pl/LC_MESSAGES/base.po @@ -805,6 +805,32 @@ msgstr "Usuń użytkownika" msgid "Configured {} interfaces" msgstr "" +msgid "This option enables the number of parallel downloads that can occur during installation" +msgstr "" + +#, python-brace-format +msgid "" +"Enter the number of parallel downloads to be enabled.\n" +" (Enter a value between 1 to {max_downloads})\n" +"Note:" +msgstr "" + +msgid " - Maximum value : {max_downloads} ( Allows {max_downloads} parallel downloads, allows {max_downloads+1} downloads at a time )" +msgstr "" + +msgid " - Minimum value : 1 ( Allows 1 parallel download, allows 2 downloads at a time )" +msgstr "" + +msgid " - Disable/Default : 0 ( Disables parallel downloading, allows only 1 download at a time )" +msgstr "" + +#, python-brace-format +msgid "Invalid input! Try again with a valid input [1 to {max_downloads}, or 0 to disable]" +msgstr "" + +msgid "Parallel Downloads" +msgstr "" + #~ msgid "Select disk layout" #~ msgstr "Wybierz układ dysku" diff --git a/archinstall/locales/pt/LC_MESSAGES/base.po b/archinstall/locales/pt/LC_MESSAGES/base.po index 2e9b461c..98d261a9 100644 --- a/archinstall/locales/pt/LC_MESSAGES/base.po +++ b/archinstall/locales/pt/LC_MESSAGES/base.po @@ -843,6 +843,32 @@ msgstr "Eliminar Utilizador" msgid "Configured {} interfaces" msgstr "" +msgid "This option enables the number of parallel downloads that can occur during installation" +msgstr "" + +#, python-brace-format +msgid "" +"Enter the number of parallel downloads to be enabled.\n" +" (Enter a value between 1 to {max_downloads})\n" +"Note:" +msgstr "" + +msgid " - Maximum value : {max_downloads} ( Allows {max_downloads} parallel downloads, allows {max_downloads+1} downloads at a time )" +msgstr "" + +msgid " - Minimum value : 1 ( Allows 1 parallel download, allows 2 downloads at a time )" +msgstr "" + +msgid " - Disable/Default : 0 ( Disables parallel downloading, allows only 1 download at a time )" +msgstr "" + +#, python-brace-format +msgid "Invalid input! Try again with a valid input [1 to {max_downloads}, or 0 to disable]" +msgstr "" + +msgid "Parallel Downloads" +msgstr "" + #~ msgid "Select disk layout" #~ msgstr "Seleciona o esquema de disco" diff --git a/archinstall/locales/pt_BR/LC_MESSAGES/base.po b/archinstall/locales/pt_BR/LC_MESSAGES/base.po index 69f8c902..3acbdb95 100644 --- a/archinstall/locales/pt_BR/LC_MESSAGES/base.po +++ b/archinstall/locales/pt_BR/LC_MESSAGES/base.po @@ -1,7 +1,6 @@ # Translators: # @Cain-dev (cain-dev.github.io) # Rafael Fontenelle - msgid "" msgstr "" "Last-Translator: Rafael Fontenelle \n" @@ -788,3 +787,29 @@ msgstr "Deletar subvolume" msgid "Configured {} interfaces" msgstr "{} interfaces configuradas" + +msgid "This option enables the number of parallel downloads that can occur during installation" +msgstr "" + +#, python-brace-format +msgid "" +"Enter the number of parallel downloads to be enabled.\n" +" (Enter a value between 1 to {max_downloads})\n" +"Note:" +msgstr "" + +msgid " - Maximum value : {max_downloads} ( Allows {max_downloads} parallel downloads, allows {max_downloads+1} downloads at a time )" +msgstr "" + +msgid " - Minimum value : 1 ( Allows 1 parallel download, allows 2 downloads at a time )" +msgstr "" + +msgid " - Disable/Default : 0 ( Disables parallel downloading, allows only 1 download at a time )" +msgstr "" + +#, python-brace-format +msgid "Invalid input! Try again with a valid input [1 to {max_downloads}, or 0 to disable]" +msgstr "" + +msgid "Parallel Downloads" +msgstr "" diff --git a/archinstall/locales/ru/LC_MESSAGES/base.po b/archinstall/locales/ru/LC_MESSAGES/base.po index a88c58a1..8aeb57ff 100644 --- a/archinstall/locales/ru/LC_MESSAGES/base.po +++ b/archinstall/locales/ru/LC_MESSAGES/base.po @@ -791,6 +791,32 @@ msgstr "Удалить подтом" msgid "Configured {} interfaces" msgstr "Настроено интерфейсов: {}" +msgid "This option enables the number of parallel downloads that can occur during installation" +msgstr "" + +#, python-brace-format +msgid "" +"Enter the number of parallel downloads to be enabled.\n" +" (Enter a value between 1 to {max_downloads})\n" +"Note:" +msgstr "" + +msgid " - Maximum value : {max_downloads} ( Allows {max_downloads} parallel downloads, allows {max_downloads+1} downloads at a time )" +msgstr "" + +msgid " - Minimum value : 1 ( Allows 1 parallel download, allows 2 downloads at a time )" +msgstr "" + +msgid " - Disable/Default : 0 ( Disables parallel downloading, allows only 1 download at a time )" +msgstr "" + +#, python-brace-format +msgid "Invalid input! Try again with a valid input [1 to {max_downloads}, or 0 to disable]" +msgstr "" + +msgid "Parallel Downloads" +msgstr "" + #, python-brace-format #~ msgid "Edit {origkey} :" #~ msgstr "Редактировать {origkey}:" diff --git a/archinstall/locales/sv/LC_MESSAGES/base.po b/archinstall/locales/sv/LC_MESSAGES/base.po index b3712972..590929c6 100644 --- a/archinstall/locales/sv/LC_MESSAGES/base.po +++ b/archinstall/locales/sv/LC_MESSAGES/base.po @@ -804,5 +804,31 @@ msgstr "Ta bort användare" msgid "Configured {} interfaces" msgstr "" +msgid "This option enables the number of parallel downloads that can occur during installation" +msgstr "" + +#, python-brace-format +msgid "" +"Enter the number of parallel downloads to be enabled.\n" +" (Enter a value between 1 to {max_downloads})\n" +"Note:" +msgstr "" + +msgid " - Maximum value : {max_downloads} ( Allows {max_downloads} parallel downloads, allows {max_downloads+1} downloads at a time )" +msgstr "" + +msgid " - Minimum value : 1 ( Allows 1 parallel download, allows 2 downloads at a time )" +msgstr "" + +msgid " - Disable/Default : 0 ( Disables parallel downloading, allows only 1 download at a time )" +msgstr "" + +#, python-brace-format +msgid "Invalid input! Try again with a valid input [1 to {max_downloads}, or 0 to disable]" +msgstr "" + +msgid "Parallel Downloads" +msgstr "" + #~ msgid "Select disk layout" #~ msgstr "Välj hårddisk-layout" diff --git a/archinstall/locales/ta/LC_MESSAGES/base.po b/archinstall/locales/ta/LC_MESSAGES/base.po index 9cf261f2..3c1cd848 100644 --- a/archinstall/locales/ta/LC_MESSAGES/base.po +++ b/archinstall/locales/ta/LC_MESSAGES/base.po @@ -790,9 +790,6 @@ msgstr "துணைத்தொகுதியை நீக்கவும்" msgid "Configured {} interfaces" msgstr "கட்டமைக்கப்பட்ட {} இடைமுகங்கள்" -msgid "Parallel Downloads" -msgstr "இணையான பதிவிறக்கங்கள்" - msgid "This option enables the number of parallel downloads that can occur during installation" msgstr "இந்த விருப்பம் நிறுவலின் போது நிகழக்கூடிய இணையான பதிவிறக்கங்களின் எண்ணிக்கையை செயல்படுத்துகிறது" @@ -818,3 +815,6 @@ msgstr " - முடக்கு/இயல்புநிலை: 0 (இணை #, python-brace-format msgid "Invalid input! Try again with a valid input [1 to {max_downloads}, or 0 to disable]" msgstr "தவறான உள்ளீடு! சரியான உள்ளீட்டில் [1 முதல் {max_downloads} வரை அல்லது முடக்க 0 வரை] மீண்டும் முயற்சிக்கவும்" + +msgid "Parallel Downloads" +msgstr "இணையான பதிவிறக்கங்கள்" diff --git a/archinstall/locales/tr/LC_MESSAGES/base.po b/archinstall/locales/tr/LC_MESSAGES/base.po index 4d978ee0..63f9dee0 100644 --- a/archinstall/locales/tr/LC_MESSAGES/base.po +++ b/archinstall/locales/tr/LC_MESSAGES/base.po @@ -803,3 +803,29 @@ msgstr "Kullanıcı Sil" msgid "Configured {} interfaces" msgstr "" + +msgid "This option enables the number of parallel downloads that can occur during installation" +msgstr "" + +#, python-brace-format +msgid "" +"Enter the number of parallel downloads to be enabled.\n" +" (Enter a value between 1 to {max_downloads})\n" +"Note:" +msgstr "" + +msgid " - Maximum value : {max_downloads} ( Allows {max_downloads} parallel downloads, allows {max_downloads+1} downloads at a time )" +msgstr "" + +msgid " - Minimum value : 1 ( Allows 1 parallel download, allows 2 downloads at a time )" +msgstr "" + +msgid " - Disable/Default : 0 ( Disables parallel downloading, allows only 1 download at a time )" +msgstr "" + +#, python-brace-format +msgid "Invalid input! Try again with a valid input [1 to {max_downloads}, or 0 to disable]" +msgstr "" + +msgid "Parallel Downloads" +msgstr "" diff --git a/archinstall/locales/ur/LC_MESSAGES/base.po b/archinstall/locales/ur/LC_MESSAGES/base.po index 2927c3ea..6494ae28 100644 --- a/archinstall/locales/ur/LC_MESSAGES/base.po +++ b/archinstall/locales/ur/LC_MESSAGES/base.po @@ -825,6 +825,32 @@ msgstr "صارف کو حذف کریں" msgid "Configured {} interfaces" msgstr "" +msgid "This option enables the number of parallel downloads that can occur during installation" +msgstr "" + +#, python-brace-format +msgid "" +"Enter the number of parallel downloads to be enabled.\n" +" (Enter a value between 1 to {max_downloads})\n" +"Note:" +msgstr "" + +msgid " - Maximum value : {max_downloads} ( Allows {max_downloads} parallel downloads, allows {max_downloads+1} downloads at a time )" +msgstr "" + +msgid " - Minimum value : 1 ( Allows 1 parallel download, allows 2 downloads at a time )" +msgstr "" + +msgid " - Disable/Default : 0 ( Disables parallel downloading, allows only 1 download at a time )" +msgstr "" + +#, python-brace-format +msgid "Invalid input! Try again with a valid input [1 to {max_downloads}, or 0 to disable]" +msgstr "" + +msgid "Parallel Downloads" +msgstr "" + #~ msgid "Select disk layout" #~ msgstr "ڈسک لے آؤٹ کو منتخب کریں" diff --git a/examples/swiss.py b/examples/swiss.py index 5d40dc68..da45cd18 100644 --- a/examples/swiss.py +++ b/examples/swiss.py @@ -164,7 +164,7 @@ class SetupMenu(archinstall.GeneralMenu): _('Archinstall language'), lambda x: self._select_archinstall_language(x), display_func=lambda x: x.display_name, - default=self.translation_handler.get_language('en'), + default=self.translation_handler.get_language_by_abbr('en'), enabled=True ) ) -- cgit v1.2.3-54-g00ecf From a2adeca5eba17afc36d964879ce30e88a0e6a3ba Mon Sep 17 00:00:00 2001 From: Daniel Girtler Date: Wed, 7 Sep 2022 23:48:14 +1000 Subject: Fix translation fonts (#1461) Co-authored-by: Daniel Girtler --- archinstall/lib/translationhandler.py | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'archinstall') diff --git a/archinstall/lib/translationhandler.py b/archinstall/lib/translationhandler.py index d6b3ccb6..08deb3e7 100644 --- a/archinstall/lib/translationhandler.py +++ b/archinstall/lib/translationhandler.py @@ -46,8 +46,8 @@ class TranslationHandler: _languages = 'languages.json' def __init__(self): - # to display cyrillic languages correctly - self._set_font('UniCyr_8x16') + # to display latin, greek, cyrillic characters + self._set_font('LatGrkCyr-8x16') self._total_messages = self._get_total_active_messages() self._translated_languages = self._get_translations() @@ -61,7 +61,7 @@ class TranslationHandler: Load all translated languages and return a list of such """ mappings = self._load_language_mappings() - defined_languages = self._defined_languages() + defined_languages = self._provided_translations() languages = [] @@ -165,13 +165,20 @@ class TranslationHandler: locales_dir = Path.joinpath(cur_path, 'locales') return locales_dir - def _defined_languages(self) -> List[str]: + def _provided_translations(self) -> List[str]: """ Get a list of all known languages """ locales_dir = self._get_locales_dir() filenames = os.listdir(locales_dir) - return list(filter(lambda x: len(x) == 2 or x == 'pt_BR', filenames)) + + translation_files = [] + for filename in filenames: + if len(filename) == 2 or filename == 'pt_BR': + if filename not in ['ur', 'ta']: + translation_files.append(filename) + + return translation_files class DeferredTranslation: -- cgit v1.2.3-54-g00ecf From d2484f67cbe9a87d8448d61dd9caaf3a99d232de Mon Sep 17 00:00:00 2001 From: Daniel Girtler Date: Thu, 8 Sep 2022 00:29:04 +1000 Subject: Update the action text (#1462) Co-authored-by: Daniel Girtler --- archinstall/lib/menu/menu.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'archinstall') diff --git a/archinstall/lib/menu/menu.py b/archinstall/lib/menu/menu.py index 1e6f0110..16153e2c 100644 --- a/archinstall/lib/menu/menu.py +++ b/archinstall/lib/menu/menu.py @@ -162,14 +162,17 @@ class Menu(TerminalMenu): action_info = '' if skip: - action_info += str(_("Use ESC to skip")) + action_info += str(_('ESC to skip')) if self._raise_error_on_interrupt: - if len(action_info) > 0: - action_info += '\n' - action_info += str(_('Use CTRL+C to reset current selection\n\n')) + action_info += ', ' if len(action_info) > 0 else '' + action_info += str(_('CTRL+C to reset')) - menu_title += action_info + if multi: + action_info += ', ' if len(action_info) > 0 else '' + action_info += str(_('TAB to select')) + + menu_title += action_info + '\n' if default_option: # if a default value was specified we move that one -- cgit v1.2.3-54-g00ecf From 2685871e6a5968521c82f0eb31351766dd4c7ce6 Mon Sep 17 00:00:00 2001 From: tajnymag Date: Thu, 8 Sep 2022 19:36:51 +0200 Subject: Updated czech translation (#1463) --- archinstall/locales/cs/LC_MESSAGES/base.mo | Bin 23739 -> 26460 bytes archinstall/locales/cs/LC_MESSAGES/base.po | 57 +++++++++++++---------------- 2 files changed, 25 insertions(+), 32 deletions(-) (limited to 'archinstall') diff --git a/archinstall/locales/cs/LC_MESSAGES/base.mo b/archinstall/locales/cs/LC_MESSAGES/base.mo index 6a54b145..b175a54e 100644 Binary files a/archinstall/locales/cs/LC_MESSAGES/base.mo and b/archinstall/locales/cs/LC_MESSAGES/base.mo differ diff --git a/archinstall/locales/cs/LC_MESSAGES/base.po b/archinstall/locales/cs/LC_MESSAGES/base.po index 194bbf78..6b6b9c3e 100644 --- a/archinstall/locales/cs/LC_MESSAGES/base.po +++ b/archinstall/locales/cs/LC_MESSAGES/base.po @@ -9,7 +9,7 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Generator: Poedit 3.0.1\n" +"X-Generator: Poedit 3.1\n" msgid "[!] A log file has been created here: {} {}" msgstr "[!] Soubor protokolu byl vytvořen zde: {} {}" @@ -66,7 +66,7 @@ msgid "Use NetworkManager (necessary to configure internet graphically in GNOME msgstr "Použít NetworkManager (potřebné pro grafickou konfiguraci v GNOME a KDE)" msgid "Select one network interface to configure" -msgstr "Zvolte zařízení ke konfiguraci" +msgstr "Zvolte síťové rozhraní ke konfiguraci" msgid "Select which mode to configure for \"{}\" or skip to use default mode \"{}\"" msgstr "Zvolte který režim má být nastaven pro \"{}\" nebo přeskočte pro použití výchozího režimu \"{}\"" @@ -654,9 +654,8 @@ msgstr "Základní instalace, která vám umožní si nastavit Arch Linux jakkol msgid "Provides a selection of various server packages to install and enable, e.g. httpd, nginx, mariadb" msgstr "Nabízí výběr různých serverových balíčků k instalaci a aktivaci, např. httpd, nginx, mariadb" -#, fuzzy msgid "Choose which servers to install, if none then a minimal installation will be done" -msgstr "Vyberte servery, které mají být nainstalovány, pokud nezvolíte žádné, bude provedena jen základní instalace" +msgstr "Vyberte, které servery mají být nainstalovány, pokud nezvolíte žádné, bude provedena jen základní instalace" msgid "Installs a minimal system as well as xorg and graphics drivers." msgstr "Nainstaluje minimalistický systém spolu s xorg a ovladači grafiky." @@ -745,56 +744,47 @@ msgstr "Volné místo" msgid "Bus-type" msgstr "Typ sběrnice" -#, fuzzy msgid "Either root-password or at least 1 user with sudo privileges must be specified" -msgstr "Musí být zadáno heslo správce (root) nebo musí existovat alespoň jeden superuživatel" +msgstr "Musí být zadáno heslo správce (root) nebo musí být specifikován alespoň jeden uživatel s sudo oprávněními" -#, fuzzy msgid "Enter username (leave blank to skip): " -msgstr "Zadejte uživatelské jméno k přidání dalšího uživatele (ponechte prázdné k přeskočení): " +msgstr "Zadejte uživatelské jméno (ponechte prázdné k přeskočení): " msgid "The username you entered is invalid. Try again" -msgstr "" +msgstr "Zadané uživatelské jméno není platné. Zkuste to znovu" -#, fuzzy msgid "Should \"{}\" be a superuser (sudo)?" -msgstr "Má být {} superuživatelem (sudoer)?" +msgstr "Má být \"{}\" superuživatelem (sudoer)?" -#, fuzzy msgid "Select which partitions to encrypt:" -msgstr "" -"{}\n" -"\n" -"Zvolte oddíl, který bude označen jako šifrovaný" +msgstr "Zvolte oddíl, který bude označen jako šifrovaný:" msgid "very weak" -msgstr "" +msgstr "velmi slabé" msgid "weak" -msgstr "" +msgstr "slabé" msgid "moderate" -msgstr "" +msgstr "středně silné" msgid "strong" -msgstr "" +msgstr "silné" -#, fuzzy msgid "Add subvolume" -msgstr " Podsvazek :{:16}" +msgstr "Přidat podsvazek" msgid "Edit subvolume" -msgstr "" +msgstr "Upravit podsvazek" -#, fuzzy msgid "Delete subvolume" -msgstr "Smazat uživatele" +msgstr "Smazat podsvazek" msgid "Configured {} interfaces" -msgstr "" +msgstr "Nakonfigurováno {} rozhraní" msgid "This option enables the number of parallel downloads that can occur during installation" -msgstr "" +msgstr "Tato možnost povolí specifikovaný počet paralelních stahování, která mohou nastat při instalaci" #, python-brace-format msgid "" @@ -802,19 +792,22 @@ msgid "" " (Enter a value between 1 to {max_downloads})\n" "Note:" msgstr "" +"Zadejte povolený počet paralelních stahování.\n" +" (Zadejte hodnotu mezi 1 a {max_downloads})\n" +"Poznámka:" msgid " - Maximum value : {max_downloads} ( Allows {max_downloads} parallel downloads, allows {max_downloads+1} downloads at a time )" -msgstr "" +msgstr " - Maximální hodnota : {max_downloads} (Povolí {max_downloads} paralelních stahování, povolí {max_downloads+1} stahování naráz )" msgid " - Minimum value : 1 ( Allows 1 parallel download, allows 2 downloads at a time )" -msgstr "" +msgstr " - Minimální hodnota : 1 (Povolí 1 paralelní stahování, povolí 2 stahování naráz)" msgid " - Disable/Default : 0 ( Disables parallel downloading, allows only 1 download at a time )" -msgstr "" +msgstr " - Zakázáno/Výchozí : 0 (Zakáže paralelní stahování, povolí pouze 1 stahování naráz)" #, python-brace-format msgid "Invalid input! Try again with a valid input [1 to {max_downloads}, or 0 to disable]" -msgstr "" +msgstr "Neplatný vstup! Zkuste to, prosím, znovu s platným vstupem [1 až {max_downloads}, nebo 0 pro vypnutí]" msgid "Parallel Downloads" -msgstr "" +msgstr "Paralelní stahování" -- cgit v1.2.3-54-g00ecf From 2d9804f8809f54c198c50519c66f19ee0e2ea1da Mon Sep 17 00:00:00 2001 From: Joel Larson <519553+JoelLarson@users.noreply.github.com> Date: Fri, 9 Sep 2022 01:17:31 -0600 Subject: Update locale files with ./locales_generator.sh to be current (#1372) --- archinstall/locales/ar/LC_MESSAGES/base.po | 9 +++++++++ archinstall/locales/base.pot | 9 +++++++++ archinstall/locales/cs/LC_MESSAGES/base.po | 10 ++++++++++ archinstall/locales/de/LC_MESSAGES/base.po | 10 ++++++++++ archinstall/locales/el/LC_MESSAGES/base.po | 10 ++++++++++ archinstall/locales/en/LC_MESSAGES/base.po | 9 +++++++++ archinstall/locales/es/LC_MESSAGES/base.po | 10 ++++++++++ archinstall/locales/fr/LC_MESSAGES/base.po | 10 ++++++++++ archinstall/locales/it/LC_MESSAGES/base.po | 10 ++++++++++ archinstall/locales/nl/LC_MESSAGES/base.po | 10 ++++++++++ archinstall/locales/pl/LC_MESSAGES/base.po | 10 ++++++++++ archinstall/locales/pt/LC_MESSAGES/base.po | 12 ++++++++++++ archinstall/locales/pt_BR/LC_MESSAGES/base.po | 10 ++++++++++ archinstall/locales/ru/LC_MESSAGES/base.mo | Bin 33483 -> 33485 bytes archinstall/locales/ru/LC_MESSAGES/base.po | 10 ++++++++++ archinstall/locales/sv/LC_MESSAGES/base.po | 10 ++++++++++ archinstall/locales/ta/LC_MESSAGES/base.po | 10 ++++++++++ archinstall/locales/tr/LC_MESSAGES/base.po | 10 ++++++++++ archinstall/locales/ur/LC_MESSAGES/base.po | 10 ++++++++++ 19 files changed, 179 insertions(+) (limited to 'archinstall') diff --git a/archinstall/locales/ar/LC_MESSAGES/base.po b/archinstall/locales/ar/LC_MESSAGES/base.po index ac14f102..51b6c3d6 100644 --- a/archinstall/locales/ar/LC_MESSAGES/base.po +++ b/archinstall/locales/ar/LC_MESSAGES/base.po @@ -773,3 +773,12 @@ msgstr "" msgid "Parallel Downloads" msgstr "" + +msgid "ESC to skip" +msgstr "" + +msgid "CTRL+C to reset" +msgstr "" + +msgid "TAB to select" +msgstr "" diff --git a/archinstall/locales/base.pot b/archinstall/locales/base.pot index b2be65f8..e08dfdc3 100644 --- a/archinstall/locales/base.pot +++ b/archinstall/locales/base.pot @@ -823,3 +823,12 @@ msgstr "" msgid "Parallel Downloads" msgstr "" + +msgid "ESC to skip" +msgstr "" + +msgid "CTRL+C to reset" +msgstr "" + +msgid "TAB to select" +msgstr "" diff --git a/archinstall/locales/cs/LC_MESSAGES/base.po b/archinstall/locales/cs/LC_MESSAGES/base.po index 6b6b9c3e..733c9cae 100644 --- a/archinstall/locales/cs/LC_MESSAGES/base.po +++ b/archinstall/locales/cs/LC_MESSAGES/base.po @@ -811,3 +811,13 @@ msgstr "Neplatný vstup! Zkuste to, prosím, znovu s platným vstupem [1 až {ma msgid "Parallel Downloads" msgstr "Paralelní stahování" + +#, fuzzy +msgid "ESC to skip" +msgstr "Pomocí ESC přeskočíte" + +msgid "CTRL+C to reset" +msgstr "" + +msgid "TAB to select" +msgstr "" diff --git a/archinstall/locales/de/LC_MESSAGES/base.po b/archinstall/locales/de/LC_MESSAGES/base.po index 11fc821d..46782bc3 100644 --- a/archinstall/locales/de/LC_MESSAGES/base.po +++ b/archinstall/locales/de/LC_MESSAGES/base.po @@ -834,6 +834,16 @@ msgstr "" msgid "Parallel Downloads" msgstr "" +#, fuzzy +msgid "ESC to skip" +msgstr "ESC drücken um zu überspringen" + +msgid "CTRL+C to reset" +msgstr "" + +msgid "TAB to select" +msgstr "" + #~ msgid "Select disk layout" #~ msgstr "Laufwerke-layout auswählen" diff --git a/archinstall/locales/el/LC_MESSAGES/base.po b/archinstall/locales/el/LC_MESSAGES/base.po index 9b342ac9..6425ba96 100644 --- a/archinstall/locales/el/LC_MESSAGES/base.po +++ b/archinstall/locales/el/LC_MESSAGES/base.po @@ -818,3 +818,13 @@ msgstr "Μη έγκυρη είσοδος! Προσπαθήστε ξανά με msgid "Parallel Downloads" msgstr "Παράλληλες Λήψεις" + +#, fuzzy +msgid "ESC to skip" +msgstr "Χρησιμοποιήστε ESC για παράλειψη" + +msgid "CTRL+C to reset" +msgstr "" + +msgid "TAB to select" +msgstr "" diff --git a/archinstall/locales/en/LC_MESSAGES/base.po b/archinstall/locales/en/LC_MESSAGES/base.po index 01d4414f..01f59274 100644 --- a/archinstall/locales/en/LC_MESSAGES/base.po +++ b/archinstall/locales/en/LC_MESSAGES/base.po @@ -769,3 +769,12 @@ msgstr "" msgid "Parallel Downloads" msgstr "" + +msgid "ESC to skip" +msgstr "" + +msgid "CTRL+C to reset" +msgstr "" + +msgid "TAB to select" +msgstr "" diff --git a/archinstall/locales/es/LC_MESSAGES/base.po b/archinstall/locales/es/LC_MESSAGES/base.po index 6186b6d8..3bdbe72f 100644 --- a/archinstall/locales/es/LC_MESSAGES/base.po +++ b/archinstall/locales/es/LC_MESSAGES/base.po @@ -817,6 +817,16 @@ msgstr "" msgid "Parallel Downloads" msgstr "" +#, fuzzy +msgid "ESC to skip" +msgstr "Use ESC para saltar" + +msgid "CTRL+C to reset" +msgstr "" + +msgid "TAB to select" +msgstr "" + #~ msgid "Select disk layout" #~ msgstr "Seleccione el diseño del disco" diff --git a/archinstall/locales/fr/LC_MESSAGES/base.po b/archinstall/locales/fr/LC_MESSAGES/base.po index 2d7de615..f85c9e25 100644 --- a/archinstall/locales/fr/LC_MESSAGES/base.po +++ b/archinstall/locales/fr/LC_MESSAGES/base.po @@ -823,6 +823,16 @@ msgstr "" msgid "Parallel Downloads" msgstr "" +#, fuzzy +msgid "ESC to skip" +msgstr "Utiliser ESC pour ignorer" + +msgid "CTRL+C to reset" +msgstr "" + +msgid "TAB to select" +msgstr "" + #~ msgid "Select disk layout" #~ msgstr "Sélectionner la disposition du disque" diff --git a/archinstall/locales/it/LC_MESSAGES/base.po b/archinstall/locales/it/LC_MESSAGES/base.po index 893fe292..905ad7cf 100644 --- a/archinstall/locales/it/LC_MESSAGES/base.po +++ b/archinstall/locales/it/LC_MESSAGES/base.po @@ -825,3 +825,13 @@ msgstr "" msgid "Parallel Downloads" msgstr "" + +#, fuzzy +msgid "ESC to skip" +msgstr "Usa ESC per saltare" + +msgid "CTRL+C to reset" +msgstr "" + +msgid "TAB to select" +msgstr "" diff --git a/archinstall/locales/nl/LC_MESSAGES/base.po b/archinstall/locales/nl/LC_MESSAGES/base.po index aa7754d2..4eb93e22 100644 --- a/archinstall/locales/nl/LC_MESSAGES/base.po +++ b/archinstall/locales/nl/LC_MESSAGES/base.po @@ -849,6 +849,16 @@ msgstr "" msgid "Parallel Downloads" msgstr "" +#, fuzzy +msgid "ESC to skip" +msgstr "Druk op Esc om over te slaan\n" + +msgid "CTRL+C to reset" +msgstr "" + +msgid "TAB to select" +msgstr "" + #~ msgid "Select disk layout" #~ msgstr "Kies een schijfindeling" diff --git a/archinstall/locales/pl/LC_MESSAGES/base.po b/archinstall/locales/pl/LC_MESSAGES/base.po index c65126ea..9b12b024 100644 --- a/archinstall/locales/pl/LC_MESSAGES/base.po +++ b/archinstall/locales/pl/LC_MESSAGES/base.po @@ -831,6 +831,16 @@ msgstr "" msgid "Parallel Downloads" msgstr "" +#, fuzzy +msgid "ESC to skip" +msgstr "Kliknij ESC aby pominąć" + +msgid "CTRL+C to reset" +msgstr "" + +msgid "TAB to select" +msgstr "" + #~ msgid "Select disk layout" #~ msgstr "Wybierz układ dysku" diff --git a/archinstall/locales/pt/LC_MESSAGES/base.po b/archinstall/locales/pt/LC_MESSAGES/base.po index 98d261a9..55569546 100644 --- a/archinstall/locales/pt/LC_MESSAGES/base.po +++ b/archinstall/locales/pt/LC_MESSAGES/base.po @@ -869,6 +869,18 @@ msgstr "" msgid "Parallel Downloads" msgstr "" +#, fuzzy +msgid "ESC to skip" +msgstr "" +"Usa ESC para saltar\n" +"\n" + +msgid "CTRL+C to reset" +msgstr "" + +msgid "TAB to select" +msgstr "" + #~ msgid "Select disk layout" #~ msgstr "Seleciona o esquema de disco" diff --git a/archinstall/locales/pt_BR/LC_MESSAGES/base.po b/archinstall/locales/pt_BR/LC_MESSAGES/base.po index 3acbdb95..73a25b19 100644 --- a/archinstall/locales/pt_BR/LC_MESSAGES/base.po +++ b/archinstall/locales/pt_BR/LC_MESSAGES/base.po @@ -813,3 +813,13 @@ msgstr "" msgid "Parallel Downloads" msgstr "" + +#, fuzzy +msgid "ESC to skip" +msgstr "Use ESC para pular" + +msgid "CTRL+C to reset" +msgstr "" + +msgid "TAB to select" +msgstr "" diff --git a/archinstall/locales/ru/LC_MESSAGES/base.mo b/archinstall/locales/ru/LC_MESSAGES/base.mo index 6c0f8450..9d9a0c17 100644 Binary files a/archinstall/locales/ru/LC_MESSAGES/base.mo and b/archinstall/locales/ru/LC_MESSAGES/base.mo differ diff --git a/archinstall/locales/ru/LC_MESSAGES/base.po b/archinstall/locales/ru/LC_MESSAGES/base.po index 8aeb57ff..e643e82b 100644 --- a/archinstall/locales/ru/LC_MESSAGES/base.po +++ b/archinstall/locales/ru/LC_MESSAGES/base.po @@ -817,6 +817,16 @@ msgstr "" msgid "Parallel Downloads" msgstr "" +#, fuzzy +msgid "ESC to skip" +msgstr "Используйте ESC, чтобы пропустить" + +msgid "CTRL+C to reset" +msgstr "" + +msgid "TAB to select" +msgstr "" + #, python-brace-format #~ msgid "Edit {origkey} :" #~ msgstr "Редактировать {origkey}:" diff --git a/archinstall/locales/sv/LC_MESSAGES/base.po b/archinstall/locales/sv/LC_MESSAGES/base.po index 590929c6..9d7f7455 100644 --- a/archinstall/locales/sv/LC_MESSAGES/base.po +++ b/archinstall/locales/sv/LC_MESSAGES/base.po @@ -830,5 +830,15 @@ msgstr "" msgid "Parallel Downloads" msgstr "" +#, fuzzy +msgid "ESC to skip" +msgstr "Använd ESC för att hoppa över" + +msgid "CTRL+C to reset" +msgstr "" + +msgid "TAB to select" +msgstr "" + #~ msgid "Select disk layout" #~ msgstr "Välj hårddisk-layout" diff --git a/archinstall/locales/ta/LC_MESSAGES/base.po b/archinstall/locales/ta/LC_MESSAGES/base.po index 3c1cd848..fa32830b 100644 --- a/archinstall/locales/ta/LC_MESSAGES/base.po +++ b/archinstall/locales/ta/LC_MESSAGES/base.po @@ -818,3 +818,13 @@ msgstr "தவறான உள்ளீடு! சரியான உள்ள msgid "Parallel Downloads" msgstr "இணையான பதிவிறக்கங்கள்" + +#, fuzzy +msgid "ESC to skip" +msgstr "தவிர்க்க ESC ஐப் பயன்படுத்தவும்" + +msgid "CTRL+C to reset" +msgstr "" + +msgid "TAB to select" +msgstr "" diff --git a/archinstall/locales/tr/LC_MESSAGES/base.po b/archinstall/locales/tr/LC_MESSAGES/base.po index 63f9dee0..c38f467e 100644 --- a/archinstall/locales/tr/LC_MESSAGES/base.po +++ b/archinstall/locales/tr/LC_MESSAGES/base.po @@ -829,3 +829,13 @@ msgstr "" msgid "Parallel Downloads" msgstr "" + +#, fuzzy +msgid "ESC to skip" +msgstr "Geçmek için ESC'yi kullanın" + +msgid "CTRL+C to reset" +msgstr "" + +msgid "TAB to select" +msgstr "" diff --git a/archinstall/locales/ur/LC_MESSAGES/base.po b/archinstall/locales/ur/LC_MESSAGES/base.po index 6494ae28..8ab6c4e2 100644 --- a/archinstall/locales/ur/LC_MESSAGES/base.po +++ b/archinstall/locales/ur/LC_MESSAGES/base.po @@ -851,6 +851,16 @@ msgstr "" msgid "Parallel Downloads" msgstr "" +#, fuzzy +msgid "ESC to skip" +msgstr "چھوڑنے کے لیے ESC استعمال کریں\n" + +msgid "CTRL+C to reset" +msgstr "" + +msgid "TAB to select" +msgstr "" + #~ msgid "Select disk layout" #~ msgstr "ڈسک لے آؤٹ کو منتخب کریں" -- cgit v1.2.3-54-g00ecf From c373607f8c9548bf9de55988629b747f32d67b3d Mon Sep 17 00:00:00 2001 From: Alexmelman88 <99257010+Alexmelman88@users.noreply.github.com> Date: Sat, 10 Sep 2022 11:26:10 +0300 Subject: Update pot file, ru locale (#1465) * Update general_conf.py * Add files via upload * Add files via upload --- archinstall/lib/user_interaction/general_conf.py | 2 +- archinstall/locales/base.pot | 3 +++ archinstall/locales/ru/LC_MESSAGES/base.mo | Bin 33485 -> 35756 bytes archinstall/locales/ru/LC_MESSAGES/base.po | 27 ++++++++++++++--------- 4 files changed, 20 insertions(+), 12 deletions(-) (limited to 'archinstall') diff --git a/archinstall/lib/user_interaction/general_conf.py b/archinstall/lib/user_interaction/general_conf.py index a121f368..34c80c21 100644 --- a/archinstall/lib/user_interaction/general_conf.py +++ b/archinstall/lib/user_interaction/general_conf.py @@ -217,7 +217,7 @@ def add_number_of_parrallel_downloads(input_number :Optional[int] = None) -> Opt while True: try: - input_number = int(TextInput("[Default value: 0] > ").run().strip() or 0) + input_number = int(TextInput(_("[Default value: 0] > ")).run().strip() or 0) if input_number <= 0: input_number = 0 elif input_number > max_downloads: diff --git a/archinstall/locales/base.pot b/archinstall/locales/base.pot index e08dfdc3..0b08b337 100644 --- a/archinstall/locales/base.pot +++ b/archinstall/locales/base.pot @@ -832,3 +832,6 @@ msgstr "" msgid "TAB to select" msgstr "" + +msgid "[Default value: 0] > " +msgstr "" diff --git a/archinstall/locales/ru/LC_MESSAGES/base.mo b/archinstall/locales/ru/LC_MESSAGES/base.mo index 9d9a0c17..8b3f0ae4 100644 Binary files a/archinstall/locales/ru/LC_MESSAGES/base.mo and b/archinstall/locales/ru/LC_MESSAGES/base.mo differ diff --git a/archinstall/locales/ru/LC_MESSAGES/base.po b/archinstall/locales/ru/LC_MESSAGES/base.po index e643e82b..6d5799eb 100644 --- a/archinstall/locales/ru/LC_MESSAGES/base.po +++ b/archinstall/locales/ru/LC_MESSAGES/base.po @@ -10,7 +10,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : 2);\n" -"X-Generator: Poedit 3.0.1\n" +"X-Generator: Poedit 3.1\n" msgid "[!] A log file has been created here: {} {}" msgstr "[!] Здесь был создан файл журнала: {} {}" @@ -792,7 +792,7 @@ msgid "Configured {} interfaces" msgstr "Настроено интерфейсов: {}" msgid "This option enables the number of parallel downloads that can occur during installation" -msgstr "" +msgstr "Этот параметр определяет количество параллельных загрузок, которые могут происходить во время установки" #, python-brace-format msgid "" @@ -800,32 +800,37 @@ msgid "" " (Enter a value between 1 to {max_downloads})\n" "Note:" msgstr "" +"Введите количество параллельных загрузок, которые будут включены.\n" +" (Введите значение от 1 до {max_downloads})\n" +"Примечание:" msgid " - Maximum value : {max_downloads} ( Allows {max_downloads} parallel downloads, allows {max_downloads+1} downloads at a time )" -msgstr "" +msgstr " - Максимальное значение: {max_downloads} ( Позволяет {max_downloads} параллельных загрузок, позволяет {max_downloads+1} загрузок одновременно )" msgid " - Minimum value : 1 ( Allows 1 parallel download, allows 2 downloads at a time )" -msgstr "" +msgstr " - Минимальное значение: 1 ( Позволяет 1 параллельную загрузку, позволяет 2 загрузки одновременно )" msgid " - Disable/Default : 0 ( Disables parallel downloading, allows only 1 download at a time )" -msgstr "" +msgstr " - Отключить/по умолчанию: 0 ( Отключает параллельную загрузку, позволяет только 1 загрузку за один раз )" #, python-brace-format msgid "Invalid input! Try again with a valid input [1 to {max_downloads}, or 0 to disable]" -msgstr "" +msgstr "Неверный ввод! Повторите попытку с правильным вводом [1 - {max_downloads}, или 0 - отключить]" msgid "Parallel Downloads" -msgstr "" +msgstr "Параллельные загрузки" -#, fuzzy msgid "ESC to skip" -msgstr "Используйте ESC, чтобы пропустить" +msgstr "ESC, чтобы пропустить" msgid "CTRL+C to reset" -msgstr "" +msgstr "CTRL+C, чтобы сбросить" msgid "TAB to select" -msgstr "" +msgstr "TAB, чтобы выбрать" + +msgid "[Default value: 0] > " +msgstr "[Значение по умолчанию: 0] > " #, python-brace-format #~ msgid "Edit {origkey} :" -- cgit v1.2.3-54-g00ecf From 94df913e0f2e68178ad64d385bbc453416b7e4b0 Mon Sep 17 00:00:00 2001 From: Daniel Girtler Date: Mon, 12 Sep 2022 05:23:21 +1000 Subject: Update handling of unsupported translations (#1467) * Handle unsupported fonts * Update archinstall/locales/README.md Co-authored-by: codefiles <11915375+codefiles@users.noreply.github.com> Co-authored-by: Daniel Girtler Co-authored-by: codefiles <11915375+codefiles@users.noreply.github.com> --- archinstall/lib/menu/menu.py | 18 +++++++--- archinstall/lib/translationhandler.py | 42 ++++++++++++++++-------- archinstall/lib/user_interaction/general_conf.py | 26 ++++++++++++--- archinstall/locales/README.md | 22 +++++++++++-- archinstall/locales/languages.json | 4 +-- 5 files changed, 85 insertions(+), 27 deletions(-) (limited to 'archinstall') diff --git a/archinstall/lib/menu/menu.py b/archinstall/lib/menu/menu.py index 16153e2c..112bc0ae 100644 --- a/archinstall/lib/menu/menu.py +++ b/archinstall/lib/menu/menu.py @@ -1,7 +1,7 @@ from dataclasses import dataclass from enum import Enum, auto from os import system -from typing import Dict, List, Union, Any, TYPE_CHECKING, Optional +from typing import Dict, List, Union, Any, TYPE_CHECKING, Optional, Callable from archinstall.lib.menu.simple_menu import TerminalMenu @@ -52,9 +52,9 @@ class Menu(TerminalMenu): sort :bool = True, preset_values :Union[str, List[str]] = None, cursor_index : Optional[int] = None, - preview_command=None, - preview_size=0.75, - preview_title='Info', + preview_command: Optional[Callable] = None, + preview_size: float = 0.75, + preview_title: str = 'Info', header :Union[List[str],str] = None, raise_error_on_interrupt :bool = False, raise_error_warning_msg :str = '', @@ -152,6 +152,7 @@ class Menu(TerminalMenu): self._multi = multi self._raise_error_on_interrupt = raise_error_on_interrupt self._raise_error_warning_msg = raise_error_warning_msg + self._preview_command = preview_command menu_title = f'\n{title}\n\n' @@ -198,7 +199,7 @@ class Menu(TerminalMenu): # show_search_hint=True, preselected_entries=self.preset_values, cursor_index=self.cursor_index, - preview_command=preview_command, + preview_command=lambda x: self._preview_wrapper(preview_command, x), preview_size=preview_size, preview_title=preview_title, raise_error_on_interrupt=self._raise_error_on_interrupt, @@ -235,6 +236,13 @@ class Menu(TerminalMenu): else: return MenuSelection(type_=MenuSelectionType.Esc) + def _preview_wrapper(self, preview_command: Optional[Callable], current_selection: str) -> Optional[str]: + if preview_command: + if self._default_option is not None and f'{self._default_option} {self._default_str}' == current_selection: + current_selection = self._default_option + return preview_command(current_selection) + return None + def run(self) -> MenuSelection: ret = self._show() diff --git a/archinstall/lib/translationhandler.py b/archinstall/lib/translationhandler.py index 08deb3e7..ef33b8ec 100644 --- a/archinstall/lib/translationhandler.py +++ b/archinstall/lib/translationhandler.py @@ -17,41 +17,55 @@ if TYPE_CHECKING: @dataclass class Language: abbr: str - lang: str + name_en: str translation: gettext.NullTranslations translation_percent: int translated_lang: Optional[str] + external_dep: Optional[str] @property def display_name(self) -> str: - if self.translated_lang: + if not self.external_dep and self.translated_lang: name = self.translated_lang else: - name = self.lang + name = self.name_en + return f'{name} ({self.translation_percent}%)' def is_match(self, lang_or_translated_lang: str) -> bool: - if self.lang == lang_or_translated_lang: + if self.name_en == lang_or_translated_lang: return True elif self.translated_lang == lang_or_translated_lang: return True return False def json(self) -> str: - return self.lang + return self.name_en class TranslationHandler: - _base_pot = 'base.pot' - _languages = 'languages.json' - def __init__(self): - # to display latin, greek, cyrillic characters - self._set_font('LatGrkCyr-8x16') + self._base_pot = 'base.pot' + self._languages = 'languages.json' + + # check if a custom font was provided, otherwise we'll + # use one that can display latin, greek, cyrillic characters + if self.is_custom_font_enabled(): + self._set_font(self.custom_font_path().name) + else: + self._set_font('LatGrkCyr-8x16') self._total_messages = self._get_total_active_messages() self._translated_languages = self._get_translations() + @classmethod + def custom_font_path(cls) -> Path: + return Path('/usr/share/kbd/consolefonts/archinstall_font.psfu.gz') + + @classmethod + def is_custom_font_enabled(cls) -> bool: + return cls.custom_font_path().exists() + @property def translated_languages(self) -> List[Language]: return self._translated_languages @@ -70,6 +84,7 @@ class TranslationHandler: abbr = mapping_entry['abbr'] lang = mapping_entry['lang'] translated_lang = mapping_entry.get('translated_lang', None) + external_dep = mapping_entry.get('external_dep', False) try: # get a translation for a specific language @@ -84,7 +99,7 @@ class TranslationHandler: # prevent cases where the .pot file is out of date and the percentage is above 100 percent = min(100, percent) - language = Language(abbr, lang, translation, percent, translated_lang) + language = Language(abbr, lang, translation, percent, translated_lang, external_dep) languages.append(language) except FileNotFoundError as error: raise TranslationError(f"Could not locate language file for '{lang}': {error}") @@ -138,7 +153,7 @@ class TranslationHandler: Get a language object by it's name, e.g. English """ try: - return next(filter(lambda x: x.lang == name, self._translated_languages)) + return next(filter(lambda x: x.name_en == name, self._translated_languages)) except Exception: raise ValueError(f'No language with name found: {name}') @@ -175,8 +190,7 @@ class TranslationHandler: translation_files = [] for filename in filenames: if len(filename) == 2 or filename == 'pt_BR': - if filename not in ['ur', 'ta']: - translation_files.append(filename) + translation_files.append(filename) return translation_files diff --git a/archinstall/lib/user_interaction/general_conf.py b/archinstall/lib/user_interaction/general_conf.py index 34c80c21..6365014d 100644 --- a/archinstall/lib/user_interaction/general_conf.py +++ b/archinstall/lib/user_interaction/general_conf.py @@ -13,7 +13,7 @@ from ..output import log from ..profiles import Profile, list_profiles from ..mirrors import list_mirrors -from ..translationhandler import Language +from ..translationhandler import Language, TranslationHandler from ..packages.packages import validate_package_list from ..storage import storage @@ -125,16 +125,34 @@ def select_archinstall_language(languages: List[Language], preset_value: Languag # name of the language in its own language options = {lang.display_name: lang for lang in languages} + def dependency_preview(current_selection: str) -> Optional[str]: + current_lang = options[current_selection] + + if current_lang.external_dep and not TranslationHandler.is_custom_font_enabled(): + font_file = TranslationHandler.custom_font_path() + text = str(_('To be able to use this translation, please install a font manually that supports the language.')) + '\n' + text += str(_('The font should be stored as {}')).format(font_file) + return text + return None + choice = Menu( _('Archinstall language'), list(options.keys()), - default_option=preset_value.display_name + default_option=preset_value.display_name, + preview_command=lambda x: dependency_preview(x), + preview_size=0.5 ).run() match choice.type_: - case MenuSelectionType.Esc: return preset_value + case MenuSelectionType.Esc: + return preset_value case MenuSelectionType.Selection: - return options[choice.value] + language: Language = options[choice.value] + # we have to make sure that the proper AUR dependency is + # present to be able to use this language + if not language.external_dep or TranslationHandler.is_custom_font_enabled(): + return language + return select_archinstall_language(languages, preset_value) def select_profile(preset) -> Optional[Profile]: diff --git a/archinstall/locales/README.md b/archinstall/locales/README.md index 51662702..37dc32e3 100644 --- a/archinstall/locales/README.md +++ b/archinstall/locales/README.md @@ -1,8 +1,26 @@ # Nationalization -Archinstall supports multiple languages, which depend on translations coming from the community :) +Archinstall supports multiple languages, which depend on translations coming from the community :) -New languages can be added simply by creating a new folder with the proper language abbrevation (see list `languages.json` if unsure). +## Important Note +Before starting a new language translation be aware that a font for that language may not be +available on the ISO. We are using the pre-installed font `/usr/share/kbd/consolefonts/LatGrkCyr-8x16.psfu.gz` in archinstall +which should cover a fair amount of different languages but unfortunately not all of them. + +We have the option to provide a custom font in case the above is not covering a specific language, which can +be achieved by installing the font yourself on the ISO and saving it to `/usr/share/kbd/consolefonts/archinstall_font.psfu.gz`. +If this font is present it will be automatically loaded and all languages which are not supported by the default font will +be enabled (but only some might actually work). + +Please make sure that the provided language works with the default font on the ISO, and if not mark it in the `languages.json` +that it needs an external dependency +``` +{"abbr": "ur", "lang": "Urdu", "translated_lang": "اردو", "external_dep": true}, +``` + +## Adding new languages + +New languages can be added simply by creating a new folder with the proper language abbreviation (see list `languages.json` if unsure). Run the following command to create a new template for a language ``` mkdir -p /LC_MESSAGES/ && touch /LC_MESSAGES/base.po diff --git a/archinstall/locales/languages.json b/archinstall/locales/languages.json index 55ddf57e..344d3d51 100644 --- a/archinstall/locales/languages.json +++ b/archinstall/locales/languages.json @@ -155,7 +155,7 @@ {"abbr": "sw", "lang": "Swahili (macrolanguage)"}, {"abbr": "sv", "lang": "Swedish", "translated_lang": "Svenska"}, {"abbr": "ty", "lang": "Tahitian"}, - {"abbr": "ta", "lang": "Tamil", "translated_lang": "தமிழ்"}, + {"abbr": "ta", "lang": "Tamil", "translated_lang": "தமிழ்", "external_dep": true}, {"abbr": "tt", "lang": "Tatar"}, {"abbr": "te", "lang": "Telugu"}, {"abbr": "tg", "lang": "Tajik"}, @@ -170,7 +170,7 @@ {"abbr": "tw", "lang": "Twi"}, {"abbr": "ug", "lang": "Uighur"}, {"abbr": "uk", "lang": "Ukrainian"}, - {"abbr": "ur", "lang": "Urdu", "translated_lang": "اردو"}, + {"abbr": "ur", "lang": "Urdu", "translated_lang": "اردو", "external_dep": true}, {"abbr": "uz", "lang": "Uzbek"}, {"abbr": "ve", "lang": "Venda"}, {"abbr": "vi", "lang": "Vietnamese"}, -- cgit v1.2.3-54-g00ecf From e83a41f3f51f54eccbe9288638759dc9669bfef6 Mon Sep 17 00:00:00 2001 From: Ali Date: Mon, 12 Sep 2022 02:35:05 +0700 Subject: Add Indonesian translation (#1468) * Add Indonesian translation * Update README * Update id translation --- README.md | 3 +- archinstall/locales/id/LC_MESSAGES/base.mo | Bin 0 -> 26367 bytes archinstall/locales/id/LC_MESSAGES/base.po | 832 +++++++++++++++++++++++++++++ archinstall/locales/languages.json | 2 +- 4 files changed, 835 insertions(+), 2 deletions(-) create mode 100644 archinstall/locales/id/LC_MESSAGES/base.mo create mode 100644 archinstall/locales/id/LC_MESSAGES/base.po (limited to 'archinstall') diff --git a/README.md b/README.md index 0027991d..5ce5e89e 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,8 @@ Current translations are listed below and vary in the amount of translations per English Deutsch Española -Française +Française +Indonesia Italiano Nederlands Polskie diff --git a/archinstall/locales/id/LC_MESSAGES/base.mo b/archinstall/locales/id/LC_MESSAGES/base.mo new file mode 100644 index 00000000..c02df9eb Binary files /dev/null and b/archinstall/locales/id/LC_MESSAGES/base.mo differ diff --git a/archinstall/locales/id/LC_MESSAGES/base.po b/archinstall/locales/id/LC_MESSAGES/base.po new file mode 100644 index 00000000..0ace1b09 --- /dev/null +++ b/archinstall/locales/id/LC_MESSAGES/base.po @@ -0,0 +1,832 @@ +msgid "" +msgstr "" +"Project-Id-Version: \n" +"POT-Creation-Date: \n" +"PO-Revision-Date: \n" +"Last-Translator: Ali Rohman \n" +"Language-Team: \n" +"Language: id\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 3.1\n" + +msgid "[!] A log file has been created here: {} {}" +msgstr "[!] File log telah dibuat di sini: {} {}" + +msgid " Please submit this issue (and file) to https://github.com/archlinux/archinstall/issues" +msgstr " Silakan kirimkan masalah ini (dan file) ke https://github.com/archlinux/archinstall/issues" + +msgid "Do you really want to abort?" +msgstr "Apakah Anda benar-benar ingin membatalkan?" + +msgid "And one more time for verification: " +msgstr "Dan sekali lagi untuk verifikasi: " + +msgid "Would you like to use swap on zram?" +msgstr "Apakah Anda ingin menggunakan swap di zram?" + +msgid "Desired hostname for the installation: " +msgstr "Nama host yang diinginkan untuk instalasi: " + +msgid "Username for required superuser with sudo privileges: " +msgstr "Nama pengguna untuk superuser yang diperlukan dengan hak sudo: " + +msgid "Any additional users to install (leave blank for no users): " +msgstr "Beberapa pengguna tambahan untuk dipasang (biarkan kosong untuk tidak menambahkan): " + +msgid "Should this user be a superuser (sudoer)?" +msgstr "Haruskah pengguna ini menjadi superuser (sudoer)?" + +msgid "Select a timezone" +msgstr "Pilih zona waktu" + +msgid "Would you like to use GRUB as a bootloader instead of systemd-boot?" +msgstr "Apakah Anda ingin menggunakan GRUB sebagai bootloader daripada systemd-boot?" + +msgid "Choose a bootloader" +msgstr "Pilih bootloader" + +msgid "Choose an audio server" +msgstr "Pilih server audio" + +msgid "Only packages such as base, base-devel, linux, linux-firmware, efibootmgr and optional profile packages are installed." +msgstr "Hanya paket seperti base, base-devel, linux, linux-firmware, efibootmgr dan paket profil opsional yang diinstal." + +msgid "If you desire a web browser, such as firefox or chromium, you may specify it in the following prompt." +msgstr "Jika Anda menginginkan web browser, seperti firefox atau chromium, Anda dapat menentukannya di prompt berikut." + +msgid "Write additional packages to install (space separated, leave blank to skip): " +msgstr "Ketik paket tambahan untuk diinstal (dipisahkan dengan spasi, biarkan kosong untuk dilewati): " + +msgid "Copy ISO network configuration to installation" +msgstr "Salin konfigurasi jaringan ISO ke instalasi" + +msgid "Use NetworkManager (necessary to configure internet graphically in GNOME and KDE)" +msgstr "Gunakan NetworkManager (diperlukan untuk mengkonfigurasi internet secara grafis di GNOME dan KDE)" + +msgid "Select one network interface to configure" +msgstr "Pilih satu interface jaringan untuk dikonfigurasi" + +msgid "Select which mode to configure for \"{}\" or skip to use default mode \"{}\"" +msgstr "Pilih mode mana yang akan dikonfigurasi untuk \"{}\" atau lewati untuk menggunakan mode default \"{}\"" + +msgid "Enter the IP and subnet for {} (example: 192.168.0.5/24): " +msgstr "Masukkan IP dan subnet untuk {} (contoh: 192.168.0.5/24): " + +msgid "Enter your gateway (router) IP address or leave blank for none: " +msgstr "Masukkan IP gateway (router) Anda atau biarkan kosong untuk tidak menggunakan apa pun: " + +msgid "Enter your DNS servers (space separated, blank for none): " +msgstr "Masukkan server DNS Anda (dipisahkan dengan spasi, untuk kosongkan tidak menggunakan apa pun): " + +msgid "Select which filesystem your main partition should use" +msgstr "Pilih filesystem mana yang harus digunakan partisi utama Anda" + +msgid "Current partition layout" +msgstr "Tata letak partisi saat ini" + +msgid "" +"Select what to do with\n" +"{}" +msgstr "" +"Pilih apa yang harus dilakukan dengan\n" +"{}" + +msgid "Enter a desired filesystem type for the partition" +msgstr "Masukkan jenis filesystem yang diinginkan untuk partisi" + +msgid "Enter the start sector (percentage or block number, default: {}): " +msgstr "Masukkan sektor awal (persentase atau nomor blok, default: {}): " + +msgid "Enter the end sector of the partition (percentage or block number, ex: {}): " +msgstr "Masukkan sektor akhir partisi (persentase atau nomor blok, mis: {}): " + +msgid "{} contains queued partitions, this will remove those, are you sure?" +msgstr "{} berisi partisi yang mengantri, ini akan menghapusnya, apakah Anda yakin?" + +msgid "" +"{}\n" +"\n" +"Select by index which partitions to delete" +msgstr "" +"{}\n" +"\n" +"Pilih berdasarkan indeks partisi mana yang akan dihapus" + +msgid "" +"{}\n" +"\n" +"Select by index which partition to mount where" +msgstr "" +"{}\n" +"\n" +"Pilih berdasarkan indeks partisi mana yang akan di mount" + +msgid " * Partition mount-points are relative to inside the installation, the boot would be /boot as an example." +msgstr " * Mount point partisi relatif terhadap di dalam instalasi, boot akan menjadi /boot sebagai contoh." + +msgid "Select where to mount partition (leave blank to remove mountpoint): " +msgstr "Pilih tempat untuk memasang partisi (biarkan kosong untuk menghapus mountpoint): " + +msgid "" +"{}\n" +"\n" +"Select which partition to mask for formatting" +msgstr "" +"{}\n" +"\n" +"Pilih partisi mana yang akan di mask untuk pemformatan" + +msgid "" +"{}\n" +"\n" +"Select which partition to mark as encrypted" +msgstr "" +"{}\n" +"\n" +"Pilih partisi mana yang akan ditandai sebagai terenkripsi" + +msgid "" +"{}\n" +"\n" +"Select which partition to mark as bootable" +msgstr "" +"{}\n" +"\n" +"Pilih partisi mana yang akan ditandai sebagai bootable" + +msgid "" +"{}\n" +"\n" +"Select which partition to set a filesystem on" +msgstr "" +"{}\n" +"\n" +"Pilih partisi mana untuk mengatur sistem file" + +msgid "Enter a desired filesystem type for the partition: " +msgstr "Masukkan jenis filesystem yang diinginkan untuk partisi: " + +msgid "Archinstall language" +msgstr "Bahasa Archinstall" + +msgid "Wipe all selected drives and use a best-effort default partition layout" +msgstr "Hapus semua drive yang dipilih dan gunakan upaya terbaik tata letak partisi default" + +msgid "Select what to do with each individual drive (followed by partition usage)" +msgstr "Pilih apa yang harus dilakukan dengan setiap drive individu (diikuti dengan penggunaan partisi)" + +msgid "Select what you wish to do with the selected block devices" +msgstr "Pilih apa yang ingin Anda lakukan dengan perangkat blok yang dipilih" + +msgid "This is a list of pre-programmed profiles, they might make it easier to install things like desktop environments" +msgstr "Ini adalah daftar profil yang telah diprogram sebelumnya, mereka mungkin memudahkan untuk menginstal hal-hal seperti desktop environment" + +msgid "Select keyboard layout" +msgstr "Pilih tata letak keyboard" + +msgid "Select one of the regions to download packages from" +msgstr "Pilih salah satu wilayah untuk mengunduh paket dari mana" + +msgid "Select one or more hard drives to use and configure" +msgstr "Pilih satu atau lebih hard drive untuk digunakan dan dikonfigurasi" + +msgid "For the best compatibility with your AMD hardware, you may want to use either the all open-source or AMD / ATI options." +msgstr "Untuk kompatibilitas terbaik dengan perangkat keras AMD Anda, Anda mungkin ingin menggunakan opsi semua sumber terbuka atau 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 "Untuk kompatibilitas terbaik dengan perangkat keras Intel Anda, Anda mungkin ingin menggunakan opsi semua sumber terbuka atau Intel.\n" + +msgid "For the best compatibility with your Nvidia hardware, you may want to use the Nvidia proprietary driver.\n" +msgstr "Untuk kompatibilitas terbaik dengan perangkat keras Nvidia Anda, Anda mungkin ingin menggunakan driver proprietary Nvidia.\n" + +msgid "" +"\n" +"\n" +"Select a graphics driver or leave blank to install all open-source drivers" +msgstr "" +"\n" +"\n" +"Pilih driver grafis atau biarkan kosong untuk menginstal semua driver open-source" + +msgid "All open-source (default)" +msgstr "Semua sumber terbuka (default)" + +msgid "Choose which kernels to use or leave blank for default \"{}\"" +msgstr "Pilih kernel mana yang akan digunakan atau biarkan kosong untuk \"{}\" default" + +msgid "Choose which locale language to use" +msgstr "Pilih locale bahasa yang akan digunakan" + +msgid "Choose which locale encoding to use" +msgstr "Pilih locale encoding yang akan digunakan" + +msgid "Select one of the values shown below: " +msgstr "Pilih salah satu nilai yang ditunjukkan di bawah ini: " + +msgid "Select one or more of the options below: " +msgstr "Pilih satu atau beberapa opsi di bawah ini: " + +msgid "Adding partition...." +msgstr "Menambahkan partisi...." + +msgid "You need to enter a valid fs-type in order to continue. See `man parted` for valid fs-type's." +msgstr "Anda harus memasukkan tipe fs yang valid untuk melanjutkan. Lihat `man parted` untuk tipe fs yang valid." + +msgid "Error: Listing profiles on URL \"{}\" resulted in:" +msgstr "Kesalahan: Mencantumkan profil pada URL \"{}\" mengakibatkan:" + +msgid "Error: Could not decode \"{}\" result as JSON:" +msgstr "Kesalahan: Tidak dapat mendekode hasil \"{}\" sebagai JSON:" + +msgid "Keyboard layout" +msgstr "Tata letak keyboard" + +msgid "Mirror region" +msgstr "Wilayah mirror" + +msgid "Locale language" +msgstr "Locale language" + +msgid "Locale encoding" +msgstr "Locale encoding" + +msgid "Drive(s)" +msgstr "Drive" + +msgid "Disk layout" +msgstr "Tata letak disk" + +msgid "Encryption password" +msgstr "Kata sandi enkripsi" + +msgid "Swap" +msgstr "Swap" + +msgid "Bootloader" +msgstr "Bootloader" + +msgid "Root password" +msgstr "Kata sandi root" + +msgid "Superuser account" +msgstr "Akun superuser" + +msgid "User account" +msgstr "Akun pengguna" + +msgid "Profile" +msgstr "Profil" + +msgid "Audio" +msgstr "Audio" + +msgid "Kernels" +msgstr "Kernel" + +msgid "Additional packages" +msgstr "Paket tambahan" + +msgid "Network configuration" +msgstr "Konfigurasi jaringan" + +msgid "Automatic time sync (NTP)" +msgstr "Sinkronisasi waktu otomatis (NTP)" + +msgid "Install ({} config(s) missing)" +msgstr "Instal ({} konfigurasi tidak ada)" + +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 "" +"Anda memutuskan untuk melewati pemilihan harddisk\n" +"dan akan menggunakan pengaturan drive apa pun yang dipasang di {} (eksperimental)\n" +"PERINGATAN: Archinstall tidak akan memeriksa kesesuaian pengaturan ini\n" +"Apakah Anda ingin melanjutkan?" + +msgid "Re-using partition instance: {}" +msgstr "Menggunakan kembali instance partisi: {}" + +msgid "Create a new partition" +msgstr "Buat partisi baru" + +msgid "Delete a partition" +msgstr "Hapus partisi" + +msgid "Clear/Delete all partitions" +msgstr "Bersihkan/Hapus semua partisi" + +msgid "Assign mount-point for a partition" +msgstr "Tetapkan titik-mount untuk sebuah partisi" + +msgid "Mark/Unmark a partition to be formatted (wipes data)" +msgstr "Tandai/Hapus tanda partisi yang akan diformat (menghapus data)" + +msgid "Mark/Unmark a partition as encrypted" +msgstr "Tandai/Hapus tanda partisi sebagai terenkripsi" + +msgid "Mark/Unmark a partition as bootable (automatic for /boot)" +msgstr "Tandai/Hapus tanda partisi sebagai bootable (otomatis untuk /boot)" + +msgid "Set desired filesystem for a partition" +msgstr "Atur filesystem yang diinginkan untuk sebuah partisi" + +msgid "Abort" +msgstr "Batalkan" + +msgid "Hostname" +msgstr "Hostname" + +msgid "Not configured, unavailable unless setup manually" +msgstr "Tidak dikonfigurasi, tidak tersedia kecuali diatur secara manual" + +msgid "Timezone" +msgstr "Zona waktu" + +msgid "Set/Modify the below options" +msgstr "Atur/Ubah opsi di bawah ini" + +msgid "Install" +msgstr "Install" + +msgid "" +"Use ESC to skip\n" +"\n" +msgstr "" +"Gunakan ESC untuk melewati\n" +"\n" + +msgid "Suggest partition layout" +msgstr "Saran tata letak partisi" + +msgid "Enter a password: " +msgstr "Masukan kata sandi: " + +msgid "Enter a encryption password for {}" +msgstr "Masukkan sandi enkripsi untuk {}" + +msgid "Enter disk encryption password (leave blank for no encryption): " +msgstr "Masukkan kata sandi enkripsi disk (biarkan kosong jika tidak ada enkripsi): " + +msgid "Create a required super-user with sudo privileges: " +msgstr "Buat pengguna super yang diperlukan dengan hak sudo: " + +msgid "Enter root password (leave blank to disable root): " +msgstr "Masukkan kata sandi root (biarkan kosong untuk menonaktifkan root): " + +msgid "Password for user \"{}\": " +msgstr "Kata sandi untuk pengguna \"{}\": " + +msgid "Verifying that additional packages exist (this might take a few seconds)" +msgstr "Memverifikasi bahwa ada paket tambahan (ini mungkin memakan waktu beberapa detik)" + +msgid "Would you like to use automatic time synchronization (NTP) with the default time servers?\n" +msgstr "Apakah Anda ingin menggunakan sinkronisasi waktu otomatis (NTP) dengan server waktu default?\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 "" +"Waktu perangkat keras dan langkah-langkah pasca-konfigurasi lainnya mungkin diperlukan agar NTP berfungsi.\n" +"Untuk informasi lebih lanjut, silakan periksa Arch wiki" + +msgid "Enter a username to create an additional user (leave blank to skip): " +msgstr "Masukkan nama pengguna untuk membuat pengguna tambahan (biarkan kosong untuk melewati): " + +msgid "Use ESC to skip\n" +msgstr "Gunakan ESC untuk melewati\n" + +msgid "" +"\n" +" Choose an object from the list, and select one of the available actions for it to execute" +msgstr "" +"\n" +"Pilih objek dari daftar, dan pilih salah satu tindakan yang tersedia untuk dieksekusi" + +msgid "Cancel" +msgstr "Batalkan" + +msgid "Confirm and exit" +msgstr "Konfirmasi dan keluar" + +msgid "Add" +msgstr "Tambah" + +msgid "Copy" +msgstr "Salin" + +msgid "Edit" +msgstr "Edit" + +msgid "Delete" +msgstr "Hapus" + +msgid "Select an action for '{}'" +msgstr "Pilih tindakan untuk '{}'" + +msgid "Copy to new key:" +msgstr "Salin ke kunci baru:" + +msgid "Unknown nic type: {}. Possible values are {}" +msgstr "Jenis nic tidak dikenal: {}. Nilai yang mungkin adalah {}" + +msgid "" +"\n" +"This is your chosen configuration:" +msgstr "" +"\n" +"Ini adalah konfigurasi yang Anda pilih:" + +msgid "Pacman is already running, waiting maximum 10 minutes for it to terminate." +msgstr "Pacman sudah berjalan, menunggu maksimal 10 menit untuk berhenti." + +msgid "Pre-existing pacman lock never exited. Please clean up any existing pacman sessions before using archinstall." +msgstr "Pacman lock yang sudah ada tidak pernah keluar. Harap bersihkan sesi pacman yang ada sebelum menggunakan archinstall." + +msgid "Choose which optional additional repositories to enable" +msgstr "Pilih repositori tambahan opsional mana yang akan diaktifkan" + +msgid "Add a user" +msgstr "Tambahkan pengguna" + +msgid "Change password" +msgstr "Ganti kata sandi" + +msgid "Promote/Demote user" +msgstr "Promosikan/Turunkan pengguna" + +msgid "Delete User" +msgstr "Hapus pengguna" + +msgid "" +"\n" +"Define a new user\n" +msgstr "" +"\n" +"Tentukan pengguna baru\n" + +msgid "User Name : " +msgstr "Nama Pengguna : " + +msgid "Should {} be a superuser (sudoer)?" +msgstr "Haruskah {} menjadi superuser (sudoer)?" + +msgid "Define users with sudo privilege: " +msgstr "Tentukan pengguna dengan hak sudo: " + +msgid "No network configuration" +msgstr "Tidak ada konfigurasi jaringan" + +msgid "Set desired subvolumes on a btrfs partition" +msgstr "Atur subvolume yang diinginkan pada partisi btrfs" + +msgid "" +"{}\n" +"\n" +"Select which partition to set subvolumes on" +msgstr "" +"{}\n" +"\n" +"Pilih partisi mana untuk mengatur subvolume" + +msgid "Manage btrfs subvolumes for current partition" +msgstr "Kelola subvolume btrfs untuk partisi saat ini" + +msgid "No configuration" +msgstr "Tidak ada konfigurasi" + +msgid "Save user configuration" +msgstr "Simpan konfigurasi pengguna" + +msgid "Save user credentials" +msgstr "Simpan kredensial pengguna" + +msgid "Save disk layout" +msgstr "Simpan tata letak disk" + +msgid "Save all" +msgstr "Simpan semua" + +msgid "Choose which configuration to save" +msgstr "Pilih konfigurasi mana yang akan disimpan" + +msgid "Enter a directory for the configuration(s) to be saved: " +msgstr "Masukkan direktori untuk konfigurasi yang akan disimpan: " + +msgid "Not a valid directory: {}" +msgstr "Bukan direktori yang valid: {}" + +msgid "The password you are using seems to be weak," +msgstr "Kata sandi yang Anda gunakan tampaknya lemah," + +msgid "are you sure you want to use it?" +msgstr "apakah Anda yakin ingin menggunakannya?" + +msgid "Optional repositories" +msgstr "Repositori opsional" + +msgid "Save configuration" +msgstr "Simpan konfigurasi" + +msgid "Missing configurations:\n" +msgstr "Konfigurasi tidak ada: \n" + +msgid "Either root-password or at least 1 superuser must be specified" +msgstr "Salah satu root-password atau setidaknya 1 superuser harus ditentukan" + +msgid "Manage superuser accounts: " +msgstr "Kelola akun superuser: " + +msgid "Manage ordinary user accounts: " +msgstr "Kelola akun pengguna biasa: " + +msgid " Subvolume :{:16}" +msgstr " Subvolume :{:16}" + +msgid " mounted at {:16}" +msgstr " di mount di {:16}" + +msgid " with option {}" +msgstr " dengan opsi {}" + +msgid "" +"\n" +" Fill the desired values for a new subvolume \n" +msgstr "" +"\n" +"Isi nilai yang diinginkan untuk subvolume baru\n" + +msgid "Subvolume name " +msgstr " Nama subvolume" + +msgid "Subvolume mountpoint" +msgstr "Titik mount subvolume" + +msgid "Subvolume options" +msgstr "Opsi subvolume" + +msgid "Save" +msgstr "Simpan" + +msgid "Subvolume name :" +msgstr "Nama subvolume :" + +msgid "Select a mount point :" +msgstr "Pilih titik mount :" + +msgid "Select the desired subvolume options " +msgstr "Pilih opsi subvolume yang diinginkan " + +msgid "Define users with sudo privilege, by username: " +msgstr "Tentukan pengguna dengan hak sudo, berdasarkan nama pengguna: " + +msgid "[!] A log file has been created here: {}" +msgstr "[!] File log telah dibuat di sini: {}" + +msgid "Would you like to use BTRFS subvolumes with a default structure?" +msgstr "Apakah Anda ingin menggunakan subvolume BTRFS dengan struktur default?" + +msgid "Would you like to use BTRFS compression?" +msgstr "Apakah Anda ingin menggunakan kompresi BTRFS?" + +msgid "Would you like to create a separate partition for /home?" +msgstr "Apakah Anda ingin membuat partisi terpisah untuk /home?" + +msgid "The selected drives do not have the minimum capacity required for an automatic suggestion\n" +msgstr "Drive yang dipilih tidak memiliki kapasitas minimum yang diperlukan untuk saran otomatis\n" + +msgid "Minimum capacity for /home partition: {}GB\n" +msgstr "Kapasitas minimum untuk partisi /home: {}GB\n" + +msgid "Minimum capacity for Arch Linux partition: {}GB" +msgstr "Kapasitas minimum untuk partisi Arch Linux: {}GB" + +msgid "Continue" +msgstr "Lanjutkan" + +msgid "yes" +msgstr "ya" + +msgid "no" +msgstr "tidak" + +msgid "set: {}" +msgstr "atur: {}" + +msgid "Manual configuration setting must be a list" +msgstr "Pengaturan konfigurasi manual harus berupa list" + +msgid "No iface specified for manual configuration" +msgstr "Tidak ada iface yang ditentukan untuk konfigurasi manual" + +msgid "Manual nic configuration with no auto DHCP requires an IP address" +msgstr "Konfigurasi nic manual tanpa DHCP otomatis memerlukan alamat IP" + +msgid "Add interface" +msgstr "Tambahkan interface" + +msgid "Edit interface" +msgstr "Edit interface" + +msgid "Delete interface" +msgstr "Hapus interface" + +msgid "Select interface to add" +msgstr "Pilih interface untuk ditambahkan" + +msgid "Manual configuration" +msgstr "Konfigurasi manual" + +msgid "Mark/Unmark a partition as compressed (btrfs only)" +msgstr "Tandai/Hapus tanda partisi sebagai terkompresi (hanya btrfs)" + +msgid "The password you are using seems to be weak, are you sure you want to use it?" +msgstr "Kata sandi yang Anda gunakan tampaknya lemah, apakah Anda yakin ingin menggunakannya?" + +msgid "Provides a selection of desktop environments and tiling window managers, e.g. gnome, kde, sway" +msgstr "Menyediakan pilihan desktop environment dan tiling window manager, cth. gnome, kde, sway" + +msgid "Select your desired desktop environment" +msgstr "Pilih desktop environment yang Anda inginkan" + +msgid "A very basic installation that allows you to customize Arch Linux as you see fit." +msgstr "Instalasi yang sangat basic yang memungkinkan Anda untuk menyesuaikan Arch Linux sesuai keinginan Anda." + +msgid "Provides a selection of various server packages to install and enable, e.g. httpd, nginx, mariadb" +msgstr "Menyediakan pilihan berbagai paket server untuk diinstal dan diaktifkan, cth. httpd, nginx, mariadb" + +msgid "Choose which servers to install, if none then a minimal installation will be done" +msgstr "Pilih server mana yang akan diinstal, jika tidak ada maka instalasi minimal akan dilakukan" + +msgid "Installs a minimal system as well as xorg and graphics drivers." +msgstr "Install sistem minimal serta xorg dan driver grafis." + +msgid "Press Enter to continue." +msgstr "Tekan Enter untuk melanjutkan." + +msgid "Would you like to chroot into the newly created installation and perform post-installation configuration?" +msgstr "Apakah Anda ingin melakukan chroot ke instalasi yang baru dibuat dan melakukan konfigurasi pasca-instalasi?" + +msgid "Are you sure you want to reset this setting?" +msgstr "Anda yakin ingin menyetel ulang setelan ini?" + +msgid "Select one or more hard drives to use and configure\n" +msgstr "Pilih satu atau lebih hard drive untuk digunakan dan dikonfigurasi\n" + +msgid "Any modifications to the existing setting will reset the disk layout!" +msgstr "Setiap modifikasi pada pengaturan yang ada akan mengatur ulang tata letak disk!" + +msgid "If you reset the harddrive selection this will also reset the current disk layout. Are you sure?" +msgstr "Jika Anda mengatur ulang pilihan harddrive, ini juga akan mengatur ulang tata letak disk saat ini. Apakah Anda yakin?" + +msgid "Save and exit" +msgstr "Simpan dan keluar" + +msgid "" +"{}\n" +"contains queued partitions, this will remove those, are you sure?" +msgstr "" +"{}\n" +"berisi partisi yang mengantri, ini akan menghapusnya, apakah Anda yakin?" + +msgid "No audio server" +msgstr "Tidak ada server audio" + +msgid "(default)" +msgstr "(default)" + +msgid "Use ESC to skip" +msgstr "Gunakan ESC untuk melewati" + +msgid "" +"Use CTRL+C to reset current selection\n" +"\n" +msgstr "" +"Gunakan CTRL + C untuk mengatur ulang pilihan saat ini\n" +"\n" + +msgid "Copy to: " +msgstr "Salin ke: " + +msgid "Edit: " +msgstr "Edit: " + +msgid "Key: " +msgstr "Kunci: " + +msgid "Edit {}: " +msgstr "Edit {}: " + +msgid "Add: " +msgstr "Tambah: " + +msgid "Value: " +msgstr "Nilai: " + +msgid "You can skip selecting a drive and partitioning and use whatever drive-setup is mounted at /mnt (experimental)" +msgstr "Anda dapat melewatkan memilih drive dan mempartisi dan menggunakan pengaturan drive apa pun yang dipasang di /mnt (eksperimental)" + +msgid "Select one of the disks or skip and use /mnt as default" +msgstr "Pilih salah satu disk atau lewati dan gunakan /mnt sebagai default" + +msgid "Select which partitions to mark for formatting:" +msgstr "Pilih partisi mana yang akan ditandai untuk pemformatan:" + +msgid "Use HSM to unlock encrypted drive" +msgstr "Gunakan HSM untuk membuka kunci drive terenkripsi" + +msgid "Device" +msgstr "Perangkat" + +msgid "Size" +msgstr "Ukuran" + +msgid "Free space" +msgstr "Ruang kosong" + +msgid "Bus-type" +msgstr "Tipe bus" + +msgid "Either root-password or at least 1 user with sudo privileges must be specified" +msgstr "Baik kata sandi root atau setidaknya 1 pengguna dengan hak sudo harus ditentukan" + +msgid "Enter username (leave blank to skip): " +msgstr " Masukkan nama pengguna (kosongkan untuk melewati):" + +msgid "The username you entered is invalid. Try again" +msgstr "Nama pengguna yang Anda masukkan tidak valid. Coba lagi" + +msgid "Should \"{}\" be a superuser (sudo)?" +msgstr "Haruskah \"{}\" menjadi superuser (sudo)?" + +msgid "Select which partitions to encrypt:" +msgstr "Pilih partisi mana yang akan dienkripsi:" + +msgid "very weak" +msgstr "sangat lemah" + +msgid "weak" +msgstr "lemah" + +msgid "moderate" +msgstr "sedang" + +msgid "strong" +msgstr "kuat" + +msgid "Add subvolume" +msgstr "Tambah subvolume" + +msgid "Edit subvolume" +msgstr "Edit subvolume" + +msgid "Delete subvolume" +msgstr "Hapus subvolume" + +msgid "Configured {} interfaces" +msgstr "Interface {} dikonfigurasi" + +msgid "This option enables the number of parallel downloads that can occur during installation" +msgstr "Opsi ini memungkinkan jumlah unduhan paralel yang dapat terjadi selama instalasi" + +#, python-brace-format +msgid "" +"Enter the number of parallel downloads to be enabled.\n" +" (Enter a value between 1 to {max_downloads})\n" +"Note:" +msgstr "" +"Masukkan jumlah unduhan paralel yang akan diaktifkan.\n" +" (Masukkan nilai antara 1 hingga {max_downloads})\n" +"Catatan:" + +msgid " - Maximum value : {max_downloads} ( Allows {max_downloads} parallel downloads, allows {max_downloads+1} downloads at a time )" +msgstr " - Nilai maksimum : {max_downloads} ( Memungkinkan {max_downloads} unduhan paralel, memungkinkan {max_downloads+1} unduhan sekaligus)" + +msgid " - Minimum value : 1 ( Allows 1 parallel download, allows 2 downloads at a time )" +msgstr " - Nilai minimum : 1 (Mengizinkan 1 unduhan paralel, memungkinkan 2 unduhan sekaligus)" + +msgid " - Disable/Default : 0 ( Disables parallel downloading, allows only 1 download at a time )" +msgstr " - Nonaktifkan/Default: 0 (Menonaktifkan pengunduhan paralel, hanya mengizinkan 1 unduhan pada satu waktu)" + +#, python-brace-format +msgid "Invalid input! Try again with a valid input [1 to {max_downloads}, or 0 to disable]" +msgstr "Input tidak valid! Coba lagi dengan input yang valid [1 untuk {max_downloads}, atau 0 untuk menonaktifkan]" + +msgid "Parallel Downloads" +msgstr "Unduhan Paralel" + +msgid "ESC to skip" +msgstr "ESC untuk melewati" + +msgid "CTRL+C to reset" +msgstr "CTRL + C untuk mengatur ulang" + +msgid "TAB to select" +msgstr "TAB untuk memilih" + +msgid "[Default value: 0] > " +msgstr "[Nilai default: 0] > " diff --git a/archinstall/locales/languages.json b/archinstall/locales/languages.json index 344d3d51..7bee29db 100644 --- a/archinstall/locales/languages.json +++ b/archinstall/locales/languages.json @@ -68,7 +68,7 @@ {"abbr": "iu", "lang": "Inuktitut"}, {"abbr": "ie", "lang": "Interlingue"}, {"abbr": "ia", "lang": "Interlingua (International Auxiliary Language Association)"}, - {"abbr": "id", "lang": "Indonesian"}, + {"abbr": "id", "lang": "Indonesian", "translated_lang": "Indonesia"}, {"abbr": "ik", "lang": "Inupiaq"}, {"abbr": "is", "lang": "Icelandic"}, {"abbr": "it", "lang": "Italian", "translated_lang": "Italiano"}, -- cgit v1.2.3-54-g00ecf From c1f21e7ca437e1e8a712ec9bed3bfdf3f4c893e5 Mon Sep 17 00:00:00 2001 From: Anton Hvornum Date: Mon, 19 Sep 2022 23:42:08 +0200 Subject: Add compression to /etc/fstab for btrfs subvolumes (#1473) * Adding a btrfs compression plugin to genfstab * Allowing the genfstab plugin to break on success --- archinstall/lib/disk/btrfs/__init__.py | 4 ---- archinstall/lib/disk/btrfs/btrfs_helpers.py | 34 +++++++++++++++++++++++++++++ archinstall/lib/installer.py | 3 ++- 3 files changed, 36 insertions(+), 5 deletions(-) (limited to 'archinstall') diff --git a/archinstall/lib/disk/btrfs/__init__.py b/archinstall/lib/disk/btrfs/__init__.py index 3c183112..a26e0160 100644 --- a/archinstall/lib/disk/btrfs/__init__.py +++ b/archinstall/lib/disk/btrfs/__init__.py @@ -54,7 +54,3 @@ def create_subvolume(installation: Installer, subvolume_location :Union[pathlib. log(f"Creating a subvolume on {target}", level=logging.INFO) if (cmd := SysCommand(f"btrfs subvolume create {target}")).exit_code != 0: raise DiskError(f"Could not create a subvolume at {target}: {cmd}") - - -def manage_btrfs_subvolumes(installation :Installer, partition :Dict[str, str]) -> list: - raise Deprecated("Use setup_subvolumes() instead.") diff --git a/archinstall/lib/disk/btrfs/btrfs_helpers.py b/archinstall/lib/disk/btrfs/btrfs_helpers.py index ab528388..f6d2734a 100644 --- a/archinstall/lib/disk/btrfs/btrfs_helpers.py +++ b/archinstall/lib/disk/btrfs/btrfs_helpers.py @@ -1,4 +1,5 @@ import logging +import re from pathlib import Path from typing import Optional, Dict, Any, TYPE_CHECKING @@ -6,6 +7,7 @@ from ...models.subvolume import Subvolume from ...exceptions import SysCallError, DiskError from ...general import SysCommand from ...output import log +from ...plugins import plugins from ..helpers import get_mount_info from .btrfssubvolumeinfo import BtrfsSubvolumeInfo @@ -14,6 +16,35 @@ if TYPE_CHECKING: from ...installer import Installer +class fstab_btrfs_compression_plugin(): + def __init__(self, partition_dict): + self.partition_dict = partition_dict + + def on_genfstab(self, installation): + with open(f"{installation.target}/etc/fstab", 'r') as fh: + fstab = fh.read() + + # Replace the {installation}/etc/fstab with entries + # using the compress=zstd where the mountpoint has compression set. + with open(f"{installation.target}/etc/fstab", 'w') as fh: + for line in fstab.split('\n'): + # So first we grab the mount options by using subvol=.*? as a locator. + # And we also grab the mountpoint for the entry, for instance /var/log + if (subvoldef := re.findall(',.*?subvol=.*?[\t ]', line)) and (mountpoint := re.findall('[\t ]/.*?[\t ]', line)): + for subvolume in self.partition_dict.get('btrfs', {}).get('subvolumes', []): + # We then locate the correct subvolume and check if it's compressed + if subvolume.compress and subvolume.mountpoint == mountpoint[0].strip(): + # We then sneak in the compress=zstd option if it doesn't already exist: + # We skip entries where compression is already defined + if ',compress=zstd,' not in line: + line = line.replace(subvoldef[0], f",compress=zstd{subvoldef[0]}") + break + + fh.write(f"{line}\n") + + return True + + def mount_subvolume(installation: 'Installer', device: 'BTRFSPartition', subvolume: Subvolume): # we normalize the subvolume name (getting rid of slash at the start if exists. # In our implementation has no semantic load. @@ -61,6 +92,9 @@ def setup_subvolumes(installation: 'Installer', partition_dict: Dict[str, Any]): if (cmd := SysCommand(f"chattr +c {installation.target}/{name}")).exit_code != 0: raise DiskError(f"Could not set compress attribute at {installation.target}/{name}: {cmd}") + if 'fstab_btrfs_compression_plugin' not in plugins: + plugins['fstab_btrfs_compression_plugin'] = fstab_btrfs_compression_plugin(partition_dict) + def subvolume_info_from_path(path: Path) -> Optional[BtrfsSubvolumeInfo]: try: diff --git a/archinstall/lib/installer.py b/archinstall/lib/installer.py index c7682655..1270959e 100644 --- a/archinstall/lib/installer.py +++ b/archinstall/lib/installer.py @@ -432,7 +432,8 @@ class Installer: for plugin in plugins.values(): if hasattr(plugin, 'on_genfstab'): - plugin.on_genfstab(self) + if plugin.on_genfstab(self) is True: + break return True -- cgit v1.2.3-54-g00ecf From 985ff449db6d681d852c4fa558d2a90ecf2a2bc3 Mon Sep 17 00:00:00 2001 From: Anton Hvornum Date: Wed, 21 Sep 2022 12:36:54 +0200 Subject: On certain hardware where virtual and physical harddrives share the same common name, a smart mapping is done and block devices will show up under /sys/class/block/ but not always under /dev/* and thus breaking the all_blockdevices() logic. This should fix that. (#1475) --- archinstall/lib/disk/helpers.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'archinstall') diff --git a/archinstall/lib/disk/helpers.py b/archinstall/lib/disk/helpers.py index a148a5db..f19125f4 100644 --- a/archinstall/lib/disk/helpers.py +++ b/archinstall/lib/disk/helpers.py @@ -220,7 +220,12 @@ def all_blockdevices(mappers=False, partitions=False, error=False) -> Dict[str, # we'll iterate the /sys/class definitions and find the information # from there. for block_device in glob.glob("/sys/class/block/*"): - device_path = f"/dev/{pathlib.Path(block_device).readlink().name}" + device_path = pathlib.Path(f"/dev/{pathlib.Path(block_device).readlink().name}") + + if device_path.exists() is False: + log(f"Unknown device found by '/sys/class/block/*', ignoring: {device_path}", level=logging.WARNING, fg="yellow") + continue + try: information = blkid(f'blkid -p -o export {device_path}') except SysCallError as ex: -- cgit v1.2.3-54-g00ecf From 53a2797af6ac0832bf7dd00dfe96b8ea1867db2e Mon Sep 17 00:00:00 2001 From: Anton Hvornum Date: Sun, 25 Sep 2022 12:05:25 +0200 Subject: Updating version to v2.5.1 --- archinstall/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'archinstall') diff --git a/archinstall/__init__.py b/archinstall/__init__.py index 4e1e6d6d..44852d4c 100644 --- a/archinstall/__init__.py +++ b/archinstall/__init__.py @@ -51,7 +51,7 @@ from .lib.hsm import ( ) parser = ArgumentParser() -__version__ = "2.5.1rc1" +__version__ = "2.5.1" storage['__version__'] = __version__ # add the custome _ as a builtin, it can now be used anywhere in the -- cgit v1.2.3-54-g00ecf