Compare commits

...

1607 Commits

Author SHA1 Message Date
renovate[bot] 389f4cfc64
Update actions/setup-python action to v7 (#4647)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-07-21 21:03:30 +10:00
Ksan 91d6d4dca1
Add Serbian translation (#4642) 2026-07-21 21:02:55 +10:00
codefiles 2f344a84ff
Remove redundant is_valid_path (#4646) 2026-07-21 20:50:56 +10:00
codefiles 2751716d2e
Set LANG to fully qualified locale name (#4645) 2026-07-21 20:44:10 +10:00
renovate[bot] b6d8fe25a1
Update dependency arch/python-markdown-it-py to v4.2.0 (#4644)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-07-21 20:39:28 +10:00
renovate[bot] b0bfb43661
Update dependency ruff to v0.15.22 (#4636)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-07-18 21:17:15 +10:00
renovate[bot] 39dbebf26c
Update pre-commit hook astral-sh/ruff-pre-commit to v0.15.22 (#4637)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-07-18 21:16:43 +10:00
Jonathan Pichel caff461f0b
Fix Galician locale (#4630)
* Sync Galician translation with template

* Delete all outdated Galician translation entries

* Improve Galician translation
2026-07-14 21:13:26 +10:00
Softer 01c9432afd
Use sentence case for summary labels (#4617)
str.title() title-cased every label word, which is wrong outside
English: it turned the Ukrainian "Ім'я хоста" into "Ім'Я Хоста" and
broke acronyms ("NTP" -> "Ntp"). The source strings and their
translations are already written with the correct casing.

Capitalize only the first letter of each label instead.
2026-07-14 21:12:53 +10:00
renovate[bot] 53158a8aad
Update pre-commit hook pre-commit/mirrors-mypy to v2.3.0 (#4629)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-07-14 10:14:03 +10:00
renovate[bot] 46320deb33
Update dependency mypy to v2.3.0 (#4628)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-07-14 10:13:43 +10:00
renovate[bot] 12baa2e64a
Update pre-commit hook pre-commit/mirrors-mypy to v2.2.0 (#4627)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-07-13 13:09:55 +10:00
renovate[bot] 2531825b59
Update dependency mypy to v2.2.0 (#4626)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-07-13 13:09:27 +10:00
renovate[bot] e3e9d43324
Update pre-commit hook astral-sh/ruff-pre-commit to v0.15.21 (#4623)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-07-13 13:09:05 +10:00
renovate[bot] 781728b91b
Update dependency ruff to v0.15.21 (#4622)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-07-13 13:08:47 +10:00
renovate[bot] 34c299e42e
Update astral-sh/ruff-action action to v4.1.0 (#4625)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-07-13 07:05:31 +10:00
renovate[bot] 3f4f815a34
Update dependency arch/python-textual to v8.2.8 (#4624)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-07-13 07:04:41 +10:00
Christos Longros c60385a6f7
Update Greek translations: TUI navigation strings (#4621) 2026-07-12 21:21:58 +10:00
correctmost c110081a42
Enable more mypy and Pylint checks for test_tooling/ (#4620) 2026-07-12 21:21:18 +10:00
correctmost 8902d2e310
Use a match statement for PasswordStrength enum values (#4619)
This unblocks the upgrade to mypy 2.2.0, which now flags the
unreachable "return None" statement.
2026-07-12 21:20:44 +10:00
BlackCatOfficial 💀 (Python, C++, Lua) aca482b691
Add Vietnamese to Archinstall (#4582)
* add vn lang, trans lang, translating ~28%

* done 80/735 (10% not ~28% sorry) and 735/735 done (counted fuzzy or google translate helper). See https://gist.github.com/BlackCatOfficialytb/e85bad1758d9e29c349f2d75b91363f1 for program to help me translate

* doing plenty of things

* up to 40% by removing fuzzy tag in correct translate words/paragraph

* fix the extension

* more words/paragraphs are unfuzzied

* trans up to 57%

* translate up to 61%
2026-07-12 21:18:50 +10:00
renovate[bot] 338e3cf4b8
Update dependency ruff to v0.15.20 (#4609)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-06-30 07:58:34 +10:00
renovate[bot] ec9295634b
Update pre-commit hook astral-sh/ruff-pre-commit to v0.15.20 (#4610)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-06-30 07:58:17 +10:00
renovate[bot] f94c27430c
Update dependency pytest to v9.1.1 (#4612)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-06-30 07:58:02 +10:00
renovate[bot] caa8887204
Update dependency arch/python-systemd to v236 (#4615)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-06-30 07:57:22 +10:00
renovate[bot] 8aec36aa0a
Update dependency arch/python-cryptography to v49 (#4614)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-06-30 07:57:04 +10:00
renovate[bot] ebdf625e5c
Update actions/checkout action to v7 (#4613)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-06-30 07:56:42 +10:00
Arvind fc3a22683e
Add Norwegian Bokmål (nb) translation (#4599)
* Add Norwegian Bokmål (nb) translation

* Register Norwegian Bokmål in languages.json
2026-06-29 21:52:02 +10:00
Softer faf6fe5ce2
Improve Ukrainian translation (#4611)
Translate the new Plymouth bootloader strings (enable warning prompt,
theme selection) and add the graphics driver label.
2026-06-29 21:46:30 +10:00
renovate[bot] e2b8697864
Update dependency pylint to v4.0.6 (#4606)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-06-29 21:45:20 +10:00
renovate[bot] 214e55248c
Update actions/setup-python digest to ece7cb0 (#4605)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-06-29 21:44:58 +10:00
Anton Hvornum 3ece182d31
Bumping version to: 4.4 (#4608) 2026-06-28 22:06:04 +02:00
brurmonemt e4b2894db5
fix ValueError exception when no disks are detected in the disk menu (#4598)
* Fix ValueError exception when no disks are detected in the disk menu

in lib/disk/disk_menu.py, the menu items are created using info from a list called "devices" (device_handler.devices). when no block devices are detected, the list is empty, creating zero MenuItems, and causing the following ValueError:

ValueError: Menu must have at least one item

this change checks if the length of the list is shorter than 1  (empty list) before constructing the menu. if the list is empty, the user will be notified that no disks were detected. otherwise, the menu is created and behaves as normal

* Fixed ruff formatting issue

* Fixed ruff formatting issue

---------

Co-authored-by: Anton Hvornum <torxed@archlinux.org>
2026-06-28 21:19:42 +02:00
Softer 12f204571e
Warn before enabling Plymouth in the bootloader menu (#4604)
Plymouth is purely cosmetic and a frequent source of boot breakage,
most notably a black screen with the NVIDIA driver and a hidden LUKS
password prompt. Show a yellow confirmation warning listing these risks
when enabling it; when Plymouth is already enabled the user is only
changing the theme, so the warning is skipped. Regenerate base.pot for
the new strings.
2026-06-28 21:13:10 +02:00
utuhiro78 4b14b795f5
Update Japanese translation (#4600) 2026-06-28 21:11:32 +02:00
emanu cce0c47e11
Fix plugin (#4594)
* change behaviour to load plugin

* add checks in _write_plugin_to_temp_file

* modify test

* fixed test
2026-06-28 21:09:20 +02:00
Daniel Girtler c6a5a130a8
Refactor configuration file (#4583) 2026-06-28 21:04:20 +02:00
renovate[bot] c777ee03f6
Update pre-commit hook astral-sh/ruff-pre-commit to v0.15.17 (#4593)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-06-13 16:29:37 +10:00
renovate[bot] f67b7c2aa0
Update dependency ruff to v0.15.17 (#4592)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-06-13 16:24:48 +10:00
renovate[bot] 5397ae7124
Update dependency arch/python-cryptography to v48.0.1 (#4591)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-06-13 16:24:31 +10:00
Softer f6a031f584
Fix Plymouth theme preset focus and add missing strings to base.pot (#4586)
select_plymouth_theme() compared enum item values against a raw string,
so the previously selected theme was never highlighted when reopening
the menu. Use set_focus_by_value() like other single-select menus.

Regenerate base.pot to pick up the three Plymouth strings introduced
in #4555.
2026-06-13 04:57:32 +10:00
Softer 919a435a6b
Skip custom mirror config when keyring sync fails (#4577)
* Skip custom mirror config when keyring sync fails

Check the exit state of archlinux-keyring-wkd-sync.service after
waiting for it to finish. If it failed, skip set_mirrors() and
continue installation with default mirrors instead of crashing
with "GPGME error: No data" during pacman -Syy.

* Reinit keyring automatically when pacman sync fails with GPGME error

Instead of skipping mirror configuration when wkd-sync fails, catch
the GPGME error at the point where it actually occurs - during
pacman -Syy. If the sync fails with a keyring-related error, reinit
the keyring with pacman-key --init/--populate and retry the sync.

* Simplify pacman sync() and guard gpg-agent kill on running state

Collapse the duplicated self.ask() blocks in sync() into a single call
via a msg variable, and drop the redundant default_cmd='pacman' (it is
already the default). In _reinit_keyring(), check that gpg-agent is
actually running (pgrep -x) before killing it, instead of catching the
killall error and assuming it was not running.
2026-06-10 17:10:29 +10:00
Softer 091665a975
Add users to seat group when seatd is selected (#4578)
* Add users to seat group when seatd is selected

When a desktop profile uses seatd for seat access, the user must be
in the seat group for the compositor to access input devices. Without
this, sway/hyprland/niri/labwc fail to start after installation.

* Move seat access provisioning into DesktopProfile.provision()

The four Wayland profiles (Hyprland, Sway, niri, labwc) each duplicated a
provision() override calling provision_seat_access(). Move that into the
base DesktopProfile.provision() loop, which already iterates the selected
profiles, and read CustomSetting.SeatAccess from each. The None check now
lives at the call site (walrus), so provision_seat_access() takes a plain
str. This removes the per-profile overrides and their TYPE_CHECKING imports.

* Use top-level imports in seat access utils

The Installer and User imports were under a TYPE_CHECKING guard, but
they cause no circular import (bspwm.py already imports both at top
level). Move them to module scope per review feedback.
2026-06-10 16:56:17 +10:00
Mário Victor Ribeiro Silva 73d78b1aa9
Add Plymouth configuration setup (#4555)
* feat: add plymouth config

* refactor: move plymouth to bootleader menu
2026-06-10 16:44:03 +10:00
Daniel Girtler c6cb7b319d
Removing pot file freshness check (#4576) 2026-06-09 09:08:38 +02:00
Softer 8ce2486846
Update Ukrainian translation (#4580) 2026-06-09 16:46:46 +10:00
Lena Pastwa c67ed4b668
Update Polish translation, fix typo (#4579)
* Update Polish translation

* Fix typo
2026-06-09 16:46:14 +10:00
Softer 0f16801448
Color-code install preview: red for errors, yellow for warnings, green for ready (#4512)
* Color-code install preview: red for errors, yellow for warnings, green for ready

Add preview_markup opt-in field to MenuItem with automatic Rich markup
escaping for all existing previews. Show missing configs and bootloader
errors in red, network warning in yellow, "Ready to install" in green.
Move network warning from confirmation dialog to install preview so it
is visible earlier.

* Fix Rich markup parsing error on JSON preview strings

Text.from_markup() replaces Label(markup=True) to avoid MarkupError
on strings containing ["

* Replace raw Rich markup with PreviewResult dataclass for typed preview levels

* Add missing translatable strings to base.pot

* Move get_install_warnings() from ConfigurationOutput to GlobalMenu

The method is only used by GlobalMenu._prev_install_invalid_config(),
so it belongs there rather than on the serialization class.

* Move level-to-style mapping into MsgLevelType.style() method

Replace the module-level _LEVEL_STYLE dict in components.py with a
style() method on the MsgLevelType enum, following the project
convention of encapsulating type-bound logic on the type itself.

* Change PreviewResult to hold a list of message-level pairs

PreviewResult.messages is now list[tuple[str, MsgLevelType]], allowing
a single result to carry multiple sections with different levels.
The preview_action signature drops list[PreviewResult] since the
dataclass itself handles multiple sections. Existing str-returning
previews still work and will be converted in follow-up PRs.

* Make MsgLevelType.style() return a typed MsgLevelStyle enum

Replace the bare style strings returned by style() with a MsgLevelStyle
StrEnum so the values are type-checked. Being a StrEnum, the members stay
plain strings and pass straight into Text.append(style=...), so no call
sites change.
2026-06-08 16:22:34 +10:00
Softer 1048f7eef0
Fix WiFi network selection in TUI prompt (#4566)
* Fix WiFi network selection in TUI prompt

TableSelectionScreen returns the selected network in Result._item,
but the check on line 136 only tested Result._data (always None
for single-select). This caused every selection to fall through
to the "No wifi networks found" error path.

Fixes #4564

* Fix empty wifi scan crash and simplify network selection

Move wifi scanning out of the TableSelectionScreen callback to avoid
MenuItemGroup([]) ValueError when no networks are found. The empty
result is now handled before the selection screen, and the Selection
branch is simplified to a direct get_value() call.
2026-06-08 04:31:07 +10:00
renovate[bot] 1aff670262
Update dependency ruff to v0.15.16 (#4573)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-06-06 18:56:47 +10:00
renovate[bot] e8d2e8f346
Update pre-commit hook astral-sh/ruff-pre-commit to v0.15.16 (#4574)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-06-06 18:56:39 +10:00
Clinton Phillips 7b8fec1af4
fix(luks): surface cryptsetup error output when unlock fails (#4570)
Luks2.unlock() ran 'cryptsetup open' with no error handling, so a failure raised a bare CalledProcessError. Python renders that exception with only the exit status and discards the captured output, so cryptsetup's stderr (merged into stdout by run()) never reached the install log.

encrypt() already wraps its cryptsetup call and raises a DiskError that includes the captured output. Mirror that for unlock() so a failure reports the actual cryptsetup message instead of an opaque traceback.

Reported in #4327, where the underlying 'device-mapper: crypt: unknown table type' error was hidden from the log for this reason.
2026-06-06 18:38:36 +10:00
Akilesh A S d38008483e
chore: update examples/config-sample.json (#4569)
TL;DR:
- fix the config for 'parallel download'
- add config for setting color output for pacman
2026-06-06 18:36:50 +10:00
renovate[bot] f9534c67cd
Update actions/checkout digest to df4cb1c (#4567)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-06-06 18:35:42 +10:00
renovate[bot] 07e10f9648
Update peaceiris/actions-gh-pages digest to 84c30a8 (#4560)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-06-06 18:25:05 +10:00
renovate[bot] a39a44188a
Update pre-commit hook astral-sh/ruff-pre-commit to v0.15.15 (#4559)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-06-06 18:23:53 +10:00
renovate[bot] 2aeb824cf9
Update dependency ruff to v0.15.15 (#4558)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-06-06 18:23:26 +10:00
Franco Castillo e27ce6e8b6
Update template and Spanish translation (#4557)
* Update translation template

Signed-off-by: Franco Castillo <castillofrancodamian@gmail.com>

* Update Spanish translation

Signed-off-by: Franco Castillo <castillofrancodamian@gmail.com>

* Update Spanish translation

Signed-off-by: Franco Castillo <castillofrancodamian@gmail.com>

---------

Signed-off-by: Franco Castillo <castillofrancodamian@gmail.com>
2026-06-06 18:22:56 +10:00
renovate[bot] b96afcc579
Update dependency arch/python-textual to v8.2.7 (#4556)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-25 21:58:49 +10:00
BB 3bc248b47f
add niri DankMaterialShell profile (#4554) 2026-05-25 21:13:56 +10:00
Anton Hvornum af2120c0e9
mkosi for test image builds (#4539)
Added a `mkosi` profile as well as organized test tooling a bit.

---------

Co-authored-by: 0xdeadd <clintdotphillips@gmail.com>
2026-05-23 13:49:54 +02:00
renovate[bot] d92a98d3bf
Update pre-commit hook astral-sh/ruff-pre-commit to v0.15.14 (#4552)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-22 12:39:28 +10:00
renovate[bot] af58671e88
Update dependency ruff to v0.15.14 (#4551)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-22 12:39:11 +10:00
utuhiro78 e17e036f54
Update Japanese translation (#4550) 2026-05-21 07:25:23 +10:00
Daniel Girtler ac4bc442de
Refactor logging and formatting logic (#4542)
* Refactor logging and formatting

* Refactor logging and formatting

* Refactor logging and formatting

* Updaet
2026-05-19 17:48:03 +02:00
Clinton Phillips 5fd2f9b627
fix: restrict EFI partition permissions with fmask/dmask=0077 (#4506)
* fix: restrict EFI partition permissions with fmask/dmask=0077

Mount the ESP with fmask=0077 and dmask=0077 to prevent world-readable
files like /efi/loader/random-seed.

Closes #4241

* fix(efi): collapse fmask/dmask dedup to dict.fromkeys one-liner

Per @Torxed's review feedback. Same semantics as the previous loop
(dedupe by exact-string match) but shorter. dict.fromkeys preserves
insertion order, where set() would not.

* fix(efi): drop defensive list wrap per review

The list() copy on line 378 was load-bearing only if options were
mutated downstream, but the EFI branch reassigns options via
dict.fromkeys() (line 381) and the non-EFI branch passes through
to mount() without mutating. Drop the copy.
2026-05-19 13:36:28 +10:00
Softer dccd0c8ccf
Add translation CI validation (#4519)
* Fix broken localization: tr(f-string) never matches translation catalog

tr(f'Invalid configuration: {error}') evaluates the f-string before
tr() runs, so xgettext extracts the literal placeholder as the msgid
while runtime passes the formatted string - the two never match.
Switch to tr('...{}').format(...) and update msgid in base.pot.

* Add CI validation for translations and pot_tools dev utility

Add translation-check workflow with two jobs:
- validate-po: msgfmt --check on changed .po files, .mo sync warning,
  tr(f-string) anti-pattern grep on changed .py files
- validate-pot: verify all tr() strings exist in base.pot when .py
  files change

Workflow only triggers on .py/.po/.pot file changes.

Add scripts/pot_tools.py developer utility (stats, list, add_missing)
for managing base.pot.

* Fix code style: use tabs and reformat xgettext arguments

Align check_pot_freshness.py and pot_tools.py with project
indentation (tabs) and ruff format requirements.

Sorry :-)

* Replace custom PO parser with msgcmp, drop pot_tools.py

Address review feedback: use standard gettext msgcmp instead of
hand-rolled parser for base.pot freshness check. Remove pot_tools.py
that duplicated locales_generator.sh functionality.

* Move translation checks into locales_generator.sh, simplify CI workflow

Use msgcmp instead of diff for base.pot validation to avoid failing on
legacy stale entries - the same cascading breakage that killed the
original workflow (disabled 2023, removed in #4483).

* Fix broken .po files: duplicate msgid in Hindi, missing format args in Finnish
2026-05-18 20:10:56 +10:00
renovate[bot] 22bf6e3c35
Update dependency arch/python-textual to v8.2.6 (#4546)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-18 15:36:33 +10:00
Matteo b5d323762b
Update Italian translation + fix a string (#4545)
* Update Italian translation

* Added new strings
* Improved existing translations

* Fix wrong string + Italian translation

* Mispelled "respository" -> "repository"
2026-05-17 11:26:30 +10:00
utuhiro78 42d9113611
Update Japanese translation (#4544) 2026-05-16 09:29:27 +10:00
Daniel Girtler 516a61d8af
Enhance log sharing capability (#4526) 2026-05-15 21:38:17 +10:00
renovate[bot] e48ca45b0b
Update pre-commit hook astral-sh/ruff-pre-commit to v0.15.13 (#4541)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-15 16:30:33 +10:00
renovate[bot] 74a1066661
Update dependency ruff to v0.15.13 (#4540)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-15 13:58:00 +10:00
HADEON b81fe955f0
Add IWD standalone option to network configuration + fix NM_IWD (#4528)
* Add iwd standalone option to network configuration

Adds NicType.IWD as a third option alongside NM and NM_IWD: install
iwd, write /etc/iwd/main.conf with EnableNetworkConfiguration=true and
NameResolvingService=systemd, enable iwd.service + systemd-resolved.service.
iwd handles DHCP itself and resolved picks up its DNS via the symlink, so
no NetworkManager pulled in.

Also fills in parse_arg cases for NM_IWD and IWD so config files
round-trip both nic types.

Assisted-By: Flint

* wire up resolv stub and networkd service

* exclude virtual devices, dont harcode iface name instead match 'ether'
similar pattern to .network files shipped in /etc/systemd/network

* use dedent and rename menu option
2026-05-15 13:57:31 +10:00
renovate[bot] 13944f3cca
Update pre-commit hook pre-commit/mirrors-mypy to v2.1.0 (#4538)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-13 08:54:05 +10:00
renovate[bot] b95321d38c
Update dependency mypy to v2.1.0 (#4535)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-13 08:33:42 +10:00
renovate[bot] 3dec5025c3
Update dependency arch/python-pydantic to v2.13.4 (#4534)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-13 08:21:44 +10:00
stinga11 f7a6f70fc8
Replace terminal and file manager in Budgie profile (#4533)
I think it was a mistake to have made the previous changes to KDE Apps. In retrospect, it seemed like a good idea since the Budgie developer had done it that way in Fedora, which is the distro the developer uses as a reference for Budgie. When you start using it, you realize there's no bridge between the desktop and the KDE Apps, and things like Dolphin recognizes icons and themes, requiring some rather annoying manual configurations. Then, if you want to change them again, you have to change those configurations again. Files don't open by default with the apps either; you have to configure them for that to work.

At first, I thought the Budgie packager for Arch had forgotten some stray dependency, but with some free time, I tested it with Fedora 44, and to my surprise, it has exactly the same problems, which is completely unacceptable for a final stable release. I suppose he'll make the necessary changes in the near future, but right now, it's a disaster.
2026-05-13 08:21:15 +10:00
Daniel Girtler 7fc33c2507
Enhance config types and summary (#4532)
* Enhance config types and summary

* Update
2026-05-10 22:35:53 +02:00
Lena Pastwa 2de7254b21
Update Polish translation (#4529) 2026-05-08 11:28:36 +10:00
renovate[bot] af106eb238
Update dependency mypy to v2 (#4523)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-07 21:57:10 +10:00
renovate[bot] 4265be6e43
Update pre-commit hook pre-commit/mirrors-mypy to v2 (#4525)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-07 21:56:30 +10:00
Softer b0b7983af2
Fix bspwm black screen: add provision() delegation and default configs (#4518)
* Fix bspwm black screen: add provision() delegation and default configs

* Move TYPE_CHECKING imports to top level in bspwm profile
2026-05-07 10:20:09 +10:00
Softer ef1cfe7b56
Add share-log subcommand to upload install.log to paste.rs (#4511)
* Add --share-log flag to upload install.log to paste.rs

* Apply ruff-format to share_log.py

* Rework share-log per review: subcommand, TUI confirmation, truncate large logs

* Replace curl/SysCommand with urllib.request, remove defensive try/except

Per review: use stdlib urllib instead of shelling out to curl,
drop unnecessary try/except around TUI confirmation,
remove tempfile (content is passed directly as bytes).

* Fix TUI imports after ui module was pulled one level up (#4515)

* Decouple share_install_log from TUI module

* Add unit tests for share_install_log function

* Update docs to use share-log subcommand syntax
2026-05-07 10:18:56 +10:00
Softer 7b5dddf34b
Fix truncated package metadata in additional packages preview (#3580) (#4510)
* Fix truncated package metadata in additional packages preview (#3580)

* Simplify package info fix: use rstrip and CSS wrap instead of env var plumbing

* Apply preview text wrap conditionally via wrap_preview parameter

* Add missing wrap-preview CSS to OptionListScreen and pass parameter through SelectMenu
2026-05-07 10:17:13 +10:00
renovate[bot] dcc38fe9aa
Update dependency arch/python-cryptography to v48 (#4520)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-06 15:25:45 +10:00
Softer 11607851c4
Keep standalone initramfs for grub-btrfs when UKI is enabled (#4513)
* Keep standalone initramfs for grub-btrfs when UKI is enabled

Fixes #4505

* Move keep_initramfs logic into add_bootloader()

The grub-btrfs snapshot detection was in guided.py, forcing custom
script authors to replicate it. Since Installer already holds
disk_config, the check belongs inside add_bootloader().
2026-05-06 14:26:59 +10:00
Daniel Girtler ba7dbeadfc
Refactor profile seat access selection (#4457)
* Refactor profile seat access selection

* Update
2026-05-04 14:45:43 +10:00
aronmr-1 b5501d9507
Improved Finnish translation further (#4516) 2026-05-04 08:16:16 +10:00
renovate[bot] 528c27fbe1
Update dependency arch/python-textual to v8.2.5 (#4517)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-04 08:14:56 +10:00
Daniel Girtler b18cc57216
Pull `ui` module one level up (#4515)
* Pull the UI module one level up

* Update
2026-05-03 23:54:42 +02:00
Softer dd34954011
Remove dead Cutefish desktop profile (#4514)
The cutefish package was never in the official Arch repos (AUR only)
and the upstream project is abandoned. Installing this profile would
always fail with a pacman "not found" error.
2026-05-03 10:33:48 +10:00
utuhiro78 76629ecc15
Update Japanese translation (#4504) 2026-04-30 17:37:37 +10:00
Softer dc7d9cf0a2
Improve Ukrainian translation (#4502) 2026-04-30 09:23:08 +10:00
correctmost b936fa11e3
Fix some inconsistent-return-statements Pylint warnings (#4503) 2026-04-30 09:22:45 +10:00
aronmr-1 6fefa3b6f5
Improved Finnish language (#4501) 2026-04-30 07:43:01 +10:00
Softer 3b026cb603
Fix broken localization in U2F, LUKS, and gfx driver preview (#4500) 2026-04-30 07:33:21 +10:00
correctmost 05560d29af
Add basic Pyrefly configuration to pyproject.toml (#4494)
This makes it easier to use the Pyrefly type checker with various
IDEs.
2026-04-29 21:54:59 +10:00
correctmost 3223ae4212
Remove the old curses-based TUI code (#4497)
The new Textual-based TUI shipped in the April .iso.
2026-04-29 17:08:24 +10:00
Steen Rabol 468e33d54f
Danish translation (#4493)
* Danish translation

* updated base.po and  created base.mo

---------

Co-authored-by: Steen Rabol <steen@rabol.dev>
2026-04-29 16:06:10 +10:00
utuhiro78 ccbc53d576
Update Japanese translation (#4498) 2026-04-29 13:44:11 +10:00
correctmost c4d68855cb
Replace time.time with time.monotonic to avoid clock drift issues (#4492)
Using time.time() can be inaccurate if the system clock gets
updated in between calls.
2026-04-28 13:34:33 +02:00
Softer 8a929f603f
Fix sway+nvidia confirmation dialog (#4481) (#4485)
* Fix sway+nvidia confirmation dialog (#4481)

Two bugs in the Sway+Nvidia driver confirmation:

1. The boolean was inverted - confirming "yes, I'm okay with issues"
   reverted the driver to the previous choice instead of keeping it.

2. The warning triggered for any Nvidia driver, including the
   open-source nouveau driver which is officially supported by Sway.

Add GfxDriver.is_nvidia_proprietary() and is_nvidia_nouveau() methods
so the warning fires only for nvidia-open-dkms (proprietary userspace).

* Address review feedback (#4485)

- Drop is_nvidia_nouveau() helper. It is not called anywhere yet; can
  be re-added when a consumer lands.
- Collapse the Sway+Nvidia confirmation result handling into a single
  expression now that allow_skip=False guarantees a boolean answer.
2026-04-28 21:02:32 +10:00
Softer e1efa34d8a
Install mkinitcpio explicitly in base packages (#4484)
Prevents pacstrap from picking a different initramfs provider
(dracut, booster) when running from a non-Arch host.

Fixes #4368
2026-04-28 21:01:05 +10:00
Softer cb0f3a6eba
Warn when no network configuration is selected (#4408)
* Make network configuration mandatory with explicit "No network" option

* Add network configuration recommendation hint and disable sorting

* Warn when network selection was skipped instead of making it mandatory

Replace the mandatory network_config menu requirement with a yellow
warning on the final confirmation screen, shown only when the user
skipped the network menu entirely. Explicitly picking "No network
configuration" is treated as a conscious choice and does not trigger
the warning.

- Drop mandatory=True from the network_config global menu item
- Rename NicType.NONE menu label from "No network" to
  "No network configuration" (an installed system still has an NIC;
  only the install-time configuration is absent)
- Add ConfigurationOutput.get_install_warnings() and render them in
  confirm_config when show_install_warnings=True
- guided.py and minimal.py enable the warning on the confirm screen
- Reuse the existing "No network configuration" msgid in .pot; add the
  warning string; update Ukrainian translations accordingly

* Drop NicType.NONE from this PR

The NONE option introduced earlier in this branch is being removed per
review feedback (#4408). Whether to add explicit "None" options across
multiple menus (greeter, gfx driver, network, bootloader) is now being
discussed in #4464 and should land as a separate change there.

This PR keeps only the warning-on-confirm behaviour: when the user
skipped the network menu entirely (network_config is None), a yellow
warning is shown on the final confirmation screen.
2026-04-28 20:17:40 +10:00
Hassaan Amin 1b7a32a3b3
Fix typos in known issues documentation (#4488)
First Edit :
- "effort" is singular so use has not have

Second Edit :
- we use "an" before vowel sounds (an old )


Third Edit :  
- use Sometimes because sometimes means occasionally and Some times means  some period or era 

Fourth Edit :
- Plural of ISO is ISOs not ISO's
2026-04-28 20:03:49 +10:00
Softer 08cba236f6
Show install summary when configuration is valid (#4475)
* Show install summary when configuration is valid

Previously the Install menu preview was empty when everything was valid,
leaving the user with no "ready" signal. Now show "Ready to install"
plus a two-column summary of the current configuration.

- New _install_summary() composes an aligned key/value table with rows
  for disks+FS+LUKS, bootloader, kernel, profile, greeter, package
  count, network, locale and timezone. Column width adapts to the
  longest translated label so translations keep the alignment.
- Rows whose underlying config is not set are skipped rather than
  rendered as empty.
- base.pot / uk base.po: add new msgids for summary labels.

* Move install summary into ConfigurationOutput

The summary helper that renders the install preview's two-column
configuration overview lived in GlobalMenu. Move it to
ConfigurationOutput.as_summary() so it sits alongside the JSON
output methods that share the same role. The preview now syncs
menu state to ArchConfig and delegates rendering.
2026-04-28 19:22:01 +10:00
Franco Castillo 8cc35f41d8
Update Spanish translation (#4490)
Signed-off-by: Franco Castillo <castillofrancodamian@gmail.com>
2026-04-28 17:08:39 +10:00
codefiles 9010ccf9eb
Add kernel enum (#4489) 2026-04-28 17:08:19 +10:00
Anton Hvornum 074dfbb178
Adding a reference to why AUR is not bundled as an option in archinstall (#4468) 2026-04-27 08:44:14 +02:00
Softer 008d303aaf
Remove disabled translation-check workflow (#4483)
The workflow has been fully commented out since #2119 (2023-09-28) when
translation handling was reworked. Because the file has no `on:` triggers,
GitHub Actions creates a failed workflow run for every push, polluting
the Actions tab without affecting PR check-runs.
2026-04-27 09:35:34 +10:00
utuhiro78 3795bfc21a
Update Japanese translation (#4482) 2026-04-27 09:32:10 +10:00
Softer 210329ed80
Add console font selection to Locales menu (#4469)
* Add console font selection to Locales menu

Add a 4th menu item "Console font" to the Locales configuration,
allowing users to select a console font for the target system.
The selected font is written to /etc/vconsole.conf.

If a terminus font (ter-*) is selected, the terminus-font package
is automatically installed on the target system.

* Switch list_console_fonts to pathlib and add @lru_cache

Address svartkanin's review on #4469. Replace os.listdir +
chained removesuffix with Path.glob('*.gz') + split('.')[0],
and cache the result via lru_cache - the kbd consolefonts
directory is static at runtime so re-scanning on every menu
reopen was wasted I/O.
2026-04-27 09:30:20 +10:00
Softer 9e05260df5
Fix argv injection in _create_user and gpasswd loop (#4473)
* Fix argv injection in _create_user and gpasswd loop

Use argv list with run() instead of f-string interpolation into
SysCommand, add debug logging on failure.

* Extract _chroot_argv helper and harden user/file ops

Address svartkanin's review on #4473: factor the
['arch-chroot', '-S', str(self.target), ...] boilerplate into a
private Installer._chroot_argv() helper, and migrate the seven
existing argv-form call sites to it (useradd, gpasswd, chpasswd,
chsh, chown, snapper-create-config, grub-install).

Two related hardening tweaks while in the area:

- Raise gpasswd failure log from debug() to warn(). The group-add
  loop has no return-False feedback channel for the caller, so a
  silent debug() means a half-configured user looks like a
  successful install.

- Add `--` end-of-options separator for useradd and chown so a
  username or path starting with `-` cannot smuggle flags. The TUI
  validates usernames, but parse_arguments() in models/users.py
  does not, so config.json is the residual hole; this closes it
  for these two sites at zero cost.
2026-04-27 09:24:51 +10:00
Softer d836ab0a66
Extend validate_bootloader_layout with UEFI-dependent checks (#4474)
* Extend validate_bootloader_layout with UEFI-dependent checks

Add is_uefi parameter and three new validations: Systemd-boot, Efistub
and rEFInd require UEFI; Efistub additionally requires a FAT boot
partition. Move the rEFInd UEFI-only check out of GlobalMenu so
guided.py and Installer silent-install paths get the same coverage.

* Encapsulate UEFI-only flag in Bootloader enum

Replace module-level _UEFI_ONLY_BOOTLOADERS tuple with an
is_uefi_only() method on the Bootloader enum, mirroring the
existing has_uki_support() / has_removable_support() pattern.

* Drop is_uefi parameter from validate_bootloader_layout

The UEFI flag is a constant system fact for the run, so the
validator retrieves it via SysInfo.has_uefi() directly instead
of having every caller pass it in. Updates all three call sites
in global_menu.py, installer.py and guided.py, and removes the
now-unused SysInfo import from guided.py.
2026-04-26 19:14:23 +10:00
renovate[bot] 3c4c87bdd6
Update dependency arch/python-cryptography to v47 (#4478)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-26 19:03:16 +10:00
renovate[bot] efda78cad5
Update pre-commit hook astral-sh/ruff-pre-commit to v0.15.12 (#4477)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-26 18:36:10 +10:00
renovate[bot] c8e5c85e20
Update dependency ruff to v0.15.12 (#4476)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-26 18:35:31 +10:00
Softer bb46e295d1
Fix OVMF paths in README QEMU examples (#4472)
All three qemu-system-x86_64 examples in README pointed both -drive
if=pflash entries at the same file (/usr/share/ovmf/x64/OVMF.4m.fd).
OVMF needs CODE for the first pflash and VARS for the second; as
written, EFI NVRAM is not initialized correctly.

The path /usr/share/ovmf/x64/ is also stale - the ovmf package has
been replaced by edk2-ovmf, which installs under /usr/share/edk2/x64/.

Fix both in the three examples (testimage loop section, base Boot ISO
block, espeakup variant).
2026-04-24 12:19:01 +02:00
Thierry M de43019094
Update base.po (#4467) 2026-04-23 20:07:54 +10:00
renovate[bot] 6e222bcdd8
Update dependency pre-commit to v4.6.0 (#4459)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-23 11:08:51 +10:00
renovate[bot] 6652197e35
Update pre-commit hook pre-commit/mirrors-mypy to v1.20.2 (#4463)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-23 11:06:09 +10:00
renovate[bot] 80ae85cc8b
Update dependency mypy to v1.20.2 (#4458)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-22 21:41:09 +10:00
correctmost 00834f9c6e
Use bools instead of time values for SysCommandWorker attributes (#4462)
Only the truthiness of the time values was being evaluated. This
also reduces the usage of time.time(), which makes the codebase
more resilient against clock drift issues.
2026-04-22 21:33:35 +10:00
Softer e7d38d0e82
Fix Limine install with ESP mounted outside /boot (#4442)
* Fix Limine install with ESP mounted outside /boot

Place limine.conf next to the EFI binary on the ESP so it is found
regardless of ESP mountpoint, and block unbootable layouts (non-UKI
Limine with ESP not at /boot and no separate /boot partition) in
GlobalMenu validation, guided.main() and _add_limine_bootloader().

Fixes #4333

* Extract bootloader layout validation into lib/bootloader/utils

* Consolidate Limine layout validation in bootloader utils

Move the boot-partition FAT check from GlobalMenu into
validate_bootloader_layout so all three call sites (GlobalMenu,
guided.py, Installer._add_limine_bootloader) share one function.

Return a BootloaderValidationFailure dataclass (kind + description)
instead of str | None, so callers can match on the failure kind and
the description is built where partition context is in scope.

* Encapsulate FAT filesystem detection in FilesystemType.is_fat()
2026-04-22 21:32:41 +10:00
correctmost d1765323d8
Use staticmethod for PasswordStrength methods (#4461)
The methods don't need access to the class, so they don't need to
be classmethods. This change reduces the number of 'bad return'
warnings seen when running Pyright, Pyrefly, and ty.
2026-04-22 21:31:06 +10:00
javier-anton-ordonez 094798b496
ES Language updated (#4456)
* ES langauje updated and added diferent translations

* Update archinstall/locales/es/LC_MESSAGES/base.po

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Cerrar -> Ocultar

Github copilot suggested

* Apply suggestion from @Copilot

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Fix Spanish translations and accents in base.po

Github suggestions

* ./locales_generator.sh generated

* Accent updated and ./locales_generator.sh generated

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-04-22 10:34:41 +10:00
stinga11 fa54c9d6c9
Change Budgie display server and update packages (#4450)
Some changes consistent with other distros.
2026-04-22 10:23:09 +10:00
renovate[bot] b842e54091
Update dependency arch/python-textual to v8.2.4 (#4448)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-21 19:52:17 +10:00
Softer 03b245a77a
Set console font automatically when selecting language (#4356)
* Set console font automatically when selecting language

Add console_font field to languages.json and Language dataclass.
When a language is activated, setfont is called automatically,
falling back to default8x16 on error or for languages without
a custom font. Also activate translation when loading language
from config file.

* Support FONT environment variable for console font override

When FONT env var is set, use it as the console font instead of the language-specific font mapping from languages.json. The font is applied at startup and preserved across language switches.

On exit (success or failure), restore the console font to default8x16.

* CI checks fix

* Try to restore original console font with setfont -O

* Fix for pylint

* Restore console font before Textual exits application mode

Move font set/restore into Textual lifecycle to prevent color
artifacts from 256/512 glyph transitions. Apply FONT env var
and language font in on_mount, restore in _on_exit_app.

Skip font change when loading language from config (set_font=False)
to defer it until TUI starts.

* Fall back to language font mapping when FONT env var is invalid

Add _using_env_font flag to skip mapping only when FONT was
successfully applied. Show info message after TUI exits if FONT
could not be set.

* Use tempfile for console font backup files

* Fix linter errors: use mkstemp, close fds, add @override

* Fix ruff formatting

* Move font state from module singleton into TranslationHandler

* Refactor font handling per review feedback

* Make font methods members of TranslationHandler, skip on non-ISO

* ci: trigger tests

* Move running_from_iso import to module level

No circular dep, simpler than per-method local imports.

* Add explicit ISO guard to restore_console_font

Matches the existing guards in _set_font and save_console_font.
Behaviour was already safe implicitly via _font_backup=None, but
the explicit check makes intent obvious at the call site.

* Skip apply_console_font off-ISO

* Use list form for setfont SysCommand calls
2026-04-21 18:36:29 +10:00
Dylan M. Taylor 7d10f9e08b
ci: Strip Arch pkgrel from Repology versions in Renovate config (#4453)
* ci: Strip Arch pkgrel from Repology versions in Renovate config

* ci: Use .+ instead of .* in extractVersionTemplate

Co-authored-by: codefiles <11915375+codefiles@users.noreply.github.com>

---------

Co-authored-by: codefiles <11915375+codefiles@users.noreply.github.com>
2026-04-21 15:18:25 +10:00
Anton Hvornum d80bdb4fad
Bumping version to: 4.3 (#4452) 2026-04-20 22:31:22 +02:00
Anton Hvornum 68d137cdce
Bumping version to: 4.3 2026-04-20 22:28:35 +02:00
Softer 82a46c66ca
Fix shell injection in user_set_shell and chown (#4443)
Use argv list with run() instead of sh -c with f-string interpolation,
fix mutable default argument in chown, add debug logging on failure.
2026-04-20 18:36:49 +10:00
Dhruv 86dc1bbc12
locale(hindi): Completed the hindi translation locale (#4446)
* locale: ran generate_locale before making change

* locale: first 1000 confirmed everything is fine

* locale(hi): fixed rest of the fuzzy and empty strings

* locale(hi): ran locale generator
2026-04-20 18:29:26 +10:00
codefiles cd62eff4a7
Fix copying into target directory (#4441) 2026-04-18 12:05:00 +10:00
Softer e8ea33c41c
Enable power management services after package installation (#4440) 2026-04-18 12:04:14 +10:00
Softer 4fcef35af0
Add optional "Additional fonts" selection to Applications menu (#4420)
* Add Fonts application with multi-select for emoji and CJK packages

* Rename to Additional fonts and add package descriptions

* Add noto-fonts to font package selection

* Move font descriptions into FontPackage enum method

* ci: trigger tests

* Add ttf-liberation and ttf-dejavu to font selection
2026-04-18 12:02:47 +10:00
codefiles 9fdd7eb12e
Refactor EncryptionType (#4438)
* Use UPPER_CASE for EncryptionType

* Use StrEnum for EncryptionType
2026-04-17 10:08:23 +10:00
codefiles 8fe8d4e35f
Pin linkify-it-py to Arch Linux package version (#4437) 2026-04-17 10:07:57 +10:00
renovate[bot] 02faf9fbb9
Update pre-commit hook astral-sh/ruff-pre-commit to v0.15.11 (#4436)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-17 10:07:09 +10:00
renovate[bot] 9b9f9d6ac0
Update dependency ruff to v0.15.11 (#4435)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-17 10:06:51 +10:00
Dylan M. Taylor 98d72a6b57
ci: Update renovate to track Arch Linux repos using repology (#4434) 2026-04-16 19:17:07 +10:00
Daniel Girtler 06488dfb9a
Fix table column error (#4406) 2026-04-16 07:30:38 +02:00
Daniel Girtler 29588fadee
Fix encrypted partition selection (#4407) 2026-04-16 07:29:53 +02:00
codefiles 3cabe860ae
Refactor LsblkInfo field validators (#4428) 2026-04-16 14:06:23 +10:00
codefiles 7ea171369a
Refactor PartitionType (#4432)
* Use UPPER_CASE for PartitionType

* Use StrEnum for PartitionType
2026-04-16 14:05:08 +10:00
Anton Hvornum 8b3be842ca
Bumping version to: 4.2 (#4433) 2026-04-15 20:47:13 +02:00
codefiles 30f50d9719
Revert pydantic update due to upstream bug (#4427) 2026-04-15 10:16:34 +10:00
tom c1771cf615
locale(german): extend and fix translation (#4421)
* chore(locale): Fix and improve German translation strings

* chore(locale): edit incorrect translations
2026-04-14 17:40:15 +10:00
Ian Dieb H. Rebouças c0d3c14b6e
Update Brazilian Portuguese translation (#4426)
Co-authored-by: Ian Dieb <idbreboucas@gmail.com>
2026-04-14 17:39:23 +10:00
correctmost 113cc7fd94
Fix urllib.parse import to avoid warnings with ty and Pyright (#4425) 2026-04-14 15:39:08 +10:00
renovate[bot] 88366ba575
Update dependency pydantic to v2.13.0 (#4424)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-14 15:38:14 +10:00
renovate[bot] 728bb450c7
Update pre-commit hook pre-commit/mirrors-mypy to v1.20.1 (#4423)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-14 15:37:56 +10:00
codefiles 2b27e565ae
Refactor ModificationStatus (#4422)
* Use UPPER_CASE for ModificationStatus member names

* Use StrEnum for ModificationStatus

* Replace LvmVolumeStatus with ModificationStatus
2026-04-14 15:37:14 +10:00
renovate[bot] a52bfc3446
Update dependency mypy to v1.20.1 (#4419)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-13 18:49:04 +10:00
renovate[bot] 5dd94e80d2
Update astral-sh/ruff-action action to v4 (#4416)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-13 18:48:17 +10:00
codefiles 335a7b792c
Refactor FilesystemType (#4417)
* Use UPPER_CASE for FilesystemType member names

* Use StrEnum for FilesystemType

* Use FilesystemType member values
2026-04-13 18:41:59 +10:00
Matteo 5553cb9eae
locale: Update Italian translation (#4415)
-Translated new strings
-Fixed a couple of old translations
2026-04-13 18:38:24 +10:00
Softer 80da3f14a1
Add Pacman settings submenu with Color and ParallelDownloads (#4404)
* Add Pacman settings submenu with Color and ParallelDownloads

Replace the standalone Parallel Downloads menu item with a Pacman
submenu containing ParallelDownloads (default 5) and Color (default on).
Settings are applied to both live and target system pacman.conf.
Hidden behind --advanced flag.

Backward compatible with old configs using "parallel_downloads" key.

* Skip _apply_to_live when user exits Pacman menu without changes

* Use TypedDict for PacmanConfiguration serialization

* Show Pacman menu by default, keep ParallelDownloads behind --advanced
2026-04-13 18:37:51 +10:00
codefiles bf9b9cb7c1
Remove invalid container PATH lookup (#4413) 2026-04-12 14:48:51 +10:00
Softer 9a2d546882
Add translation support for TUI help groups and binding descriptions (#4363)
* Add translation support for TUI help groups and binding descriptions

Help group names shown via F1 (General, Navigation, Selection, Search) and key binding descriptions in the Textual footer (Down, Up, Cancel, Confirm, etc.) were hardcoded in English and never went through the translation system.

* ruff_format_check and mypy fixes

* Refactor _translate_bindings to accept BindingsMap instead of Any

Add TApp.translate_bindings() to avoid exporting private functions
across modules.

* Revert deprecated curses help.py change

* Move TApp import to module level in global_menu

* Change translate_bindings from staticmethod to member method
2026-04-12 14:24:46 +10:00
codefiles d6de03ab76
Use auto() for eligible StrEnum members (#4411) 2026-04-11 22:51:43 +10:00
Koutheir Attouchi 51600ecd2a
Update Arabic translation (#4410) 2026-04-11 18:14:14 +10:00
Softer 60bcded743
Replace tab with spaces in preview package lists (#4409) 2026-04-11 17:48:26 +10:00
codefiles 934407414e
Add constant for mirrorlist (#4403) 2026-04-11 10:17:29 +10:00
renovate[bot] 1a4eedf868
Update actions/upload-artifact digest to 043fb46 (#4402)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-11 10:16:58 +10:00
Daniel Girtler b2f413124b
Allow granular plasma configuration (#4389)
* Flexible plasma profile selection

* Update

* Update

* Update

* Update
2026-04-10 07:07:28 +02:00
renovate[bot] 101f647319
Update dependency ruff to v0.15.10 (#4400)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-10 07:24:30 +10:00
renovate[bot] 9059a18dfe
Update pre-commit hook astral-sh/ruff-pre-commit to v0.15.10 (#4401)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-10 07:24:01 +10:00
correctmost d6987b4e9d
Fix del-attr-with-constant ruff warnings (#4399) 2026-04-09 10:19:02 +10:00
codefiles 1bf87c6f4a
Use Path.copy() (#4398) 2026-04-08 15:18:09 +02:00
codefiles 6505e17f34
Refactor sync_log_to_install_medium() (#4397) 2026-04-08 14:35:35 +02:00
Daniel Girtler 78987d75fe
Revert enter behavior on multi-select (#4386) 2026-04-08 09:17:38 +02:00
renovate[bot] b906a34a5d
fix(deps): update dependency pytest to v9.0.3 (#4391)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-08 17:05:33 +10:00
correctmost 18c77b94f2
Remove unnecessary 'unused-ignore' mypy directives (#4395)
The directives were added because a PR branch accidentally lagged
behind master and did not contain the mypy python_version bump from
commit 0175949ca.

This fixes commit d70e03fa3.
2026-04-08 08:42:49 +02:00
codefiles 3ef0848ffe
Refactor copy_iso_network_config() (#4394) 2026-04-08 08:13:14 +02:00
codefiles a92cd50aec
Remove deprecated __future__ imports (#4393) 2026-04-08 08:11:05 +02:00
Crystal eda9ee338b
Update German translation for base.po (#4334)
* Update German translations in base.po

Updated German translations for various prompts and messages in the base.po file.

* Apply suggestions from code review

Co-authored-by: Luca Zeuch <l-zeuch@email.de>

* Removed the # fuzzy´s from the already translated sentences.

---------

Co-authored-by: Luca Zeuch <l-zeuch@email.de>
2026-04-07 23:23:22 +10:00
Ghosted Owl caf285a6dc
Czech translation (#4370)
* Complete Czech translation

* Complete Czech translation
2026-04-07 23:21:52 +10:00
codefiles 7609a1634e
Bump ruff target-version to Python 3.14 (#4390)
* Bump ruff target-version to Python 3.14

* Update exception syntax to pass ruff format
2026-04-07 23:09:14 +10:00
Daniel Girtler f37ae8b282
Handle empty mountpoint input (#4388) 2026-04-07 13:54:18 +02:00
codefiles d57709cb2f
Remove quotes from type annotation (#4384) 2026-04-07 12:21:51 +10:00
Lena Pastwa 9e8cbd0181
Update Polish translation (#4383) 2026-04-07 12:21:19 +10:00
HADEON 3ba29f1193
Patch plasma profile (#4358)
* add essentials #4336

* rem unrelated change
2026-04-06 22:43:06 +10:00
codefiles a8d265184c
Add constant for archiso mountpoint (#4377) 2026-04-06 22:41:33 +10:00
codefiles 37159dcb6d
Add LPath execute permissions methods (#4378) 2026-04-06 09:16:21 +02:00
codefiles e2bd7b3405
Remove is_subpath() and use Path.is_relative_to() (#4372) 2026-04-06 16:42:45 +10:00
codefiles 56bec01979
Add constant for /etc/pacman.conf (#4375) 2026-04-05 23:18:22 +02:00
Ghosted Owl 41858db832
Russian translation (#4367)
* Сomplete russian translation

* Сomplete russian translation
2026-04-03 23:41:28 +11:00
renovate[bot] 5a4b6131c1
fix(deps): update dependency ruff to v0.15.9 (#4366)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-03 09:50:16 +11:00
renovate[bot] c91e19e534
chore(deps): update pre-commit hook astral-sh/ruff-pre-commit to v0.15.9 (#4365)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-03 09:41:45 +11:00
Dylan M. Taylor 6c6c8d8000
Stop installing xorg packages for Wayland profiles (#4348)
* Add WaylandProfile to avoid installing xorg packages for Wayland compositors

* Refactor: use composition (is_wayland) instead of WaylandProfile inheritance

* Fix X11 profiles to inherit xorg packages from XorgProfile

* Style: use consistent multi-line super().__init__ for Wayland profiles

* Refactor: replace is_wayland with DisplayServerType enum

Add DisplayServerType enum (Xorg/Wayland) to Profile. All profiles
now inherit Profile directly with an explicit display_server param.
desktop.py installs xorg-server and xorg-xinit for Xorg profiles.
XorgProfile remains for standalone Xorg selection.

* Remove unnecessary super().packages from desktop profiles
2026-04-03 09:38:02 +11:00
Julio Napurí 6c9f66265a
i18n: Updated Spanish translation (#4357) 2026-04-02 18:21:49 +11:00
Softer 5544abd380
Improved translation into Ukrainian (#4355) 2026-04-02 14:40:40 +11:00
renovate[bot] deb8080322
chore(deps): update pre-commit hook pre-commit/mirrors-mypy to v1.20.0 (#4351)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-02 07:52:30 +11:00
correctmost d70e03fa3b
Update mypy to 1.20.0 (#4352)
* Update mypy to 1.20.0

This commit also removes a cast that is no longer needed after
https://github.com/python/mypy/pull/20602

* Ignore os.system deprecation warnings from mypy to fix CI
2026-04-02 07:51:47 +11:00
Dylan M. Taylor 29b73302ae
Don't write encryption keyfiles to an unencrypted root partition (#4349) 2026-04-01 15:35:33 +11:00
Dylan M. Taylor a3c6bd5d45
Use nvidia-open instead of nvidia-open-dkms for mainline kernels (#4347) 2026-04-01 15:24:11 +11:00
Anton Hvornum 0175949cab
Bumping version to: 4.1 (#4346) 2026-03-31 23:02:14 +02:00
Dylan M. Taylor 179d9c7b48
Remove Nvidia proprietary driver option (nvidia-dkms no longer in repos) (#4343)
* Remove Nvidia proprietary driver option (nvidia-dkms no longer in repos)

* Remove libva-mesa-driver (now provided by mesa)
2026-03-31 22:51:57 +02:00
Odyssey bdf6f92991
Update catalan locales (#4344) 2026-04-01 07:33:34 +11:00
Dylan M. Taylor ef4d7cfc3a
Move auth config helpers to AuthenticationConfiguration class (#4340) 2026-03-31 11:29:26 +11:00
Dylan M. Taylor 603c432e18
Warn when a desktop profile's greeter can't log in without a regular user (#4331) 2026-03-31 10:48:01 +11:00
Anton Hvornum e3e9563aa6
Bumping version to: 4.0 2026-03-30 23:35:51 +02:00
renovate[bot] 398d6cfdbe
chore(deps): update pre-commit hook astral-sh/ruff-pre-commit to v0.15.8 (#4329)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-03-27 14:33:13 +11:00
renovate[bot] c76fd90074
fix(deps): update dependency ruff to v0.15.8 (#4328)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-03-27 14:32:55 +11:00
Daniel Girtler 4b9087e2f4
Fix AwaitComplete runtime error (#4325) 2026-03-26 13:04:43 +01:00
Daniel Girtler dc64e15327
Handle enter on filter confirm (#4324) 2026-03-26 13:04:09 +01:00
Daniel Girtler dd0da34ed9
Move luks into disk module (#4296) 2026-03-21 18:36:00 +11:00
Daniel Girtler e763c1109c
Refactor interactive module (#4315)
* Refactor interactive module

* Refactor interactive module

* Update
2026-03-21 18:35:44 +11:00
Daniel Girtler 1764b4971d
Refactor mirrors (#4274) 2026-03-21 17:57:33 +11:00
Daniel Girtler 8d6c56ca2b
Allow skip on password confirmation (#4273) 2026-03-21 17:57:17 +11:00
Daniel Girtler e06dd6299f
Zram - remove custom size in config (#4272) 2026-03-21 17:56:59 +11:00
Daniel Girtler 8e34303175
Fix iwd network installation and setup (#4271)
* Fix 4223 - IWD

* Update

* Update
2026-03-21 17:56:41 +11:00
renovate[bot] cfdcebcacd
fix(deps): update dependency ruff to v0.15.7 (#4312)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-03-21 12:35:25 +11:00
renovate[bot] b21ac742c2
chore(deps): update pre-commit hook astral-sh/ruff-pre-commit to v0.15.7 (#4311)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-03-21 12:34:40 +11:00
Rosy 594cf54c8a
Update Turkish translations and refresh locale template (#4310) 2026-03-19 08:36:23 +11:00
Piyush Singh e74a72f482
fix: reintegrate PasswordStrength into password prompt (#4111) (#4291) 2026-03-18 22:48:05 +11:00
Daniel Girtler b186fb3f64
Async menu (#4308)
* Move to async TUI

* Update

* Update
2026-03-16 10:39:36 +11:00
renovate[bot] ffa130fe99
chore(deps): update pre-commit hook astral-sh/ruff-pre-commit to v0.15.6 (#4303)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-03-13 15:51:48 +11:00
amode e718a12b42
Removed unnecessary signal for multi-line comment. (#4298) 2026-03-13 15:01:52 +11:00
renovate[bot] 28f4904a3c
fix(deps): update dependency ruff to v0.15.6 (#4304)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-03-13 15:01:20 +11:00
Valerii bace59aef8
better Ukrainian 1.4.2 (#4301)
* Add files via upload

* Add files via upload
2026-03-13 14:59:26 +11:00
Atharv Singh Negi 8b65bd9a6a
Add nepali translation (#4295)
* Improve Hindi translations (base.po)

* Improve all Fuzzy and more hindi translations

* Update base.po

* Update base.po

* Update Hindi translations in base.po

* Update translation for Network Manager iwd backend

* Create base.po

* Update base.po

* Update base.po

* Update languages.json

* Update base.po

* Complete Nepali translation and generated .mo file

* Update languages.json

* Update languages.json

* Update Nepali translations with system and user strings

* Add translations for Partitioning, Bootloader, and Network

* Add disk and configuration translations

* Reach 500+ lines: User management, NTP, and BTRFS subvolumes

* Reached 700+ strings: Desktop profiles, BTRFS setup, and final installation prompts

* Fix syntax error in base.po and update translations
2026-03-09 21:22:53 +11:00
Atharv Singh Negi a4bfd379f5
Add nepali translation (#4294)
* Improve Hindi translations (base.po)

* Improve all Fuzzy and more hindi translations

* Update base.po

* Update base.po

* Update Hindi translations in base.po

* Update translation for Network Manager iwd backend

* Create base.po

* Update base.po

* Update base.po

* Update languages.json

* Update base.po

* Complete Nepali translation and generated .mo file

* Update languages.json

* Update languages.json

* Update Nepali translations with system and user strings

* Add translations for Partitioning, Bootloader, and Network

* Add disk and configuration translations

* Reach 500+ lines: User management, NTP, and BTRFS subvolumes

* Reached 700+ strings: Desktop profiles, BTRFS setup, and final installation prompts
2026-03-09 12:31:36 +11:00
Atharv Singh Negi 2b63d573af
Locales: Add Nepali (ne) translation (Initial 300+ strings) (#4288)
* Improve Hindi translations (base.po)

* Improve all Fuzzy and more hindi translations

* Update base.po

* Update base.po

* Update Hindi translations in base.po

* Update translation for Network Manager iwd backend

* Create base.po

* Update base.po

* Update base.po

* Update languages.json

* Update base.po

* Complete Nepali translation and generated .mo file

* Update languages.json

* Update languages.json

* Update Nepali translations with system and user strings

* Add translations for Partitioning, Bootloader, and Network

* Add disk and configuration translations

* Reach 500+ lines: User management, NTP, and BTRFS subvolumes
2026-03-07 16:57:37 +11:00
renovate[bot] 33b0131e4e
fix(deps): update dependency ruff to v0.15.5 (#4287)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-03-06 12:06:53 +11:00
renovate[bot] 8638726e7a
chore(deps): update pre-commit hook astral-sh/ruff-pre-commit to v0.15.5 (#4286)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-03-06 12:06:33 +11:00
codefiles 6d87a062fd
Move all LVM helpers to dedicated module (#4283) 2026-03-05 09:13:04 +11:00
Atharv Singh Negi e133cb0d28
Add nepali translation (#4282)
* Improve Hindi translations (base.po)

* Improve all Fuzzy and more hindi translations

* Update base.po

* Update base.po

* Update Hindi translations in base.po

* Update translation for Network Manager iwd backend

* Create base.po

* Update base.po

* Update base.po

* Update languages.json

* Update base.po

* Complete Nepali translation and generated .mo file

* Update languages.json

* Update languages.json

* Update Nepali translations with system and user strings

* Add translations for Partitioning, Bootloader, and Network
2026-03-05 09:11:45 +11:00
codefiles 452abe4277
Move udev_sync() to disk.utils (#4281) 2026-03-04 12:43:47 +11:00
codefiles 813b9b34b3
Refactor arch_config_handler to use DI (#4280) 2026-03-03 20:11:22 +11:00
codefiles 64567a748a
Remove support for NTFS root file system (#4279)
* Remove support for NTFS root file system

* Fix rootfstype value
2026-03-03 12:21:31 +11:00
codefiles b809c84ad5
Use os.sync() instead of sync command (#4278) 2026-03-02 07:48:22 +11:00
codefiles 501759d979
Remove obsolete GRUB package install (#4277) 2026-03-02 07:04:32 +11:00
codefiles 839e6bfc55
Move get_version() to version module (#4270) 2026-03-01 11:31:13 +11:00
codefiles 74a230dae9
Enable if-key-in-dict-del ruff rule (#4269) 2026-03-01 08:06:49 +11:00
codefiles f19f8d195f
Replace Installer with path parameter in Boot (#4268) 2026-03-01 08:06:15 +11:00
codefiles 76d6f08841
Remove unnecessary post-init (#4267) 2026-02-28 17:30:59 +11:00
codefiles 390b4959bd
Refactor ISO check (#4264) 2026-02-28 11:20:02 +11:00
correctmost d413c01fde
Fix a reportUnnecessaryIsInstance Pyright warning (#4263) 2026-02-27 17:39:46 +11:00
renovate[bot] d781c9d857
fix(deps): update dependency ruff to v0.15.4 (#4259)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-02-27 15:39:03 +11:00
renovate[bot] 33f3709c31
chore(deps): update pre-commit hook astral-sh/ruff-pre-commit to v0.15.4 (#4261)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-02-27 15:38:49 +11:00
renovate[bot] ec8bd01ced
chore(deps): update actions/upload-artifact action to v7 (#4260)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-02-27 12:14:25 +11:00
codefiles 3cd85c023e
Remove unneeded chmod (#4262) 2026-02-27 12:13:59 +11:00
renovate[bot] b6ce255b36
chore(deps): update pre-commit hook astral-sh/ruff-pre-commit to v0.15.3 (#4258)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-02-27 06:59:38 +11:00
Daniel Girtler e4faba2de0
Convert imports to absolute imports (#4196)
* Enable ruff absolute import check

* Convert all relative imports to absolute

* Update

* Update
2026-02-26 20:17:48 +11:00
Anton Hvornum c92a457142
Revert "Locale timezone python chmod (#4210)" (#4257)
This reverts commit 01d3af9fbb.
2026-02-25 22:48:03 +01:00
Favilances 01d3af9fbb
Locale timezone python chmod (#4210)
* Set timezone during minimal install

* Clean up conflicting boot entries

* Revert "Clean up conflicting boot entries"

This reverts commit e673301b99.
2026-02-25 22:47:25 +01:00
Daniel Girtler 683996c44f
Add missing linkify dependency (#4208)
* Add missing linkify dependency

* Update PKGBUILD
2026-02-25 22:45:28 +01:00
Daniel Girtler 4f87ccba28
Refactor general utility functions (#4212) 2026-02-25 22:45:21 +01:00
renovate[bot] 3447d2f47d
fix(deps): update dependency pylint to v4.0.5 (#4253)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-02-24 08:45:24 +11:00
codefiles d86daa531a
Add provision() to configure users for profiles (#4254) 2026-02-22 07:53:58 +11:00
renovate[bot] a9c939cb86
chore(deps): update pre-commit hook astral-sh/ruff-pre-commit to v0.15.2 (#4251)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-02-20 17:34:04 +11:00
renovate[bot] 415fefef26
fix(deps): update dependency ruff to v0.15.2 (#4252)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-02-20 17:33:41 +11:00
codefiles 2d18b55fa7
Remove unused advanced member from Profile (#4248) 2026-02-19 12:32:57 +11:00
nubprogrammer bb76f96bd5
locales: Add Nepali (ne) translation (#4222)
* Improve Hindi translations (base.po)

* Improve all Fuzzy and more hindi translations

* Update base.po

* Update base.po

* Update Hindi translations in base.po

* Update translation for Network Manager iwd backend

* Create base.po

* Update base.po

* Update base.po

* Update languages.json

* Update base.po

* Complete Nepali translation and generated .mo file

* Update languages.json

* Update languages.json

* Update Nepali translations with system and user strings
2026-02-19 07:22:43 +11:00
Mário Victor Ribeiro Silva 377b3bee97
feat: add `plasma-login-manager` (#4247) 2026-02-19 07:20:13 +11:00
codefiles 618c0bd5dc
Remove arch_config_handler from installer (#4246) 2026-02-19 07:18:53 +11:00
codefiles bd35473b5d
Move LVM helpers to dedicated module (#4245) 2026-02-18 15:57:10 +11:00
codefiles f2c17c6341
Move get_parent_device_path() to disk.utils (#4243) 2026-02-18 09:12:47 +11:00
HADEON f736b8c4ec
install gfx before DE/WM/Server (#4238) 2026-02-17 13:19:11 +11:00
codefiles 8edab9fafd
Move get_unique_path_for_device() to disk.utils (#4242) 2026-02-17 13:15:07 +11:00
codefiles 083a73eab1
Move unlock_luks2_dev() (#4234) 2026-02-17 07:35:25 +11:00
codefiles 35c2ff3ef5
Move swapon() to disk.utils (#4233) 2026-02-16 14:43:10 +11:00
HADEON 8148b1d9bf
fix efistub bootloader to use backslashes (#4231)
* fix efistub to use backslashes

* comment

* cf1

Co-authored-by: codefiles <11915375+codefiles@users.noreply.github.com>

* cf2

Co-authored-by: codefiles <11915375+codefiles@users.noreply.github.com>

---------

Co-authored-by: codefiles <11915375+codefiles@users.noreply.github.com>
2026-02-16 13:10:52 +11:00
codefiles 3b6f7db942
Move mount() to disk.utils (#4232) 2026-02-16 13:08:59 +11:00
codefiles 9bd2131792
Refactor SysInfo.has_uefi() to DI for bootloader (#4230) 2026-02-15 12:34:40 +11:00
renovate[bot] ec9ee80062
fix(deps): update dependency ruff to v0.15.1 (#4224)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-02-15 09:58:02 +11:00
renovate[bot] cfe61c0993
chore(deps): update pre-commit hook astral-sh/ruff-pre-commit to v0.15.1 (#4225)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-02-15 09:57:47 +11:00
Franco Castillo 6ce0556c2c
Update Spanish translation (#4228) 2026-02-15 08:40:19 +11:00
correctmost a61d4e5314
Revert "Handle whole-disk LUKS root params (#4205)" (#4229)
This reverts commit 0dddc7308d.
2026-02-15 08:38:55 +11:00
Mário Victor Ribeiro Silva 21358f77dd
feat: update `pt_BR` translations (#4221) 2026-02-12 12:30:14 +11:00
Matteo a7901d172d
Translation: Update Italian (#4219)
- Added new strings
- Improved old translation
2026-02-06 07:49:01 +11:00
utuhiro78 c0d47db75d
Update Japanese translation (#4217) 2026-02-04 19:34:31 +11:00
renovate[bot] 66e0dd119f
Update dependency ruff to v0.15.0 (#4214)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-02-03 20:49:30 +00:00
renovate[bot] 13b7c7194a
Update pre-commit hook astral-sh/ruff-pre-commit to v0.15.0 (#4215)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-02-04 07:48:52 +11:00
renovate[bot] 3dab440cbf
Update actions/checkout digest to de0fac2 (#4213)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-02-04 07:06:48 +11:00
Daniel Girtler 1d8352b466
Use TypeAdapter for Json serialization (#4183) 2026-02-03 22:27:51 +11:00
Favilances 0dddc7308d
Handle whole-disk LUKS root params (#4205)
Co-authored-by: favilances <favilances@proton.me>
2026-02-03 22:03:22 +11:00
Daniel Girtler 4a8604ac88
Make list manager run private (#4192) 2026-02-03 11:22:56 +01:00
Daniel Girtler aac6c896d9
Add missing galician mo file (#4209) 2026-02-03 11:18:11 +01:00
gaelgnz f8304b0bd1
Added Galician language support (#4202)
* Added Galician language support

* Delete archinstall/locales/gl/LC_MESSAGES/base.mo
2026-02-03 11:35:33 +11:00
codefiles 0394a735a7
Fix typo locale -> local (#4201) 2026-02-03 11:34:53 +11:00
codefiles 12bd83ca8a
Refactor skip_boot to use dependency injection (#4200) 2026-02-03 11:34:27 +11:00
correctmost b5f710425f
Remove an unused milliseconds member from Installer (#4199) 2026-02-01 22:48:30 +11:00
correctmost 331634fd80
Measure install time with monotonic clock instead of system clock (#4198)
Using time.time() can be inaccurate if the system clock gets
updated in between calls.
2026-02-01 22:48:09 +11:00
correctmost 173c64c847
Avoid union syntax in an isinstance check (#4197)
This is a partial revert of commit 44f4bc86. The UP038 ruff rule
was removed and using union syntax is no longer recommended.
2026-02-01 22:47:39 +11:00
renovate[bot] 47a4caf163
Update astral-sh/ruff-action action to v3.6.1 (#4195)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-01-31 09:40:51 +11:00
Daniel Girtler 449c1bfb36
Rename ask* functions to select* (#4191) 2026-01-31 08:17:11 +11:00
renovate[bot] e2ba6cbc54
Update astral-sh/ruff-action action to v3.6.0 (#4193)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-01-30 21:47:52 +11:00
Federico Berrueta 97dd099c0e
Fix: Resolve fuzzy strings and add note for 'Seat access translation' (#4186) 2026-01-29 09:49:16 +11:00
HADEON 26014aa092
Add sponsors button (#4056)
* Add archlinux funding file

* Fix formatting of custom funding URL
2026-01-28 22:01:56 +01:00
nubprogrammer 6d89770e7a
Update Hindi translations for archinstall (#4185)
* Improve Hindi translations (base.po)

* Improve all Fuzzy and more hindi translations

* Update base.po

* Update base.po

* Update Hindi translations in base.po

* Update translation for Network Manager iwd backend
2026-01-29 07:56:59 +11:00
codefiles 2cb81d8758
Reuse MirrorListHandler instance (#4184) 2026-01-29 07:54:18 +11:00
Daniel Girtler 5612325dc3
Refactor code to reduce circular dep (#4175)
* Refactor to reduce circular dep

* Update

* Update
2026-01-28 13:43:57 +01:00
correctmost 8f104bc829
Remove archinstall.svg from project root (#4180)
The file was accidentally added in commit bde544ca.
2026-01-28 11:43:28 +11:00
codefiles 18105fff22
Use main() as script entrypoint (#4179) 2026-01-28 11:42:51 +11:00
codefiles 76284b601b
Remove superfluous __future__ import (#4178) 2026-01-28 07:23:25 +11:00
codefiles 8ffc20b6c1
Refactor script list (#4177) 2026-01-27 17:47:36 +01:00
Daniel Girtler bde544caca
Refactor syscommand (#4176)
* Refactor SysCommand

* Refactor syscommand
2026-01-27 13:31:33 +01:00
Daniel Girtler 316251f6e0
Refactor network config installer (#4143)
* Refactor network config installer

* Update

* Move network menu

* Remove singleton
2026-01-27 19:39:45 +11:00
Daniel Girtler 5fe42bd2f5
Refactor user menu (#4141) 2026-01-27 18:50:09 +11:00
correctmost 15460e4a88
Fix useless-return warnings reported by Pylint (#4173) 2026-01-27 16:40:38 +11:00
codefiles d7bcd431a7
Refactor application_handler to use DI (#4172) 2026-01-27 16:39:42 +11:00
codefiles ef3b6ab853
Refactor auth_handler to use dependency injection (#4171) 2026-01-27 12:46:31 +11:00
Daniel Girtler 2421e538a8
Move Pacman out of init (#4150)
* Move pacman out of init

* Update archinstall/lib/pacman/pacman.py

Co-authored-by: codefiles <11915375+codefiles@users.noreply.github.com>

* Update archinstall/lib/pacman/pacman.py

Co-authored-by: codefiles <11915375+codefiles@users.noreply.github.com>

---------

Co-authored-by: codefiles <11915375+codefiles@users.noreply.github.com>
2026-01-27 12:34:48 +11:00
codefiles 28f7aec2af
Refactor mirror_list_handler to use DI (#4170) 2026-01-27 11:23:01 +11:00
Daniel Girtler a025c79ac3
Delete dead code (#4144) 2026-01-27 11:22:03 +11:00
nubprogrammer 93736349a2
Improve Hindi translations and resolve all fuzzy entries (#4167)
* Improve Hindi translations (base.po)

* Improve all Fuzzy and more hindi translations

* Update base.po

* Update base.po
2026-01-26 23:35:32 +01:00
Daniel Girtler 9bd16e998c
Fix - Handle cancel from list manger properly (#4160) 2026-01-26 23:34:58 +01:00
Daniel Girtler 7a0b4c2a30
Fix - disk partitioning menu (#4158) 2026-01-26 23:34:23 +01:00
Daniel Girtler 63e3825756
Remove obsolete package functions (#4145) 2026-01-26 23:33:21 +01:00
Daniel Girtler a57bb801c0
[README update] Clarify archinstall upgrade steps (#4138)
* Clarify upgrade steps on Live ISO

* Update

* Update

* Update

* Update README.md

Spelling fix

---------

Co-authored-by: Anton Hvornum <torxed@archlinux.org>
2026-01-26 23:30:27 +01:00
codefiles 2ed6182575
Refactor wifi_handler to use dependency injection (#4161) 2026-01-23 14:40:08 +11:00
renovate[bot] b07bbeecd3
Update pre-commit hook astral-sh/ruff-pre-commit to v0.14.14 (#4166)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-01-23 13:13:08 +11:00
renovate[bot] 2c2b17b8a6
Update dependency ruff to v0.14.14 (#4165)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-01-23 13:12:47 +11:00
nubprogrammer 7fb8fb57ee
Improve Hindi translations (base.po) (#4163) 2026-01-23 06:44:23 +11:00
renovate[bot] 3500bc3b41
Update actions/setup-python digest to a309ff8 (#4157)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-01-22 18:32:02 +11:00
codefiles 192aff0b94
Replace sys.exit calls with return values (#4156) 2026-01-22 13:58:40 +11:00
codefiles 4d2864ba76
Refactor error message (#4153) 2026-01-21 16:39:49 +11:00
codefiles 78969c58c7
Move script entry point (#4151) 2026-01-21 12:10:19 +11:00
nubprogrammer 7cf1566902
Improve Hindi translations in base.po (#4152)
* Improve Hindi translations in base.po

This PR improves and fixes Hindi translations in base.po.
It also corrects previously incorrect fuzzy translations.
No functional code changes.

* Update base.po

* removed fuzzy from the things i fixed in translation
2026-01-21 12:08:43 +11:00
codefiles c7dbf0105e
Rework has_default_btrfs_vols (#4147) 2026-01-20 11:18:22 +11:00
codefiles 38462db2db
Enable GRUB UKI menu entries (#4139) 2026-01-19 15:46:02 +11:00
Daniel Girtler 0aca992ac5
Migrate UI to textual (#3997)
* Footer textual

* Linting

* Revert pre-commit for pylint

* Add missing textual

* Reinstate example

* Linting
2026-01-19 07:01:40 +11:00
codefiles 9a38b73baf
Enable quoted-annotation ruff rule and fixes (#4137) 2026-01-18 08:19:07 +11:00
codefiles a150a8d9f7
Remove quotes from Installer type annotations (#4136) 2026-01-17 18:52:18 +11:00
codefiles 7b45613996
Use Self for remaining occurrences (#4135) 2026-01-17 18:51:44 +11:00
renovate[bot] e1d9935f30
Update pre-commit hook astral-sh/ruff-pre-commit to v0.14.13 (#4133)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-01-16 10:50:45 +11:00
renovate[bot] 65190a253e
Update dependency ruff to v0.14.13 (#4131)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-01-16 10:50:19 +11:00
Kenraaliskuutteri 7995d6e815
Updated Finnish translation in base.po (#4129)
Updated Finnish translations for various messages in base.po.
2026-01-16 06:36:36 +11:00
codefiles 2c154245cb
Use Self for Tui (#4130) 2026-01-16 06:36:11 +11:00
codefiles 2c85b5eab0
Remove storage module (#4128) 2026-01-15 14:09:35 +11:00
codefiles 972e278555
Remove leftover code from unattended script (#4127) 2026-01-15 12:18:47 +11:00
codefiles e5a14c0cfe
Use Self in tui (#4126) 2026-01-15 07:05:43 +11:00
Hannan c4de093122
Add header and update urdu translations (#4122)
* add header

* update urdu translations
2026-01-14 19:54:33 +11:00
codefiles 90d1b08628
Remove unused installation_hooks property (#4118) 2026-01-14 19:53:43 +11:00
codefiles 20460e1c29
Use Self in default_profiles (#4125) 2026-01-14 16:03:32 +11:00
codefiles 2e9d5e4829
Refactor Boot (#4124) 2026-01-14 13:29:22 +11:00
codefiles 5811f81e59
Use Self for parameters to dunder methods (#4123) 2026-01-14 13:24:56 +11:00
codefiles 8f7d59b718
Replace __enter__ return type with Self (#4121) 2026-01-13 15:45:21 +01:00
Mattyan89 b779345a5b
fixes (#4093) 2026-01-13 20:59:02 +11:00
codefiles f6eca309ac
Use sys.exit instead of exit (#4120) 2026-01-13 07:51:08 +11:00
codefiles 82512eed0e
Remove superfluous list creation in join calls (#4119) 2026-01-12 12:56:55 +11:00
codefiles db6c11345a
Remove superfluous __future__ imports (#4117) 2026-01-12 10:20:07 +11:00
codefiles 3374b47d50
Use Self for return instances of cls (#4116) 2026-01-12 09:06:19 +11:00
codefiles bde3b0ed6e
Change staticmethods to classmethods (#4115) 2026-01-12 07:17:21 +11:00
codefiles b1290672bb
Change classmethods to staticmethods (#4114) 2026-01-11 17:40:43 +11:00
codefiles 43509d8ce1
Use instance method for type_to_text (#4113) 2026-01-11 11:29:39 +11:00
codefiles efd57870d0
Use instance method for _load_config (#4112) 2026-01-11 11:29:01 +11:00
codefiles cb4b7e3db0
Update classmethods to use cls (#4110) 2026-01-11 10:29:32 +11:00
codefiles 01bee60cd1
Fix typos (#4109) 2026-01-11 10:28:53 +11:00
Tobias Stoeckmann e0c1b869a6
Fix typos in comments (#4107)
Typos found with codespell.

No functional change.
2026-01-10 10:17:50 +11:00
correctmost d07a9b4a92
Disable the non-empty-init-module ruff rule (#4106)
This allows ruff check --preview to pass again.
2026-01-10 10:17:00 +11:00
HADEON ef9f704761
hotfix: Firewall (#4100)
* Needed to have default files + enabled status

* Modify conf file directly

* nl

* more thnx to codefiles

* Fix previews in menu
2026-01-10 10:02:35 +11:00
Benjamin Smith 5fbe1deea4
Add missing spanish translations (#4098)
* added some missing Spanish translations

* added missing translations, fixed typos

* added a bunch of missing translations, fixed some too
2026-01-09 15:54:56 +11:00
renovate[bot] 7292a9e449
chore(deps): update dependency ruff to v0.14.11 (#4095)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-01-09 15:54:10 +11:00
renovate[bot] 85d38f063b
chore(deps): update pre-commit hook astral-sh/ruff-pre-commit to v0.14.11 (#4096)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-01-09 15:53:52 +11:00
HADEON 62edc56a52
hotfix: Revert Grub changes (#4099)
* Hotfix grub

* revert changes
2026-01-09 11:30:12 +11:00
correctmost 84c36adb1f
Avoid a reportPossiblyUnboundVariable warning with Pyright (#4092) 2026-01-07 18:49:07 +11:00
correctmost e2e158973f
Remove unused pytest-mock dependency (#4091) 2026-01-07 12:01:10 +11:00
correctmost ef3369b1c5
Add node_modules to .gitignore and Pylint's ignore list (#4089)
This makes it easier to use Pyright locally.
2026-01-07 11:54:54 +11:00
correctmost bb13139339
Fix an invalid-type-form error reported by ty (#4088)
The 'bytes' annotation for the 'bytes' property was actually a
forward reference to the property instead of builtins.bytes:
https://github.com/astral-sh/ty/issues/1747#issuecomment-3609042917
2026-01-07 11:54:15 +11:00
correctmost 0470495cb1
Migrate pytest configs to native TOML and enable strict mode (#4087) 2026-01-07 11:52:46 +11:00
correctmost 8e0ff2d2a9
Update comment in _final_warning (#4086)
Device paths are no longer mentioned as of adbadbf6.
2026-01-07 10:05:58 +11:00
correctmost cec29d123b
Use serialization TypedDicts to reduce Any instances (#4085) 2026-01-07 10:05:13 +11:00
Valerii f2e40742bb
Better Ukrainian v1.4 (#4084) 2026-01-07 09:57:35 +11:00
HADEON 0188459917
fix: bootloader changes (#4073)
* Bootloader changes:

	-> GRUB: Support for UKI
		- Disable 10_linux or breaks at kernel updates
		- Create 09_custom entry
	-> rEFInd:
		- Remove fallback entry similar to other bootloaders
		- With UKI still one dead entry can be hidden with DEL key
	-> All bootloaders:
		- Default to UKI on if supported, if using no UKI and /efi
		Causes systemd boot to not load, because it needs a XTLDRBOOT part
		Safer default for modern setups and simpler sec boot compat

* Add new models

* Modify based on grub-2.14-rc1 -> No need to use chainload
Thanks to codefiles for the heads-up

* Simplify has_uki_support

* Tab

* checks
2026-01-06 20:04:01 +11:00
HADEON cc6e247dcf
State libfido2 dependency (#4082) 2026-01-06 19:55:58 +11:00
HADEON 450664cdc4
feat: firewalls (#4074)
* Firewall Init

* Enable service
2026-01-05 20:04:43 +11:00
HADEON e590277e69
Another small readme change for clarity (#4077) 2026-01-05 12:35:42 +11:00
summoner 9488233a5a
Translation: Update hungarian po/mo (#4078)
Fix typos and mistakes
2026-01-05 12:35:08 +11:00
HADEON 146a2352bc
Change plasma-meta -> -desktop. (#4076)
This avoids to pull in sddm-kcm (to respect user's choice of login manager)
And to not pull in discover and related tools that should also be up to the user.
2026-01-04 19:37:58 +11:00
summoner 5eb3307efd
Translation: Update hu.po (#4071)
Translate new strings
fix typos
fix wording
2026-01-04 19:22:08 +11:00
HADEON d1a74edf9d
fix pre-commit hook (#4070) 2026-01-02 13:33:24 +11:00
walken fd143af05b
Czech localization update (#4068) 2026-01-02 13:29:11 +11:00
scrypt-kitty 4582d60f13
Do not mount btrfs partitions unless required, tested working and solves issue #3689 (#3992) 2026-01-02 13:27:53 +11:00
Luna Jernberg 7889a5417f
Update Arch Installer translation before Jan 2026 release (#4065)
* Update base.po

Update Swedish for January 2026 iso

* Update Swedish translations before release today

Updated Swedish translations for various messages in base.po.
2026-01-01 20:21:49 +11:00
Daniel Girtler bff715ddab
Add instructions for booting Arch ISO in a VM (#4041)
* Add instructions to boot ISO in VM

* Update

---------

Co-authored-by: Daniel Girtler <dgirtler@atlassian.com>
2026-01-01 10:10:24 +01:00
utuhiro78 051352e218
Update Japanese translation (#4064) 2026-01-01 10:14:31 +11:00
Abdullah Koyuncu 9433f15573
Update Turkish translation (#4062) 2026-01-01 10:13:28 +11:00
Matteo d5b554be1e
Update Italian translation (#4060)
- Translated new strings
- Improved some string
2026-01-01 10:12:37 +11:00
Anton Hvornum aabf6ae19e
Bumping version to: 3.0.15 (#4058)
* Bumping version to: 3.0.15

* ruff formatting
2025-12-31 13:02:10 +01:00
justbispo cb6fe6b34b
Add support for rEFInd boot manager (#3707)
* Add support for rEFInd boot manager

* Fix ruff formatting complaints

* Added support for different mountpoints for /efi and /boot

Also fixed issue where if /boot is located in a BTRFS root partition, the initrd path wasn't including the subvol name.

* Fix ruff formatting complaints

* Replace SysCommand with self.arch_chroot call

* Fix ruff formatting complaints

---------

Co-authored-by: Diogo Bispo <gpg.jta36@slmail.me>
2025-12-31 15:24:22 +11:00
Mariya 446d23c59d
feat(applications): add support for power-profiles-daemon/tuned as a power management daemon (#4015)
* fix(profiles): install power-profiles-daemon by default in the desktop
profile

* fix: only install power-profiles-daemon if a battery is detected

* chore: clean up has_battery method

* fix: make power management daemon a configurable application

* fix: make linter happy after merge

* fix: fix merge issues

* fix: give has_battery a return type to make linter happy

* chore: add locale msgids for power management related strings

* fix: changes requested in review

* fix: cache has_battery result

* fix: changes requested in review

* fix: just return none directly

* fix: add selected power management daemon to applications menu preview
2025-12-31 13:22:27 +11:00
HADEON 83c9bf06b2
Modify archinstall language display to be handled like other sections. (#4048)
* Modify archinstall language display to be handled like other sections.
This fixes a bug where language names that were too long would break curses menu.

* Revert types change
2025-12-31 10:46:46 +11:00
HADEON eb5e88f317
Mirrors sort #4046 (#4050)
* Mirrors sort #4046

* Change logic to be just sorted on bitrate
2025-12-30 15:20:45 +01:00
Vincent Dahmen 9f4f29bd29
lib/network: adds symlink to configure systemd-resovled properly (#4052)
* lib/network: adds symlink to configure systemd-resovled properly

* lib/network: adds overwrite mechanism to enforce resolved symlink

---------

Co-authored-by: Vincent Dahmen <wahrwolf@wolfpit.net>
2025-12-30 16:01:01 +11:00
HADEON 2954e4397b
Feat: Zram algorithm config (#4042)
* Add configuration for swap algorithm. Backward compatible implementation

* Fix interaction to default to Yes and show (default)

* Fix mypy error

* Any -> str, str

* feedback Enums

* test file

* line length warning

* Renames

* Fix default values in TUI menu for display

* Address feedback

* More feedback, really appreciate it.

* Adapt to use same | None = None pattern

* Pytests

* Add missing import for Zram
2025-12-30 15:52:35 +11:00
HADEON 747385a883
Lvm2/LUKS fixes/Mirror Logic (#4047)
* Lvm hotfix attempt

* Use --force and --yes flags

* Changed mirror behavior and more lvm testing

* Handle properly LvmOnLuks to only export in one fo the scenarios

* Idek

* Remove dead block

* Use -f flag and wipefs to remove any existing headers avoid "has signatures"

* oops

* Revert mirror change
2025-12-29 17:35:24 +01:00
HADEON ac984b7622
This commit changes the order of the main menu. (#4043)
Since in the next NVIDIA update, the kernel choice will have an impact on profiles.
The order this way makes it more logical: Bootloader => Kernel => Hw drivers
2025-12-28 22:20:17 +11:00
HADEON 4e52dc7493
README clarifications/corrections (#4038)
* A smaller readme tweak to stop answering the same questions :D

* rem
2025-12-28 11:28:40 +11:00
HADEON 79313c4942
Fix mirrors hang when /status endpoint is down (#4031)
* add explicit _fetched_remote bool

* Attempt 2

* Adds about 15 seconds time-out to fetch_data_from_url with 3 retries (4, 5, 6)
Then fallsback to fully local list

* Feedbacks: 20 -> 30
Do not return early
Add debug
Remove new flag
60 second timeout for reflector

* Clean up install logs by hiding mirror scores behind --verbose
2025-12-28 11:10:03 +11:00
HADEON c1eae10e93
Enable IWD to be used as back-end in network selection (#4025)
* feedback

* feedback2

* Refactor for less duplicate code and more conscise logic
Group NM types and handle configurations appropriatly
	- For IWD -> Copy from ISO + Disable standalone and configure back-end
	- For standard -> Install wpa_supplicant
	- For both install applet only when Desktop profile

Added comments for clearer logic

* Rem comments

* Rem copy to ISO

* the one commit to rule them all
2025-12-28 11:09:37 +11:00
Mintsuki 42a4ee8472
Make removable location the default for bootloader installation (#4030)
Also update the option's description to make it clear that it being enabled is the sane default.
2025-12-27 14:38:14 +01:00
Daniel Girtler 6968a33508
Fix kurdish translation files (#4004)
Co-authored-by: Daniel Girtler <dgirtler@atlassian.com>
2025-12-27 12:41:02 +01:00
utuhiro78 4d01d1dbbb
Update Japanese translation (#4040) 2025-12-27 22:37:11 +11:00
Daniel Girtler 7635474772
Explicitly allow selecting any additional repository (#3973)
Co-authored-by: Daniel Girtler <dgirtler@atlassian.com>
2025-12-27 09:25:15 +01:00
HADEON a4ad1b3724
Remove whitespace in timestamp (#4039) 2025-12-27 17:38:03 +11:00
HADEON 5fcea379b9
Fix LVM creation/ info (#4024)
* use pull and udev sync

* 30s -> 5min
2025-12-25 13:07:26 +11:00
HADEON e5ccdb0c1c
Adds a timer to post install screen (#4028)
* Add timer to end screen of guided

* ruff check
2025-12-25 11:06:03 +11:00
HADEON 9e7a5f6931
Do not install base-devel by default (#4022)
* replace base-devel with sudo and add disclaimer texts

* revert basepot and add rem comments
2025-12-25 11:00:34 +11:00
HADEON 9412f97771
Set up Zram dynamically based on best practice (#4027)
* Use the total available RAM / 2 for swap size dynamically.

* ws

* - Systems with 8 GB RAM or less will get 4096 MB zram
- Systems with more than 8 GB RAM will get half their RAM as zram

* Add debug print
2025-12-25 10:59:03 +11:00
Luis Antonio 1faac77c0d
Update Portuguese translations (pt and pt_BR) and metadata. (#4021)
* Revise Portuguese translations in base.po

Updated translations for various messages in Portuguese.

* Update Brazilian Portuguese translations in base.po

Updated translations and metadata in the Brazilian Portuguese locale file.

* Update Last-Translator in Brazilian Portuguese locale
2025-12-22 22:08:02 +11:00
HADEON 1227babd8c
Change LVM /root def to adapt dynamically (#4005)
* Change def size from 20 -> 32
Rest is still calculated from available - root.

* Use the existing process_root_partition_size():
For LVM just like regular disk best-effort.
This is only for single disk layouts.
2025-12-22 22:05:30 +11:00
Mariya ba5f924540
fix: enable the cosmic-greeter service (#4023) 2025-12-22 09:07:47 +11:00
HADEON f639290c20
ly.service -> ly@tty1.service (#4006)
* ly -> ly@tty1

* ly -> ly@tty1 with disable getty

* ws

* ws2

* ws3

* ws4

* conditionally disable and define
2025-12-21 21:37:06 +11:00
Luna Jernberg 043cd68a7c
Update base.po (#4020)
Update Swedish for January 2026 iso
2025-12-21 21:36:02 +11:00
Mariya 9876558f74
chore: cosmic is stable now, don't hide it behind --advanced flag (#4017)
* chore: cosmic is stable now, don't hide it behind --advanced flag

* fix: remove --advanced check in GreeterType

* chore: remove unused import to make linter happy
2025-12-21 14:45:51 +11:00
Mariya d7b559c67e
feat(applications): add CUPS installation support (#4013)
* feat(applications): add CUPS installation support

* fix: use translation for print service preview_action

* fix: incorrect action for print service menu item

* chore: refactor naming, printer -> print service

* fix: commit untracked file

* chore: fix formatting to make linter happy
2025-12-21 14:30:11 +11:00
Mariya cf31148e46
fix: fix fido warning message being spammed (#4016) 2025-12-21 14:16:06 +11:00
Mariya dee2a84057
fix: fix translation for bluetooth preview_action (#4014) 2025-12-21 13:57:29 +11:00
HADEON 17dc001857
Cache property of graphics_devices (#4007)
* On horrible hardware this makes it so that the "Graphics drivers" section loads directly.
By initializing it with launch instead of on the fly.

* Init after logs

* This cache the property of graphics drivers properly.
Instead of trying to hack early init.
2025-12-21 12:22:59 +11:00
renovate[bot] 6f768ea87c
chore(deps): update pre-commit hook astral-sh/ruff-pre-commit to v0.14.10 (#4012)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-19 18:36:04 +11:00
renovate[bot] e2cdf42690
chore(deps): update dependency ruff to v0.14.10 (#4011)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-19 18:35:50 +11:00
Odyssey b579773421
Update catalan locales (#4010) 2025-12-19 15:51:21 +11:00
renovate[bot] d13882fca1
chore(deps): update dependency pre-commit to v4.5.1 (#4003)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-19 15:50:37 +11:00
HADEON 6b23eff422
H2T (Host-to-target) installs and prevent host pollution (#3978)
* Add host-to-target (H2T) installation mode detection

- Add running_from_host() function to detect if running from installed system vs ISO
- Function checks for /run/archiso existence (ISO mode) vs host mode
- Add clear logging of installation mode on startup
- Skip keyboard layout changes when running from host system
- Fix Pyright type error in jsonify() by using Any instead of object
- Update README to mention installation from existing system

This enables archinstall to be run from an existing Arch installation
to perform host-to-target installs on other disks/partitions.

* match existing style

* rem debug

* info -> debug
2025-12-16 10:59:04 +11:00
renovate[bot] 810a50e46c
chore(deps): update pre-commit hook pre-commit/mirrors-mypy to v1.19.1 (#3998)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-16 08:26:52 +11:00
renovate[bot] 582c54f4e2
chore(deps): update dependency mypy to v1.19.1 (#3996)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-15 16:54:57 +11:00
CYAXXX bc738a48be
Add Kurdish translation (#3994)
* Add Kurdish translation

* Update base.po
2025-12-15 16:34:12 +11:00
CYAXXX 0a6fd6a07e
Delete archinstall/locales/ku (#3995) 2025-12-15 14:23:48 +11:00
scrypt-kitty 20718ead79
Remove /tmp/archlive before building. Otherwise latest changes are not built. (#3993) 2025-12-15 11:23:01 +11:00
CYAXXX fff783ed93
Add Kurdish language (#3991)
* Add Kurdish language

This pull request introduces full Kurdish language integration into archinstall, allowing Kurdish speaking users to navigate and use the installer entirely in their native language.

* Fix translation for timezone selection prompt
2025-12-15 11:20:51 +11:00
renovate[bot] f65cc5f6c7
chore(deps): update actions/upload-artifact action to v6 (#3985)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-15 11:18:54 +11:00
Jesper Otten cffe47a369
Adding new Dutch translations (#3987) 2025-12-15 11:14:26 +11:00
renovate[bot] 0117205f73
chore(deps): update pre-commit hook astral-sh/ruff-pre-commit to v0.14.9 (#3983)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-15 11:12:21 +11:00
renovate[bot] 1f1daf1afc
chore(deps): update dependency ruff to v0.14.9 (#3982)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-15 11:11:46 +11:00
walken c9b0b171b3
Czech localization update (#3980) 2025-12-10 22:46:58 +11:00
HADEON 326232098a
Full disclosure for bootloaders/keymaps (#3979)
* Clarify LUKS2 encryption and keyboard layout context in locales README

* ws

* clarity

* final
2025-12-10 22:46:21 +11:00
HADEON 6b50815eb6
Vconsole.conf KEYMAP= FONT=
_base mkinitcpio.conf v40 error (#3928)

* pr1

* pr2

* pr2-2

* pr2-3

* Revert genfstab and pacstrap command changes

* mistake
2025-12-08 19:25:20 +11:00
renovate[bot] 57bd613679
chore(deps): update dependency pytest to v9.0.2 (#3972)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-07 17:07:39 +11:00
renovate[bot] 8872f98c8d
chore(deps): update dependency mypy to v1.19.0 (#3956)
* chore(deps): update dependency mypy to v1.19.0

* Update

* Update

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Daniel Girtler <dgirtler@atlassian.com>
2025-12-06 21:40:37 +11:00
renovate[bot] 601e033188
chore(deps): update pre-commit hook astral-sh/ruff-pre-commit to v0.14.8 (#3969)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-06 20:23:52 +11:00
Gabriel A Hernandez 07ab6bf4a0
Menu now filters items and sorts using priority, improving UX. (#3967)
* Menu now filters and sorts using priority, improving UX.

* Refactor: improve logic, removed redundancy

* Refactor: improve logic, removed redundancy

* Improved logic when getting view items in menuItems

* Improved logic when getting view items in menuItems
2025-12-06 20:10:01 +11:00
Gabriel A Hernandez 7398e2785d
Typo and grammar fixes (#3970)
* Menu now filters and sorts using priority, improving UX.

* Refactor: improve logic, removed redundancy

* Refactor: improve logic, removed redundancy

* Typo and grammar fixes

* Typo and grammar fixes

* Fix comment formatting in .gitlab-ci.yml

* Fix comment

* Removed code from separate pull request

* Update menu_item.py

* removed white space

* Remove unnecessary blank lines in menu_item.py

>:(
2025-12-06 20:06:07 +11:00
Mintsuki d176b9514c
Remove GRUB removable fallback path (#3971)
As mentioned by @svartkanin on #3950, given we now have a way for the user to
explicitly specify if they want to install to the removable location, having a
fallback like this seems undesirable.

On top of that, as mentioned by @correctmost on the same PR, the code that said
PR introduced was bugged and would always raise an exception anyways.
2025-12-05 20:05:24 +11:00
renovate[bot] 66fb49617a
chore(deps): update dependency ruff to v0.14.8 (#3968)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-05 20:03:05 +11:00
renovate[bot] dbfa60bfa8
chore(deps): update actions/checkout digest to 8e8c483 (#3965)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-05 20:02:24 +11:00
Abdullah Koyuncu e7442bf5c6
Translation: Update the Turkish base.po/base.mo (#3964) 2025-12-03 12:26:09 +11:00
renovate[bot] 627530fd82
chore(deps): update pre-commit hook pre-commit/mirrors-mypy to v1.19.0 (#3959)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-01 12:24:06 +01:00
renovate[bot] 94f22fcc55
chore(deps): update dependency pylint to v4.0.4 (#3962)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-01 18:58:26 +11:00
summoner 8387c8f589
Translation: Update hungarian base.po/base.mo (#3961)
Translate new strings
Fix translation
2025-12-01 18:57:59 +11:00
Anton Hvornum 3290175084
Bumping version to: 3.0.14 (#3960) 2025-11-29 22:19:59 +01:00
renovate[bot] 0221099398
chore(deps): update pre-commit hook astral-sh/ruff-pre-commit to v0.14.7 (#3958)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-11-29 11:55:23 +11:00
renovate[bot] 29cb454fda
chore(deps): update dependency ruff to v0.14.7 (#3957)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-11-29 11:55:05 +11:00
Mintsuki 6fc0bc3671
Fix GRUB fallback-from-removable logic introduced in c095eb56d8 (#3950)
Commit c095eb56d8 was supposed to introduce logic
such that if the `grub-install` command failed with a `--removable` flag, then
another attempt would be made with such flag removed.

This was broken because the `--removable` flag was kept in both cases (likely a
copy-paste mistake). This has been an issue since, in all future iterations of
the code.

What this commit does is fix this logic, but also invert the cases tested:
first test without `--removable`, then add it should that case fail, as this is
the most sensible thing to do.
2025-11-29 11:10:04 +11:00
Gabriel A Hernandez 7732d50016
Improved regex in _validate_value() that checks user input for partition value and unit. (#3952)
- Allows for white space in between groups, aligning better with displayed example.
- Removed unneeded | symbol, which was checking as literal rather than working as "or %"
2025-11-29 11:04:39 +11:00
Mintsuki d7e5dc3692
Do not unconditionally set `prompt` to `None` in list_manager.py (#3955)
May address issue #3954.
2025-11-29 11:04:12 +11:00
Mintsuki 70a6c3499a
Do not create BLS and Limine entries for fallback initramfs (#3949)
* Do not create BLS and Limine entries for fallback initramfs

Fallback initramfs seem to no longer be built by default.

* Remove initramfs variant logic altogether
2025-11-29 11:00:43 +11:00
renovate[bot] b751ad5dab
chore(deps): update dependency pydantic to v2.12.5 (#3951)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-11-27 21:23:38 +11:00
renovate[bot] 147447face
chore(deps): update actions/setup-python digest to 83679a8 (#3946)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-11-26 10:31:55 +11:00
renovate[bot] 60302060e3
chore(deps): update dependency pre-commit to v4.5.0 (#3944)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-11-23 09:33:20 +11:00
correctmost 5f0742a87a
Use dummy variables instead of unused-awaitable suppressions (#3943) 2025-11-22 21:16:11 +11:00
correctmost 73ceb0c99d
Use ClassVar to avoid mutable-class-default (RUF012) warnings (#3942) 2025-11-22 21:15:41 +11:00
renovate[bot] 2ee66a059e
chore(deps): update pre-commit hook astral-sh/ruff-pre-commit to v0.14.6 (#3941)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-11-22 08:36:34 +11:00
renovate[bot] a94d94a8e1
chore(deps): update dependency ruff to v0.14.6 (#3940)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-11-22 08:36:14 +11:00
Mintsuki eb815d817f
Add dialog to install EFI bootloader to removable location (#3932)
* Add dialog to install EFI bootloader to removable location

This is just for GRUB and Limine for now.

* Move bootloader removable and UKI selections to bootloader submenu

* Update ask_for_bootloader_removable() prompt for ease of translation

* Fix issue where removable and UKI options were always enabled at first

* Minor cosmetic fixes to bootloader removable code

* Add has_removable_support to Bootloader

* Validate UKI and removable options in installer

* Use has_removable_support() where appropriate

* Fix potential AttributeError when bootloader_config is None

* Set default value for bootloader configuration menu item

* Update documentation after EFI removable/Limine changes

* Update limine.conf and non-removable location paths (as per Wiki)

* Do not create fallback boot menu entries when using UKIs on Limine

* Remove useless ask_* wrappers in bootloader_menu

* Improve bootloader menu previews

* Make bootloader menu __init__.py empty
2025-11-21 11:41:24 +11:00
renovate[bot] 840c1c0f7e
chore(deps): update actions/checkout action to v6 (#3939)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-11-21 07:41:57 +11:00
renovate[bot] bf3784fc0c
chore(deps): update actions/checkout digest to 93cb6ef (#3937)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-11-20 21:14:16 +11:00
utuhiro78 4c8fe60a28
Update Japanese translation (#3938) 2025-11-20 21:13:51 +11:00
HADEON 46072132a1
Readme Tweak (#3929)
* pr1

* pr2

* pr3

* pr3-2

* pr3-3

* pr3-4

* pr4

* Revert hardware.py to original state on snapshots branch

* readme

* Revert installer.py to original state on readme branch

* match base branch

* Revert genfstab and pacstrap command changes

* readme tweaks2
2025-11-17 08:50:35 +11:00
HADEON c3aba06a01
Fix f-string in snapshot debug installation (#3934)
* pr1

* pr2

* pr3

* pr3-2

* pr3-3

* pr3-4

* pr4

* Revert hardware.py to original state on snapshots branch

* Revert genfstab and pacstrap command changes

* f string
2025-11-17 06:51:35 +11:00
HADEON 375d64a600
Snapshots Fix Snapper-Grub (#3930)
* pr1

* pr2

* pr3

* pr3-2

* pr3-3

* pr3-4

* pr4

* Revert hardware.py to original state on snapshots branch

* Revert genfstab and pacstrap command changes
2025-11-16 21:40:38 +11:00
HADEON 6bdb756650
Add --needed to pacstrap to prevent re-installs 2025-11-16 21:30:47 +11:00
renovate[bot] 803ff4236e
chore(deps): update pre-commit hook astral-sh/ruff-pre-commit to v0.14.5 (#3927)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-11-15 12:54:53 +11:00
renovate[bot] 117b9d9a5d
chore(deps): update dependency pylint to v4.0.3 (#3923)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-11-15 11:03:01 +11:00
Benjamin Smith e6bbd05121
added some missing Spanish translations (#3925) 2025-11-15 10:40:42 +11:00
renovate[bot] 3da27570f7
chore(deps): update dependency pytest to v9.0.1 (#3922)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-11-15 10:38:53 +11:00
renovate[bot] 566dcb51c3
chore(deps): update dependency pytest to v9 (#3912)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-11-10 08:36:02 +01:00
renovate[bot] b77f03e94a
chore(deps): update dependency pre-commit to v4.4.0 (#3911)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-11-09 13:55:03 +11:00
Luna Jernberg 811c1d95b5
Update Swedish translations for wifi (#3910)
Update Swedish translations for wifi
2025-11-09 13:54:40 +11:00
Matteo 165636b2e6
Update Italian translation (#3904)
- Translated new strings
2025-11-07 20:56:41 +01:00
summoner e7553c114c
Translation: Update hungarian base.po/base.mo (#3908)
Translate new strings
2025-11-07 15:45:32 +01:00
renovate[bot] b2fccb0b3b
chore(deps): update pre-commit hook astral-sh/ruff-pre-commit to v0.14.4 (#3907)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-11-07 09:09:59 +01:00
renovate[bot] 83aab9cd4f
chore(deps): update dependency ruff to v0.14.4 (#3906)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-11-07 09:09:23 +01:00
damachine a996670a60
Fix plural form in device selection message (#3905)
Corrected the plural form in the German translation for device selection.
2025-11-07 09:03:12 +01:00
renovate[bot] 240919826f
chore(deps): update dependency pydantic to v2.12.4 (#3900)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-11-06 20:23:08 +00:00
Anton Hvornum c131269c08
Bumping version to: 3.0.13 (#3903) 2025-11-06 20:02:49 +01:00
Anton Hvornum a3d85c1c58
Fixed an issue where re-writing a smaller mkinitcpio.conf than previously existed, the 'no' part at the end became a trailing 'o' causing syntax issues. (#3902) 2025-11-06 15:26:44 +01:00
Rachel bf8f72cc54
Add missing --script option in documentation for pre-programmed scripts (#3895) 2025-11-03 11:21:26 +11:00
summoner 996566291d
Translation: Update Hungarian transaltion (#3894)
* Translation: Update Hungarian transaltion

Translate new string
Fixing translation

* Translation: Fixing typos in hungarian translation

Translation: Fixing typos and wording in hungarian translation
2025-11-02 10:50:33 +01:00
Luna Jernberg 2808442f8b
Update with November 2025 Swedish translations (#3893)
Update with November 2025 Swedish translations
2025-11-01 14:44:55 +01:00
Daniel Girtler 76ab9482e9
Wifi connection menu with textual (#3879)
* Wifi connector

* Update

---------

Co-authored-by: Daniel Girtler <dgirtler@atlassian.com>
2025-11-01 13:55:58 +01:00
Anton Hvornum 7af94c8fe5
Bumping version to: 3.0.12 (#3892) 2025-11-01 13:08:48 +01:00
Anton Hvornum c2d3daeb25
Added the new -S flag for arch-chroot (#3891)
* Added the new -S flag for arch-chroot which does: Run in systemd mode.

* Fixed some formatting issues, and removed unused *args and **kwargs for run_command()

* Formatting issue

* Formatting issue
2025-11-01 12:48:20 +01:00
Klaus Zipfel 1174800cca
Skip bootloader config check when 'No Bootloader' is selected as bootloader (#3875)
* Allow installation via TUI when 'No Bootloader' is selected as bootloader (--skip-boot)

* Update global_menu.py

Fixed ruff formatting issue

---------

Co-authored-by: Anton Hvornum <anton.feeds+github@gmail.com>
2025-11-01 11:59:24 +01:00
Daniel Girtler adbadbf606
Fix 3863 (#3880)
* Modify formatting warning text to be less scary

* Update

---------

Co-authored-by: Daniel Girtler <dgirtler@atlassian.com>
2025-11-01 11:55:54 +01:00
Tertle950 ed67e9fd67
replace 'leafpad' with 'l3afpad' (#3890)
seemed like the most obvious replacement but maybe another one would suffice
2025-11-01 11:55:02 +01:00
Daniel Girtler bf6245815b
Save and load UKI setting (#3783)
Co-authored-by: Daniel Girtler <dgirtler@atlassian.com>
2025-11-01 11:54:31 +01:00
Daniel Girtler 4ceddacb4e
Only install applications when enabled (#3861)
Co-authored-by: Daniel Girtler <dgirtler@atlassian.com>
2025-11-01 11:54:09 +01:00
renovate[bot] 00c90d9e45
chore(deps): update pre-commit hook astral-sh/ruff-pre-commit to v0.14.3 (#3888)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-11-01 21:46:16 +11:00
renovate[bot] a03e9bcdc6
chore(deps): update dependency ruff to v0.14.3 (#3887)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-11-01 21:45:56 +11:00
renovate[bot] 552c7b7dd9
chore(deps): update actions/upload-artifact action to v5 (#3884)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-25 16:21:30 +11:00
renovate[bot] 772652bc69
chore(deps): update pre-commit hook astral-sh/ruff-pre-commit to v0.14.2 (#3883)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-25 15:38:12 +11:00
renovate[bot] b0679974d5
chore(deps): update dependency ruff to v0.14.2 (#3882)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-25 15:37:52 +11:00
renovate[bot] 90bf24b3ce
chore(deps): update dependency pylint to v4.0.2 (#3877)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-21 18:22:59 +11:00
renovate[bot] e0ea072032
chore(deps): update dependency pydantic to v2.12.3 (#3874)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-18 13:04:32 +11:00
correctmost 1fa8f2013b
Remove an unneeded Pylint suppression (#3873)
The related bug has been fixed in Pylint 4.0.1.
2025-10-18 13:04:09 +11:00
renovate[bot] 6505c073c9
chore(deps): update dependency pylint to v4.0.1 (#3864)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-17 17:13:45 +11:00
renovate[bot] a84a97fdc7
chore(deps): update pre-commit hook astral-sh/ruff-pre-commit to v0.14.1 (#3872)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-17 15:31:20 +11:00
renovate[bot] 0a032b04d5
chore(deps): update dependency ruff to v0.14.1 (#3871)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-17 15:30:59 +11:00
renovate[bot] 46380f5da3
chore(deps): update dependency pydantic to v2.12.2 (#3869)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-15 07:34:22 +11:00
renovate[bot] 6c43a8c6d3
chore(deps): update dependency pydantic to v2.12.1 (#3868)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-14 16:34:18 +11:00
Vasiliy Stelmachenok 53e8cb3a8c
Do not install Btrfs module and binary in mkinitcpio (#3865)
* Do not install Btrfs module and binary in mkinitcpio

This is what btrfs hook already does.

Signed-off-by: Vasiliy Stelmachenok <ventureo@cachyos.org>

* Remove unused properties from FilesystemType

They were only needed for Btrfs

Signed-off-by: Vasiliy Stelmachenok <ventureo@cachyos.org>

---------

Signed-off-by: Vasiliy Stelmachenok <ventureo@cachyos.org>
2025-10-14 07:33:45 +11:00
Vasiliy Stelmachenok daab8e6ff6
Do not re-order amdgpu and radeon modules in mkinitcpio (#3866)
This is not necessary as kms hook for mkinitcpio already takes care
of adding amdgpu and radeon modules.

Signed-off-by: Vasiliy Stelmachenok <ventureo@cachyos.org>
2025-10-13 09:12:41 +00:00
correctmost 8fb83a7beb
Upgrade Pylint to 4.0.0 (#3867)
This commit also removes the pylint-pydantic plug-in, which is not
yet compatible with Pylint v4.
2025-10-13 09:03:00 +00:00
renovate[bot] b0b87400c2
chore(deps): update pre-commit hook astral-sh/ruff-pre-commit to v0.14.0 (#3859)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-08 07:58:29 +00:00
renovate[bot] 97790145c4
chore(deps): update dependency ruff to v0.14.0 (#3858)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-08 16:48:13 +11:00
renovate[bot] d7f74b4b32
chore(deps): update dependency pydantic to v2.12.0 (#3856)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-08 16:47:57 +11:00
Muhammadyoqub 472ffd4e6a
Add Uzbek (uz) language support (#3854)
* Add Uzbek (uz) language support

* Add Uzbek (uz) language support
2025-10-07 21:11:42 +11:00
Pierre Ambroise 68d8af3df3
Update french translation (#3853)
* Update french translation

* Add mo file
2025-10-07 09:56:48 +11:00
renovate[bot] 88266f5c74
chore(deps): update dependency pylint to v3.3.9 (#3851)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-06 09:19:56 +11:00
renovate[bot] a3e219a2e4
chore(deps): update dependency pydantic to v2.11.10 (#3850)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-05 09:31:15 +11:00
renovate[bot] 5777880d18
chore(deps): update dependency ruff to v0.13.3 (#3848)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-03 10:25:20 +00:00
renovate[bot] c8429aee23
chore(deps): update pre-commit hook astral-sh/ruff-pre-commit to v0.13.3 (#3849)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-03 10:25:01 +00:00
damachine 60e70f507f
Fix German translations for consistency and clarity (#3844)
* Fix German translations for consistency and clarity

Corrected capitalization and punctuation in German translations.

* Update German translations for disk configuration messages

sounds better

* Update German translations for clarity and consistency

* Update German translations in base.po

* Update German translation for object selection message

much more understandable

* Update German translations in base.po

friendlier

* Refine German translations in base.po

SORRY for the many changes. I only want the best.

* Update German translation for Btrfs subvolumes

* Update German translation for btrfs subvolume message

correct translation o)
2025-10-01 07:25:11 +10:00
Valerii b03948bbfe
Better Ukrainian v1.3.4 (#3843) 2025-10-01 07:24:41 +10:00
damachine 21f9972040
Fix typo in German translation for network interface (#3842)
sorry. another one has sneaked in.
2025-09-30 13:04:02 +10:00
damachine e0ce0bdd45
Fix typo in German translation for bootable partition (#3841)
small typo fix o)
2025-09-30 11:56:43 +10:00
summoner c86b0be79f
Translation: Update hu_HU.po (#3839)
Translate new strings
Fixing translation
2025-09-28 17:50:02 +10:00
renovate[bot] 853309d311
chore(deps): update pre-commit hook astral-sh/ruff-pre-commit to v0.13.2 (#3838)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-09-28 17:49:24 +10:00
renovate[bot] 2f1b8cd692
chore(deps): update dependency ruff to v0.13.2 (#3837)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-09-28 17:49:06 +10:00
Luna Jernberg e1f7a314a7
Bumping version to: 3.0.11 (archlinux#3835) (Swedish Translation) (#3836)
* Update base.po (Swedish)

Update Swedish Translation

* Update base.po (Swedish)

Updated Swedish translation
Uppdaterad svensk översättning

* Bumping version to: 3.0.11 (archlinux#3835)

Bumping version to: 3.0.11 (archlinux#3835)
2025-09-25 17:20:43 +10:00
Anton Hvornum ebeb4c7daa
Bumping version to: 3.0.11 (#3835) 2025-09-24 23:51:08 +02:00
Matteo 88753b1f40
Update Italian translation (#3832)
Translated new strings
2025-09-24 07:14:37 +10:00
utuhiro78 ca85f39b71
Update Japanese translation (#3831) 2025-09-24 07:14:20 +10:00
renovate[bot] 5f96390719
chore(deps): update pre-commit hook pre-commit/mirrors-mypy to v1.18.2 (#3823)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-09-19 20:38:59 +10:00
renovate[bot] fceee34dfa
chore(deps): update dependency ruff to v0.13.1 (#3810)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-09-19 17:43:37 +10:00
renovate[bot] 49ead6fa38
chore(deps): update pre-commit hook astral-sh/ruff-pre-commit to v0.13.1 (#3811)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-09-19 16:44:30 +10:00
Bruno Rosa 792db9e8b8
quick fix to run archinstall and enable systemd services (#3815) 2025-09-19 15:52:30 +10:00
renovate[bot] df3b5d7593
chore(deps): update dependency mypy to v1.18.2 (#3816)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-09-19 15:45:43 +10:00
Daniel Girtler d256e70480
Fix 3785 - F2FS parameters require 'extra_attr' (#3796)
Co-authored-by: Daniel Girtler <dgirtler@atlassian.com>
2025-09-17 10:32:04 +02:00
Monochrome de05dcb7e0
changed version of cryptography package to 45.0.7 (#3795)
Co-authored-by: QuotientParadoxx <117741113+QuotientParadox@users.noreply.github.com>
2025-09-16 10:25:43 +00:00
Rémy Marquis 9ddd41da56
Remove outdated link to video demo installer (#3790) 2025-09-16 10:25:24 +00:00
renovate[bot] cec68b6e9b
chore(deps): update dependency pydantic to v2.11.9 (#3791)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-09-15 08:38:27 +10:00
renovate[bot] c60d9bd232
chore(deps): update pre-commit hook pre-commit/mirrors-mypy to v1.18.1 (#3792)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-09-15 08:37:45 +10:00
renovate[bot] ad02f5bffc
chore(deps): update dependency mypy to v1.18.1 (#3788)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-09-15 07:29:10 +10:00
renovate[bot] 3c416943e2
chore(deps): update pre-commit hook astral-sh/ruff-pre-commit to v0.13.0 (#3787)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-09-15 07:28:46 +10:00
renovate[bot] e846a0ec58
chore(deps): update dependency ruff to v0.13.0 (#3786)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-09-15 07:28:30 +10:00
BlocksumoGuys d40d77ce25
Finalized French Translation (with improvments) (#3784)
The french translation is hopefully finished, I also improved in some sectors of the translations
2025-09-09 17:03:48 +10:00
veprogames de50a31609
Fundamentally improve German translations (#3780)
* Get rid of all warnings that poedit displayed

Bring translations closer to the English original, also removing some extraneous information. Get rid of all warnings poedit displayed. Correct translation that didn't match at all.

* Fix locales_generator.sh detection

xgettext was not recognizing tr() invocations. Following https://stackoverflow.com/a/11901925 fixed the issue

* Add more German translations

Improve consistency with some translations. Add translations for messages that were just detected in the previous commit. Add translations for Graphics Drivers

* Add more translations

Look for untranslated strings in the source files and add make them recognized by gettext

* Improve conistency of German translations and correct typos

* formatting

* Remove translations from enum members

* More translation tweaks
2025-09-09 17:02:24 +10:00
Dee 1ef52f56cb
gracefully return "undefined" if DMI is not in sysfs (#3771)
* gracefully return "undefined" if DMI is not in sysfs

fixes #3770, in theory

* None works too and is consistent with other behaviour

* None doesn't *just* work
2025-09-08 10:51:28 +00:00
BlocksumoGuys bca3f4b660
Update French Language inside of base.po (#3782)
Some error found inside the base.po file
2025-09-08 19:06:20 +10:00
renovate[bot] 9bb7ced10e
chore(deps): update pre-commit hook astral-sh/ruff-pre-commit to v0.12.12 (#3779)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-09-05 21:34:33 +10:00
renovate[bot] b8baf096dd
chore(deps): update dependency ruff to v0.12.12 (#3778)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-09-05 21:34:11 +10:00
renovate[bot] 0ad513a8e5
chore(deps): update dependency pytest to v8.4.2 (#3777)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-09-05 21:33:54 +10:00
renovate[bot] ed8b6ac045
chore(deps): update actions/setup-python action to v6 (#3776)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-09-04 18:39:12 +10:00
veprogames fd2c20a900
Add missing German translations (#3774) 2025-09-04 16:51:11 +10:00
Anton Hvornum f87ece0b95
Bumping version to: 3.0.10 (#3773) 2025-09-02 12:33:50 +02:00
renovate[bot] 4949bb4c2d
chore(deps): update dependency ruff to v0.12.11 (#3767)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-30 19:02:21 +10:00
renovate[bot] 5208dfd539
chore(deps): update pre-commit hook astral-sh/ruff-pre-commit to v0.12.11 (#3768)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-30 19:02:05 +10:00
Daniel Girtler 6a228aa70a
Handle empty menu when focusing item (#3742) 2025-08-27 10:30:19 +02:00
Daniel Girtler ea8d64a6d3
Fix upgrade version header (#3738)
* Fix header new version display

* Update
2025-08-27 10:29:23 +02:00
Daniel Girtler d342c50aec
Remove beta label from LVM (#3737) 2025-08-27 10:28:45 +02:00
Daniel Girtler e4e30b31d4
Disable btrfs snapshots when no subvolumes defined (#3736) 2025-08-27 10:28:17 +02:00
Daniel Girtler 663e46f86e
Remove unattended script (#3733) 2025-08-27 10:27:25 +02:00
Daniel Girtler 7d94210cd3
Fix parsing of systemd package version (#3732) 2025-08-27 10:23:03 +02:00
Daniel Girtler a4324ec5f1
Setup grub-btrfs correctly for timeshift (#3728) 2025-08-27 10:21:47 +02:00
Luna Jernberg f0f882f68b
Update base.po (Swedish) (#3758)
Update Swedish Translation
2025-08-26 09:45:44 +10:00
renovate[bot] 08b6b617a7
chore(deps): update pre-commit hook astral-sh/ruff-pre-commit to v0.12.10 (#3755)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-22 08:24:30 +10:00
renovate[bot] d09d4a3acd
chore(deps): update dependency ruff to v0.12.10 (#3754)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-22 08:23:22 +10:00
Valerii af54095405
Better Ukrainian v.1.3.3 (#3749)
* Better Ukrainian v.1.3.2

Now, the translation is complete.

* Better Ukrainian v1.3.3
2025-08-22 07:56:34 +10:00
Guillaume BOEHM 0cebaa00f7
Fix documentations and samples mentioning `custom-commands` instead of `custom_commands` (#3745) 2025-08-16 11:59:18 +10:00
renovate[bot] 6910b7a872
fix(deps): update dependency ruff to v0.12.9 (#3740)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-15 12:33:08 +10:00
renovate[bot] 0394eba63c
chore(deps): update pre-commit hook astral-sh/ruff-pre-commit to v0.12.9 (#3739)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-15 12:32:50 +10:00
renovate[bot] 982f10b9d7
chore(deps): update astral-sh/ruff-action action to v3.5.1 (#3730)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-13 07:55:14 +10:00
renovate[bot] bf808110f1
chore(deps): update actions/checkout action to v5 (#3727)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-12 11:18:09 +00:00
renovate[bot] c9d28e0cc8
chore(deps): update pre-commit hook pre-commit/pre-commit-hooks to v6 (#3721)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-10 06:08:53 +00:00
renovate[bot] 5bb21b69ea
fix(deps): update dependency pylint to v3.3.8 (#3718)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-10 06:08:26 +00:00
neko_0xff d5b8c66d3b
Update base.po (#3723) 2025-08-10 06:08:09 +00:00
Guilherme Licodiedoff 05c25f10ea
Improve pt_BR translation flow (#3722) 2025-08-10 06:07:34 +00:00
renovate[bot] f6697f22ee
fix(deps): update dependency pre-commit to v4.3.0 (#3720)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-10 06:06:54 +00:00
Odyssey c6674ee8e4
Update catalan locales (#3716) 2025-08-10 06:05:50 +00:00
renovate[bot] c172c78012
fix(deps): update dependency ruff to v0.12.8 (#3715)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-10 06:05:30 +00:00
renovate[bot] da8c16400f
chore(deps): update pre-commit hook astral-sh/ruff-pre-commit to v0.12.8 (#3714)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-10 06:05:13 +00:00
correctmost b0ede3c165
Fix a type annotation for list_available_packages (#3711)
The repositories parameter is a variable-length tuple instead of a
one-element tuple.
2025-08-06 07:02:01 +00:00
Andreamp0 5e96448f37
Fixing 3 lines in the italian translation (#3710) 2025-08-05 12:55:30 +00:00
EK 4c17b75134
move additional packages down (#3709) 2025-08-04 19:45:38 +02:00
renovate[bot] 2f05481329
fix(deps): update dependency mypy to v1.17.1 (#3704)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-31 11:49:08 +00:00
Hugo Carvalho 1e841a1816
Translation: Update pt.po (#3702) 2025-07-31 11:48:38 +00:00
renovate[bot] d09a512946
chore(deps): update pre-commit hook pre-commit/mirrors-mypy to v1.17.1 (#3703)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-31 11:48:17 +00:00
summoner 6cca6f9866
Translation: Update HU.po (#3701)
Fix translation wording
2025-07-31 06:59:25 +00:00
Daniel Girtler ab1793a4f4
Add version to test (#3699) 2025-07-31 04:52:09 +00:00
summoner 11e33ed9f3
Translation: Update Hu.po (#3698)
Translate new strings
Fix sentences
2025-07-30 17:34:56 +02:00
Anton Hvornum 0cd3f2ea26
Bumping version to: 3.0.9 (#3697) 2025-07-30 10:22:31 +02:00
renovate[bot] 1cd6792bba
fix(deps): update dependency ruff to v0.12.7 (#3696)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-30 07:05:52 +00:00
renovate[bot] 34489d4834
chore(deps): update pre-commit hook astral-sh/ruff-pre-commit to v0.12.7 (#3695)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-30 07:05:30 +00:00
Anton Hvornum 3607029d59
Reverted profiles and application installation order in order to not break DE's vs audioserver setups (#3694) 2025-07-30 08:16:36 +02:00
Daniel Girtler 1ba9d0371a
Correctly populate version in config (#3693) 2025-07-29 20:30:17 +00:00
Daniel Girtler 91609c16b5
Fix circular bootloader dependency (#3686) 2025-07-29 19:48:23 +02:00
renovate[bot] dd5a86165c
fix(deps): update dependency ruff to v0.12.5 (#3682)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-24 18:21:42 +00:00
renovate[bot] d799812f63
chore(deps): update pre-commit hook astral-sh/ruff-pre-commit to v0.12.5 (#3681)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-24 18:21:15 +00:00
Simon Skoczylas 436a28b34c
Update documentation to also mention the --config-url option (#3683)
* Add missing config-url option

* Update example in documentation
2025-07-24 17:19:27 +02:00
VENOIRE ccebb6882e
Fix boot detection to use PartitionFlag.BOOT instead of mountpoint (#3659)
Co-authored-by: VENOIRE <venoire@protonmail.com>
Co-authored-by: Torxed <torxed@archlinux.org>
2025-07-24 16:11:18 +02:00
correctmost b77a43b201
Remove unneeded None annotation from Bootloader.get_default (#3680) 2025-07-23 20:00:21 +02:00
Anton Hvornum 5355c7141a
Add --skip-boot to allow for bypassing installation of a bootloader (#3677)
* Adding the option to skip boot loader

* Fixed a variable complaint

* Fixed ruff and mypy

* Fixed mypy

* Fixed mypy

* Fixed import recursion

* Fixed ruff

* Fixed circular imports

* Fixed ruff

* Hiding the menu option for bootloader when --skip-boot is given. Still setting it default to None to avoid it sneaking into the config file or being set behind the scenes causing if statements to trigger.

* Created an Enum None type for Bootloader called NO_BOOTLOADER

* Fixed ruff

* Spelling error

* Hiding NO_BOOTLOADER if --skip-boot is omitted

* Fixed TUI error when bootloader was missing

* Fixed mypy complaints

* Fixed ruff complaint

* Made the Bootloader option visible during --skip-boot and set the default value to NO_BOOTLOADER when --skip-boot is present
2025-07-23 16:52:01 +02:00
Luiz Felipe ee6dcbe2b2
Improve PT‑BR translation and adjust punctuation (#3679)
Co-authored-by: LuizWT <xluiz452@gmail.com>
2025-07-23 11:10:02 +00:00
Daniel Girtler 3e99cfbba7
Move users menu into authentication submenu (#3678)
* Move users menu into authentication submenu

* Tests

* Update

* Update
2025-07-22 08:57:39 +02:00
Daniel Girtler 725c3fed09
Rename network_configuration -> network (#3641) 2025-07-21 19:26:15 +00:00
renovate[bot] b0908b88c5
fix(deps): update dependency ruff to v0.12.4 (#3674)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-19 11:48:00 +02:00
renovate[bot] 1da69cec18
chore(deps): update pre-commit hook astral-sh/ruff-pre-commit to v0.12.4 (#3673)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-19 00:15:26 +00:00
Daniel Girtler 1e058df92b
Fix imports (#3675) 2025-07-18 21:59:32 +00:00
Daniel Girtler e0c3bb3869
Move root password menu into authentication menu (#3650) 2025-07-18 05:53:31 +00:00
correctmost 8736926fb2
Update mypy to 1.17.0 (#3671)
This commit also removes a type ignore comment that is no longer
needed after python/mypy#18976.
2025-07-17 12:37:06 +10:00
utuhiro78 f059d897fb
Update Japanese translation (#3670) 2025-07-16 10:16:55 +10:00
renovate[bot] 9f83d67c9e
chore(deps): update pre-commit hook pre-commit/mirrors-mypy to v1.17.0 (#3669)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-16 10:16:27 +10:00
Daniel Girtler 231530d5f9
Handle no U2F device available (#3648) 2025-07-15 09:35:54 +02:00
Daniel Girtler 47f4e63006
Rename profile_model -> profile (#3640) 2025-07-15 09:30:15 +02:00
Daniel Girtler 96aaf5b6ac
Rename module device_model -> device (#3639) 2025-07-15 09:29:58 +02:00
renovate[bot] 703c9548c0
chore(deps): update astral-sh/ruff-action action to v3.5.0 (#3667)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-15 08:06:55 +10:00
renovate[bot] b73aa79415
fix(deps): update dependency ruff to v0.12.3 (#3664)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-12 12:22:35 +10:00
renovate[bot] 725b95c5a6
chore(deps): update pre-commit hook astral-sh/ruff-pre-commit to v0.12.3 (#3663)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-12 12:22:04 +10:00
Muhammad Salman eb5512f5cd
Install inotify-tools when using grub with btrfs config (#3656) 2025-07-08 20:12:57 +10:00
renovate[bot] 9b0b5e8af2
chore(deps): update pre-commit hook astral-sh/ruff-pre-commit to v0.12.2 (#3652)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-05 08:32:21 +10:00
renovate[bot] b0038eb277
fix(deps): update dependency ruff to v0.12.2 (#3653)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-04 18:49:11 +10:00
Matteo 30f0693ce7
Update Italian translation (#3651) 2025-07-03 08:42:30 +10:00
correctmost 3652dbd578
Replace an Any instance in U2FLoginConfiguration.parse_arg (#3649) 2025-07-01 08:54:46 +10:00
correctmost 2bb98bc06e
Remove an unused member variable from AuthenticationHandler (#3644) 2025-07-01 07:55:04 +10:00
correctmost 2072c29745
Use union syntax instead of typing.Optional (#3643) 2025-07-01 07:54:41 +10:00
correctmost c22c6c7399
Remove unneeded container code from ruff format workflow (#3642) 2025-07-01 07:54:09 +10:00
Daniel Girtler 55a383764f
Add support for U2F authentication (#3638)
* Add U2F login support

* Update

* Update

* Update

* Update
2025-06-30 21:51:45 +10:00
Haouari haitam Kouider b3b00aa00f
Add interface to change LUKS iteration time (#3634)
* Added User Interface to change iteration time for LUKS encryption

* removing unneessary try catch and imports

* used the same constant in luks.py file

* fixed issue with error firing in default value

* fixed ruf preview warnings

* preview even if its default value. (iter_time)

* check encryption type is not non before showing iter_time

* using _real_input with input_vp instead of _current_text

* proper check for enc_type

* added Interation time to outer menu preview

* removed (ms) from title. so that we don't need to translate "Iteration time" and "iteration time (ms)".

* a comment slipped in. this was not supposed to be in this pull

* fixed comparison str with EncryptionType
2025-06-30 11:11:24 +10:00
Daniel Girtler 19459731ad
Make type field in lsblk optional (#3633) 2025-06-27 12:31:04 +02:00
Anton Hvornum 9dd92321a5
Added temporary hold on bootctl's --variables=BOOL usage, as it's notin systemd main yet (#3625)
* Added temporary hold on bootctl's --variables=BOOL usage, as it's not in systemd main yet

* Fixed ruff format check

* Fixed mypy type check issue

* Spelling error

* Fixed flake8 complaint
2025-06-27 12:29:35 +02:00
renovate[bot] 9d0e1e5576
fix(deps): update dependency ruff to v0.12.1 (#3632)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-27 11:53:03 +10:00
renovate[bot] 8cb899ef39
chore(deps): update pre-commit hook astral-sh/ruff-pre-commit to v0.12.1 (#3631)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-27 11:52:47 +10:00
correctmost 572b4b6c29
Remove a ruff check auto-fix from the ruff format workflow (#3628)
Running an auto-fix in CI can cause the format check to pass, even
though the same format check fails locally.
2025-06-24 21:29:06 +10:00
correctmost 85f83214f7
Fix ruff format for local builds (#3626) 2025-06-24 13:30:04 +10:00
Anton Hvornum 63e559e502
Changed quotation marks (#3624) 2025-06-22 17:10:28 +02:00
DarkXero 677f4349be
Add missing xdg-user-dirs (#3484)
* Update cosmic.py

* Reverted incorrect Python logic surrounding the greeter type.

---------

Co-authored-by: Torxed <torxed@archlinux.org>
2025-06-22 15:17:25 +02:00
summoner001 7f189727a2
Update hungarian translation (#3622)
fix wording
2025-06-22 14:17:45 +02:00
Anton Hvornum 7fdfede270
Fixed ruff quotation marks (#3623) 2025-06-22 14:16:27 +02:00
Korbin Bickel 46550221d1
Update bootctl command for new --variables= option (#3396)
Co-authored-by: Anton Hvornum <torxed@archlinux.org>
2025-06-22 13:55:38 +02:00
Daniel Girtler 43963a1d8f
Fix script docs (#3613) 2025-06-22 12:47:00 +02:00
renovate[bot] fbbc3edac2
fix(deps): update dependency flake8 to v7.3.0 (#3618)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-21 08:19:45 +10:00
renovate[bot] 526eb3fb18
chore(deps): update pre-commit hook pycqa/flake8 to v7.3.0 (#3617)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-21 08:05:49 +10:00
Daniel Girtler 9769786ad6
Fix app config (#3614) 2025-06-20 23:59:10 +02:00
Daniel Girtler 77558e2be5
Fix 3598 - Utilize script field from config when present (#3611)
* Fix 3598 - Utilize script field from config when present

* Update

* Update
2025-06-20 15:58:14 +10:00
Daniel Girtler 37b3985625
Move audio configuration to application config (#3612) 2025-06-20 07:27:23 +10:00
renovate[bot] 63848f645f
fix(deps): update dependency pytest to v8.4.1 (#3608)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-18 22:06:02 +10:00
Daniel Girtler 27f53717b0
Add bluetooth support (#3604)
* Add bluetooth option
2025-06-18 09:57:54 +02:00
renovate[bot] f0cb3ad77a
fix(deps): update dependency ruff to v0.12.0 (#3607)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-18 07:38:42 +10:00
renovate[bot] fa5f9cfaf3
chore(deps): update pre-commit hook astral-sh/ruff-pre-commit to v0.12.0 (#3606)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-18 07:38:24 +10:00
renovate[bot] bf8379a2aa
chore(deps): update pre-commit hook pre-commit/mirrors-mypy to v1.16.1 (#3605)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-18 07:36:33 +10:00
Screamnox 973f4af1f5
fix(lvm): align offset to PE size to avoid LV allocation failure (#3603) 2025-06-17 22:26:16 +10:00
renovate[bot] 4d0a6ceb62
fix(deps): update dependency mypy to v1.16.1 (#3602)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-17 07:38:35 +10:00
Serdar Sağlam dd75371fc1
Turkish language current (#3597)
It was a very bad and wrong translation, but it is good now.
2025-06-16 09:53:20 +10:00
renovate[bot] c800a0357d
fix(deps): update dependency pydantic to v2.11.7 (#3595)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-14 23:13:43 +10:00
renovate[bot] aa5a13b732
fix(deps): update dependency pydantic to v2.11.6 (#3594)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-13 22:46:46 +10:00
Anton Hvornum 867fc7c691
Bumping version to: 3.0.8 (#3593) 2025-06-12 21:27:28 +02:00
Anton Hvornum 2038e68560
Removed xf86-video-vmware as it's been dropped: https://gitlab.archlinux.org/archlinux/packaging/packages/xf86-video-vmware/-/issues/3 (#3590) 2025-06-12 08:48:21 +02:00
Daniel Girtler 12c8a5c62e
Mount partitions in minimal script before starting installation (#3585) 2025-06-12 07:14:54 +10:00
Daniel Girtler 063b9643b4
Add new version indicator in the title of the main menu (#3587)
* Add new version indicator in the title of the main menu

* Update
2025-06-12 07:14:30 +10:00
Daniel Girtler 7b3b7c9ebf
Fix recursive call in scripts (#3586) 2025-06-11 19:38:28 +02:00
Anton Hvornum a91a922ef4
Spelling error on extras package (#3582) 2025-06-09 13:27:24 +02:00
renovate[bot] d0f1fdf4b4
fix(deps): update dependency ruff to v0.11.13 (#3578)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-07 07:33:18 +10:00
renovate[bot] ee94cd9d4f
chore(deps): update pre-commit hook astral-sh/ruff-pre-commit to v0.11.13 (#3577)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-07 07:32:57 +10:00
correctmost 1e7a4831ae
Use a generic instead of Any in MenuHelper (#3574)
This commit also removes an unused _get_table_header method.
2025-06-04 11:55:07 +10:00
correctmost 2843d01600
Enable stricter mypy definition checks in archinstall/lib/ (#3573) 2025-06-04 07:30:14 +10:00
correctmost 557e1cac0d
Honor the sort_items parameter on MenuItemGroup.from_enum (#3572) 2025-06-03 23:17:42 +10:00
correctmost fafb180ffe
Remove unused arguments from internal functions (#3571)
This makes it easier to run Pylint's unused-argument checks on the
codebase.
2025-06-03 23:17:10 +10:00
renovate[bot] fe9b853d25
fix(deps): update dependency pytest to v8.4.0 (#3570)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-03 08:15:27 +10:00
Daniel Girtler 18ef716b0f
Add sync after installation completed (#3569) 2025-06-02 13:50:34 +02:00
Daniel Girtler 92b384d1d3
Fix restore edit content on help menu close (#3568)
* Fix restore edit content on help menu close

* Update
2025-06-02 10:17:17 +02:00
correctmost fef97bed32
Fix return values used with a Textbox.edit callback in curses (#3566) 2025-06-01 11:43:01 +02:00
correctmost a580da2bbd
Enable the bad-exit-annotation ruff rule and fix related warnings (#3564) 2025-06-01 11:41:34 +02:00
Anton Hvornum 55fd59d94e
Moved python-cryptography from makedepends to depends (#3558) 2025-05-31 13:19:37 +02:00
codefiles dd686b291c
Use PEP 639 license expression (#3556) 2025-05-31 08:25:29 +02:00
correctmost a1b83ad29f
Remove unused _DeferredTranslation methods and references (#3557) 2025-05-31 16:04:23 +10:00
correctmost e245a11463
Remove return value check for Installer.minimal_installation (#3555)
The minimal_installation method always returns None.
2025-05-31 08:20:54 +10:00
renovate[bot] 48c3f6367b
chore(deps): update pre-commit hook pre-commit/mirrors-mypy to v1.16.0 (#3551)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-05-30 23:33:58 +02:00
lubuoren 47e6d82ee5
Update installer.py (#3540)
Fix the bug of installation failure caused by incorrect service name
2025-05-30 17:04:04 +02:00
codefiles 1dccfe6c33
Rework install log (#3550) 2025-05-30 23:08:02 +10:00
correctmost a5d995b546
Remove underscore from _FrameDim because it's used externally (#3547)
This commit fixes a reportUnusedClass warning from Pyright.
2025-05-30 18:42:00 +10:00
codefiles 16405ab435
Refactor command logs (#3549) 2025-05-30 18:39:20 +10:00
correctmost c2ea6ffe9c
Add type annotations to global storage dictionary (#3548)
This will help catch issues like #3530.
2025-05-30 09:18:17 +02:00
correctmost b689656547
Remove some unnecessary None checks from desktop profile code (#3546)
This commit fixes some warnings reported by Pyright's
reportUnnecessaryComparison checker.
2025-05-30 09:12:49 +02:00
correctmost bd36c0c5d3
Remove workaround for mypy 1.15.0 crash (#3545)
This reverts commit ae38e92100.
2025-05-30 09:12:05 +02:00
correctmost 1b39c7dbad
Remove strict_bytes from the mypy config (#3544)
In mypy 1.16.0, strict mode automatically enables strict_bytes
checks.
2025-05-30 07:32:25 +02:00
Daniel Girtler c2443e8902
Reference guided.py script instead of symlink from README (#3543) 2025-05-30 07:31:54 +02:00
renovate[bot] 5805ea4a3f
chore(deps): update pre-commit hook astral-sh/ruff-pre-commit to v0.11.12 (#3538)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-05-29 21:36:00 +02:00
renovate[bot] 7b9a658c7b
fix(deps): update dependency ruff to v0.11.12 (#3539)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-05-29 21:35:35 +02:00
renovate[bot] 46f18baca7
fix(deps): update dependency mypy to v1.16.0 (#3541)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-05-29 21:33:34 +02:00
Daniel Girtler 8bed035e21
Fix 3530 (#3535)
* Fix 3530

* Update
2025-05-29 13:54:28 +02:00
Daniel Girtler d4b16cb406
Fix 3534 (#3537) 2025-05-29 13:53:22 +02:00
Daniel Girtler 3359779594
Fix 3626 (#3536) 2025-05-29 13:52:34 +02:00
codefiles 7316b56274
Fix empty username (#3533) 2025-05-29 12:17:18 +10:00
codefiles e6a9105df4
Fix empty password (#3531) 2025-05-29 12:13:07 +10:00
correctmost 3da78fcb49
Enable truthy-bool checks in mypy and fix related warnings (#3528) 2025-05-29 12:11:32 +10:00
codefiles b2b36a2cef
Refactor default Btrfs subvolumes (#3525) 2025-05-28 22:45:56 +10:00
codefiles 728fee4a7c
Fix root partition device mapper name (#3524) 2025-05-28 22:02:00 +10:00
correctmost 426650a3c4
Fix invalid-annotation warnings reported by Pyrefly (#3523) 2025-05-28 22:00:52 +10:00
correctmost 26c6812827
Remove extraneous None type annotations (#3522) 2025-05-28 21:52:43 +10:00
Daniel Girtler 52face9254
Fix 3513 (#3520) 2025-05-28 20:47:56 +10:00
correctmost c2f4d92fd9
Enable unreachable code checks in lib/ with mypy (#3521) 2025-05-28 20:47:40 +10:00
Anton Hvornum 2cf7c85728
Bumping version to: 3.0.7 (#3519) 2025-05-28 11:15:59 +02:00
correctmost 5c8721a3a8
Enable unreachable code checks in tui/ with mypy (#3518) 2025-05-28 16:23:06 +10:00
Farhan Ghani 50747a5a71
Updated translation and fixed errors in last translation. (#3515)
* still updating

* Updated urdu translation

Because it is very hard to display urdu fonts in consol. I changed urdu
writing to latin script which is also known as "Roman Urdu". For more
information check out https://en.wikipedia.org/wiki/Roman_Urdu.

* Updated errors and translation

As it is mentioned in #3463 the errors has been rectified and more
translation is added.
2025-05-28 16:19:40 +10:00
correctmost 5aa1c90b12
Enable mypy's show_traceback option in pyproject.toml (#3514)
This makes it easier to debug mypy crashes when running 'mypy'
in the project directory.
2025-05-28 16:19:03 +10:00
codefiles df8cb4fb39
Fix home partition device mapper name (#3516) 2025-05-28 07:27:07 +02:00
Luiz Felipe 7a455cb625
adjust PT-BR translations and remove fuzzy markers (#3511)
* adjust PT-BR translations and remove fuzzy markers

* Add "Luiz Felipe" to pt-BR translators list in archinstall
2025-05-27 07:51:47 +02:00
codefiles c8f1f78679
Remove duplicate LUKS unlock check (#3510) 2025-05-27 13:08:45 +10:00
codefiles 2623039fff
luks: rework is_unlocked() (#3509) 2025-05-27 09:36:23 +10:00
renovate[bot] 9f110849e6
chore(deps): update astral-sh/ruff-action action to v3.4.0 (#3508)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-05-27 09:35:35 +10:00
Daniel Girtler 8c12d15a41
Fix disk encryption emnu (#3506) 2025-05-26 21:21:30 +10:00
Anton Hvornum 6c7260fa33
Added a more humane error message on no initial network (#3501)
* Added a more humane error message on no initial network

* Fixed ruff complaints
2025-05-25 13:30:47 +02:00
Daniel Girtler 6d1a450440
Fix 2304 (#3503) 2025-05-25 21:25:15 +10:00
Daniel Girtler cdb1debe2e
Move disk encryption into disk config menu (#3502) 2025-05-25 21:23:37 +10:00
Daniel Girtler 5a54902935
Add support for Btrfs snapshots (#3500)
* Add btrfs snapshot support

* Update

* Update

* Update
2025-05-25 17:22:41 +10:00
Daniel Girtler d3f32f308c
Update ruff formatter (#3496)
* Update ruff formatter

* Update
2025-05-24 07:58:42 +00:00
Omrifo4 9af23218c4
Generate empty string on empty custom_servers config (#3498) 2025-05-24 09:11:45 +10:00
Daniel Girtler 4c065c3698
Symlink example files to actual scripts (#3495) 2025-05-23 13:09:42 +02:00
renovate[bot] 1308897d79
fix(deps): update dependency ruff to v0.11.11 (#3494)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-05-23 19:15:59 +10:00
renovate[bot] aef3fd6690
fix(deps): update dependency pydantic to v2.11.5 (#3493)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-05-23 19:15:43 +10:00
renovate[bot] ec5a7e6264
chore(deps): update pre-commit hook astral-sh/ruff-pre-commit to v0.11.11 (#3492)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-05-23 19:15:28 +10:00
Daniel Girtler 3e2f792280
Fix qemu command to boot image (#3491) 2025-05-22 11:25:29 +02:00
Anton Hvornum c9b0c9f7b5
Fix pypi auto release (#3490)
* Updated pypi release by also removing the pyparted hardcoded github version link
2025-05-22 00:22:22 +02:00
Anton Hvornum 79a4c7c0ef
Bumping version to: 3.0.6 (#3488) 2025-05-21 19:34:02 +02:00
Anton Hvornum 5a4773cdd3
Added --skip-wkd to skip waiting for the arch linux keyring wkd sync (#3483)
* Added --skip-wkd to skip waiting for the arch linux keyring wkd sync

* Package spelling error

* Forgot to add argument to Arguments()

* Added missing --skip-wkd arg to arg tester

* Corrected help text for --skip-wkd
2025-05-20 11:38:40 +02:00
correctmost 3e5f879d52
Remove remaining bare _ translation references (#3485)
This helps simplify the linter configs and improves compatibility
with type checkers.
2025-05-20 18:44:25 +10:00
correctmost a945606834
Add some missing type annotations for return values (#3486) 2025-05-20 07:37:35 +10:00
Anton Hvornum 97eeef8c76
Fixed missing archlinux container usage (#3480) 2025-05-19 16:31:40 +02:00
Daniel Girtler 57bd2451e9
Simplify translating of strings (#3479)
* Simplify translation fucntion

* Simplify translation fucntion
2025-05-19 22:33:02 +10:00
Daniel Girtler 790a7a2be9
Fix 3474 (#3476)
* Fix 3474 - Parse mountpoint correctly

* Fix 3474 - Parse mountpoint correctly

* Update
2025-05-19 10:59:42 +02:00
Daniel Girtler f7f6b27a8a
Fix refression for sudoers file (#3475) 2025-05-19 17:00:57 +10:00
Luna Jernberg 363a96a0a2
Update base.po - Swedish translation for 3.0.5 (#3471)
Swedish translation for 3.0.5
2025-05-16 22:00:42 +10:00
renovate[bot] f2136e55ed
fix(deps): update dependency ruff to v0.11.10 (#3470)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-05-16 07:36:30 +10:00
renovate[bot] 7decef1dc3
chore(deps): update pre-commit hook astral-sh/ruff-pre-commit to v0.11.10 (#3469)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-05-16 07:36:12 +10:00
Daniel Girtler c67ac97f18
Ruff formatting (#3459)
* Update

* Update
2025-05-15 14:26:41 +02:00
Anton Hvornum f71e91c85e
Bumping version to: 3.0.5 (#3463) 2025-05-15 08:50:34 +02:00
Anton Hvornum 83a45e8f9f
Fixes --silent in conjuction with --config-url (#3465) 2025-05-14 20:30:38 +02:00
Farhan Ghani b062271b2c
Updated urdu translation (#3462)
* Updated urdu translation

Because it is very hard to display urdu fonts in consol. I changed urdu
writing to latin script which is also known as "Roman Urdu". For more
information check out https://en.wikipedia.org/wiki/Roman_Urdu.

* More translation

Some messages were not translated.
2025-05-14 11:58:18 +10:00
walken ffb9697499
Czech localization update (#3461) 2025-05-13 08:36:50 +10:00
Daniel Girtler e61b966575
Ruff use tabs for formatting (#3458) 2025-05-12 21:07:55 +10:00
Daniel Girtler e18c00c4d9
Convert bytes to str (#3457) 2025-05-12 21:07:36 +10:00
Valerii fd9f2893e6
UWSM for Hyprland (#3455)
UWSM
2025-05-12 08:10:36 +10:00
Lena a291857bdc
Update Polish translation (#3454) 2025-05-12 08:09:25 +10:00
renovate[bot] d3f40a217e
fix(deps): update dependency ruff to v0.11.9 (#3453)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-05-10 13:59:04 +10:00
renovate[bot] 9facf6811c
chore(deps): update pre-commit hook astral-sh/ruff-pre-commit to v0.11.9 (#3452)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-05-10 13:58:46 +10:00
utuhiro78 3dccbc1247
Update Japanese translation (#3451) 2025-05-10 13:58:24 +10:00
correctmost 5cd5d714e9
Disable the loop-iterator-mutation rule in ruff (#3450)
This allows ruff check --preview to succeed again.
2025-05-09 07:28:56 +10:00
Odyssey 583945028f
Update catalan locales (#3447) 2025-05-09 07:27:54 +10:00
codefiles 2e4603e464
Fix btrfs subvolume creation (#3446) 2025-05-08 15:39:43 +02:00
Valerii 1228a0c75e
Better Ukrainian v1.3.1 compiled .mo file (#3445) 2025-05-08 21:29:35 +10:00
renovate[bot] 2bf2b665e6
chore(deps): update astral-sh/ruff-action action to v3.3.1 (#3444)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-05-08 09:00:38 +10:00
ncdm-stldr 4dc7cb9ee6
[fix] Sway: dmenu is no longer the default application launcher. It was changed for wmenu. (#3442)
I couldn't start the application launcher with mod+d after a fresh installation using archinstall, where I selected sway as a desktop.
The reason is that the default application launcher for sway changed (see ab9b164e52 and b44015578a).
The fix is simply to install this new application launcher wmenu instead of dmenu.
2025-05-08 09:00:10 +10:00
Valerii a3c1e20ea0
Better Ukrainian v1.3 (#3441)
* Add files via upload

* Add files via upload
2025-05-06 17:56:40 +10:00
summoner001 6f2fe45ce7
Update hungarian translation (#3440)
Translate new strings
2025-05-06 17:56:20 +10:00
Valerii 3adfc21c69
Add files via upload (#3439) 2025-05-06 09:57:34 +10:00
Daniel Girtler 9a98a1500b
Revert wayfire (#3432) 2025-05-05 10:08:42 +02:00
correctmost 781760a157
Break an import cycle between lib/luks and lib/disk/device_handler (#3438) 2025-05-05 17:04:16 +10:00
correctmost 4ed6d0da9b
Remove unused pydantic-settings dependency from pre-commit config (#3437) 2025-05-05 08:25:01 +10:00
renovate[bot] 38213a02bf
fix(deps): update dependency pylint to v3.3.7 (#3433)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-05-05 08:24:42 +10:00
correctmost ae38e92100
Add an inline annotation to avoid a crash with mypy 1.15.0 (#3434)
The annotation prevents intermittent crashes when running mypy
with a clean cache:

./archinstall/tui/curses_menu.py:723: error: INTERNAL ERROR

RuntimeError: Partial type "<partial list[?]>" cannot be checked with "issubtype()"
2025-05-05 07:04:18 +10:00
Matteo 1e2f9704c8
Another Italian translation update (#3436)
- Translated new strings
- Run locales_generator for all files, so all base.po have been updated
2025-05-05 07:03:09 +10:00
Matteo 6fe680f0ec
Update Italian translation (#3428) 2025-05-04 07:44:10 +10:00
Daniel Girtler 4023cfe2ca
Fix 3412 - Take optional repositories into account (#3427) 2025-05-03 16:06:27 +02:00
correctmost 9a939d8378
Enable tracebacks when running mypy (#3425)
This will make it easier to diagnose intermittent mypy crashes
2025-05-03 08:20:47 +10:00
renovate[bot] 914ff2002f
chore(deps): update pre-commit hook astral-sh/ruff-pre-commit to v0.11.8 (#3422)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-05-02 15:45:40 +10:00
renovate[bot] c776c46eb9
fix(deps): update dependency ruff to v0.11.8 (#3423)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-05-02 13:37:36 +10:00
renovate[bot] 9ac2a29ff5
fix(deps): update dependency pydantic to v2.11.4 (#3420)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-04-30 15:28:03 +02:00
correctmost 9c633924ba
Remove extraneous inline type annotations (#3418) 2025-04-30 08:31:28 +10:00
correctmost e8fd1de006
Avoid using generics with EditMenu (#3415)
This is a follow-up to commit 0de90bd55.
2025-04-29 07:12:32 +10:00
correctmost 437bb9c439
Remove a reference to twine (#3416)
This is a follow-up to commit a29a48f45.
2025-04-28 21:20:38 +02:00
Daniel Girtler 4c20331633
Fix 3376 - header alignment (#3414) 2025-04-28 14:04:15 +02:00
renovate[bot] c161d6fbd7
chore(deps): update astral-sh/ruff-action action to v3.3.0 (#3413)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-04-27 20:57:55 +02:00
utuhiro78 e04ee8a18f
Update Japanese translation (#3410) 2025-04-27 13:03:22 +10:00
Celestial.y 557fef5bfc
Update zh-CN translation, fix locales/README.md (#3409)
* Update zh-CN translation

* Fix locales/README.md
2025-04-27 13:02:02 +10:00
correctmost 0de90bd55b
Specify menu return types using generics instead of Any (#3400) 2025-04-27 13:01:17 +10:00
Daniel Girtler fae210dfea
Add optional file encryption for user credentials configuration (#3391)
* Optional encryption of user credentials configuration file

* Update README

* Update

* Update
2025-04-26 20:25:43 +10:00
renovate[bot] b8923807c7
fix(deps): update dependency ruff to v0.11.7 (#3403)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-04-26 20:02:08 +10:00
renovate[bot] f8a478d59a
chore(deps): update pre-commit hook astral-sh/ruff-pre-commit to v0.11.7 (#3402)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-04-26 20:01:06 +10:00
Anton Hvornum 16e9bbe583
Removed the @.snapshots volume in order to support both Snapper and Timeshift #3363 (#3408) 2025-04-26 11:57:36 +02:00
Celestial.y fd92873ff7
Improve, fix and complete zh-CN translation (#3404) 2025-04-26 19:57:23 +10:00
renovate[bot] d389db4a54
chore(deps): update actions/setup-python digest to a26af69 (#3401)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-04-26 19:57:00 +10:00
Franco Castillo 1756fe56da
Update archinstall/locales/es/LC_MESSAGES/base.mo & archinstall/locales/es/LC_MESSAGES/ (#3405) 2025-04-26 19:56:06 +10:00
Anton Hvornum a29a48f452
Swapping to python-uv for building and distribution (#3407)
* Swapping to python-uv for building archinstall

* Tweaked UV parameters to not use a venv

* Tweaking uv to not resolve/install any dependencies during installation.

* Added remaining dependencies to the build runner

* Swapped to uv for publishing, using pypi 'trusted publisher' instead of token access

* Installing uv and dependencies for publishing

* Swapped to uv in the building of the test ISO
2025-04-26 11:55:19 +02:00
renovate[bot] 935cda7a05
fix(deps): update dependency ruff to v0.11.6 (#3398)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-04-18 10:46:06 +10:00
renovate[bot] cb29369d26
chore(deps): update pre-commit hook astral-sh/ruff-pre-commit to v0.11.6 (#3397)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-04-18 10:45:49 +10:00
James Knight 3f06d2b058
Add niri package to profile (#3395) 2025-04-17 11:09:43 +10:00
Daniel Girtler 2f18b8d2fe
Fix 1747 | Additional post-installation menu options (#3393)
* Provide more post installation options

* Update
2025-04-16 07:31:49 +10:00
correctmost 130d1a6ff8
Split out unicode_ljust and unicode_rjust to break import cycle (#3388)
* Split out unicode_ljust and unicode_rjust to break import cycle

Previously, there was an import cycle between tui.menu_item and
lib.output.

* Move unicode.py from lib/ to lib/utils/
2025-04-13 15:47:33 +10:00
correctmost e281c2fa6a
Split out Result and ResultType to break import cycle (#3387)
Previously, there was an import cycle between tui.menu_item and
tui.types.
2025-04-13 15:06:48 +10:00
Thierry M 57a63053cd
Add files via upload (#3386) 2025-04-13 15:05:40 +10:00
codefiles bb87cfacaf
Fix GPT end (#3390) 2025-04-13 15:01:42 +10:00
Daniel Girtler a842fb48a2
Fix 3362 (#3377) 2025-04-11 06:58:12 +02:00
neko_0xff bf944a7459
i18n(zh-TW): re-Update base.po (20250411) (#3384)
* Update base.po

* Update base.po

* Update base.po
2025-04-11 14:09:32 +10:00
renovate[bot] 2db14ca2d1
fix(deps): update dependency ruff to v0.11.5 (#3383)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-04-11 10:59:52 +10:00
renovate[bot] 0dcc4862e2
chore(deps): update pre-commit hook astral-sh/ruff-pre-commit to v0.11.5 (#3382)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-04-11 10:57:31 +10:00
correctmost a9fd14fee1
Remove some unnecessary type unions (#3378) 2025-04-09 14:16:23 +02:00
correctmost 3dd8679734
Replace an Any instance with a TypedDict (#3375) 2025-04-09 18:47:53 +10:00
correctmost d35ac2a235
Remove unused SysCommand and SysCommandWorker fields (#3374) 2025-04-09 18:47:30 +10:00
correctmost 0028a572e8
Remove some Any instances from the codebase (#3372) 2025-04-09 15:22:02 +10:00
Matteo 20bd845fbe
Update Italian translation (#3371)
Translated new strings
2025-04-09 07:15:59 +10:00
renovate[bot] dc9d86c4b3
fix(deps): update dependency pydantic to v2.11.3 (#3370)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-04-08 21:31:43 +02:00
summoner001 409be2196d
Update hungarian translation (#3369)
Update hungarian translation
2025-04-08 21:08:55 +02:00
correctmost d5c210f933
Remove unused variable reported by Pyright (#3368) 2025-04-08 15:14:49 +02:00
correctmost a67b2dea60
Remove unused imports reported by Pyright (#3367) 2025-04-08 22:28:06 +10:00
utuhiro78 ffb2230f33
Update Japanese translation (100%) (#3366) 2025-04-08 22:27:40 +10:00
Valerii a7985233e9
Better Ukrainian v1.1 (#3365)
Ill add more with time
2025-04-08 14:19:35 +02:00
Valerii 03e19c714f
Better Ukrainian (#3364) 2025-04-08 19:29:07 +10:00
Daniel Girtler 4f1d1b4739
Store password as hash instead of plaintext (#3276)
* Rework user password to be hash

* Update

* Update

* Update

* Update

* Update

* Update

* Update

* Update

* Generate yescrypt hash

* Update

* Update

* Update

* Update
2025-04-08 08:53:18 +02:00
Daniel Girtler bae0e29e18
Fix #3330 (#3360)
* Fix #3330

* Update
2025-04-08 08:46:19 +02:00
Daniel Girtler a3fc658c90
Fix 3350 (#3358) 2025-04-08 08:45:47 +02:00
Daniel Girtler 00e87eb15f
Fix 3334 (#3359) 2025-04-08 08:45:21 +02:00
Daniel Girtler c1de65e5b3
Fix 3313 translation file (#3361) 2025-04-08 08:44:50 +02:00
correctmost 873e7b2c64
Remove unused description fields from profiles (#3357) 2025-04-07 14:26:17 +10:00
killertofus 390f4f15f4
added some more profiles (#3323)
* gave descriptions to profiles

* added some more profiles

* removed the descriptions for all of them and fixed the class name

* made some fixes

* removed the reference to seat

* forgot a comma

* forgot this seat reference

* rewrote river.py

* forgot to include river

* removed lightdm and added upercase X

* added some more fixes

* forgot to add labwc as a dep
2025-04-07 13:48:40 +10:00
codefiles 63b2f986c3
Move system info logging to function (#3356) 2025-04-07 13:19:18 +10:00
codefiles d7a5a59342
Fix disk config validation regression (#3355) 2025-04-07 12:24:17 +10:00
codefiles 5b06ec7c37
Remove check for sphinx and pylint modules (#3353) 2025-04-07 12:23:11 +10:00
Daniel Girtler f985da6f9a
Case insensitive sorting of profiles (#3329)
* Case insensitive sorting of profiles

* Update
2025-04-06 22:37:51 +02:00
mintsuki de3416f55b
Start the boot partition at 1MiB by default on MBR too (#3344) 2025-04-06 22:34:20 +02:00
Matteo da29b315a5
Update Italian translation (#3347)
Translated new strings
2025-04-05 22:55:23 +11:00
renovate[bot] 0ea1a48ead
fix(deps): update dependency ruff to v0.11.4 (#3346)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-04-05 22:55:04 +11:00
renovate[bot] 790051d17a
chore(deps): update pre-commit hook astral-sh/ruff-pre-commit to v0.11.4 (#3345)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-04-05 22:54:50 +11:00
Daniel Girtler f5a16307bd
Add ruff auto sort imports hook (#3342) 2025-04-04 13:46:32 +02:00
correctmost 6cdf9d2889
Use curses.window instead of curses._CursesWindow in annotations (#3341) 2025-04-04 18:50:55 +11:00
correctmost 16d8b209fc
Enable possibly-undefined warnings in mypy (#3340)
This commit also fixes the two remaining possibly-undefined
warnings.
2025-04-04 18:50:29 +11:00
renovate[bot] bdc260e7e8
fix(deps): update dependency ruff to v0.11.3 (#3339)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-04-04 10:15:11 +11:00
renovate[bot] 34881fb860
fix(deps): update dependency pydantic to v2.11.2 (#3338)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-04-04 10:14:34 +11:00
renovate[bot] 3c9eca8ef4
chore(deps): update pre-commit hook astral-sh/ruff-pre-commit to v0.11.3 (#3337)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-04-04 10:12:35 +11:00
mintsuki fa581021eb
Improve partition type detection, assignment, and misconfig handling (#3336) 2025-04-04 10:03:02 +11:00
mintsuki e6b0ebb5f3
Actually prevent installing if the config is invalid (#3335)
This also makes use of the previously unused _is_config_valid() method.
2025-04-04 09:46:55 +11:00
mintsuki 0f90d5991d
Use default EFI boot app path for Limine if installing to USB (#3331) 2025-04-04 09:43:07 +11:00
correctmost 1678fb5192
Use assert_never to fix some possibly-undefined mypy warnings (#3333) 2025-04-03 11:59:12 +11:00
wszqkzqk 5af2d2bb07
fix(installer): use platform.machine() for target architecture in grub-install (#3320)
Signed-off-by: Zhou Qiankang <wszqkzqk@qq.com>
2025-04-02 19:29:34 +11:00
EK ed0e9bd3c4
replace GTK theme package for Budgie build with an active one (#3327)
* replace GTK theme package with an active one

* add gtk theme to optdepends
2025-04-02 09:54:17 +02:00
utuhiro78 02c6fec0fc
Force to make pipewire symlinks (#3328) 2025-04-02 09:47:31 +02:00
utuhiro78 790a662ce3
Update Japanese translation (#3326) 2025-04-02 12:21:18 +11:00
neko_0xff 28f764fed1
i18n(zh-TW): re-Update base.po (20250401) (#3324)
* Update base.po

* Update base.po
2025-04-02 09:58:10 +11:00
Daniel Girtler 294eea0a1c
Fix 3298 - Add package gruops to selection (#3322) 2025-04-01 07:34:20 +11:00
summoner001 7513ef1cc8
Update hungarian translation (#3321)
Update hungarian translation
*Translating new strings
2025-03-31 22:09:41 +11:00
Anton Hvornum dc104e6967
Bumping version to 3.0.4 (#3319) 2025-03-31 09:51:40 +02:00
Luna Jernberg 5899a82cf2
Update base.po - Swedish (#3318)
Update Swedish translation for the new release
2025-03-31 09:02:05 +02:00
Daniel Girtler f837387d49
Fix 3315 - package loading (#3317) 2025-03-31 07:44:53 +02:00
Anton Hvornum bab3653144
Updated all the locales in prep for release (#3314) 2025-03-30 21:29:56 +02:00
Anton Hvornum f0159e1278
Fixed root_password and users[superuser=True] check (#3312) 2025-03-30 21:06:42 +02:00
Anton Hvornum 1fbb21f38a
Made sure to update the package databases before running --info (#3311) 2025-03-30 20:53:41 +02:00
renovate[bot] da6e2f3618
chore(deps): update pre-commit hook pycqa/flake8 to v7.2.0 (#3310)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-03-30 10:32:58 +02:00
renovate[bot] b4bec7149d
fix(deps): update dependency flake8 to v7.2.0 (#3309)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-03-30 09:53:49 +02:00
Lisichka d616de25f6
fix(hardware): Improve Nvidia driver installation (#3302)
Fixes a few issues related to the installation of Nvidia drivers.

1. No longer install the redudant nvidia-open package as it's provided
by the nvidia-open-dkms package.
2. Install vulkan-nouveau when selecting the open-source nouveau driver.
3. Install the libva-nvidia-driver package for hardware accelerated
video decoding.
2025-03-30 09:53:17 +02:00
mintsuki 9f7c3bab0f
Detect boot partition regardless of boot flags if mounted on /boot (#3303) 2025-03-29 21:17:33 +01:00
renovate[bot] c4bea107b0
fix(deps): update dependency pydantic to v2.11.1 (#3306)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-03-29 11:17:15 +11:00
mintsuki ea94535e26
Improve Limine without boot partition unsupported message (#3305) 2025-03-29 11:16:55 +11:00
renovate[bot] 21249ee2c7
fix(deps): update dependency pydantic to v2.11.0 (#3304)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-03-28 11:43:36 +11:00
correctmost 4711f7abad
Fix Pydantic deprecation warnings (#3301)
This commit also enables mypy checks for deprecated calls.
2025-03-26 08:14:11 +11:00
correctmost d43482e585
Move run_custom_user_commands to fix an import cycle (#3254) 2025-03-26 08:13:18 +11:00
renovate[bot] cb42003b2b
chore(deps): update actions/setup-python digest to 8d9ed9a (#3300)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-03-25 23:05:05 +11:00
Daniel Girtler 1b890492d0
Refactor code (#3247) 2025-03-25 09:49:18 +01:00
Efe TUROĞLU c15dbf0b0d
Added more Turkish translations (#3299) 2025-03-25 08:00:09 +11:00
Daniel Girtler 3d8ecf12ae
Fix 1591 - add user to wheel only when sudo (#3293) 2025-03-24 10:19:52 +01:00
Daniel Girtler 75b6bbaeff
Fix regression for NTP sync (#3294) 2025-03-24 10:18:52 +01:00
Daniel Girtler d3330ff3ab
Only allow ascii chars in input (#3244) 2025-03-24 10:17:37 +01:00
renovate[bot] 9ee9dcec4d
chore(config): migrate config renovate.json (#3297)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-03-23 12:36:41 +11:00
correctmost 0e8d2c139b
Enable config migration PRs from Renovate (#3296)
This will help keep the config file updated with renamed options
and values.
2025-03-23 12:31:36 +11:00
renovate[bot] 4d37212a9a
chore(deps): pin dependencies (#3295)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-03-23 10:16:59 +11:00
mintsuki c78f78fa9a
More properly support FAT12 and FAT16 ESPs (#3268)
FAT12 and FAT16 are also valid filesystems for ESPs, therefore, try to support them
2025-03-23 10:14:52 +11:00
correctmost 083194f0e8
Pin astral-sh/ruff-action to a specific commit (#3265)
The GitHub docs recommend pinning third-party actions to specific
commits for security hardening purposes.
2025-03-23 10:14:05 +11:00
codefiles 02729f0a50
Do not write passwords to /tmp (#3292) 2025-03-23 09:58:09 +11:00
codefiles 0e71bcff78
Do not write passwords to the command log (#3291) 2025-03-22 15:23:18 +11:00
codefiles 16a84ba662
Disable default credentials save (#3290) 2025-03-22 15:21:43 +11:00
codefiles d326ceff45
Add udev sync after LUKS encrypt (#3289) 2025-03-22 11:16:19 +11:00
renovate[bot] 54e7a94cf8
fix(deps): update dependency ruff to v0.11.2 (#3288)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-03-22 09:36:14 +11:00
renovate[bot] f6eb99d816
chore(deps): update pre-commit hook astral-sh/ruff-pre-commit to v0.11.2 (#3287)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-03-22 09:35:34 +11:00
codefiles 6615d18246
Dedent Limine hook (#3286) 2025-03-22 09:35:14 +11:00
neko_0xff edf8bf9b0a
Update base.po (#3285) 2025-03-21 22:12:08 +11:00
codefiles dcce29b91c
Refactor creation of BLS entries (#3283) 2025-03-21 22:08:21 +11:00
neko_0xff 51497bd079
re-update zh_TW base.po (#3282)
* Update base.po

* Update archinstall/locales/zh-TW/LC_MESSAGES/base.po

Co-authored-by: pan93412 <pan93412@gmail.com>

* Update base.po

---------

Co-authored-by: pan93412 <pan93412@gmail.com>
2025-03-21 09:16:43 +11:00
mintsuki 931f47a037
Limine: use UUID for accessing boot partition if not same as ESP (#3267) 2025-03-21 08:35:32 +11:00
renovate[bot] 26194d6b47
fix(deps): update dependency pylint to v3.3.6 (#3279)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-03-21 08:30:51 +11:00
renovate[bot] 469e0f0a67
chore(deps): update pre-commit hook astral-sh/ruff-pre-commit to v0.11.1 (#3278)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-03-21 08:30:04 +11:00
codefiles cc6716be99
Disable irrelevant validation in mountpoint prompt (#3280) 2025-03-21 08:29:20 +11:00
renovate[bot] 4efc461b98
fix(deps): update dependency ruff to v0.11.1 (#3281)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-03-21 08:28:26 +11:00
codefiles c8e2c3eca8
Fix loader configuration location (#3275) 2025-03-20 14:21:06 +11:00
codefiles 4ffff49d5f
Add XBOOTLDR to manual partitioning (#3273) 2025-03-20 14:19:28 +11:00
renovate[bot] 2ba40dd8e3
fix(deps): update dependency pre-commit to v4.2.0 (#3271)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-03-20 09:24:37 +11:00
Matteo 1891df74da
Update Italian translation (#3270)
-Translated new strings
-Improved some translation
2025-03-20 09:21:24 +11:00
mintsuki 48053fb822
Create proper EFI boot menu entry for Limine (#3263) 2025-03-20 09:18:47 +11:00
mintsuki f046495bda
Put Limine config and BIOS files in a limine/ subdir (#3264) 2025-03-20 09:14:41 +11:00
correctmost 87fb96d249
Fix grammar in existing-session error message (#3262) 2025-03-15 18:59:17 +11:00
correctmost aa444748b9
Replace an Any instance with TypedDict (#3261) 2025-03-15 09:37:32 +11:00
renovate[bot] ae19299e5f
fix(deps): update dependency ruff to v0.11.0 (#3260)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-03-15 09:36:57 +11:00
renovate[bot] 4899d555eb
chore(deps): update pre-commit hook astral-sh/ruff-pre-commit to v0.11.0 (#3259)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-03-15 09:36:41 +11:00
correctmost 4938d79873
Fix a blanket type ignore comment (#3258)
This commit allows the ignore-without-code mypy warning to be
enabled. It also allows the pygrep-hooks ruff rules to be enabled.
2025-03-14 09:06:36 +11:00
correctmost b6983a2d5a
Enable additional mypy error codes (#3257) 2025-03-14 08:16:27 +11:00
renovate[bot] 933f2c8cd4
fix(deps): update dependency ruff to v0.10.0 (#3256)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-03-14 08:16:05 +11:00
renovate[bot] 6c9462e9cf
chore(deps): update pre-commit hook astral-sh/ruff-pre-commit to v0.10.0 (#3255)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-03-14 08:15:49 +11:00
correctmost 83c3a76197
Enable import checks in __init__.py files with Pylint (#3253) 2025-03-13 15:17:45 +11:00
correctmost f100e5110d
Use __all__ in __init__.py files to fix unused-import warnings (#3252)
This commit allows ruff and flake8 ignores to be removed. It also
allows mypy to be run in strict mode by default.
2025-03-13 14:19:05 +11:00
correctmost e7ca4f56d5
Remove unneeded flake8 ignore for __init__.py files (#3250) 2025-03-13 08:28:44 +11:00
correctmost 057feacf0e
Remove unused stdlib imports from __init__.py files (#3249) 2025-03-13 08:28:24 +11:00
correctmost 269e6f8e54
Enable most flake8-pyi rules in ruff and fix a warning (#3248) 2025-03-13 08:27:53 +11:00
Daniel Girtler e46aa7c1b0
Add timestamp to logs (#3245) 2025-03-12 18:37:13 +11:00
correctmost 7f88e909c6
Remove unused _set_font code (#3243)
This code has been unused since commit dee792658.
2025-03-11 21:26:08 +11:00
correctmost 0b0dc76558
Fix SysCallError import cycle between exceptions.py and general.py (#3242)
This commit updates SysCallError to accept a worker log argument
instead of an entire SysCommandWorker.
2025-03-11 21:25:25 +11:00
correctmost dbf45e23cc
Introduce a string-specific version of clear_vt100_escape_codes (#3241)
This commit helps fix some existing type errors in the code. It
also helps avoid ~280,000 isinstance calls when opening the
additional packages menu.
2025-03-11 12:11:04 +11:00
correctmost 2819ea02b1
Speed up _count_wchars by avoiding east_asian_width calls (#3240)
This commit helps avoid ~390,000 duplicate east_asian_width calls
when opening the additional packages menu.
2025-03-11 12:10:33 +11:00
correctmost a5fcf21a12
Speed up _parse_package_output by caching normalized key strings (#3239)
This commit helps avoid ~260,000 chained strip(), lower(), and
replace() sequences.
2025-03-10 22:04:41 +11:00
correctmost 624143ed96
Speed up clear_vt100_escape_codes by caching an encode() result (#3238)
This commit helps avoid ~280,000 redundant encode() calls when
opening the additional packages menu.
2025-03-10 22:03:29 +11:00
Daniel Girtler 55941cc40e
Fix package text (#3236) 2025-03-10 22:02:40 +11:00
Daniel Girtler 12562f4cae
Add newline after countdown (#3237) 2025-03-10 22:02:26 +11:00
Carlo Teubner 24f479892f
guided.rst: fix formatting & typos (#3235) 2025-03-09 20:57:56 +11:00
renovate[bot] c9ebf3c881
fix(deps): update dependency pylint to v3.3.5 (#3234)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-03-09 20:53:21 +11:00
correctmost 6a90760e67
Clean up most no-implicit-reexport warnings from mypy (#3233)
This makes it easier to run mypy --strict from the command line
and should hopefully make it easier to clean up import cycles in
future commits.
2025-03-09 19:50:56 +11:00
renovate[bot] 01f1cd314f
fix(deps): update dependency ruff to v0.9.10 (#3231)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-03-08 10:02:29 +11:00
renovate[bot] cdf846eee8
chore(deps): update pre-commit hook astral-sh/ruff-pre-commit to v0.9.10 (#3230)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-03-08 10:02:13 +11:00
Yaron Shahrabani cf75a38a28
Update Hebrew translation. (#3229) 2025-03-06 21:47:33 +11:00
correctmost 54d426e54c
Fix Pyright warning with urllib.parse (#3228) 2025-03-06 18:23:43 +11:00
correctmost 9a3ec27645
Fix repositories typo in debug message (#3227) 2025-03-06 18:23:18 +11:00
correctmost 49347c2f82
Fix falsy-dict-get-fallback ruff warning (#3226) 2025-03-06 13:05:59 +11:00
Daniel Girtler 697ccd1ac5
Fix 2379 - Mirror and region definitions (#3223)
* Fix 2379 - Mirror and repository settings

* Fix alignment
2025-03-05 22:19:50 +11:00
correctmost 5f7b16b152
Remove some Any instances from the codebase (#3221) 2025-03-03 08:24:36 +11:00
renovate[bot] d6ee5a66b2
fix(deps): update dependency pytest to v8.3.5 (#3220)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-03-03 07:33:59 +11:00
correctmost d9ac33dbe8
Fix a non-pep695-generic-function ruff warning (#3218) 2025-03-02 22:01:56 +11:00
correctmost ddbd465a34
Remove python-simple-term-menu installation from build_iso.sh (#3217)
The dependency is no longer needed as of 0f2e0095.
2025-03-02 10:43:46 +11:00
Alexmelman88 1e830c16a6
Update Russian translation (#3216) 2025-03-02 10:43:10 +11:00
correctmost 70c6a10c3c
Add missing typing.override annotation reported by Pyright (#3215) 2025-03-02 10:41:21 +11:00
correctmost f94e8b8984
Fix Pyright warnings with importlib.util (#3214) 2025-03-02 10:40:53 +11:00
correctmost 1c6085f86c
Fix Pyright warning with curses.textpad (#3213) 2025-03-02 10:40:20 +11:00
renovate[bot] 4f72c0177b
fix(deps): update dependency ruff to v0.9.9 (#3210)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-03-02 10:39:37 +11:00
renovate[bot] c2672aaa79
chore(deps): update pre-commit hook astral-sh/ruff-pre-commit to v0.9.9 (#3209)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-03-02 10:39:09 +11:00
mintsuki 98d604d097
Do not enable UKI at archinstall start if using BIOS (#3208) 2025-03-02 10:38:38 +11:00
mintsuki 645e8d0144
Enable UKI support for the Limine bootloader option (#3207) 2025-03-02 10:33:07 +11:00
mintsuki 0b551d729e
Do not force install GRUB on BIOS when not chosen as bootloader (#3206) 2025-03-02 10:22:27 +11:00
correctmost 142883c9c3
Fix typing syntax for multiple string literals (#3212) 2025-03-01 17:20:42 +11:00
correctmost d6ea7b011f
Fix a used-dummy-variable ruff warning (#3203) 2025-02-26 07:35:25 +11:00
Daniel Girtler 1ddc74af21
Remove debug output for all commands (#3201) 2025-02-25 11:20:43 +01:00
Daniel Girtler 245b84194a
Remove duplicate loading of archinstall (#3200) 2025-02-25 20:31:38 +11:00
Daniel Girtler 74b41dea96
Add additional package selector (#3196) 2025-02-24 17:57:26 +11:00
codefiles 4a477351e0
Fix manual partitioning device wipe status (#3198) 2025-02-24 12:18:14 +11:00
codefiles 4b07f8a3ae
Rework default partition table (#3197) 2025-02-23 21:16:11 +01:00
Daniel Girtler 8b375c97a5
Fix version parsing for local branches (#3190)
* Fix version parsing for local branches

* Fix tests

* Fix tests
2025-02-23 09:44:25 +01:00
codefiles a51475e0ed
Refactor default partition table (#3194) 2025-02-23 18:51:25 +11:00
codefiles d69441a2da
Fix typing for enc_conf parameter (#3195) 2025-02-23 18:50:32 +11:00
codefiles 201968cf2e
Show device wipe status in Info for Partitioning (#3193) 2025-02-23 10:20:37 +11:00
codefiles b83bc79d91
Fix MBR conditional (#3192) 2025-02-23 10:20:06 +11:00
summoner001 c364917324
Update hungarian translation (#3191)
Fix typos with Lokalize and PO-Edit.
2025-02-22 23:02:54 +11:00
correctmost 4c2ec5deba
Enable --strict-bytes checks in mypy (#3189)
Strict-bytes checks will be enabled by default in mypy 2.0, so this
commit will help prevent violations from being introduced into the
codebase.
2025-02-22 14:24:52 +11:00
renovate[bot] 957fa06ade
fix(deps): update dependency ruff to v0.9.7 (#3187)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-02-21 08:14:20 +11:00
renovate[bot] 81edc8784a
chore(deps): update pre-commit hook astral-sh/ruff-pre-commit to v0.9.7 (#3186)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-02-21 08:14:05 +11:00
Moritz 3f762feced
Update base.po (#3184)
-Translation Update
2025-02-20 07:37:13 +11:00
Daniel Girtler b57f7f91cf
Integrate new arguments data structure (#3167)
* Integrate new args dataclass

* Integrate args

* Update

* Update

* Update

* Update
2025-02-20 07:35:59 +11:00
Celestial.y a9ae064359
Improve, fix and complete zh-CN translation (#3180)
* Minor fixing README for translation.

* Improve/fix/add translation for zh-CN

* Compile translation
2025-02-19 08:04:24 +11:00
renovate[bot] c00f609c1b
fix(deps): update dependency flake8 to v7.1.2 (#3178)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-02-17 17:06:43 +11:00
renovate[bot] 7347259a4b
chore(deps): update pre-commit hook pycqa/flake8 to v7.1.2 (#3177)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-02-17 17:06:29 +11:00
Odyssey f73800c6dd
Update Catalan translation (#3175) 2025-02-14 12:21:39 +11:00
Luna Jernberg 579f2ba498
Update base.po (#3171)
Update Swedish translation
2025-02-11 18:25:20 +11:00
renovate[bot] 604884fa07
fix(deps): update dependency ruff to v0.9.6 (#3170)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-02-11 18:24:59 +11:00
renovate[bot] ef5f61d5df
chore(deps): update pre-commit hook astral-sh/ruff-pre-commit to v0.9.6 (#3169)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-02-11 18:24:44 +11:00
Korsil Vladivostok bcbdf2346b
Update base.po (#3164)
* Update base.po

* Update base.po

Latest review made at base.po pt-br file before Pull Request
2025-02-08 11:54:04 +11:00
renovate[bot] 9e88cd0cc8
fix(deps): update dependency ruff to v0.9.5 (#3162)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-02-08 11:53:12 +11:00
walken 85d89c7b33
Czech localization update (#3163) 2025-02-08 11:52:16 +11:00
renovate[bot] e489f7f33d
chore(deps): update pre-commit hook astral-sh/ruff-pre-commit to v0.9.5 (#3161)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-02-08 11:51:43 +11:00
renovate[bot] 889f0ad5ae
chore(deps): update pre-commit hook pre-commit/mirrors-mypy to v1.15.0 (#3159)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-02-06 19:32:42 +11:00
renovate[bot] 8c4634c4d6
fix(deps): update dependency mypy to v1.15.0 (#3158)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-02-05 17:00:51 +11:00
utuhiro78 419b320e9e
Update Japanese translation (#3157) 2025-02-02 10:14:49 +11:00
correctmost fb3dd7da4c
Use the official ruff GitHub action instead of custom code (#3156)
This speeds up PR checks and reduces network I/O.
2025-02-01 17:04:28 +11:00
summoner001 94ae4e3dd7
Update hungarian translation (#3153)
Translate new strings and add minor fixes.
2025-02-01 08:30:56 +11:00
renovate[bot] 77059e8819
fix(deps): update dependency ruff to v0.9.4 (#3151)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-31 17:08:44 +11:00
renovate[bot] 40b6c160e3
chore(deps): update pre-commit hook astral-sh/ruff-pre-commit to v0.9.4 (#3150)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-31 17:07:58 +11:00
DrakeCoding 71a6c84df0
Fixed grammar under function "get_arguments" (#3152) 2025-01-31 14:24:51 +11:00
Franco Castillo ae3f59ccae
Update .po, base.pot and archinstall/locales/es/LC_MESSAGES/base.mo files. (#3149)
Signed-off-by: Franco Castillo <castillofrancodamian@gmail.com>
2025-01-31 07:25:44 +11:00
uday e110492b56
Replace Sway with Hyprland in profile seat selection (#3145) 2025-01-29 08:15:31 +11:00
correctmost 7b0efd35f0
Remove unneeded mypy override for archinstall.scripts (#3147)
The override is no longer needed after commit fc63d45fe6.
2025-01-29 08:14:45 +11:00
renovate[bot] 4f53961392
fix(deps): update dependency pylint to v3.3.4 (#3146)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-29 07:33:20 +11:00
renovate[bot] 0f6f5dae86
fix(deps): update dependency pydantic to v2.10.6 (#3143)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-25 10:04:15 +11:00
Wise 0b89966720
Update missing translation strings for TR (#3142) 2025-01-24 12:32:06 +11:00
renovate[bot] 59b90d65a1
fix(deps): update dependency ruff to v0.9.3 (#3141)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-24 09:58:55 +11:00
renovate[bot] 88eedf04aa
chore(deps): update pre-commit hook astral-sh/ruff-pre-commit to v0.9.3 (#3140)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-24 09:58:40 +11:00
codefiles f05af2e6c4
Consolidate preparations for lvm and partitions (#3135) 2025-01-23 17:50:35 +11:00
Anton Hvornum 6653a4e5a9
Removed requirement for root for pylint (#3138) 2025-01-22 19:46:44 +01:00
Anton Hvornum 7ccc288b14
Bumping to version 3.0.2 (#3137) 2025-01-22 19:03:33 +01:00
Daniel Girtler 6c6ceef6f2
Fix remote mirrorlist parsing (#3136) 2025-01-22 10:04:59 +01:00
correctmost 8aa479bf3e
Use float instead of int for pre-validated mirror score fields (#3079)
This fixes an unnecessary-round ruff warning in validate_score.
2025-01-22 18:54:32 +11:00
Anton Hvornum 6d371da5df
Remove reiserfs as it's been deprecated since 2022 (https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=a452c4eb404df8a7f2a79a37ac77b90b6db1a2c9) and been removed in the kernel as of 2024-11-21 (https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=c01f664e4ca210823b7594b50669bbd9b0a3c3b0) (#3134) 2025-01-21 18:53:55 +01:00
Daniel Girtler 4aa8317b7c
Add skip for partitioning menus (#3121) 2025-01-21 18:42:16 +01:00
Daniel Girtler 985775b143
Fix misaligned table headers (#3120) 2025-01-21 18:41:47 +01:00
Daniel Girtler 64f08cc890
Fix scrolling in console (#3113) 2025-01-21 18:41:23 +01:00
Daniel Girtler fb159a8255
Fix 3081 - Local mirrorlist parsing bug (#3104)
* Fix 3081 - shortcircuit on empty mirror options

* Update

* Update
2025-01-21 18:40:54 +01:00
codefiles c9bdaa209e
Replace list with link to contributors page (#3102) 2025-01-21 12:53:36 +01:00
Daniel Girtler fc63d45fe6
Remove deprecated swiss config (#3042)
* Remove deprecated swiss config

* Update
2025-01-21 12:42:31 +01:00
renovate[bot] 2bd4344d43
fix(deps): update dependency pre-commit to v4.1.0 (#3131)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-21 12:17:25 +11:00
codefiles ee69e19f8b
Refactor preparations for fs type and encryption (#3130) 2025-01-20 20:22:43 +11:00
codefiles 19c390e072
disk: add support for creating swap partitions (#3129) 2025-01-18 16:48:48 +11:00
renovate[bot] 8d923ff09e
chore(deps): update pre-commit hook astral-sh/ruff-pre-commit to v0.9.2 (#3127)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-17 09:28:34 +11:00
renovate[bot] 99fe401979
fix(deps): update dependency ruff to v0.9.2 (#3125)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-17 09:28:17 +11:00
correctmost c94d0a56d9
Enable most flake8-commas rules in ruff and fix warning (#3122) 2025-01-15 16:30:13 +11:00
codefiles 41215741f0
disk: add udev sync after partitioning (#3119) 2025-01-14 14:23:25 +11:00
codefiles d5bbda1e2f
Refactor cmd path check using startswith() (#3117) 2025-01-14 14:22:47 +11:00
codefiles b7a5d00676
Remove superfluous /usr/bin/ from commands (#3115) 2025-01-13 14:42:39 +11:00
correctmost c0a2de4330
Enable the set-attr-with-constant ruff rule and fix warnings (#3114) 2025-01-12 15:02:06 +11:00
correctmost fd77b5d4ce
Enable the strip-with-multi-characters ruff rule (#3112)
Commit 4212357c6 fixed the remaining warnings.
2025-01-12 12:39:10 +11:00
correctmost 457e790bd0
Enable most flake8-bugbear rules in ruff (#3110) 2025-01-12 11:51:06 +11:00
correctmost 4212357c6f
Use removeprefix/removesuffix instead of incorrect lstrip/rstrip calls (#3109) 2025-01-12 11:50:09 +11:00
codefiles 6681501904
Fix Btrfs subvolume mount options (#3108) 2025-01-12 11:46:34 +11:00
correctmost 47736c4060
Avoid reassigning a parameter value to fix Pyright warnings (#3106) 2025-01-12 11:45:41 +11:00
renovate[bot] df2791295d
chore(deps): update pre-commit hook astral-sh/ruff-pre-commit to v0.9.1 (#3100)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-12 11:30:59 +11:00
codefiles 3409f84e79
Use list comprehension (#3105) 2025-01-12 11:30:27 +11:00
Melroy van den Berg 7202d964dd
Make libera.chat irc link clickable (#3099)
Fix libera.chat link in markdown
2025-01-12 11:27:30 +11:00
correctmost e7f2a8c203
Fix some mypy warnings in archinstall/lib/ (#3103) 2025-01-11 15:44:43 +11:00
codefiles 22b410d082
Change to import Path for consistency (#3101) 2025-01-11 15:42:50 +11:00
Melroy van den Berg a575ac2c47
Use Matrix channel invite link (#3098) 2025-01-11 15:40:13 +11:00
renovate[bot] 39c7eda352
fix(deps): update dependency ruff to v0.9.1 (#3097)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-11 15:37:33 +11:00
codefiles 700294f19a
disk: validate first partition start (#3096) 2025-01-10 20:12:47 +11:00
renovate[bot] ad015033b8
fix(deps): update dependency ruff to v0.9.0 (#3095)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-10 08:21:18 +11:00
renovate[bot] cb414c1c5b
chore(deps): update pre-commit hook astral-sh/ruff-pre-commit to v0.9.0 (#3093)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-10 08:19:37 +11:00
renovate[bot] 2778ca60f6
fix(deps): update dependency pydantic to v2.10.5 (#3092)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-10 08:19:21 +11:00
codefiles c081f77d57
pacman/repo: use StrEnum (#3088) 2025-01-08 12:13:11 +11:00
correctmost 10a12dc855
Fix mutable-class-default ruff warnings (#3087) 2025-01-08 10:23:07 +11:00
renovate[bot] 34ef6527ce
fix(deps): update dependency pylint-pydantic to v0.3.5 (#3086)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-08 07:52:24 +11:00
codefiles 6398f6852d
audio: use StrEnum (#3084) 2025-01-08 07:45:19 +11:00
correctmost 40210f8733
Fix used-dummy-variable ruff warnings (#3083) 2025-01-08 07:44:48 +11:00
codefiles 9163e8c84c
disk: rework manual partitioning (#3071)
* disk: rework manual partitioning

* disk: fix end alignment

* disk: validate config

* test: fix disk config partition overlap
2025-01-08 07:44:03 +11:00
correctmost 25b7bbb0ed
Add if-key-in-dict-del ruff rule to ignore list (#3082)
The rule is concerned with code style rather than correctness or
performance.
2025-01-08 07:41:25 +11:00
correctmost e712144e5d
Fix falsy-dict-get-fallback ruff warnings (#3077) 2025-01-08 07:38:40 +11:00
codefiles fd91cbaac1
pacman/repo: update enum members to uppercase (#3076) 2025-01-08 07:37:43 +11:00
codefiles fa515dfdc6
general: remove superfluous callbacks variable (#3075) 2025-01-08 07:36:12 +11:00
renovate[bot] 984fa6af46
fix(deps): update dependency ruff to v0.8.6 (#3074)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-08 07:34:31 +11:00
renovate[bot] 7cba07b730
chore(deps): update pre-commit hook astral-sh/ruff-pre-commit to v0.8.6 (#3073)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-08 07:34:12 +11:00
renovate[bot] f1f08c811b
fix(deps): update dependency ruff to v0.8.5 (#3064)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-03 15:52:58 +11:00
codefiles 6dab4650fa
audio: capitalize enums (#3067) 2025-01-03 15:24:10 +11:00
renovate[bot] cb6417be6e
fix(deps): update dependency mypy to v1.14.1 (#3057)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-03 14:13:00 +11:00
renovate[bot] 77f5b075b6
fix(deps): update dependency pylint to v3.3.3 (#3046)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-03 14:12:46 +11:00
renovate[bot] 82bcb59044
chore(deps): update pre-commit hook pre-commit/mirrors-mypy to v1.14.1 (#3062)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-03 13:56:33 +11:00
renovate[bot] 9d1a47df13
chore(deps): update pre-commit hook astral-sh/ruff-pre-commit to v0.8.5 (#3063)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-03 13:56:16 +11:00
codefiles 547ce8033d
audio: remove incorrect use of dataclass (#3058) 2025-01-03 13:44:25 +11:00
codefiles 18ef7fd469
Use Path.chmod() (#3051) 2025-01-03 13:41:41 +11:00
codefiles 459b84b6fe
Rework mount point argument (#3041) 2024-12-23 11:04:16 +11:00
codefiles d5c5b60d5c
Rework profiles path (#3040) 2024-12-23 09:08:48 +11:00
codefiles 5f8cdcb39b
disk: change from_partition() parameters (#3039) 2024-12-23 09:08:02 +11:00
renovate[bot] a8c2a5a54f
fix(deps): update dependency mypy to v1.14.0 (#3036)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-12-22 10:38:20 +11:00
renovate[bot] 2996e0ae14
chore(deps): update pre-commit hook pre-commit/mirrors-mypy to v1.14.0 (#3037)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-12-22 10:37:58 +11:00
codefiles 24ff132f93
general: remove unspecified exception handling (#3035) 2024-12-22 10:21:56 +11:00
codefiles c978c841de
disk: move ENC_IDENTIFIER (#3034) 2024-12-22 10:21:21 +11:00
codefiles 9b5fd6bad5
mirrors: use pydantic model_validate_json() (#3033) 2024-12-20 17:26:45 +11:00
codefiles 367c8d781c
general: rework environment_vars (#3032) 2024-12-20 17:26:11 +11:00
codefiles f685849b8d
luks: remove superfluous _mapper_dev (#3031) 2024-12-20 17:25:12 +11:00
renovate[bot] 75459f4ac2
Update pre-commit hook astral-sh/ruff-pre-commit to v0.8.4 (#3030)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-12-20 12:01:27 +11:00
renovate[bot] 5a82ce7719
Update dependency ruff to v0.8.4 (#3029)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-12-20 12:01:09 +11:00
renovate[bot] 05441a4c11
Update dependency pydantic to v2.10.4 (#3026)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-12-19 17:50:14 +11:00
codefiles ae51af67a3
Remove disk retries and timeouts (#3025) 2024-12-19 17:49:44 +11:00
Mohamed E d2ef961b32
[Feat] Wayfire support (#3020)
* add profile

* fix pylint
2024-12-18 07:04:48 +11:00
lazysixoeight 5288e246ec
Specified GNOME as an acronym (#3023) 2024-12-16 20:49:42 +11:00
renovate[bot] fb27fbdfa8
Update pre-commit hook astral-sh/ruff-pre-commit to v0.8.3 (#3019)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-12-15 09:18:28 +11:00
renovate[bot] 7b09c5a7ca
Update dependency ruff to v0.8.3 (#3018)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-12-15 09:18:03 +11:00
Daniel Girtler 1ff04c6df0
Use ctrl+h for help menu trigger (#2996) 2024-12-12 09:43:54 +01:00
renovate[bot] 27df486dda
Update dependency pylint-pydantic to v0.3.4 (#3017)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-12-09 15:54:31 +11:00
codefiles 4dccd54cbd
Replace commonprefix() with commonpath() (#3016) 2024-12-09 13:25:08 +11:00
codefiles 3716df9bb7
Fix pre-mounted Btrfs subvolumes root detection (#3014) 2024-12-09 10:38:16 +11:00
codefiles 4592280baa
Refactor set_mirrors() (#3011) 2024-12-08 15:07:17 +11:00
codefiles ae3b0f8d75
Remove superfluous try in get_btrfs_info() (#3010) 2024-12-08 09:01:51 +11:00
Daniel Girtler 1d278f8abd
Fix 2991 - Restructure the mirror list handling (#3007)
* Fix 2991 - mirror configuration

* Update

* Update

* Update
2024-12-08 08:58:16 +11:00
codefiles 8f2bf2b737
Refactor set_hostname() (#3009) 2024-12-08 08:57:31 +11:00
codefiles 3400991c9b
Refactor enable_sudo() (#3008) 2024-12-08 08:56:58 +11:00
codefiles 19a0d49509
Update partition flags value (#3006) 2024-12-07 11:48:49 +11:00
codefiles 0a9fae2e57
Replace deprecated pydantic parse_raw() (#3004) 2024-12-07 10:20:23 +11:00
renovate[bot] fbdb3c4f37
Update pre-commit hook astral-sh/ruff-pre-commit to v0.8.2 (#3002)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-12-06 17:17:49 +11:00
renovate[bot] 2d4128fd84
Update dependency ruff to v0.8.2 (#3001)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-12-06 17:17:03 +11:00
renovate[bot] 89cd718462
Update dependency pydantic to v2.10.3 (#2999)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-12-04 21:05:29 +11:00
zbik 3905bfe31a
Update plasma.py (#2998)
changed kwrite to kate as the two packages merged together in 2022 and removed egl-wayland (why was it there in the first place?)
2024-12-03 20:03:42 +11:00
renovate[bot] 03e41d3721
Update dependency pylint to v3.3.2 (#2992)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-12-02 18:18:21 +11:00
renovate[bot] 7d0acbcc6d
Update dependency pylint-pydantic to v0.3.3 (#2995)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-12-02 18:17:52 +11:00
renovate[bot] ac75dda390
Update dependency pytest to v8.3.4 (#2989)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-12-02 13:12:05 +11:00
Michael Ziminsky (Z) 256f206b9e
btrfs improvements and fixes (#2970) 2024-12-01 18:35:30 +11:00
correctmost 60842bd1cf
Enable bare-except linter rules and fix warnings (#2988) 2024-12-01 18:34:51 +11:00
correctmost 0bc2ad700f
Enable the "unreachable" pylint warning and remove unused code (#2987)
The os.fsync call causes an "invalid argument" OSError when it
actually runs, so it has been removed altogether.

Closes #2773
2024-12-01 18:34:00 +11:00
correctmost 507e4322d6
Remove unused SysCommand.__json__ method (#2986) 2024-12-01 18:33:22 +11:00
correctmost fcf9658f8f
Disable some rules that warn when using ruff's preview mode (#2985) 2024-12-01 17:50:33 +11:00
correctmost 8fa5ec15af
Enable the yield-in-for-loop ruff rule and fix warnings (#2984) 2024-12-01 17:50:11 +11:00
correctmost af043afa88
Enable the unnecessary-lambda pylint rule and fix warnings (#2983) 2024-12-01 17:44:39 +11:00
correctmost e0db642366
Fix "selction" typo (#2981) 2024-12-01 17:43:29 +11:00
correctmost b49b5bfa11
Fix "Pssword" typo (#2980) 2024-12-01 17:42:33 +11:00
correctmost 760963f7a6
Enable the unused-variable pylint rule and fix warnings (#2978) 2024-12-01 17:41:34 +11:00
correctmost f578ac4ade
Remove unused argument from GlobalMenu._get_menu_options (#2977) 2024-12-01 17:41:03 +11:00
correctmost eacc28d577
Remove unused argument from AbstractCurses._confirm_interrupt (#2976) 2024-12-01 11:13:04 +11:00
correctmost a8fad93ae0
Add missing typing.override annotations reported by Pyright (#2974)
This commit also removes duplicated code in Viewport._replace_str.
2024-12-01 11:01:16 +11:00
correctmost e33ac034dc
Replace deprecated stage name in pre-commit config (#2975)
This commit fixes the following warning:

"top-level `default_stages` uses deprecated stage names (commit)
which will be removed in a future version."
2024-12-01 11:01:02 +11:00
correctmost 6a6642a9c1
Replace some Any instances with specific type hints (#2973) 2024-12-01 09:17:10 +11:00
correctmost 0a1d036750
Remove unused VersionDef class (#2972)
This allows the comparison-with-callable pylint rule to be enabled.
2024-12-01 08:40:38 +11:00
renovate[bot] cdd9e0cbcc
Update pre-commit hook astral-sh/ruff-pre-commit to v0.8.1 (#2956)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-11-30 22:57:01 +11:00
correctmost 007f2ff797
Use TypedDict to annotate disk-related serializations (#2935) 2024-11-30 22:56:46 +11:00
correctmost 11f8490b59
Enable the bad-indentation pylint rule and fix space indentations (#2968) 2024-11-30 22:54:53 +11:00
correctmost 1e6492d34a
Enable the printf-string-formatting ruff rule and fix warnings (#2967) 2024-11-30 22:54:20 +11:00
correctmost b0222111f5
Enable the redefined-builtin pylint rule and fix warnings (#2966) 2024-11-30 22:53:54 +11:00
renovate[bot] 6f42eba2f4
Update dependency ruff to v0.8.1 (#2955)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-11-30 22:52:03 +11:00
correctmost 604526c3c8
Enable the f-string ruff rule and fix warnings (#2965) 2024-11-30 20:03:09 +11:00
correctmost d4c04a83a3
Enable the redefined-outer-name pylint rule and fix warnings (#2964) 2024-11-30 20:01:38 +11:00
correctmost 544400606f
Enable mypy checks for tests/ files (#2963) 2024-11-30 20:00:35 +11:00
correctmost 2825818af6
Enable useless-parent-delegation pylint rule and fix warnings (#2962) 2024-11-30 19:59:28 +11:00
correctmost 45bc9c2e65
Use the ruff version specified in pyproject.toml for CI checks (#2960)
Previously, the ruff system package was used, which could lag
behind the PyPI version.
2024-11-30 19:58:10 +11:00
correctmost 80eebcff4f
Enable the explicit-f-string-type-conversion rule and fix warnings (#2954) 2024-11-29 06:43:13 +11:00
renovate[bot] 7b291a6681
Update dependency pydantic to v2.10.2 (#2942)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-11-28 22:45:34 +11:00
correctmost e3ff449bc4
Enable the Ruff-specific ruleset (#2951) 2024-11-28 20:15:30 +11:00
correctmost f314b7be54
Replace some Any instances with specific type hints (#2950) 2024-11-28 20:14:58 +11:00
renovate[bot] 8646c9aac2
Update dependency pytest to v8 (#2941)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-11-27 18:05:12 +11:00
correctmost e49a679fb8
Enable pytest test runs on CI (#2947)
This commit also fixes fixture and test issues that caused failures.
2024-11-27 17:42:22 +11:00
correctmost a28fb27a7a
Use human-friendly names in mypy and Pylint ignore directives (#2946) 2024-11-27 06:48:38 +11:00
correctmost 7bdef2f017
Fix mypy warnings in tests/test_args.py (#2945) 2024-11-27 06:46:17 +11:00
Daniel Girtler 198efb5f53
Fix 2916 - Reinstate prompt in list menus (#2940)
* Reinstate prompt in list menus

* Ruff
2024-11-26 11:10:48 +01:00
Daniel Girtler e51f7adf21
Dataclasses for args and config (#2936)
* Introduce dataclass for arguments and configuration

* Update

* Update
2024-11-26 11:08:36 +01:00
correctmost f2bc5ff280
Remove unused Selector class (#2938)
The code is unused as of 88b91ae201.
2024-11-26 12:22:16 +11:00
correctmost ee2ed3fe54
Start using typing.override to annotate overridden methods and properties (#2934) 2024-11-25 19:51:16 +11:00
correctmost 8d807c08ee
Use precise type hints for most DeferredTranslation references (#2929)
The remaining "_: Any" instances will require accompanying code
changes.
2024-11-25 18:49:22 +11:00
correctmost 46e4e28294
Bump the minimum Python version to 3.12 (#2933) 2024-11-25 18:45:50 +11:00
correctmost 6c37ba68e2
Remove unused singleton utility code (#2931) 2024-11-25 18:45:01 +11:00
correctmost 9cabc981b2
Remove python-simple-term-menu installations from CI workflows (#2932)
The dependency is no longer needed as of 0f2e0095.
2024-11-25 08:26:09 +01:00
correctmost d89ae04e0e
Delete ignore directive for Ruff rule that was removed (#2928)
The unpacked-list-comprehension rule was removed in Ruff 0.8.0.
2024-11-25 14:25:53 +11:00
Anton Hvornum aa80f8cf41
Bump to version 3.0.1 (#2920) 2024-11-23 11:45:32 +01:00
codefiles 7eb1f47084
Use binary units (#2917) 2024-11-23 08:53:32 +01:00
Daniel Girtler 5c83e230df
Fix 2915 - Reinstate partition information in device selection (#2919)
* Fix regresion in device selection - show partition info

* Fix linting
2024-11-23 08:52:53 +01:00
ots25 41600aefa4
Add files via upload (#2912)
Update  and fix Arabic translation
2024-11-23 08:19:36 +11:00
renovate[bot] 4d1318e71a
Update pre-commit hook astral-sh/ruff-pre-commit to v0.8.0 (#2911)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-11-22 22:15:27 +11:00
renovate[bot] 4cbf0f49db
Update dependency ruff to v0.8.0 (#2910)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-11-22 22:15:11 +11:00
renovate[bot] 1579483193
Update dependency pydantic to v2.10.1 (#2901)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-11-22 22:05:11 +11:00
Thierry M b2b3a728a0
Update base.po (French) (#2907)
Hello,
Here is the update on the French language.
Best regards,
Roxfr
2024-11-22 19:07:11 +11:00
codefiles f5447e91c4
Increase suggested root partition size (#2905) 2024-11-22 07:23:21 +11:00
codefiles bda0752eec
Change partition flag name Boot -> BOOT (#2903) 2024-11-21 12:22:50 +11:00
codefiles 7fd726f03f
Fix log disk states (#2902) 2024-11-21 10:50:43 +11:00
utuhiro78 1464806f18
Update Japanese translation (#2900) 2024-11-21 09:01:09 +11:00
codefiles 0eac05cecc
Add linux-home partition flag (#2898) 2024-11-20 15:32:29 +01:00
codefiles 611af783aa
Fix partition flag value (#2897) 2024-11-20 14:49:34 +01:00
codefiles 83d222cec6
Rework partition flag (#2895) 2024-11-20 07:55:09 +01:00
codefiles 3453816b38
Fix hostname None (#2893) 2024-11-20 16:32:05 +11:00
walken f827851560
Czech localization update (#2891) 2024-11-20 13:04:56 +11:00
Hugo Carvalho 1e3fb257a2
Update portuguese translation (#2886) 2024-11-19 23:41:57 +01:00
codefiles 4f704b8501
Refactor partition type GUID (#2890) 2024-11-19 23:41:27 +01:00
Daniel Girtler 20cc124a6d
Fix seat-access selection (#2885)
* Fix seat-access selection

* Format import
2024-11-19 14:50:16 +01:00
BringBack1800s 69b443c1ad
Update hyprland.py (#2879) 2024-11-19 18:49:16 +11:00
summoner001 68a221ea1b
Update hungarian translation (#2884)
Fixing the „custom” word coherence.
Fixing mispelled „zram” -> zRam
2024-11-19 18:48:41 +11:00
codefiles f19f35897b
Add _get_key_file() (#2882) 2024-11-19 18:37:24 +11:00
codefiles 594ca3504f
Fix btrfs skip mount options (#2881) 2024-11-19 18:36:31 +11:00
Odyssey f034c3693c
Update Catalan translation (#2883) 2024-11-19 18:31:11 +11:00
correctmost f3f7700945
Remove unused Any instances from TYPE_CHECKING blocks (#2878)
This will make it easier to start removing more Any instances from
the codebase.
2024-11-19 18:30:41 +11:00
correctmost 3255744278
Sort and format remaining imports (#2877)
This commit also enables isort rules in the Ruff config.
2024-11-19 11:18:47 +11:00
correctmost 955b2cfc3e
Sort and format imports in lib/disk/ (#2875) 2024-11-18 23:29:56 +01:00
correctmost b3421c0a82
Sort and format imports in scripts/, tui/, and top-level files (#2874) 2024-11-19 08:16:38 +11:00
correctmost 0aa6dcc78e
Sort and format imports in examples/ and default_profiles/ (#2873) 2024-11-19 07:54:17 +11:00
Anton Hvornum d3fa738bdd
Changed the invitation link to discord to go from #general to #help channel, as it's not always given how discord works (#2870) 2024-11-19 07:51:33 +11:00
correctmost 7776f82cbc
Reduce the max line length from 220 to 160 by wrapping some lines (#2867)
This will make it easier to auto-format import sections.
2024-11-19 07:50:53 +11:00
utuhiro78 89425912b9
Update Japanese translation (#2869) 2024-11-18 22:01:18 +11:00
correctmost 80b4dab092
Remove remaining Optional and Union usage from the codebase (#2868) 2024-11-18 20:59:08 +11:00
correctmost 97d6d84c3c
Replace most Union[] instances with pipe syntax (#2843) 2024-11-18 20:07:14 +11:00
correctmost 9626965982
Remove remaining deprecated typing.Dict and typing.List usage (#2859) 2024-11-18 20:02:35 +11:00
Daniel Girtler 41e5a0fcfd
Fixes 2849 (#2862) 2024-11-18 09:54:29 +01:00
Daniel Girtler f648eb6d66
Fix 2860 (#2863) 2024-11-18 09:52:32 +01:00
correctmost d79e082837
Remove outdated formatting note from contributors doc (#2857)
Binary operators are formatted consistently as of 6102a08c.
2024-11-18 09:04:44 +11:00
codefiles 6ca80d1fd7
Fix partition creation size end (#2858) 2024-11-18 09:04:12 +11:00
codefiles 8fc3dc4358
Parse lsblk data with pydantic (#2775) 2024-11-18 07:42:09 +11:00
Franco Castillo 74fd463873
Update Spanish translation (#2853) 2024-11-18 07:22:21 +11:00
summoner001 0c9064d6ad
Update Hungarian Translation (#2852)
Translate new strings
2024-11-18 07:22:04 +11:00
codefiles 80bba6c52b
Fix partition creation default size (#2856) 2024-11-18 07:20:12 +11:00
codefiles fad97e8465
Fix EditMenu input text (#2855) 2024-11-18 07:18:42 +11:00
utuhiro78 5aa73a5edc
Update Japanese translation (#2854) 2024-11-18 07:17:49 +11:00
Luna Jernberg 242ecc1ed2
Update base.po (#2848)
Update Swedish translation for 3.0
2024-11-17 12:07:38 +01:00
Anton Hvornum c16df5d80e
Bump to version 3.0.0 (#2847) 2024-11-17 10:02:51 +01:00
codefiles 68e2d8c3fa
Fix _mount_luks_partition() (#2838) 2024-11-17 09:40:52 +01:00
correctmost 80ad332d31
Enable multiple-statements-on-one-line-colon rule and fix warnings (#2845) 2024-11-17 19:39:14 +11:00
correctmost f783042e28
Only skip unused-import checks in __init__.py files (#2844)
This will help catch unused imports in other files when using Ruff.
2024-11-17 12:08:51 +11:00
correctmost f13f3d53b6
Enable arguments-renamed Pylint rule and fix warnings (#2842) 2024-11-17 11:03:18 +11:00
correctmost 0dc77f8e8a
Replace more Optional instances with union syntax in lib/ (#2841) 2024-11-17 11:01:57 +11:00
correctmost 57e4362a49
Remove unreachable return statement in _handle_interrupt (#2840) 2024-11-17 11:00:16 +11:00
correctmost 6383b5e82f
Replace Optional with union syntax in scripts/ and tui/ (#2839) 2024-11-17 09:49:10 +11:00
correctmost 25172bd0f8
Start replacing Optional with union syntax in lib/ (#2837) 2024-11-17 09:03:01 +11:00
correctmost 8cda091e6d
Start replacing Optional with union syntax (UP007 rule in Ruff) (#2836) 2024-11-17 09:02:08 +11:00
Anton Hvornum 58e4a94fdf
Converting systemctl call to a simple ln call for debus reasons (#2835)
* Converting systemctl call to a simple ln call for debus reasons #2764
2024-11-16 18:55:21 +01:00
correctmost 87fe1dbd8a
Enable most of the pyupgrade checks in Ruff (#2834) 2024-11-16 21:21:10 +11:00
correctmost 9bed81522d
Fix unnecessary-class-parentheses (UP039) Ruff warning (#2833) 2024-11-16 20:55:17 +11:00
correctmost b96194d51a
Fix super-call-with-parameters (UP008) Ruff warning (#2832) 2024-11-16 20:54:46 +11:00
correctmost 44eb7f92e9
Fix useless-object-inheritance (UP004) Ruff warning (#2831) 2024-11-16 20:54:14 +11:00
correctmost d644b5cae2
Replace deprecated socket.error exception with OSError (#2830)
This warning was raised by the UP024 rule in Ruff.
2024-11-16 20:53:43 +11:00
Daniel Girtler 0f2e00952f
Remove redundant simple-term-menu package (#2824)
* Remove redundant simple-term-menu package

* Update PKGBUILD

Added missing python package (this simply reflects a change in upstream PKGBUILD)

---------

Co-authored-by: Anton Hvornum <torxed@archlinux.org>
2024-11-16 10:53:33 +01:00
correctmost 2d6eef4672
Fix redundant-open-modes (UP015) warnings from Ruff (#2828) 2024-11-16 20:52:55 +11:00
correctmost 44f4bc8612
Use union syntax for isinstance checks (UP038 rule in Ruff) (#2829) 2024-11-16 10:47:01 +01:00
Daniel Girtler b61b5c82fa
Simplify translation call in f-string (#2826) 2024-11-16 10:46:33 +01:00
correctmost 2408b597be
Enable the E128 flake8 rule for all code except for __init__.py (#2827)
This commit also fixes a few files that had non-uniform indentation.
2024-11-16 19:34:29 +11:00
correctmost 6102a08c6d
Enable the W504 binary operator rule in flake8 (#2825) 2024-11-16 18:57:08 +11:00
correctmost 3d2673ac78
Enable the Pylint-warnings rules in Ruff (#2823)
The rule implementations can differ between Ruff and Pylint, so
enable them both for maximum coverage.
2024-11-16 18:28:00 +11:00
correctmost ecad6762e5
Fix some mypy warnings in the lib/ directory (#2822) 2024-11-16 18:27:26 +11:00
correctmost c682ddf391
Enable the E123 closing bracket rule in flake8 (#2812) 2024-11-16 18:23:52 +11:00
goose3228 a0d88f5ee2
Warn user when UEFI is disabled (#2806) 2024-11-16 18:23:08 +11:00
correctmost a71fe41585
Remove unnecessary mypy overrides for lib/models/mirrors.py (#2821) 2024-11-16 17:07:49 +11:00
correctmost 1af5135013
Enable the flake8-implicit-str-concat Ruff rules (#2819) 2024-11-16 17:07:14 +11:00
correctmost 3b3dca7bc1
Enable the UP025 Ruff rule to flag unnecessary Unicode prefixes (#2820) 2024-11-16 14:04:15 +11:00
correctmost 01b72b9293
Remove most of the remaining deprecated typing imports (#2818) 2024-11-16 14:01:24 +11:00
correctmost e23e5e7f2a
Enable stricter global mypy defaults (#2817)
Some checks only need to be disabled for the lib/ directory now.
2024-11-16 13:56:43 +11:00
correctmost a4935bdd10
Fix mypy warnings in the tui/ directory (#2816) 2024-11-16 12:00:31 +11:00
correctmost 316711d261
Enable flake8-datetimez and flake8-future-annotations Ruff checks (#2815) 2024-11-16 11:59:09 +11:00
correctmost 091a070e4e
Enable the f-string-without-interpolation Pylint rule (#2814) 2024-11-16 11:58:23 +11:00
correctmost c87c723549
Remove most deprecated typing.Dict usage (#2813) 2024-11-16 11:57:46 +11:00
correctmost d9fa2718ec
Make mypy checks more strict for lib/ and tui/ directories (#2811) 2024-11-16 10:14:25 +11:00
correctmost dff101e279
Remove most deprecated typing.List usage (#2810) 2024-11-16 10:13:51 +11:00
renovate[bot] 360118f68f
fix(deps): update dependency ruff to v0.7.4 (#2808)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-11-16 08:31:58 +11:00
renovate[bot] 3ec4b86409
chore(deps): update pre-commit hook astral-sh/ruff-pre-commit to v0.7.4 (#2807)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-11-16 07:48:30 +11:00
correctmost 1b40067e5a
Enable the expression-not-assigned Pylint rule (#2809)
Commit 88b91ae201 fixed the last instance that existed in the
codebase.
2024-11-16 07:47:59 +11:00
Daniel Girtler 88b91ae201
Integrate new curses menu (#2663)
* Edit text menu

* Fix alignment

* Scroll functionality

* Fix flake8

* Migrate locales menu

* Fix language translation

* Fix interrupt

* Fix flake8

* Edit mode preset

* Convert print to tui prints

* Fix mypy

* Fix cycling through long menu

* Fix profile view

* Fix scrolling

* Fix scrolling

* Fix mypy

* Fix swiss script

* Display asterisk for passwords

* Corrected a variable usage in the local mirror parsing

* Made sure that curses menu selection on mirrors use url object from mirror.url instead of the class instance

* Fixed mypy type on mirror list

---------

Co-authored-by: Torxed <torxed@archlinux.org>
2024-11-15 08:23:22 +01:00
Jack Desert 591b8317ea
Notify user of LOG_PATH upon completion (#2804)
Co-authored-by: jack <jack>
2024-11-15 13:56:54 +11:00
Thiago Castro 040a6aba27
Package name correction 'xss-lock', i3.py (#2796)
Package name correction 'xss-lock' needed in the base installation of the i3 desktop.

Link to the caused error and related issue:
Issue: https://github.com/archlinux/archinstall/issues/2790
Pull: https://github.com/archlinux/archinstall/pull/2791
Man: https://man.archlinux.org/man/xss-lock.1
2024-11-11 10:57:50 +11:00
Daniel Girtler 28eaa8c0e4
Wait for LVM info to appear (#2778)
* Wait forever for LVM info

* Update
2024-11-09 14:20:25 +01:00
Jack Desert de664dfa39
Include xss-set when installing i3wm (#2791)
Co-authored-by: jack <jack>
2024-11-09 10:16:15 +01:00
Anton Hvornum 4a9aca2f78
Added missing package dependencies related to fs-operations (#2792) 2024-11-09 10:01:25 +01:00
Daniel Girtler 9951c90bf9
Fix local mirror selection (#2789) 2024-11-09 09:49:23 +01:00
renovate[bot] fbc9431697
fix(deps): update dependency ruff to v0.7.3 (#2785)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-11-09 07:48:01 +11:00
renovate[bot] c8333ee2a6
chore(deps): update pre-commit hook astral-sh/ruff-pre-commit to v0.7.3 (#2784)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-11-09 07:36:39 +11:00
Vincent 26cf04655a
Document LUKS encryption password in creds-sample.json (#2782) 2024-11-08 07:35:50 +11:00
Vincent 7098a6a848
Document network config in config-sample.json (#2781)
Specifically document the CIDR notation of the IP address
2024-11-07 16:17:32 +01:00
Daniel Girtler 0f4e76f142
Update pre-commit hooks (#2777)
* Add missing pydantic dependencies to pre-commit mypy hook

* Add pylint to pre-commit checks
2024-11-07 13:33:34 +01:00
Daniel Girtler 83ece36ec3
Ignore disk encryption config when no password found (#2779) 2024-11-07 13:08:42 +01:00
correctmost 0370e893ac
Enable the self-assigning-variable Pylint warning (#2772) 2024-11-04 18:34:05 +01:00
Vincent 11987a06d6
Update config-sample.json to comply with the requirements for version 2.8.6 (#2754)
I did not add the 'dev_path' key to each one of the partitions, as this may not be required in the 'default_layout' section, but it was required in my configuration when I chose 'manual_partitioning'.
2024-11-04 14:35:44 +01:00
correctmost aecf3ea553
Add Pylint support and enable Pylint CI checks (#2658) 2024-11-04 14:30:28 +01:00
Suica e3123671bf
Retry when speedtest fails. (#2657) 2024-11-04 12:59:39 +01:00
Daniel Girtler 996b75e18c
Fix issue link reference (#2752) 2024-11-04 12:44:22 +01:00
Daniel Girtler 3d5aa1bd84
Add auto-merge for dev tools (#2749) 2024-11-04 12:43:32 +01:00
Daniel Girtler 4a06131f4d
fix-2740 - Handle empty iface selection (#2747) 2024-11-04 12:42:54 +01:00
Daniel Girtler 6553967be6
Add FAQ entry for keyring out-of-date (#2746)
* Add FAQ for keyring out-of-date

* Update

* Update
2024-11-04 12:42:36 +01:00
Daniel Girtler 918ac5c765
Fix 2735 - Erase luks partition explicitly (#2745) 2024-11-04 12:42:12 +01:00
codefiles 7437668f1e
Handle lsblk output bytes in json.loads() (#2741) 2024-11-04 12:39:31 +01:00
codefiles 481b570dae
Move logging code outside of command execution try-except block (#2739) 2024-11-04 12:38:58 +01:00
Daniel Girtler 8ec1715eb8
Fix 1716 - Retry on mirror list fetching (#2736)
* Fix 1716 - retry on http calls

* Update

* Update
2024-11-03 21:46:08 +01:00
renovate[bot] 69294e1f9f
fix(deps): update dependency ruff to v0.7.2 (#2767)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-11-02 18:51:14 +11:00
renovate[bot] c54d499ae4
chore(deps): update pre-commit hook astral-sh/ruff-pre-commit to v0.7.2 (#2766)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-11-02 18:51:00 +11:00
Aindriú Mac Giolla Eoin 2fab780c74
Added Irish/Gaeilge to installer languages (#2761) 2024-10-31 10:39:57 +11:00
Hugo Carvalho b3249badf3
Update Portuguese translation (#2763)
Improvements and corrections
2024-10-31 09:49:05 +11:00
Favilances 59384615a5
Update Turkish translation (#2760) 2024-10-28 22:13:28 +11:00
renovate[bot] 551807fbe9
chore(deps): update pre-commit hook astral-sh/ruff-pre-commit to v0.7.1 (#2759)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-10-25 10:21:55 +11:00
renovate[bot] eaff04a84f
chore(deps): update dependency ruff to v0.7.1 (#2758)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-10-25 10:21:39 +11:00
renovate[bot] 51ce724562
chore(deps): update pre-commit hook pre-commit/mirrors-mypy to v1.13.0 (#2753)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-10-24 08:15:24 +11:00
renovate[bot] 2c4a62c049
chore(deps): update dependency mypy to v1.13.0 (#2751)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-10-23 22:15:21 +11:00
renovate[bot] d91b6568c2
chore(deps): update pre-commit hook pre-commit/mirrors-mypy to v1.12.1 (#2743)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-10-21 21:57:49 +11:00
renovate[bot] 912c9c5a83
chore(deps): update dependency mypy to v1.12.1 (#2742)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-10-20 22:29:16 +11:00
renovate[bot] 292569c64f
chore(deps): update pre-commit hook astral-sh/ruff-pre-commit to v0.7.0 (#2738)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-10-18 08:21:40 +11:00
renovate[bot] eb44bc8eb9
chore(deps): update dependency ruff to v0.7.0 (#2737)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-10-18 08:21:24 +11:00
summoner001 b8f0944b19
Update hungarian translation (#2733)
Minor fixes and polishing the text.
2024-10-16 07:48:35 +11:00
renovate[bot] 57bfe2da42
chore(deps): update pre-commit hook pre-commit/mirrors-mypy to v1.12.0 (#2732)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-10-15 22:23:59 +11:00
renovate[bot] abfdc1e73a
chore(deps): update dependency mypy to v1.12.0 (#2731)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-10-15 08:00:57 +11:00
Jakub Klinkovský fa0cd4ff9d
docs: remove line block markup (#2729)
I don't see a point in using [line blocks][1] anywhere in the
documentation. Note that mandoc consequently renders it with a `<pre>`
tag which looks ugly on [man.archlinux.org][2].

Also simplified the URL in `index.rst` which can be written verbatim
without any special markup.

See this [archmanweb issue][3] for details.

[1]: https://docutils.sourceforge.io/docs/ref/rst/restructuredtext.html#line-blocks
[2]: https://man.archlinux.org/man/archinstall.1
[3]: https://gitlab.archlinux.org/archlinux/archmanweb/-/issues/49#note_213730

Co-authored-by: Jakub Klinkovský <1289205+lahwaacz@users.noreply.github.com>
2024-10-14 09:59:08 +11:00
summoner001 e452804625
Update hungarian translation (#2730)
fix misspells
fix coherence in the sentences
simplifying senteces
make more corence with other linux installers (example: ubiquity, calamares)
2024-10-14 09:56:04 +11:00
renovate[bot] e749e67a84
chore(deps): update dependency pre-commit to v4.0.1 (#2724)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-10-10 07:49:32 +11:00
Luna Jernberg a061e8e4f3
Update and Complete -- Swedish Translation (#2725)
* Update base.po

Found a typo when installing Arch Linux to a couple of new NVMEs from Seagate/WD from Inet/Webhallen yesterday and today, found a typo fixed a typo, added some more Swedish while i was at it

* Update base.po

Update and complete Swedish Translation
2024-10-09 12:20:49 +11:00
renovate[bot] 9cf19a7dd0
chore(deps): update pre-commit hook pre-commit/pre-commit-hooks to v5 (#2722)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-10-06 11:15:50 +11:00
renovate[bot] d9abf9d5b7
chore(deps): update dependency pre-commit to v4 (#2721)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-10-06 11:15:35 +11:00
renovate[bot] 1a56c86c8a
chore(deps): update pre-commit hook astral-sh/ruff-pre-commit to v0.6.9 (#2719)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-10-05 08:20:52 +10:00
renovate[bot] 0fd306b257
chore(deps): update dependency ruff to v0.6.9 (#2718)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-10-05 08:20:04 +10:00
Luna Jernberg 155610add0
Update base.po (#2717)
Found a typo when installing Arch Linux to a couple of new NVMEs from Seagate/WD from Inet/Webhallen yesterday and today, found a typo fixed a typo, added some more Swedish while i was at it
2024-10-04 07:43:20 +10:00
codefiles 661328767c
Exclude archiso loop device (#2715) 2024-10-03 16:11:20 +10:00
Rafael Fontenelle 92079b0e8e
Do not try to update github-pages on pull_request (#2711) 2024-10-02 07:25:15 +10:00
Rafael Fontenelle 4959c76c34
Fix PyPI name and installing from, in python.rst (#2710) 2024-10-02 07:21:49 +10:00
summoner001 a93bac15da
Fixing hungarian translation (#2709)
Minor fix
2024-10-02 07:20:47 +10:00
summoner001 7341383d90
Fixing hungarian translation (#2702)
Fixing hungarian translation
2024-09-29 12:05:16 +10:00
codefiles 1682574905
Remove duplicate sector_size (#2701) 2024-09-28 09:39:45 +10:00
renovate[bot] 15ccdd34a6
chore(deps): update pre-commit hook astral-sh/ruff-pre-commit to v0.6.8 (#2700)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-27 06:45:16 +10:00
renovate[bot] f0672b011e
chore(deps): update dependency ruff to v0.6.8 (#2699)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-27 06:45:06 +10:00
codefiles 8db3c7d65d
Add get_loop_devices() (#2698) 2024-09-25 23:02:51 +10:00
codefiles 8e9b1bc727
Remove lsblk default columns (#2697) 2024-09-24 09:57:45 +10:00
codefiles ff3b44e191
Remove import of pyparted _ped (#2696) 2024-09-23 11:51:54 +10:00
renovate[bot] 5526e39679
chore(deps): update dependency ruff to v0.6.7 (#2694)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-22 10:04:06 +10:00
renovate[bot] 11427ceee9
chore(deps): update pre-commit hook astral-sh/ruff-pre-commit to v0.6.7 (#2695)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-22 10:03:55 +10:00
K.B.Dharun Krishna 3d5fa9270d
po: update Tamil translation (#2693) 2024-09-22 07:35:52 +10:00
summoner001 db3c86dd86
Update Hungarian translation (#2692)
Minor sentence fixes
2024-09-22 07:35:33 +10:00
renovate[bot] 92db197f75
Update dependency ruff to v0.6.6 (#2690)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-21 17:50:06 +10:00
renovate[bot] 9deb8c081a
Update pre-commit hook astral-sh/ruff-pre-commit to v0.6.6 (#2691)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-21 17:49:45 +10:00
renovate[bot] a1c9e1cf8d
Update dependency pydantic to v2.9.2 (#2688)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-18 07:14:13 +10:00
renovate[bot] 3f2b4c1e55
Update pre-commit hook astral-sh/ruff-pre-commit to v0.6.5 (#2683)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-14 08:09:11 +10:00
renovate[bot] 9de2df7ef0
Update dependency ruff to v0.6.5 (#2682)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-14 08:08:48 +10:00
renovate[bot] 3c94e96064
Update dependency pydantic to v2.9.1 (#2677)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-09 21:55:18 +10:00
codefiles a45bd248c7
Convert lsblk mountpoint str to Path object (#2676) 2024-09-09 07:28:09 +10:00
correctmost 7235e21c3a
Remove some deprecated typing.Dict and typing.List usage (#2673) 2024-09-08 08:10:38 +10:00
correctmost 6ba0e5c441
Fix minor copy/paste errors in GitHub workflow configs (#2672) 2024-09-08 08:08:55 +10:00
codefiles 876d155be9
Move device after options in lsblk command (#2670) 2024-09-07 09:26:27 +10:00
codefiles 6a2a204f18
Add udev_sync() (#2669) 2024-09-06 23:29:12 +02:00
renovate[bot] 7c08822d08
Update dependency pydantic to v2.9.0 (#2667)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-06 11:50:46 +10:00
renovate[bot] 6857938ab0
Update pre-commit hook astral-sh/ruff-pre-commit to v0.6.4 (#2666)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-06 10:54:32 +10:00
renovate[bot] a817fe2404
Update dependency ruff to v0.6.4 (#2665)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-06 10:54:16 +10:00
Thierry Massart 6a7a65f619
French language update (#2664)
A translated word
2024-09-03 16:46:52 +10:00
renovate[bot] 342122e0b0
Update pre-commit hook astral-sh/ruff-pre-commit to v0.6.3 (#2661)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-08-30 02:24:49 +10:00
renovate[bot] 588d69bd7d
Update dependency ruff to v0.6.3 (#2660)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-08-30 02:24:32 +10:00
correctmost 8391668a2e
Add ruff linting support (#2654) 2024-08-29 13:51:12 +02:00
Anton Hvornum 3d35da71df
Bumping version to: v2.8.6 (#2656) 2024-08-28 22:45:46 +02:00
correctmost 35c8eb3394
Fix unnecessary f-strings and enable flake8 rule (#2653) 2024-08-29 03:01:55 +10:00
correctmost 62b4099c8d
Fix whitespace issues detected by flake8 (#2652)
This commit also removes exclusions that are no longer needed.
2024-08-29 01:40:53 +10:00
correctmost 7b5f1f72f9
Expand mypy checks to include more files and more checks (#2651)
This commit also centralizes the mypy configuration in one spot.
2024-08-29 00:39:22 +10:00
correctmost 62d66e1caf
Fix most mypy errors in archinstall/scripts/, docs/, and the __init__ file (#2641) 2024-08-29 00:24:08 +10:00
Suica 0601708a02
Use `0` instead of `None` when the speedtest fails. (#2650) 2024-08-28 11:57:21 +02:00
Daniel Girtler 0fc9d6f4f4
Fix 2625 - server profile selection (#2647) 2024-08-28 09:41:37 +02:00
Anton Hvornum 74f4fb02cd
Bumping version to: v2.8.5 (#2645) 2024-08-28 07:57:05 +02:00
Anton Hvornum 905479c1b2
Added error handling for invalid certificates during speedtest. Also added a generic error handler to catch all network errors (#2644) 2024-08-28 07:50:13 +02:00
correctmost c7aeead7d2
Fix various mypy errors in archinstall/lib/ (#2640)
* Fix various mypy errors in archinstall/lib/

* Additional mypy fixes in archinstall/lib/ to pass CI checks
2024-08-28 05:43:54 +10:00
correctmost 63b4184f70
Fix most of the mypy errors in archinstall/lib/disk/ (#2639) 2024-08-28 05:40:51 +10:00
correctmost 1e7f1194d7
Fix most of the mypy errors in archinstall/tui/ (#2638) 2024-08-28 00:55:53 +10:00
correctmost 7835784be5
Fix most of the mypy errors in archinstall/default_profiles/ (#2636) 2024-08-27 15:07:49 +10:00
Franco Castillo 446aa44007
Update Spanish translation (#2635)
Signed-off-by: Franco Castillo <castillofrancodamian@gmail.com>
2024-08-27 04:20:33 +10:00
Anton Hvornum fe5e7cdbf7
Bumping version to: v2.8.4 (#2633) 2024-08-26 13:03:49 +02:00
Vasiliy Stelmachenok 3fa70722a9
Do not overwrite the contents of mkinitcpio.conf (#2532) 2024-08-26 12:57:45 +02:00
Anton Hvornum 9abd3a82cc
Added error handling for mirrors that time out mid-read (#2632) 2024-08-26 12:50:37 +02:00
summoner001 949337ddf3
Update Hungarian translation (#2630)
After testing Archinstal v2.8.3, I fixed some minor translation and typo mistakes.
Sorry for my mistakes.
This translation is ready to use.
2024-08-26 02:37:48 +10:00
Hugo Carvalho dd5cbc93fa
Update Portuguese translation (#2629) 2024-08-26 02:37:27 +10:00
renovate[bot] a55922cd56
chore(deps): update pre-commit hook pre-commit/mirrors-mypy to v1.11.2 (#2628)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-08-26 02:36:46 +10:00
Anton Hvornum 1097e5ca17
Bumping version to: v2.8.3 (#2627) 2024-08-25 10:20:32 +02:00
renovate[bot] 211ce2d65b
chore(deps): update dependency mypy to v1.11.2 (#2626)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-08-25 15:21:01 +10:00
codefiles 179ba3cd9a
Fix load_devices() lsblk (#2565)
* Fix load_devices() lsblk

* Add udev sync before load_devices() lsblk call
2024-08-23 17:22:26 +02:00
Odyssey b9183f4df3
Add Catalan translation (#2623) 2024-08-23 08:29:23 +02:00
codefiles d2acdb4977
Refactor create_btrfs_volumes() (#2621) 2024-08-22 16:41:10 +10:00
Anton Hvornum 6d0cf26eba
Added a advanced=bool flag to Profile() class and enabled it on the cosmic-epoch profile (#2619)
* Added a advanced=True flag to Profile() class, to be able to hide certain profiles behind --advanced

* Removed debugging sleep

* Made sure cosmic-greeter was hidden behind --advanced, and cleaned up --advanced checks on Profile()

* storage['arguments'] is not defined during code-init, falling back to sys.argv for cosmic-greeter check
2024-08-22 08:28:16 +02:00
utuhiro78 00eeae0abd
Update Japanese translation (#2620) 2024-08-21 17:49:37 +02:00
arlsdk ff24ceb8d4
#2587 Sugesstions for Cinammon default_profile (#2612) 2024-08-20 18:41:01 +10:00
summoner001 5707372bb4
Update hungarian translation (#2618)
Translating the new string

Ready to merge.
2024-08-19 13:48:29 +02:00
killertofus b1ead53846
added cosmic for a desktop (#2615)
* cosmic is out of the aur
2024-08-17 16:40:07 +02:00
Anton Hvornum f6776f3801
Bumping version to: v2.8.2 (#2616) 2024-08-17 10:07:02 +02:00
Daniel E Rodriguez Rivera 58d74ea237
Refactor Argument Parsing Logic (#2605)
* Update Spanish translation for 'greeter'

* Moved the os.execve call below the debug logging statement in SysCommandWorker

* Fix call to removed function in DesktopProfile class

* Refactor: Move precondition check for '=' to the beginning of the loop

This commit moves the check for the '=' element to the start of the while loop in the `parse_unspecified_argument_list` function. This change improves code readability and ensures that the precondition is evaluated before processing other elements, enhancing the overall flow of the argument parsing logic.

* Refactor: Remove redundant 'else' statement in argument parsing logic

This commit simplifies the control flow in the `parse_unspecified_argument_list` function by removing a redundant 'else' block. The logic is streamlined to improve readability and maintainability while preserving the original functionality. The removal of unnecessary nesting helps clarify the conditions under which elements are processed.

* Refactor: Remove redundant 'else' statement in argument parsing logic

This commit simplifies the control flow in the `parse_unspecified_argument_list` function by removing a redundant 'else' block. The logic is streamlined to improve readability and maintainability while preserving the original functionality. The removal of unnecessary nesting helps clarify the conditions under which elements are processed.

* Replace conditional validation with filtering

This commit modifies the `parse_unspecified_argument_list` function to filter out unwanted elements from the `unknowns` list instead of using a conditional check with an `if` statement. This change improves code readability and efficiency by utilizing list comprehension to create a new list that excludes elements equal to "=".
2024-08-05 12:38:53 +02:00
renovate[bot] 65b09ca618
chore(deps): update pre-commit hook pycqa/flake8 to v7.1.1 (#2608)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-08-05 07:34:38 +10:00
renovate[bot] 727368e09d
chore(deps): update dependency dev/flake8 to v7.1.1 (#2607)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-08-05 07:34:19 +10:00
mintsuki fed39f21c9
Updates for new Limine 8.x config filename and syntax (#2606) 2024-08-03 11:56:07 +02:00
Anton Hvornum 98518e444a
Use `/mirrors/status/json/` instead of `/mirrorlist/` to get mirror lists (#2599)
* Using JSON endpoint instead of ASCII endpoint for mirror listing, as the JSON endpoint is cached and easier to parse

* Added a TODO to handle unknown regional mirrors (which lacks info in the backend)

* Filtered out 'bad' mirrors. Also added a sorting mechanism that uses the mirrors 'score' rather than just the URL name. This will emulate the reflector.service/rankmirrors behavior and thus reducing the need to re-rank the mirrors.

* Added the ability to sort mirrors via latency or download speed using sorted(mirror_list, key=lambda mirror: (mirror.score, mirror.speed)) - but I have not implemented the sorting via the menu yet, and I have not integrated the new MirrorStatus model into the handling of URL's. I still need to figure out where the {region: [url, url]} is being used, so that i can convert to {region: [mirror.url, mirror.url]} logic.

* Converting MirrorStatus model to {mirror: [url, url]}

* Added debug information for /var/log/archinstall/install.log

* Fixing flake8

* Fixed issue where 'dead' mirrors have no score, and thus can't be round():ed

* Forgot to return model validation data after validation

* Improving debug/info output

* Reverting change in #2350 - Writing over instead of appending to mirrorlist

* Mirror URL's reported by the JSON endpoint does not contain the repo format, only the base location for the mirror. So we have to adjust for this.

* pydantic did not honor 'private' variables in 'before' model validator, had to change to 'after' instead.

* Sorted out mypy typing matching the new MirrorStatus model

* Added pydantic as a dependency, it's time!

* Updated workflow to include pydantic

* Added return values from model @property decorators.
2024-08-02 15:24:44 +02:00
NorwayFun 4af3b02707
po: Update Georgian translation (#2604)
* Add files via upload

* Update Georgian translation
2024-08-02 16:09:31 +10:00
Tristan d'Audibert a72d798ee6
fix(lib/installer.py) Patch mkinitcpio.conf with putting encrypt after keymap (#2601)
Signed-off-by: Tristan d'Audibert <tristan.daudibert@gmail.com>
2024-08-02 14:47:00 +10:00
renovate[bot] 997e28d8dd
Update pre-commit hook pre-commit/mirrors-mypy to v1.11.1 (#2603)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-31 21:00:28 +10:00
renovate[bot] 2f4bb97483
Update dependency dev/mypy to v1.11.1 (#2602)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-31 12:32:01 +10:00
Daniel E Rodriguez Rivera 74ba8fb3b4
Fix call to removed function in DesktopProfile class (#2596)
* Update Spanish translation for 'greeter'

* Moved the os.execve call below the debug logging statement in SysCommandWorker

* Fix call to removed function in DesktopProfile class
2024-07-30 21:55:34 +10:00
walken a5fd20595d
Czech localization update (#2597) 2024-07-30 21:52:34 +10:00
codefiles a2e539a2bd
Fix mount order (#2595) 2024-07-29 08:24:29 +02:00
Daniel E Rodriguez Rivera 3bdead0390
Reposition os.execve call to enable debug logging before child process termination (#2593)
* Update Spanish translation for 'greeter'

* Moved the os.execve call below the debug logging statement in SysCommandWorker
2024-07-29 08:16:46 +10:00
renovate[bot] 0e8efecfa1
Update dependency dev/pre-commit to v3.8.0 (#2594)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-29 08:15:37 +10:00
Daniel Girtler 32bc37545e
Upgrade mypy 1.11 (#2588)
* Upgrade mypy 1.11

* Update

* Update

* Remove TProfile type
2024-07-27 07:23:47 +10:00
Daniel E Rodriguez Rivera 494cc29a3f
Update Spanish translation for 'greeter' (#2592) 2024-07-26 07:37:41 +10:00
renovate[bot] 48f510bd37
Update pre-commit hook pre-commit/mirrors-mypy to v1.11.0 (#2582)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-23 18:05:00 +10:00
Wellinton Kricowski 552930a98a
PT BR translation improvements (#2586)
* Update pt-BR translation

* [pt_BR] locales_generator + translation improvements

* PT BR translation improvements
2024-07-23 15:55:43 +10:00
*=0=1=4=* 8ecc77992f
`disk.Size(1, disk.Unit.GiB, sector_size)` for issue #913 (#2583)
* `disk.Size(1, disk.Unit.GiB, sector_size)` for issue #913

* default boot sector size is same for all partition layouts
2024-07-23 14:33:45 +10:00
Alexmelman88 ef252f5d0a
Update Russian translation (#2578) 2024-07-20 17:16:16 +10:00
Wise 5c85026582
Update Turkish translation (#2577) 2024-07-19 07:19:36 +10:00
GandalfBaum12371723613 52a795da66
Corrected one translation and added some more (#2574) 2024-07-12 07:26:01 +10:00
Martin f3fa5d5dec
Run oxipng/svgo against the images to save 40KB (#2420) 2024-07-11 20:05:26 +02:00
renovate[bot] 48e46ac067
Update pre-commit hook pycqa/flake8 to v7.1.0 (#2573)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-11 20:03:33 +02:00
renovate[bot] 4bfefc5470
Update pre-commit hook pre-commit/mirrors-mypy to v1.10.1 (#2572)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-11 20:03:13 +02:00
GandalfBaum12371723613 490e67e832
Update base.po (#2571) 2024-07-11 20:03:00 +02:00
Daniel Girtler 713f23b7ad
Enable pre-commit renovate support (#2570) 2024-07-11 19:57:49 +02:00
Daniel Girtler b9ab1e2b16
Curses menu - Continued (#2569)
* Edit text menu

* Fix alignment

* Scroll functionality

* Fix flake8
2024-07-11 19:54:24 +02:00
Kenneth Seet 0f1c8ab4be
Update user permission check for --help (#2568)
* Update user permission check for --help

* Fix code style

* Fix code style

* Fix docstring

* Fix newline

* Fix newline

* Fix argument error

* Fix formatting
2024-07-11 11:43:58 +10:00
Alexmelman88 50d269957a
Update Russian translation (#2564) 2024-07-07 15:31:47 +10:00
Anton Hvornum cc4925855e
Adding bug and feature request templates (#2560) 2024-07-02 12:45:48 +02:00
K.B.Dharun Krishna 755ce76e31
l10n/po: update Tamil translation (#2551) 2024-06-28 17:54:19 +02:00
Franco Castillo 18478dcb20
Update base.pot and base.po (es) (#2552)
Signed-off-by: Franco Castillo <castillofrancodamian@gmail.com>
2024-06-28 17:54:02 +02:00
summoner001 3dce07f6ba
Fixing mistakes (#2555)
Fixing mistakes after testing Archinstall v2.8.1
2024-06-28 17:53:33 +02:00
utuhiro78 31917a7e94
Update Japanese translation (#2550) 2024-06-26 07:57:10 +10:00
summoner001 054701f991
Translation of the new strings (#2545)
Translation of the new strings and minor fixes.
2024-06-25 18:30:24 +10:00
Roxfr 79ddbf724f
Add files via upload (#2548) 2024-06-25 18:29:42 +10:00
renovate[bot] aae4c5d35b
Update dependency dev/mypy to v1.10.1 (#2549)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-06-25 12:03:40 +10:00
Anton Hvornum e938074123
Updated all language files in prep for release (#2544) 2024-06-23 10:16:49 +02:00
Anton Hvornum 354fa5a2e4
Bumping version to v2.8.1 (#2543) 2024-06-23 10:13:22 +02:00
summoner001 0af6cfbc35
Cleaning translation (#2541)
I fixing misspells, typos, and make the text more readable.
I have reworded it in several places to make it easier to understand, and to make it more similar to the Hungarian text of other more common Linux installers.

Ready to use.
2024-06-20 22:10:32 +10:00
renovate[bot] 8c9802078c
Update dependency dev/flake8 to v7.1.0 (#2537)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-06-16 08:53:41 +10:00
Daniel Girtler aa87fb1db5
Strict mypy - Phase 1 (#2533)
* Strict mypy for examples/
2024-06-13 21:35:54 +02:00
Daniel Girtler 9c5a66b145
Add beta label to LVM support (#2531) 2024-06-08 09:18:19 +02:00
arlsdk 4d35409a53
Improved Turkish Translation for archinstall (#2530) 2024-06-08 09:24:47 +10:00
Daniel Girtler 5c180f0741
New menu implementation with curses (#2506)
* TUI

* Fix menu iterating

* Add help menu

* Add column menu

* Fix filter

* Tweaked import statement

---------

Co-authored-by: Anton Hvornum <torxed@archlinux.org>
2024-06-06 22:31:15 +02:00
616C6C 6524ada762
Update base.po (#2528) 2024-06-05 07:36:46 +10:00
codefiles 6747c9e5d8
Skip devices that fail to get pyparted Disk (#2526) 2024-06-05 07:36:06 +10:00
Alexmelman88 b2d29eeba3
Update Russian translation (#2521) 2024-05-28 22:49:13 +10:00
Alexandre Petit 6b48d788b5
Update mkinitcpio.conf hooks for upstream consistency (#2515)
This commit adjusts the hooks in mkinitcpio.conf to follow the changes
in the upstream mkinitcpio repository.
It also add the consolefont hook if udev is used instead of systemd.

Addresses upstream commits:
[mkinitcpio.conf: add kms to the default HOOKS array](b99eb1c0d5)
[mkinitcpio.conf: adjust the placement of the modconf hook for consistency](0b052b1461)

Additionally, it replaces the missing `consolefont` hook if the
`keyboard` hook is used instead of the `sd-vconsole` hook.
For more details, see the Arch Wiki:
[dm-crypt/System configuration - 1.1 mkinitcpio](https://wiki.archlinux.org/title/Dm-crypt/System_configuration#mkinitcpio)
2024-05-25 17:57:04 +10:00
Raven 6863994118
Adds dosfstools to the PKGBUILD depends (#2439)
One of the tools needed by archinstall is mkfs.fatXX and this wasn't automatically installed.

Co-authored-by: Raven <github.onereddime@rubicon.aleeas.com>
2024-05-25 17:50:51 +10:00
AbderrazakBouasker ffe8279127
arabic translation updated and fully completed (#2518)
* added 50% of the translation

* 51% done

* completed arabic translation
2024-05-22 22:11:06 +10:00
codefiles cee32670f3
Refactor umount() (#2516) 2024-05-19 11:29:02 +10:00
codefiles 63cfee434e
Convert partition path string to a Path object (#2514) 2024-05-19 08:04:48 +10:00
codefiles 09fdb9e80c
Refactor format() (#2512) 2024-05-19 08:03:11 +10:00
codefiles 15ee84b7c9
Refactor suggest_single_disk_layout() (#2508) 2024-05-17 22:57:03 +10:00
Franco Castillo 8b8b668414
Update base.pot and base.po (es) (#2509)
Signed-off-by: Franco Castillo <castillofrancodamian@gmail.com>
2024-05-16 11:54:35 +10:00
ngn 39d096b79f
Use the current layout instead of the us layout (#2495)
* use the current layout instead of the us layout

* fix linting erros and add exception handling for SysCommand
2024-05-15 21:41:42 +10:00
Daniel Girtler bab06e4d75
Fix 2496 - umounting all partitions (#2498)
* Fix 2496 - umounting all partitions

* Update
2024-05-15 12:47:20 +02:00
codefiles 06baa08750
Set root partition type GUID (#2505) 2024-05-15 13:06:27 +10:00
arlsdk af9d741175
Turkish translate has been improved (#2502) 2024-05-15 12:16:24 +10:00
Anton Hvornum 195eb0ba6d
Fixing issue with `python -m build --wheel` generating "_Warning: Package 'archinstall.default_profiles' is absent from the `packages` configuration" (#2499)
* Fixing issue of: _Warning: Package 'archinstall.default_profiles' is absent from the 'packages' configuration. x50+

* Corrected the package name from 'where' to 'archinstall'

* Undoing change to 'package-data'
2024-05-13 15:17:05 +02:00
renovate[bot] 20f802dfc3
chore(deps): update dependency dev/pre-commit to v3.7.1 (#2497)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-11 16:27:04 +10:00
Anton Hvornum 3381cd5567
Changing to use github archive as dependency-url for pyparted as there hasn't been an update on pypi.org for pyparted in almost 12 months. Tracking issue https://github.com/dcantrell/pyparted/issues/106 (#2494) 2024-05-09 23:49:43 +02:00
Daniel Girtler fd23efdcfb
Fix 2479 - remove unnecessary partiton info field (#2485) 2024-05-09 23:06:06 +02:00
Kevin FERRIER 3af850632f
change default root partition size (#2415) 2024-05-09 13:37:38 +10:00
simonfogliato 9543f59a17
Corrected minor bash formatting warnings reported by shellcheck. (#2493) 2024-05-08 16:15:09 +10:00
Uday Jadhav e5b6f46032
Add applications to Hyprland desktop profile (#2481) 2024-05-05 15:08:03 +10:00
a 3ccb5140aa
Update base.po (#2468)
* Update base.po

* Update base.po

* update tr

* tr update
2024-05-02 08:14:51 +10:00
utuhiro78 b8052c566c
Update Japanese translation (#2478) 2024-04-27 08:47:05 +10:00
renovate[bot] eb36a94781
chore(deps): update dependency dev/mypy to v1.10.0 (#2476)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-25 10:12:15 +10:00
correctmost bf368a94f5
Fix debug message for unknown device type (#2472) 2024-04-24 07:32:57 +10:00
Roxfr 473074a945
Update for the french language (#2473) 2024-04-24 07:20:23 +10:00
Daniel Girtler beeb9d7fde
Fix 2191 - Handle unknown device/partition type (#2470) 2024-04-23 09:02:07 +02:00
Martin 0ea6dbbd76
Rename "Kde" profile to the correct "KDE Plasma" / "Plasma" (#2421)
* schema.json: Remove dead misspelled i3-gasp profile

* schema.json: Rename KDE Plasma profile to the correct "Plasma" shorthand

* Rename to KDE Plasma in user facing parts and keep the old "Kde" profile for now

* Add back an accidental deleted character

* Backwards compat v2
2024-04-19 22:47:18 +10:00
MahtiAnkka f7913f46ee
New Arch install Finnish language package (#2466)
Translated into Finnish using the Poedit program.
2024-04-17 22:14:12 +10:00
Daniel Girtler cd587792e1
Fix master merge conflicts from LVM branch (#2463) 2024-04-16 14:06:03 +02:00
Daniel Girtler db798eec71
Fix 2445 - handle no free spaces and deleted parittions (#2448) 2024-04-16 14:05:19 +02:00
Hao Xiang 8f5bc523db
Fix null fs_type of partition (#2458) (#2459) 2024-04-16 20:56:44 +10:00
renovate[bot] 5aa616e70d
chore(deps): update dependency dev/pre-commit to v3.7.0 (#2434)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-16 20:28:10 +10:00
summoner001 f4ce69b5c7
Update Hungarian translation (#2462)
After testing the text in the new version of Archinstaller.

I fixing misspells, typos, and make the text more readable.
I have reworded it in several places to make it easier to understand, and to make it more similar to the English text of other more common Linux installers.

Ready to use.
2024-04-16 20:02:02 +10:00
Martin 7011ac095f
Fix up locale generator to exit on error instead of ignoring it, handle filenames better (#2422)
Don't mix tabs and spaces, use tabs, just like the main script
2024-04-16 19:05:50 +10:00
renovate[bot] 3f4fbed7b7
chore(deps): update peaceiris/actions-gh-pages action to v4 (#2451)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-16 19:00:55 +10:00
Daniel Girtler b470b16ec9
LVM support (#2104)
* Submenu for disk configuration

* Update

* Add LVM manual config

* PV selection

* LVM volume menu

* Update

* Fix mypy

* Update

* Update

* Update

* Update

* Update

* Update

* Update

* Update

* Update LVM

* Update

* Update

* Btrfs support

* Refactor

* LVM on Luks

* Luks on LVM

* Update

* LVM on Luks

* Update

* Update

* mypy

* Update

* Fix bug with LuksOnLvm and Btrfs

* Update

* Update

* Info -> Debug output
2024-04-15 18:49:00 +10:00
Anton Hvornum 7d9e9d8ba0
Bumping version to: v2.8.0 (#2460) 2024-04-15 06:50:17 +02:00
utuhiro78 1542f6c027
Update Japanese translation (#2410) 2024-04-15 06:48:37 +02:00
K.B.Dharun Krishna 2c87f0e13c
l10n/po: update Tamil translation (#2392) 2024-04-15 06:48:27 +02:00
Alexmelman88 b3894c8d08
Update Russian translation (#2409) 2024-04-15 06:48:16 +02:00
Giovanni Scafora d265b2038e
Update Italian translation (#2414)
Update
2024-04-15 06:48:09 +02:00
Brock Vojkovic 4505f6febb
Switch from weekly official to daily official image (https://github.com/archlinux/archinstall/issues/2443) (#2453) 2024-04-11 07:33:00 +02:00
codefiles df2884085d
Add udev sync before lsblk that follows formatting (#2412) 2024-03-12 10:25:15 +01:00
codefiles 613bec6562
Fix GRUB boot directory (#2408) 2024-03-11 19:38:10 +01:00
codefiles c210cdcb8f
Fix Btrfs mount options (#2404) 2024-03-11 08:09:26 +01:00
codefiles 1064f74846
Increase ESP size to 1 GiB (#2401) 2024-03-10 15:20:13 +01:00
codefiles b87c41e92f
Fix fstab line endings (#2400) 2024-03-10 15:19:22 +01:00
codefiles 2a33d7cd97
Set keyboard layout in minimal installation (#2399) 2024-03-10 09:34:32 +01:00
renovate[bot] 635ae335be
chore(deps): update dependency dev/mypy to v1.9.0 (#2395)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-10 09:33:41 +01:00
codefiles 624d3d5bf6
Rename Hungarian translation files (#2398) 2024-03-09 21:35:20 +01:00
codefiles fef9269d38
Fix home partition start and length (#2391) 2024-03-08 11:24:35 +01:00
Franco Castillo c3c175047e
Update base.pot and Spanish translation (#2389)
Signed-off-by: Franco Castillo <castillofrancodamian@gmail.com>
2024-03-07 23:46:16 +01:00
fortifiedhill 85fda53847
Update microcode handling (#2384)
As of mkinitcpio v38, microcode is handled by a hook
and inserted into the initrd. Therefore, we don't have to
add microcode entries to bootloaders anymore.
2024-03-07 23:45:45 +01:00
renovate[bot] 1c071f3bb3
chore(deps): update dependency dev/mypy to v1.8.0 (#2308)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-07 15:10:19 +01:00
fortifiedhill 0e8d7aac16
Update resize root partition ArchWiki link (#2385) 2024-03-07 15:09:57 +01:00
renovate[bot] 214f82d43e
chore(deps): update actions/upload-artifact action to v4 (#2369)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-07 15:07:14 +01:00
renovate[bot] 3df7d91bff
chore(deps): update dependency simple-term-menu to v1.6.4 (#2303)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-07 15:06:41 +01:00
renovate[bot] e4f072315d
chore(deps): update dependency dev/pre-commit to v3.6.2 (#2297)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-07 15:06:29 +01:00
renovate[bot] 9ae1048262
chore(deps): update actions/setup-python action to v5 (#2289)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-07 15:06:19 +01:00
Daniel Girtler 08a6d402c4
Fix 2215 | Display installed packages for all profile submenus (#2355)
* Display all packages to be installed

* Display all packages to be installed
2024-03-07 14:43:51 +01:00
Daniel Girtler f927fb6e6a
Fix 2307 - Custom mirrors (#2350)
* Fix 2307 - Custom mirrors

* Update
2024-03-07 14:43:16 +01:00
Daniel Girtler 21dd295259
Fix 2337 (and similar) - Ignore existing partitions (#2342)
* Fix 2337

* Update
2024-03-07 14:42:25 +01:00
codefiles 9b1fd2e44f
Fix enabling of testing repositories (#2340) 2024-03-07 14:41:25 +01:00
codefiles b39e3dc886
Fix partition table commit (#2294) 2024-03-07 13:49:14 +01:00
aidanthewiz 1bf68311c2
Improve the README (#2174)
Co-authored-by: Anton Hvornum <anton@hvornum.se>
2024-03-07 13:47:45 +01:00
Rafael Fontenelle 0d5e1cf752
Fix misspellings (#2306) 2024-03-07 13:19:44 +01:00
Chaman Vétéran 98f2431728
fixed mistake in fr locale (#2295)
Co-authored-by: Chaman-veteran <maillen@bde.enseeiht.fr>
2024-03-07 13:17:03 +01:00
utuhiro78 169068d755
Update Japanese translation (#2291) 2024-03-07 13:16:47 +01:00
walken e1a50210b1
Czech localization update (#2366) 2024-03-07 12:58:48 +01:00
Ansh Goel e58892faec
po: Update Hindi translation (#2357)
* Added first Hindi language support

* po: Update Hindi translation
2024-03-07 12:58:34 +01:00
Yaron Shahrabani fbc005d2f1
Added Hebrew translation. (#2348)
* Added Hebrew translation.

* Updated README with simpler instructions

* cd instruction restored

Restored the required instruction.

---------

Co-authored-by: Yaron Shahrabani <yaron.shahrabrani@axonius.com>
2024-03-07 12:58:19 +01:00
summoner001 cea1ded104
Add Hungarian translation files (#2313)
The hungarian translation is complete and ready to use
2024-03-07 12:56:46 +01:00
Dominik Stasiak 1387652b7b
Update Polish translation (#2311) 2024-03-07 12:56:30 +01:00
Wise 6c2a0d9b97
Update translation of tr (#2299) 2024-03-07 12:56:10 +01:00
Rafael Fontenelle 2cd0d3fdad
Update Brazilian Portuguese translation (#2287) 2024-03-07 12:55:19 +01:00
Christos Longros d02b0d2359
Update greek base.po, add translations, fix typos (#2284)
* Update greek base.po, add translations, fix typos
2024-03-07 12:54:22 +01:00
Anton Hvornum 74476de1f1
Version bump 2.7.2 (#2387) 2024-03-07 12:27:26 +01:00
Dylan M. Taylor 8e25f2e992
plasma-workspace replaces plasma-wayland-session (#2386) 2024-03-07 07:49:51 +01:00
Alessio Cuccovillo f107104103
UPD it/LC_MESSAGES/base.mo (#2276)
UPD it/LC_MESSAGES/base.po
2023-12-01 16:17:38 +01:00
Florijan Demidov 7b0d092d6e
Add Lithuanian translation (#2274)
* Add Lithuanian translation

* Update languages.json
2023-12-01 16:17:14 +01:00
codefiles 5db4456dba
Restrict UKI to supported options (#2280) 2023-12-01 15:59:44 +01:00
codefiles 2aeb1b5762
Minor fixes for UKI (#2279) 2023-12-01 14:32:08 +01:00
codefiles dc477fb1d9
Fix UKI default value (#2278) 2023-12-01 13:03:13 +01:00
Anton Hvornum 4955b64a8c
Added --skip-ntp to docs (#2273) 2023-11-29 13:04:56 +01:00
Anton Hvornum c13d5fae05
Preparing release: v2.7.1 (#2272) 2023-11-28 17:02:54 +01:00
K.B.Dharun Krishna 8637cd06e7
po: update Tamil translation (#2271) 2023-11-28 10:13:39 +01:00
Hugo Carvalho e76ca0ad94
Update Portuguese (pt) translation (#2270) 2023-11-27 16:46:46 +01:00
Wellinton Kricowski 749efaca30
Update pt-BR translation (#2267) 2023-11-27 13:44:50 +01:00
utuhiro78 4aa8b9fc5b
Add Japanese translation (#2265)
* Add Japanese translation

* Update Japanese translation

* Update Japanese translation

* Update Japanese translation

* Update Japanese translation

* Update Japanese translation

* Update Japanese translation

* Update Japanese translation
2023-11-27 13:44:10 +01:00
Mário Victor Ribeiro Silva 8885d92485
build(gh-pages): change rule to docs build (#2269) 2023-11-27 13:41:34 +01:00
Daniel Girtler 5605958b98
Fixes #2262 and GFX rewrite (#2266)
* Rework GFX installation

* Update

* Update

---------

Co-authored-by: Daniel Girtler <girtler.daniel@gmail.com>
2023-11-27 13:31:26 +01:00
renovate[bot] 03c1989270
Update actions/setup-python action to v4 (#2236)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-11-24 08:13:41 +01:00
renovate[bot] f27c55d170
Update dependency dev/mypy to v1.7.1 (#2256)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-11-24 08:13:19 +01:00
Daniel Girtler b0c8f33de6
Fix 2253 (#2259)
Co-authored-by: Daniel Girtler <girtler.daniel@gmail.com>
2023-11-24 07:59:12 +01:00
Alan Barzilay f6446323fc
pyproject.toml: add missing dependencies (#2257)
we were missing 2 dependencies, pyparted and systemd-python(optional), that would lead pip installations to fail sometimes. 

I added them and attributed systemd_python to a new optional dependency group called log since it only seems to be used for system logging:

64c91cdbcb/archinstall/lib/output.py (L133)
2023-11-23 23:28:12 +01:00
renovate[bot] 64c91cdbcb
Update actions/checkout action to v4 (#2235)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-11-23 18:14:41 +01:00
renovate[bot] 61d549fbab
Update dependency dev/mypy to v1.7.0 (#2209)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-11-23 18:14:31 +01:00
Alexmelman88 084cffc363
Update Russian translation (#2254) 2023-11-23 17:25:34 +01:00
Anton Hvornum 62296cfa12
Prepare for release 2.7.0 (#2252)
* Preparing release

* Bumping version to: v2.7.0
2023-11-23 09:45:47 +01:00
walken 22e2b7fc29
Czech localization update (#2204)
* Updates and corrections for Czech localization
2023-11-23 09:42:40 +01:00
Roxfr e30654d497
French language update (#2219)
* Delete archinstall/locales/fr/LC_MESSAGES/base.po

* Delete archinstall/locales/fr/LC_MESSAGES/base.mo

* Add files via upload

* Rename archinstall/locales/base.po to archinstall/locales/fr/LC_MESSAGES/base.po

* Delete archinstall/locales/base.mo

* Add files via upload
2023-11-23 09:42:25 +01:00
Anton Hvornum a62f833332
Fixing --skip-ntp. Changed nargs -> action in argparse! (#2250) 2023-11-22 23:45:13 +01:00
Anton Hvornum 2437e901d9
Added a --skip-ntp parameter to deal with #2144 (#2225)
* Added a --skip-ntp parameter to deal with #2144

* Made info/warn strings translateable

* Corrected spelling mistake
2023-11-22 22:52:21 +01:00
Anton Hvornum e28ba95370
Restoring back the docs with a commit, as I'm clearly incapable of grasping git's reset/revert features.. (#2249) 2023-11-22 22:45:25 +01:00
Anton Hvornum f3b4858a26
Removed readthedocs.io's requirements.txt (#2248) 2023-11-22 22:36:58 +01:00
Anton Hvornum 1489883571
Removed requirements from .readthedocs.yaml, can we remove this file without readthedocs being sad? (#2247) 2023-11-22 22:35:51 +01:00
Anton Hvornum d7eb35f4ee
Nuking docs to allow for redirect (ouff) (#2245) 2023-11-22 22:24:29 +01:00
Anton Hvornum db326590ba
Redirect readthedocs (#2244)
* Adding permanent redirect for readthedocs

* Have to remove pyparted because readthedocs can't build it

* Removed pyparted from pyproject.toml as readthedocs read that one too afterall.
2023-11-22 22:12:29 +01:00
Anton Hvornum 8b774a9cfa
Redirect readthedocs (#2243)
* Adding permanent redirect for readthedocs

* Have to remove pyparted because readthedocs can't build it
2023-11-22 21:56:07 +01:00
Anton Hvornum bb67c5a3a9
Added nvidia-dkms when installing propri driver to (#2241)
* Added nvidia-dkms when installing propri driver to fix #2233, #2214 and #2002

* Forgot class-name infront of NvidiaDKMS
2023-11-22 21:52:27 +01:00
Anton Hvornum 2b3142527a
Adding permanent redirect for readthedocs (#2242) 2023-11-22 21:52:01 +01:00
Anton Hvornum 922f6082b5
Added a CNAME file, as well as removed some debugging (#2240) 2023-11-21 23:56:39 +01:00
Anton Hvornum e73ac39a7e
It appears jekyll might be needed? (#2239)
* It appears jekyll might be needed? https://github.com/peaceiris/actions-gh-pages#%EF%B8%8F-enable-built-in-jekyll-enable_jekyll

* Added some debugging

* Maybe jekyll is not needed?
2023-11-21 23:45:55 +01:00
Anton Hvornum 349c21d7a2
GitHub pages improvement (#2237)
* Moved to arch container

* Swapped branch for testing

* Removed publish if condition for now

* I think I got it this time, publish_branch has to be separate in order for the runner to create it and have access to pushing things?

* Missing 'git' depndency, to work with git heh
2023-11-21 23:02:47 +01:00
Anton Hvornum f02af54356
Testing github pages (#2234)
* Testing github pages

* Adding libparted-dev to the ubuntu machine (I'd like to move away from ubuntu, but the runner recommended it)

* Debugging

* changed to master branch
2023-11-21 22:27:10 +01:00
Anton Hvornum d62a5ff838
libparted -> pyparted (#2232) 2023-11-21 19:55:26 +01:00
Anton Hvornum 344b1cf296
Fix readthedocs runner (#2231)
* The new build system requires a requirements.txt

* .txt is in .gitignore, had to force it in

* Missing requirements. I don't like this odd side loading of requirements.. but need to get docs built quickly.
2023-11-21 19:52:53 +01:00
Anton Hvornum 5077219a5f
Fix readthedocs runner (#2230)
* The new build system requires a requirements.txt

* .txt is in .gitignore, had to force it in
2023-11-21 19:47:15 +01:00
Anton Hvornum f3ad97fc3f
The new build system requires a requirements.txt (#2229) 2023-11-21 19:42:31 +01:00
Anton Hvornum 40715549cb
Add sphinx-rtd-theme to conf.py (#2228)
* According to https://sphinx-rtd-theme.readthedocs.io/en/stable/installing.html - extension = [] needs to be added too

* Fixed wonky indentation
2023-11-21 19:34:02 +01:00
Anton Hvornum 9b2d192817
New format requires build.os instead of build.image (#2227) 2023-11-21 19:24:48 +01:00
Anton Hvornum 94ae8f800f
Renamed readthedocs file to comply with strict file endings (#2226) 2023-11-21 19:19:59 +01:00
Anton Hvornum cc806d9c4c
Started a re-write of the docs (#1967)
* Started a re-write of the docs, using CSV for tables and re-organizing parameter definitions

* Added final config options in --config, some have external references which needs to be populated

* Forgot to escape a comma

* Clarified a note

* Added disk configuration and disk encryption docs

* Changed way of installing using source and python

* Added a 'list script' that lists available scripts. This could be converted to a argparse later. But this does the trick for now. And it's added to ease documentation and listing of available options.

* Added a 'Known issues' section, as well as renamed the issues tab

* Finished up the known issues section

* Added a section regarding --plugin

* Added plugin description, tweaked disk_config to the latest changes from #2221

* Added custom-commands docs, and improved some creds and known issue links
2023-11-21 14:34:30 +01:00
czapek e6344f93f7
Fix Limine bootloader deployment (#2216)
* Add `get_unique_path_for_device` to `DeviceHandler`

* Fix Limine bootloader deployment

* Fail if UKI is enabled with Limine

* Support more configuration options with Limine

* Fix linter errors

* Fix boot partition fs_type check for Limine
2023-11-21 10:19:17 +01:00
codefiles f16af43949
Fix GPT end alignment (#2210) 2023-11-20 12:58:09 +01:00
codefiles f876ddc68e
Remove superfluous use of `partprobe` (#2212) 2023-11-20 12:56:12 +01:00
codefiles 6ee6d1eda0
Remove `select_language()` duplicate of `select_kb_layout()` (#2151)
* Remove `select_language()` duplicate of `select_kb_layout()`

* Added a deprecation warning on select_language()

* Moved select_language() back into it's original location, just to keep the PR diff minimal

* Removed import for now, to please flake8

---------

Co-authored-by: Anton Hvornum <anton@hvornum.se>
2023-11-20 12:55:45 +01:00
codefiles 30a374a65b
Fix parsing pre-mounted disk configuration from configuration file (#2221) 2023-11-20 12:54:04 +01:00
renovate[bot] f6106324eb
chore(deps): update dependency simple-term-menu to v1.6.3 (#2208)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-11-09 20:10:21 +01:00
renovate[bot] af6713e8df
chore(deps): update dependency simple-term-menu to v1.6.2 (#2203)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-11-09 12:50:26 +01:00
codefiles 940468117a
Fix logic error in `encrypt()` loop (#2207) 2023-11-09 12:47:30 +01:00
Wellinton Kricowski c9755b35e7
PT BR translation improvements (#2199) 2023-11-06 17:55:50 +01:00
codefiles 5b6cab27f1
Fix logic error in `_fetch_lsblk_info()` loop (#2196) 2023-10-31 17:57:59 +01:00
codefiles 2831c97338
Fix password preview (#2190) 2023-10-25 09:27:18 +02:00
Celestial.y 474861c155
Update translation of zh-CN (#2165) 2023-10-23 09:26:51 +02:00
renovate[bot] 78ab858b3b
chore(deps): update dependency dev/mypy to v1.6.1 (#2184)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-18 08:00:16 +02:00
Daniel Girtler ce9828c293
Fixes for prev PR (#2175)
* Fixes for prev PR

* Update

---------

Co-authored-by: Daniel Girtler <girtler.daniel@gmail.com>
2023-10-18 16:57:44 +11:00
codefiles 8117c0eed8
Fix EFISTUB `cmdline` (#2181) 2023-10-18 07:54:29 +02:00
codefiles bc3b3a35e6
Add support for unified kernel image (#1519) 2023-10-17 11:23:09 +02:00
codefiles 332ec0d623
Fix reset in locales menu (#2178) 2023-10-17 11:21:39 +02:00
codefiles 5dda32f17e
Refactor `_add_systemd_bootloader()` newlines (#2173)
* Refactor `_add_systemd_bootloader()` newlines

* Revert f-string change
2023-10-16 16:42:42 +02:00
Daniel Girtler c4c5cc4224
User error info and version check (#2169)
* Add user information for error

* Show output if newer version available

* Update

* Update

* flake8

---------

Co-authored-by: Daniel Girtler <girtler.daniel@gmail.com>
2023-10-15 20:26:27 +11:00
codefiles 07b0bb1835
Fix `MOUNT_POINT` for pre-mounted disk configuration (#2168) 2023-10-15 09:26:34 +02:00
renovate[bot] 3c2ed1c121
chore(deps): update dependency dev/pre-commit to v3.5.0 (#2164)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-13 20:44:04 +02:00
renovate[bot] d1ea6db9aa
chore(deps): update dependency dev/mypy to v1.6.0 (#2155)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-13 09:56:36 +02:00
codefiles 7930ea58fd
Fix install text initialization (#2162) 2023-10-13 18:50:35 +11:00
codefiles 5e59acf937
Add handling of signal interrupt and EOF at input prompts (#2154) 2023-10-10 10:00:22 +02:00
codefiles dc69acd4b4
Fix keyboard layout and timezone menus (#2153) 2023-10-09 21:40:59 +11:00
Daniel Girtler edbc135903
Extend the mypy checks (#2120)
* Extend the mypy checks

* Update

* Update

* Update

---------

Co-authored-by: Daniel Girtler <girtler.daniel@gmail.com>
2023-10-03 18:31:17 +11:00
Daniel Girtler 5c903df55f
Simplify SysCommand decoding (#2121) 2023-10-02 21:01:23 +11:00
Dylan M. Taylor a095e393d8
Fix ArchInstall ISO build (#2142) 2023-10-02 07:50:58 +02:00
codefiles 8257e9f73f
Fix missing info for pre-mounted disk configuration (#2143) 2023-10-02 07:50:20 +02:00
Ansh Goel 71048721ec
Added first Hindi language support (#2134) 2023-10-01 20:51:28 +11:00
Alexmelman88 66fd201045
Update Russian translation (#2136) 2023-10-01 20:51:04 +11:00
K.B.Dharun Krishna a34e374634
po: update Tamil translation (#2105)
* po: update Tamil translation

* po: update translation files

* po: update translation files, Tamil translation

* Revert "po: update translation files, Tamil translation"

This reverts commit 98ef415138.

* po: update Tamil translation

---------

Signed-off-by: K.B.Dharun Krishna <kbdharunkrishna@gmail.com>
2023-10-01 07:57:35 +11:00
Anton Hvornum a78ab490be
Bumping version to: v2.6.3 (#2135) 2023-09-30 15:56:22 +02:00
codefiles 9f5c2bb70b
Add support for ESP partition flag (#2133) 2023-09-29 16:09:28 +02:00
codefiles 5f5b95f245
Fix GRUB boot directory (#2130) 2023-09-29 07:11:30 +02:00
codefiles 7a9a934ae3
Refactor `_add_efistub_bootloader()` use cmd list (#2127) 2023-09-29 08:29:54 +10:00
codefiles 3695c37bc4
Fix mount command whitespace (#2126) 2023-09-28 21:00:06 +10:00
Daniel Girtler 1e296b2637
Fix 2118 (#2119)
* Update locales generation

* Update README

* Disable translation check

---------

Co-authored-by: Daniel Girtler <girtler.daniel@gmail.com>
2023-09-28 08:44:18 +10:00
Anton Hvornum 72856ed5ec
Bumping version to: v2.6.2 (#2123) 2023-09-27 23:17:26 +02:00
codefiles 072519ad11
Simplify command in `README.md` example (#2122) 2023-09-27 17:20:13 +02:00
T13nou 2394e64dc2
FR Translation updated (#2112) 2023-09-27 08:50:14 +02:00
Wise 454b4bf7e9
tr translation files updated (#2115) 2023-09-27 08:49:55 +02:00
codefiles 0b4909b492
Use unpacking for list creation (#2117) 2023-09-27 08:49:20 +02:00
codefiles a811decea5
Fix mount debug message (#2116) 2023-09-27 07:39:35 +02:00
Daniel Girtler bc8d4ea234
Fix 2103 (#2114)
Co-authored-by: Daniel Girtler <girtler.daniel@gmail.com>
2023-09-26 10:57:50 +02:00
codefiles 717a22371f
Fix `mountpoint` for pre-mounted disk configuration (#2113)
* Fix `mountpoint` for pre-mounted disk configuration

* Add missing commas
2023-09-26 10:57:45 +02:00
Anton Hvornum c427391543
Disabled fstrim on BTRFS by default (#2109)
* Disabled fstrim on BTRFS by default

* Changed variable name to conform with suggestion in #2109
2023-09-26 09:56:34 +02:00
Daniel Girtler b141609990
Fix 1669 | Refactor display of sizes in tables (#2100)
* Use sector as default display

* Display tables in sector size

* Refactor size

* Update

* Update

* fix flake8

---------

Co-authored-by: Daniel Girtler <girtler.daniel@gmail.com>
2023-09-24 19:47:38 +10:00
codefiles 9e3e4a5df5
Refactor microcode (#2099) 2023-09-24 19:18:52 +10:00
Daniel Girtler 360a1b4f33
Unify json functions (#2102)
Co-authored-by: Daniel Girtler <girtler.daniel@gmail.com>
2023-09-24 10:14:02 +02:00
Daniel Girtler 877e34de63
Fix line break (#2101)
Co-authored-by: Daniel Girtler <girtler.daniel@gmail.com>
2023-09-24 09:36:32 +02:00
K.B.Dharun Krishna abd5aeba6a
po: update Tamil translation (#2096)
* po: update Tamil translation

* Update translation workflow check

* Update translation workflow check

* Update translation workflow check

* Update translation files

* Update translation workflow check

---------

Co-authored-by: Daniel Girtler <girtler.daniel@gmail.com>
2023-09-24 11:03:04 +10:00
codefiles ab5de3e2e6
Add support for loop devices (#2097) 2023-09-24 10:51:20 +10:00
Niko Hoffrén f078c74692
Fix small typo in README.md (#2095) 2023-09-24 08:48:09 +10:00
Anton Hvornum 7f5b100743
Bumped version to: v2.6.1 (#2094) 2023-09-23 15:16:58 +02:00
Anton Hvornum 5513ac0af5
Bumped version to: v2.6.1 2023-09-23 15:15:11 +02:00
Thomas Aldrian ad6cbcfd3d
Fix GRUB with non-/boot ESP (#2015)
* Fix GRUB with non-/boot ESP

Fixes #2001

* GRUB EFI fixes

* Fix flake8 and mypy

---------

Co-authored-by: Anton Hvornum <anton@hvornum.se>
Co-authored-by: Daniel Girtler <girtler.daniel@gmail.com>
2023-09-23 12:11:21 +10:00
Anton Hvornum ca3051ebf3
Added kitty, dolphin, wofi to hyprland (#2092) 2023-09-22 16:47:50 +02:00
Sxmourai d6e3a4651f
Renamed hyperland to hyprland, fixed seatd via post_installation and added waybar-hyprland (#1824)
* Renamed hyperland to hyprland, fixed seatd via post_installation and installed waybar

* Removed the launching of seatd on the installation process

* Starting to add nvidia support, and automatic configuring of hyprland

* Starting to add auto configuration of hyprland... But this will need maintenance

* Added hyprpaper auto config
Gonna make waybar auto config next

* Waybar auto config is starting...
I can't test rn I'm on vacation and my connection is quite bad (68 days for arch iso)

* Added wlogout support (and swaylock)

* Fixed file managers printing

* Starting to add a shell config... Definitely don't push this

* Reverted custom-shell config (create a separate PR)

* Removed systemd-logind, as that was just for testing the selector

* Added polkit as an option for the seat. As it's a dependency of the hyprland package

* Flake8 fix

* The name change wasn't propegated to the menu

* Added newline at the end of general_conf.py to not alter it

* Removed newline at the end of general_conf.py to not alter it

* Renamed the Hyprland class

---------

Co-authored-by: Anton Hvornum <anton@hvornum.se>
Co-authored-by: Anton Hvornum <anton.feeds+github@gmail.com>
2023-09-22 11:46:59 +02:00
renovate[bot] 4f9e8d2381
chore(deps): update dependency dev/pre-commit to v3.4.0 (#2090)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-09-22 11:46:10 +02:00
renovate[bot] d6ef345fc3
chore(deps): update dependency dev/mypy to v1.5.1 (#2089)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-09-22 11:45:03 +02:00
renovate[bot] db057aee1e
Add renovate.json (#2086)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-09-22 11:43:27 +02:00
Daniel Girtler 8e40de85fb
Only parse profile classes when loading modules (#2088)
Co-authored-by: Daniel Girtler <girtler.daniel@gmail.com>
2023-09-22 11:43:12 +02:00
codefiles 6d908e8cd7
Fix `_add_efistub_bootloader()` partition number with partn (#2084) 2023-09-21 17:13:22 +02:00
Daniel Girtler c75ae97f00
Sort the profiles with ignore case (#2080)
Co-authored-by: Daniel Girtler <girtler.daniel@gmail.com>
2023-09-21 19:48:49 +10:00
Daniel Girtler 0e93d5b468
Update instructions to run archinstall from ISO (#2076)
Update instructions to run archinstall from ISO
2023-09-21 18:34:11 +10:00
codefiles da9599a9f6
Rework `_get_kernel_params()` for `_add_grub_bootloader()` (#2079)
* Rework `_get_kernel_params()` for `_add_grub_bootloader()`

* Remove uncommenting of GRUB config line for encrypted /boot support
2023-09-21 09:46:55 +02:00
codefiles 3e2999bc27
Fix acquisition of UUID (#2077)
* Fix acquisition of UUID

* Fix inadequate solution

* Add check for UUID
2023-09-20 20:49:29 +02:00
codefiles b1e0068795
Use `_preset` for defaults in `LocaleMenu` (#2071)
* Use `_preset` for defaults in `LocaleMenu`

* Fix adjacent typos
2023-09-20 08:04:23 +02:00
codefiles 33d084f16a
Use `SUPPORTED` file for locale options (#2069)
* Use `SUPPORTED` file for locale options

* Add glibc to `PKGBUILD` depends
2023-09-20 06:51:20 +10:00
Daniel Girtler c0ff55d55b
Allow assigning mountpoint on existing partitions (#2067)
Co-authored-by: Daniel Girtler <girtler.daniel@gmail.com>
2023-09-19 06:47:46 +10:00
Daniel Girtler f6acdf5b5e
Update README with instructions (#2066)
* Update README with instructions

* Update

* Update

---------

Co-authored-by: Daniel Girtler <girtler.daniel@gmail.com>
2023-09-19 06:47:24 +10:00
codefiles 6ec2bd4b55
Add `_get_kernel_params()` (#2064) 2023-09-18 23:22:55 +10:00
Alexander Seiler 12b7017240
Fix many typos (#1692)
Signed-off-by: Alexander Seiler <seileralex@gmail.com>
2023-09-18 22:04:36 +10:00
codefiles ca09e1e63d
Refactor `_add_efistub_bootloader()` kernel parameters (#2061)
* Refactor `_add_efistub_bootloader()` kernel parameters

* Remove obsolete comment
2023-09-18 07:02:29 +10:00
codefiles 71ecfcc24e
Remove git install from `build_iso.sh` (#2063) 2023-09-17 21:38:19 +02:00
Daniel Girtler 91c2906f3c
Fix broken action check (#2060)
* Fix broken action check
2023-09-17 22:12:34 +10:00
codefiles 15e52b7768
Refactor `_add_efistub_bootloader()` cmdline (#2059) 2023-09-17 17:17:48 +10:00
codefiles b9d962bec2
Refactor `_add_grub_bootloader()` installation (#1968)
* Refactor `_add_grub_bootloader()` installation

* Remove whitespace
2023-09-17 17:14:47 +10:00
Himadri Bhattacharjee f4a6d11373
fix: make nodatacow and compress mutually exclusive (#1998)
* fix: make nodatacow and compress mutually exclusive

* fix: raise ValueError when both compress and nodatacow flags are set
2023-09-17 09:21:08 +10:00
Wu Xiaotian 47ed711743
Support CJK text alignment (#2012)
* Add functions for unicode string alignment

* use unicode alignment function to show menu

* Allow table content to support unicode text alignment
2023-09-17 09:08:38 +10:00
codefiles c9e2027725
Fix encryption debug message in `_add_efistub_bootloader()` (#1991) 2023-09-17 07:30:46 +10:00
Anton Hvornum 2cc0d64619
Added a forced buffer flush on each worker stdin write (#2057) 2023-09-16 14:58:20 +02:00
Campbell Jones 06d46ac762
Add option to use slick-greeter with lightdm (#1970) 2023-09-15 21:51:36 +10:00
Hugo Carvalho 418351d5ef
Update Portuguese translation (#1976)
More corrections
2023-09-15 18:41:20 +10:00
Christian Heusel f270a47f27
add the option to use ly as display manager (#2004)
Signed-off-by: Christian Heusel <christian@heusel.eu>
2023-09-14 22:10:26 +10:00
yenaras 9e079020b1
fix instructions for Using a Live ISO Images (#2021)
replaced `--break-operating-system` with the correct flag
`--break-system-packages` and also added the flag as required for
`pip uninstall --break-system-packages`
2023-09-14 21:49:46 +10:00
Stephen Houser 31bd5e80e3
fix custom-commands issue #2025 (#2026) 2023-09-14 21:41:48 +10:00
Adrian Sausenthaler 4e243fa868
'Packete' made my eyes bleed; fixed common german mistakes; added missing (#2029)
Signed-off-by: Adrian Sausenthaler <gpg@sausenthaler.de>
2023-09-14 21:16:35 +10:00
Roxfr c3d18fecdf
New translation for the French language (#2024)
* French language translation update

Hello,
Here is the update of the translation for the French language.
Regards,
Roxfr

* Add files via upload

Hello,
Here is the new translation for the French language:
- Update of the translation via the latest .pot file,
- Improved translation.
Regards,
Roxfr
2023-09-14 21:16:08 +10:00
Andrei Iancu 9518a4bf39
Add romanian translation to archinstall (#2034)
* Add romanian translation for installer

* Ad romanian translation.

* Update translation
2023-09-14 21:13:03 +10:00
Kazunari Sasa 386fbccffb
Correct the simple typo in the comment (#2042) 2023-09-14 21:11:42 +10:00
Daniel Girtler f185538355
Rename profile in sub-menu (#2033)
Co-authored-by: Daniel Girtler <girtler.daniel@gmail.com>
2023-09-14 20:56:06 +10:00
Daniel Girtler 56567221b6
Fix 1971 - manual partitioning (#2031)
Co-authored-by: Daniel Girtler <girtler.daniel@gmail.com>
2023-09-14 20:06:23 +10:00
Daniel Girtler 0258b0335e
Fix Bootloader installation (#2032)
* Fix broken path

* Update

* Update

---------

Co-authored-by: Daniel Girtler <girtler.daniel@gmail.com>
2023-09-14 20:05:53 +10:00
Daniel Girtler dcf3dfef57
Fix 2035 - Profile configuration (#2036)
Co-authored-by: Daniel Girtler <girtler.daniel@gmail.com>
2023-09-14 20:05:05 +10:00
Daniel Girtler c8e0b9a4d6
Default to unknown on partition types (#2037)
Co-authored-by: Daniel Girtler <girtler.daniel@gmail.com>
2023-09-14 20:04:25 +10:00
Ikko Eltociear Ashimine 2252dcf9bb
Fix typo in README.md (#2050)
interative -> interactive
2023-09-14 20:03:59 +10:00
Daniel Girtler 3ba1a3718e
Fix 1973 - pipewire (#2030)
Co-authored-by: Daniel Girtler <girtler.daniel@gmail.com>
2023-09-14 19:59:32 +10:00
Daniel Girtler 9bfd8c622a
Merge pull request #2038 from svartkanin/fix-github-action
Fix github action
2023-09-14 07:02:35 +10:00
Daniel Girtler be7ffbdd7e Update 2023-09-05 21:38:56 +10:00
Daniel Girtler bcf1eb3e36 Update 2023-09-05 21:32:30 +10:00
Daniel Girtler d93bf84e59 Fix github action 2023-09-05 21:21:08 +10:00
Hugo Carvalho 81ef09c336
Fix and update Portuguese translation (#1972) 2023-08-02 12:27:47 +02:00
Pedro Chaparro f7604c81a6
Translate: Add some missing Spanish translations (#1969)
* feat(locales/es): Add some missing spanish translations

* feat(locales/es): Run `locales_generator.sh` script to update the `base.mo` file

Follow the `archinstall/locales/README.md` instructions to add / update languages.

* feat(locales/es): Add some new missing translations

* feat(locales/es): Run `locales_generator.sh` script to update the `base.mo` file
2023-07-31 20:45:32 +02:00
Hasan Oruc 0852a7cacb
Updated and corrected translation. (#1910)
* Updated and corrected translation.

* Updated and corrected translation.
2023-07-31 09:41:26 +02:00
Himadri Bhattacharjee f8d2690920
move preview text method for profiles into xorg superclass, override when needed (#1918)
Co-authored-by: Anton Hvornum <anton@hvornum.se>
2023-07-31 09:40:45 +02:00
Wu Xiaotian d878496a2f
Improve the Chinese, Japanese and Korean text menu layout (#1945)
Before this patch, menus in Korean language would not be aligned:

```
  Archinstall 언어            Korean (71%)
> Mirrors
  Locales                   Defined
  Disk configuration
  부트로더                      Systemd-boot
  스왑                        True
```

After apply this patch, menus in Korean language are aligned:

```
  Archinstall 언어          Korean (71%)
> Mirrors
  Locales                   Defined
  Disk configuration
  부트로더                  Systemd-boot
  스왑                      True
```
2023-07-31 09:39:06 +02:00
Mário Victor Ribeiro Silva 9cbb2b7594
Parallel downloads (#1952)
* refactor: remove max_downloads limit

* Update parallel downloads

* Update parallel downloads
2023-07-31 09:38:42 +02:00
codefiles 7dd95f8c69
Refactor `_add_grub_bootloader()` configuration (#1962) 2023-07-31 09:38:29 +02:00
Anton Hvornum ada1ffeaad
Bumping version (#1965) 2023-07-30 23:44:52 +02:00
Anton Hvornum 3cea9baff6
Muted partprobe (#1964)
* Muted partprobe

* Missing import
2023-07-30 23:40:40 +02:00
Anton Hvornum a1ad25ff45
Mkinitcpio turn on output (#1963)
* Turning on output for mkinitcpio, otherwise the prompt stand still for a while after enabling fstrim.

* Added error message for when mkinitcpio errors out (but also say we're continuing)

* Pleasing mypy
2023-07-30 22:08:51 +02:00
Wu Xiaotian 355a0dbe06
Update Simplified Chinese translation (#1943) 2023-07-30 09:59:31 +02:00
Anton Hvornum a43344c5ae
Adding pack packages to profiles after they were removed (#1956)
* Added back xinit for awesome, since it can be used without a greeter, as well as other useful tools we've had in previous releases

* Fixing xinitrc for awesome profile

* Attempting to grab xorg packages when installing the desktop profile

* Spelling error on xorg-server

* Fixed sway value error on seat selection
2023-07-30 00:28:21 +02:00
codefiles 29b5280725
Add `awesome` package to Awesome profile (#1954) 2023-07-29 12:20:55 +02:00
codefiles 7326d51161
Fix boot loader disk encryption conditional (#1950) 2023-07-26 15:22:01 +02:00
Wu Xiaotian 1af21c3e95
Let the Chinese translation show in the menu item (#1944)
Even though the translation files exist, we still can't find Simplified or
Traditional Chinese translations from the language menu, this patch fixes that.
2023-07-26 09:19:45 +02:00
Alexmelman88 08b84d239c
Update Russian translation (#1947) 2023-07-25 13:29:22 +02:00
Mário Victor Ribeiro Silva 728e5773e9
feat: add more translations (#1936) 2023-07-25 13:24:57 +02:00
Daniel Girtler a548d7df70
Fix 1916 (#1920)
* Do not stdout when menu is active

* Handle missing libfido2 gracefully

* Update

---------

Co-authored-by: Daniel Girtler <girtler.daniel@gmail.com>
2023-07-25 11:19:14 +02:00
Daniel Girtler 439bb5428b
Fix 1934 - audio server regression (#1946)
* Audio configuration

* Update

* Update schema

---------

Co-authored-by: Daniel Girtler <girtler.daniel@gmail.com>
2023-07-25 11:17:09 +02:00
codefiles d76f4a0296
Fix boot partition regression (#1942)
* Fix boot partition regression

* Fix spelling
2023-07-25 11:16:02 +02:00
codefiles 69c37e7c79
Uncomment `/etc/locale.gen` entry and use first column for `LANG` variable (#1939) 2023-07-19 08:49:40 +02:00
358 changed files with 85609 additions and 17926 deletions

View File

@ -1,10 +1,8 @@
[flake8]
count = True
# Several of the following could be autofixed or improved by running the code through psf/black
ignore = E123,E126,E128,E203,E231,E261,E302,E402,E722,F541,W191,W292,W293,W503
ignore = W191,W503,E704,E203
max-complexity = 40
max-line-length = 236
max-line-length = 160
show-source = True
statistics = True
builtins = _
per-file-ignores = __init__.py:F401,F403,F405 simple_menu.py:C901,W503 guided.py:C901 network_configuration.py:F821
exclude = .git,__pycache__,build,docs,actions-runner

4
.github/FUNDING.yml vendored Normal file
View File

@ -0,0 +1,4 @@
# These are supported funding model platforms
github: [archlinux]
custom: ['https://archlinux.org/donate/']

85
.github/ISSUE_TEMPLATE/01_bug.yml vendored Normal file
View File

@ -0,0 +1,85 @@
name: bug report
description: archinstall crashed or could not install properly?
body:
- type: markdown
attributes:
value: >
Please read the ~5 known issues first:
https://archinstall.archlinux.page/help/known_issues.html
- type: markdown
attributes:
value: >
**NOTE: Always try the latest official ISO**
- type: input
id: iso
attributes:
label: Which ISO version are you using?
description: 'Always use the latest ISO version'
placeholder: '"2024-12-01" or "Dec 1:st"'
validations:
required: true
- type: textarea
id: bug-report
attributes:
label: The installation log
description: 'note: located at `/var/log/archinstall/install.log`'
placeholder: |
Hardware model detected: Dell Inc. Precision 7670; UEFI mode: True
Processor model detected: 12th Gen Intel(R) Core(TM) i7-12850HX
Memory statistics: 31111048 available out of 32545396 total installed
Disk states before installing: {'blockdevices': ... }
Testing connectivity to the Arch Linux mirrors ...
...
render: json
validations:
required: true
- type: markdown
attributes:
value: >
**Note**: Assuming you have network connectivity,
you can easily upload the installation log and get a shareable URL by running:
`archinstall share-log`
- type: textarea
id: freeform
attributes:
label: describe the problem
description: >
Please describe your issue as best as you can.
And please consider personal preferences vs what the recommended
steps/values are in https://wiki.archlinux.org/title/Installation_guide
as we try to abide by them as best we can.
value: |
#### Description of the issue
I was installing on X hardware ...
Then X Y Z happened and archinstall crashed ...
#### Virtual machine config:
```xml
<domain type="kvm">
<name>my-arch-machine</name>
...
</devices>
</domain>
```
```console
/usr/bin/qemu-system-x86_64 -name guest=my-arch-machine,debug-threads=on -object ...
```
validations:
required: true
- type: markdown
attributes:
value: >
**Note**: Feel free to modify the textarea above as you wish.
But it will grately help us in testing if we can generate the specific qemu command line,
for instance via:
`sudo virsh domxml-to-native qemu-argv --domain my-arch-machine`

17
.github/ISSUE_TEMPLATE/02_feature.yml vendored Normal file
View File

@ -0,0 +1,17 @@
name: feature request
description: a new feature!
body:
- type: markdown
attributes:
value: >
Please read our short mission statement before requesting more features:
https://github.com/archlinux/archinstall?tab=readme-ov-file#mission-statement
- type: textarea
id: freeform
attributes:
label: describe the request
description: >
Feel free to write any feature you think others might benefit from:
validations:
required: true

View File

@ -1,12 +1,12 @@
on: [ push, pull_request ]
name: Bandit security checkup
jobs:
flake8:
bandit:
runs-on: ubuntu-latest
container:
image: archlinux:latest
image: archlinux/archlinux:latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7
- run: pacman --noconfirm -Syu bandit
- name: Security checkup with Bandit
run: bandit -r archinstall || exit 0

View File

@ -1,14 +1,23 @@
on: [ push, pull_request ]
name: flake8 linting (15 ignores)
name: flake8 linting
jobs:
flake8:
runs-on: ubuntu-latest
container:
image: archlinux:latest
image: archlinux/archlinux:latest
steps:
- uses: actions/checkout@v3
- run: pacman --noconfirm -Syu python python-pip
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7
- name: Prepare arch
run: |
pacman-key --init
pacman --noconfirm -Sy archlinux-keyring
pacman --noconfirm -Syyu
pacman --noconfirm -Sy python-pip python-pyparted pkgconfig gcc
- run: pip install --break-system-packages --upgrade pip
- run: pip install --break-system-packages flake8
# this will install the exact version of flake8 that is in the pyproject.toml file
- name: Install archinstall dependencies
run: pip install --break-system-packages .[dev]
- run: python --version
- run: flake8 --version
- name: Lint with flake8
run: flake8

41
.github/workflows/github-pages.yml vendored Normal file
View File

@ -0,0 +1,41 @@
name: documentation
on:
push:
paths:
- "docs/**"
pull_request:
paths:
- "docs/**"
workflow_dispatch:
permissions:
contents: write
jobs:
docs:
runs-on: ubuntu-latest
container:
image: archlinux/archlinux:latest
options: --privileged
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7
- name: Install pre-dependencies
run: |
pacman -Sy --noconfirm tree git python-pyparted python-setuptools python-sphinx python-sphinx_rtd_theme python-build python-installer python-wheel
- name: Sphinx build
run: |
sphinx-build docs _build
- name: Deploy to GitHub Pages
uses: peaceiris/actions-gh-pages@84c30a85c19949d7eee79c4ff27748b70285e453 # v4
if: ${{ github.event_name != 'pull_request' }}
with:
publish_branch: gh-pages
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: _build/
force_orphan: true
enable_jekyll: false # This is required to preserve _static (and thus the theme)
cname: archinstall.archlinux.page

View File

@ -23,17 +23,17 @@ jobs:
build:
runs-on: ubuntu-latest
container:
image: archlinux:latest
image: archlinux/archlinux:latest
options: --privileged
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7
- run: pwd
- run: find .
- run: cat /etc/os-release
- run: pacman-key --init
- run: pacman --noconfirm -Sy archlinux-keyring
- run: ./build_iso.sh
- uses: actions/upload-artifact@v3
- run: ./test_tooling/mkarchiso/build_iso.sh
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
with:
name: Arch Live ISO
path: /tmp/archlive/out/*.iso

View File

@ -4,15 +4,20 @@ jobs:
mypy:
runs-on: ubuntu-latest
container:
image: archlinux:latest
image: archlinux/archlinux:latest
steps:
- uses: actions/checkout@v3
- run: pacman --noconfirm -Syu python mypy python-pip
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7
- name: Prepare arch
run: |
pacman-key --init
pacman --noconfirm -Sy archlinux-keyring
pacman --noconfirm -Syyu
pacman --noconfirm -Sy python-pip python-pyparted pkgconfig gcc
- run: pip install --break-system-packages --upgrade pip
- run: pip install --break-system-packages fastapi pydantic
# this will install the exact version of mypy that is in the pyproject.toml file
- name: Install archinstall dependencies
run: pip install --break-system-packages .[dev]
- run: python --version
- run: mypy --version
# one day this will be enabled
# run: mypy --strict --module archinstall || exit 0
- name: run mypy
run: mypy --config-file pyproject.toml

22
.github/workflows/pylint.yaml vendored Normal file
View File

@ -0,0 +1,22 @@
on: [ push, pull_request ]
name: Pylint linting
jobs:
pylint:
runs-on: ubuntu-latest
container:
image: archlinux/archlinux:latest
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7
- name: Prepare arch
run: |
pacman-key --init
pacman --noconfirm -Sy archlinux-keyring
pacman --noconfirm -Syyu
pacman --noconfirm -Sy python-pip python-pyparted pkgconfig gcc
- run: pip install --break-system-packages --upgrade pip
- name: Install Pylint
run: pip install --break-system-packages .[dev]
- run: python --version
- run: pylint --version
- name: Lint with Pylint
run: pylint .

View File

@ -4,12 +4,18 @@ jobs:
pytest:
runs-on: ubuntu-latest
container:
image: archlinux:latest
image: archlinux/archlinux:latest
options: --privileged
steps:
- uses: actions/checkout@v3
- run: pacman --noconfirm -Syu python python-pip qemu gcc
- run: python -m pip install --break-system-packages --upgrade pip
- run: pip install --break-system-packages pytest
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7
- name: Prepare arch
run: |
pacman-key --init
pacman --noconfirm -Sy archlinux-keyring
pacman --noconfirm -Syyu
pacman --noconfirm -Sy python-pip python-pyparted pkgconfig gcc
- run: pip install --break-system-packages --upgrade pip
- name: Install archinstall dependencies
run: pip install --break-system-packages .[dev]
- name: Test with pytest
run: python -m pytest || exit 0
run: pytest

View File

@ -8,32 +8,32 @@ jobs:
deploy:
runs-on: ubuntu-latest
container:
image: archlinux:latest
image: archlinux/archlinux:latest
options: --privileged
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7
- name: Prepare arch
run: |
pacman-key --init
pacman --noconfirm -Sy archlinux-keyring
pacman --noconfirm -Sy python-pip python-pyparted python-simple-term-menu pkgconfig gcc
- name: Install build dependencies
run: |
python -m pip install --break-system-packages --upgrade pip
pip install --break-system-packages --upgrade build twine wheel setuptools installer
pip uninstall archinstall -y --break-system-packages
pacman --noconfirm -Syyu
pacman --noconfirm -Sy python-uv python-setuptools python-pip
pacman --noconfirm -Sy python-pyparted python-pydantic python-textual
- name: Remove existing archinstall (if any)
run:
uv pip uninstall archinstall --break-system-packages --system
- name: Build archinstall
run: python -m build --wheel --no-isolation
run: uv build --no-build-isolation --wheel
- name: Install archinstall
run: python -m installer dist/*.whl
run: |
uv pip install dist/*.whl --break-system-packages --system --no-build --no-deps
- name: Run archinstall
run: |
python -V
archinstall --script guided -v
archinstall --script swiss -v
archinstall --script only_hd -v
archinstall --script minimal -v
- uses: actions/upload-artifact@v3
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
with:
name: archinstall
path: dist/*

View File

@ -1,4 +1,4 @@
# This workflow will upload a Python Package using Twine when a release is created
# This workflow will upload a Python Package when a release is created
# For more information see: https://help.github.com/en/actions/language-and-framework-guides/using-python-with-github-actions#publishing-to-package-registries
name: Upload archinstall to PyPi
@ -11,23 +11,23 @@ jobs:
deploy:
runs-on: ubuntu-latest
permissions:
# IMPORTANT: this permission is mandatory for Trusted Publishing
id-token: write
container:
image: archlinux/archlinux:latest
options: --privileged
steps:
- uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.x'
- name: Install dependencies
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7
- name: Prepare arch
run: |
python -m pip install --upgrade pip
pip install build twine
pacman-key --init
pacman --noconfirm -Sy archlinux-keyring
pacman --noconfirm -Syyu
pacman --noconfirm -Sy python python-uv python-setuptools python-pip python-pyparted python-pydantic python-textual
- name: Build archinstall
run: |
python -m build . --wheel
uv build --no-build-isolation --wheel
- name: Publish archinstall to PyPi
env:
TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }}
TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }}
run: |
twine upload dist/*
uv publish --trusted-publishing always

9
.github/workflows/ruff-format.yaml vendored Normal file
View File

@ -0,0 +1,9 @@
on: [ push, pull_request ]
name: ruff check formatting
jobs:
ruff_format_check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7
- uses: astral-sh/ruff-action@278981a28ce3188b1e39527901f38254bf3aac89 # v4.1.0
- run: ruff format --diff

8
.github/workflows/ruff-lint.yaml vendored Normal file
View File

@ -0,0 +1,8 @@
on: [ push, pull_request ]
name: ruff check linting
jobs:
ruff:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7
- uses: astral-sh/ruff-action@278981a28ce3188b1e39527901f38254bf3aac89 # v4.1.0

View File

@ -1,22 +1,22 @@
name: Translation validation
on:
push:
paths:
- 'archinstall/locales/**'
- 'archinstall/**/*.py'
- 'archinstall/locales/**'
- '.github/workflows/translation-check.yaml'
pull_request:
paths:
- 'archinstall/locales/**'
name: translation file checks
- 'archinstall/**/*.py'
- 'archinstall/locales/**'
- '.github/workflows/translation-check.yaml'
jobs:
translation-check:
translations:
name: Validate translations
runs-on: ubuntu-latest
container:
image: archlinux:latest
steps:
- uses: actions/checkout@v3
- run: pacman --noconfirm -Syu python
- run: cd archinstall/locales
- run: pwd
- run: ls -l
- run: bash locales_generator.sh
- run: git diff --name-only
- run: ls
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7
- name: Install gettext
run: sudo apt-get update && sudo apt-get install -y gettext
- name: Run translation checks
run: bash archinstall/locales/locales_generator.sh check

40
.github/workflows/uki-build.yaml vendored Normal file
View File

@ -0,0 +1,40 @@
# This workflow will build an Arch Linux UKI file with the commit on it
name: Build Arch UKI with ArchInstall Commit
on:
push:
branches:
- master
- main # In case we adopt this convention in the future
pull_request:
paths-ignore:
- 'docs/**'
- '**.editorconfig'
- '**.gitignore'
- '**.md'
- 'LICENSE'
- 'PKGBUILD'
release:
types:
- created
jobs:
build:
runs-on: ubuntu-latest
container:
image: archlinux/archlinux:latest
options: --privileged
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7
- run: pwd
- run: find .
- run: cat /etc/os-release
- run: pacman-key --init
- run: pacman --noconfirm -Sy archlinux-keyring
- run: pacman --noconfirm -Sy mkosi
- run: (cd test_tooling/mkosi/ && mkosi build -B)
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
with:
name: Arch Live UKI
path: test_tooling/mkosi/mkosi.output/*.efi

12
.gitignore vendored
View File

@ -21,10 +21,11 @@ SAFETY_LOCK
**/**.network
**/**.target
**/**.qcow2
**/**.log
**/**.fd
/test*.py
**/archiso
/guided.py
/install.log
venv
.venv
.idea/**
@ -35,3 +36,12 @@ venv
/*.sig
/*.json
requirements.txt
/.gitconfig
/actions-runner
/cmd_output.txt
node_modules/
uv.lock
test_tooling/mkosi/mkosi.output/*image*
test_tooling/mkosi/mkosi.cache/**
test_tooling/mkosi/mkosi.tools/**
test_tooling/mkosi/mkosi.tools.manifest

View File

@ -4,7 +4,7 @@
# These jobs should leverage the same tag as that runner. If necessary, change the tag from 'docker' to the one it uses.
# All jobs will be run in the official archlinux container image, so we will declare that here.
image: archlinux:latest
image: archlinux/archlinux:latest
# This can be used to handle common actions. In this case, we do a pacman -Sy to make sure repos are ready to use.
before_script:
@ -36,7 +36,7 @@ flake8:
- flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
# We currently do not have unit tests implemented but this stage is written in anticipation of their future usage.
# When a stage name is preceeded with a '.' it's treated as "disabled" by GitLab and is not executed, so it's fine for it to be declared.
# When a stage name is preceded with a '.' it's treated as "disabled" by GitLab and is not executed, so it's fine for it to be declared.
.pytest:
stage: test
tags:

View File

@ -1,19 +1,17 @@
default_stages: ['commit']
default_stages: ['pre-commit']
repos:
- repo: https://github.com/pycqa/autoflake
rev: v2.1.1
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.15.22
hooks:
- id: autoflake
args: [
'--in-place',
'--remove-all-unused-imports',
'--ignore-init-module-imports'
]
files: \.py$
require_serial: true
fail_fast: true
# fix unused imports and sort them
- id: ruff
args: ["--extend-select", "I", "--fix"]
# format the code
- id: ruff-format
# run the linter
- id: ruff
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.4.0
rev: v6.0.0
hooks:
# general hooks:
- id: check-added-large-files # Prevent giant files from being committed
@ -23,20 +21,35 @@ repos:
- id: check-yaml # Attempts to load all yaml files to verify syntax
- id: destroyed-symlinks # Detects symlinks which are changed to regular files
- id: detect-private-key # Checks for the existence of private keys
- id: end-of-file-fixer # Makes sure files end in a newline and only a newline
- id: trailing-whitespace # Trims trailing whitespace
# Python specific hooks:
- id: check-ast # Simply check whether files parse as valid python
- id: check-docstring-first # Checks for a common error of placing code before the docstring
- repo: https://github.com/pycqa/flake8
rev: 6.0.0
rev: 7.3.0
hooks:
- id: flake8
args: [--config=.flake8]
fail_fast: true
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.1.1
rev: v2.3.0
hooks:
- id: mypy
args: [--config=pyproject.toml]
args: [
'--config-file=pyproject.toml'
]
fail_fast: true
additional_dependencies:
- pydantic
- pytest
- hypothesis
- cryptography
- textual
- repo: local
hooks:
- id: pylint
name: pylint
entry: pylint
language: system
types: [python]
fail_fast: true
require_serial: true

View File

@ -3,4 +3,4 @@ index-servers =
pypi
[pypi]
repository = https://upload.pypi.org/legacy/
repository = https://upload.pypi.org/legacy/

15
.readthedocs.yaml Normal file
View File

@ -0,0 +1,15 @@
# .readthedocs.yml
# Read the Docs configuration file
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
version: 2
sphinx:
builder: html
configuration: docs/conf.py
fail_on_warning: true
build:
os: "ubuntu-22.04"
tools:
python: "3.12"

View File

@ -1,22 +0,0 @@
# .readthedocs.yml
# Read the Docs configuration file
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
# Required
version: 2
# Build documentation in the docs/ directory with Sphinx
sphinx:
configuration: docs/conf.py
# Build documentation with MkDocs
#mkdocs:
# configuration: mkdocs.yml
# Optionally build your docs in additional formats such as PDF
formats:
- pdf
# Optionally set the version of Python and requirements required to build your docs
python:
version: 3.8

View File

@ -16,7 +16,7 @@ Patch releases will be done against their own branches, branched from stable tag
## Discussions
Currently, questions, bugs and suggestions should be reported through [GitHub issue tracker](https://github.com/archlinux/archinstall/issues).<br>
For less formal discussions there is also an [archinstall Discord server](https://discord.gg/cqXU88y).
For less formal discussions there is also an [archinstall Discord server](https://discord.gg/aDeMffrxNg).
## Coding convention
@ -27,9 +27,7 @@ The exceptions to PEP8 are:
* Archinstall uses [tabs instead of spaces](https://www.python.org/dev/peps/pep-0008/#tabs-or-spaces) simply to make it
easier for non-IDE developers to navigate the code *(Tab display-width should be equal to 4 spaces)*. Exception to the
rule are comments that need fine-tuned indentation for documentation purposes.
* [Line length](https://www.python.org/dev/peps/pep-0008/#maximum-line-length) a maximum line length is enforced via flake8 with 236 characters
* [Line breaks before/after binary operator](https://www.python.org/dev/peps/pep-0008/#should-a-line-break-before-or-after-a-binary-operator)
is not enforced, as long as the style of line breaks is consistent within the same code block.
* [Line length](https://www.python.org/dev/peps/pep-0008/#maximum-line-length) a maximum line length is enforced via flake8 with 160 characters
* Archinstall should always be saved with **Unix-formatted line endings** and no other platform-specific formats.
* [String quotes](https://www.python.org/dev/peps/pep-0008/#string-quotes) follow PEP8, the exception being when
creating formatted strings, double-quoted strings are *preferred* but not required on the outer edges *(
@ -40,7 +38,7 @@ There might therefore be older code which does not follow the coding convention
## Git hooks
`archinstall` ships pre-commit hooks that make it easier to run check such as `mypy` and `flake8` locally.
`archinstall` ships pre-commit hooks that make it easier to run checks such as `mypy`, `ruff check`, and `flake8` locally.
The checks are listed in `.pre-commit-config.yaml` and can be installed via
```
pre-commit install
@ -70,15 +68,4 @@ squash commits when the pull request is merged.
Maintainer:
* Anton Hvornum ([@Torxed](https://github.com/Torxed))
At present the current contributors are (alphabetically):
* Anton Hvornum ([@Torxed](https://github.com/Torxed))
* Borislav Kosharov ([@nikibobi](https://github.com/nikibobi))
* demostanis ([@demostanis](https://github.com/demostanis))
* Dylan Taylor ([@dylanmtaylor](https://github.com/dylanmtaylor))
* Giancarlo Razzolini (@[grazzolini](https://github.com/grazzolini))
* Jerker Bengtsson ([@jaybent](https://github.com/jaybent))
* j-james ([@j-james](https://github.com/j-james))
* Ninchester ([@ninchester](https://github.com/ninchester))
* nullrequest ([@advaithm](https://github.com/advaithm))
* Philipp Schaffrath ([@phisch](https://github.com/phisch))
* Varun Madiath ([@vamega](https://github.com/vamega))
[Contributors](https://github.com/archlinux/archinstall/graphs/contributors)

View File

@ -1,36 +1,53 @@
# Maintainer: David Runge <dvzrv@archlinux.org>
# Maintainer: Giancarlo Razzolini <grazzolini@archlinux.org>
# Maintainer: Anton Hvornum <torxed@archlinux.org>
# Contributor: Anton Hvornum <anton@hvornum.se>
# Contributor: demostanis worlds <demostanis@protonmail.com>
pkgname=archinstall
pkgver=2.6.0
pkgver=4.4
pkgrel=1
pkgdesc="Just another guided/automated Arch Linux installer with a twist"
arch=(any)
url="https://github.com/archlinux/archinstall"
license=(GPL3)
license=(GPL-3.0-only)
depends=(
'arch-install-scripts'
'btrfs-progs'
'coreutils'
'cryptsetup'
'dosfstools'
'e2fsprogs'
'glibc'
'kbd'
'libcrypt.so'
'libxcrypt'
'pciutils'
'procps-ng'
'python'
'python-cryptography'
'python-pydantic'
'python-pyparted'
'python-simple-term-menu'
'python-textual'
'python-markdown-it-py'
'python-linkify-it-py'
'systemd'
'util-linux'
'xfsprogs'
'lvm2'
'f2fs-tools'
'libfido2'
)
makedepends=(
'python-setuptools'
'python-sphinx'
'python-build'
'python-installer'
'python-setuptools'
'python-sphinx'
'python-wheel'
'python-sphinx_rtd_theme'
'python-pylint'
'python-pylint-pydantic'
'ruff'
)
optdepends=(
'python-systemd: Adds journald logging'
@ -39,14 +56,17 @@ provides=(python-archinstall archinstall)
conflicts=(python-archinstall archinstall-git)
replaces=(python-archinstall archinstall-git)
source=(
$pkgname-$pkgver.tar.gz::$url/archive/refs/tags/v$pkgver.tar.gz
$pkgname-$pkgver.tar.gz.sig::$url/releases/download/v$pkgver/$pkgname-$pkgver.tar.gz.sig
$pkgname-$pkgver.tar.gz::$url/archive/refs/tags/$pkgver.tar.gz
$pkgname-$pkgver.tar.gz.sig::$url/releases/download/$pkgver/$pkgname-$pkgver.tar.gz.sig
)
sha512sums=('64cb3593c5091b3885ad14ef073cfab31090b4f9bcb4405b18cf9b19adb5ca42255ba8891ec62e21f92d59872541ef6d94f186fb05c625822af63525441e08d9'
'SKIP')
b2sums=('9c0ec0871841804377ba8310dc744711adcec4eed7319a8d89d684af8e7b822bb9d47540b00f4d746a9fcd7b9ea1b9e07bac773e6c28fabc760e4df38b16748b'
'SKIP')
validpgpkeys=('256F73CEEFC6705C6BBAB20E5FBBB32941E3740A') # Anton Hvornum (Torxed) <anton@hvornum.se>
sha512sums=()
b2sums=()
validpgpkeys=('8AA2213C8464C82D879C8127D4B58E897A929F2E') # torxed@archlinux.org
check() {
cd $pkgname-$pkgver
ruff check
}
pkgver() {
cd $pkgname-$pkgver
@ -54,13 +74,6 @@ pkgver() {
awk '$1 ~ /^__version__/ {gsub("\"", ""); print $3}' archinstall/__init__.py
}
prepare() {
cd $pkgname-$pkgver
# use real directories for examples and profiles, as symlinks do not work
rm -fv $pkgname/{examples,profiles}
}
build() {
cd $pkgname-$pkgver

310
README.md
View File

@ -6,195 +6,148 @@
[![Lint Python and Find Syntax Errors](https://github.com/archlinux/archinstall/actions/workflows/flake8.yaml/badge.svg)](https://github.com/archlinux/archinstall/actions/workflows/flake8.yaml)
Just another guided/automated [Arch Linux](https://wiki.archlinux.org/index.php/Arch_Linux) installer with a twist.
The installer also doubles as a python library to install Arch Linux and manage services, packages and other things inside the installed system *(Usually from a live medium)*.
The installer also doubles as a python library to install Arch Linux and manage services, packages, and other things inside the installed system *(Usually from a live medium or from an existing installation)*.
* archinstall [discord](https://discord.gg/cqXU88y) server
* archinstall [matrix.org](https://app.element.io/#/room/#archinstall:matrix.org) channel
* archinstall [#archinstall@irc.libera.chat](irc://#archinstall@irc.libera.chat:6697)
* archinstall [documentation](https://archinstall.readthedocs.io/)
* archinstall [discord](https://discord.gg/aDeMffrxNg) server
* archinstall [#archinstall:matrix.org](https://matrix.to/#/#archinstall:matrix.org) Matrix channel
* archinstall [#archinstall@irc.libera.chat:6697](https://web.libera.chat/?channel=#archinstall)
* archinstall [documentation](https://archinstall.archlinux.page/)
# Installation & Usage
> [!TIP]
> In the ISO you are root by default. Use sudo if running from an existing system.
$ sudo pacman -S archinstall
```shell
pacman-key --init
pacman -Sy archinstall
archinstall
```
Alternative ways to install are `git clone` the repository or `pip install --upgrade archinstall`.
Alternative ways to install are `git clone` the repository (and is better since you get the latest code regardless of [build date](https://archlinux.org/packages/?sort=&q=archinstall)) or `pip install --upgrade archinstall`.
## Upgrade `archinstall` on live Arch ISO image
Upgrading archinstall on the ISO needs to be done via a full system upgrade using
```shell
pacman -Syu
```
When booting from a live USB, the space on the ramdisk is limited and may not be sufficient to allow running a re-installation or upgrade of the installer.
In case one runs into this issue, any of the following can be used
* Resize the root partition https://wiki.archlinux.org/title/Archiso#Adjusting_the_size_of_the_root_file_system
* Specify the boot parameter copytoram=y (https://gitlab.archlinux.org/archlinux/mkinitcpio/mkinitcpio-archiso/-/blob/master/docs/README.bootparams#L26) which will copy the root filesystem to tmpfs
## Running the [guided](https://github.com/archlinux/archinstall/blob/master/archinstall/scripts/guided.py) installer
Assuming you are on an Arch Linux live-ISO or installed via `pip`:
Assuming you are on an Arch Linux live-ISO or installed via `pip`, `archinstall` will use the `guided` script by default
```shell
archinstall
```
similar goes for running the [guided](https://github.com/archlinux/archinstall/blob/master/archinstall/scripts/guided.py) installer using `git
# archinstall
```shell
git clone https://github.com/archlinux/archinstall
cd archinstall
python -m archinstall $@
```
## Running the [guided](https://github.com/archlinux/archinstall/blob/master/archinstall/scripts/guided.py) installer using `git`
To run alternative scripts using the `--script` parameter
# cd archinstall-git
# cp archinstall/scripts/guided.py
# python guided.py
```
archinstall --script <name>
```
#### Advanced
Some additional options that are not needed by most users are hidden behind the `--advanced` flag.
Some additional options that most users do not need are hidden behind the `--advanced` flag and all options/args can be consulted through `-h` or `--help`.
## Running from a declarative configuration file or URL
`archinstall` can be run with a JSON configuration file. There are 2 different configuration files to consider,
the `user_configuration.json` contains all general installation configuration, whereas the `user_credentials.json`
contains the sensitive user configuration such as user password, root password and encryption password.
contains the sensitive user configuration such as user password, root password, and encryption password.
An example of the user configuration file can be found here
[configuration file](https://github.com/archlinux/archinstall/blob/master/examples/config-sample.json)
and example of the credentials configuration here
and an example of the credentials configuration here
[credentials file](https://github.com/archlinux/archinstall/blob/master/examples/creds-sample.json).
**HINT:** The configuration files can be auto-generated by starting `archinstall`, configuring all desired menu
points and then going to `Save configuration`.
To load the configuration file into `archinstall` run the following command
```
```shell
archinstall --config <path to user config file or URL> --creds <path to user credentials config file or URL>
```
### Credentials configuration file encryption
By default, all user account credentials are hashed with `yescrypt` and only the hash is stored in the saved `user_credentials.json` file.
This is not possible for disk encryption password which needs to be stored in plaintext to be able to apply it.
However, when selecting to save configuration files, `archinstall` will prompt for the option to encrypt the `user_credentials.json` file content.
A prompt will require to enter a encryption password to encrypt the file. When providing an encrypted `user_configuration.json` as a argument with `--creds <user_credentials.json>`
there are multiple ways to provide the decryption key:
* Provide the decryption key via the command line argument `--creds-decryption-key <password>`
* Store the encryption key in the environment variable `ARCHINSTALL_CREDS_DECRYPTION_KEY` which will be read automatically
* If none of the above is provided a prompt will be shown to enter the decryption key manually
# Help or Issues
If you come across any issues, kindly submit your issue here on GitHub or post your query in the
[discord](https://discord.gg/aDeMffrxNg) help channel.
When submitting an issue, please:
* Provide the stacktrace of the output if applicable
* Attach the `/var/log/archinstall/install.log` to the issue ticket. This helps us help you!
* To upload the log from the ISO image and get a shareable URL, run<br>
```shell
archinstall share-log
```
# 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
Arabic
Brazilian Portuguese
Czech
Dutch
Estonian
French
Georgian
German
Indonesian
Italian
Korean
Modern Greek
Polish
Portuguese
Russian
Spanish
Swedish
Tamil
Turkish
Ukrainian
Urdu
```
The language can be switched inside the installer (first menu entry). Bear in mind that not all languages provide
full translations as we rely on contributors to do the translations. Each language has an indicator that shows
how much has been translated.
Any contributions to the translations are more than welcome,
to get started please follow [the guide](https://github.com/archlinux/archinstall/blob/master/archinstall/locales/README.md)
# Help or Issues
## Fonts
The ISO does not ship with all fonts needed for different languages.
Fonts that use a different character set than Latin will not be displayed correctly. If those languages
want to be selected then a proper font has to be set manually in the console.
Submit an issue here on GitHub, or submit a post in the discord help channel.<br>
When doing so, attach the `/var/log/archinstall/install.log` to the issue ticket. This helps us help you!
# Mission Statement
Archinstall promises to ship a [guided installer](https://github.com/archlinux/archinstall/blob/master/archinstall/scripts/guided.py) that follows
the [Arch Principles](https://wiki.archlinux.org/index.php/Arch_Linux#Principles) as well as a library to manage services, packages and other Arch Linux aspects.
The guided installer will provide user-friendly options along the way, but the keyword here is options, they are optional and will never be forced upon anyone.
The guided installer itself is also optional to use if so desired and not forced upon anyone.
---
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 compatibility after notifying about such changes.
All available console fonts can be found in `/usr/share/kbd/consolefonts` and set with `setfont LatGrkCyr-8x16`.
# Scripting your own installation
## Scripting interactive installation
There are some examples in the `examples/` directory that should serve as a starting point.
For an example of a fully scripted, interactive installation please refer to the example
[interactive_installation.py](https://github.com/archlinux/archinstall/blob/master/archinstall/scripts/guided.py)
The following is a small example of how to script your own *interative* installation:
```python
from pathlib import Path
from archinstall import Installer, ProfileConfiguration, profile_handler, User
from archinstall.default_profiles.minimal import MinimalProfile
from archinstall.lib.disk.device_model import FilesystemType
from archinstall.lib.disk.encryption_menu import DiskEncryptionMenu
from archinstall.lib.disk.filesystem import FilesystemHandler
from archinstall.lib.interactions.disk_conf import select_disk_config
fs_type = FilesystemType('ext4')
# Select a device to use for the installation
disk_config = select_disk_config()
# Optional: ask for disk encryption configuration
data_store = {}
disk_encryption = DiskEncryptionMenu(disk_config.device_modifications, data_store).run()
# initiate file handler with the disk config and the optional disk encryption config
fs_handler = FilesystemHandler(disk_config, disk_encryption)
# perform all file operations
# WARNING: this will potentially format the filesystem and delete all data
fs_handler.perform_filesystem_operations()
mountpoint = Path('/tmp')
with Installer(
mountpoint,
disk_config,
disk_encryption=disk_encryption,
kernels=['linux']
) as installation:
installation.mount_ordered_layout()
installation.minimal_installation(hostname='minimal-arch')
installation.add_additional_packages(['nano', 'wget', 'git'])
# Optionally, install a profile of choice.
# In this case, we install a minimal profile that is empty
profile_config = ProfileConfiguration(MinimalProfile())
profile_handler.install_profile_config(installation, profile_config)
user = User('archinstall', 'password', True)
installation.create_users(user)
```
This installer will perform the following:
* Prompt the user to configurate the disk partitioning
* Prompt the user to setup disk encryption
* Create a file handler instance for the configured disk and the optional disk encryption
* Perform the disk operations (WARNING: this will potentially format the disks and erase all data)
* Installs a basic instance of Arch Linux *(base base-devel linux linux-firmware btrfs-progs efibootmgr)*
* Installs and configures a bootloader to partition 0 on uefi. On BIOS, it sets the root to partition 0.
* Install additional packages *(nano, wget, git)*
* Create a new user
> **Creating your own ISO with this script on it:** Follow [ArchISO](https://wiki.archlinux.org/index.php/archiso)'s guide on how to create your own ISO.
> **To create your own ISO with this script in it:** Follow [ArchISO](https://wiki.archlinux.org/index.php/archiso)'s guide on creating your own ISO.
## Script non-interactive automated installation
For an example of a fully scripted, automated installation please see the example
For an example of a fully scripted, automated installation please refer to the example
[full_automated_installation.py](https://github.com/archlinux/archinstall/blob/master/examples/full_automated_installation.py)
## Unattended installation based on MAC address
Archinstall comes with an [unattended](https://github.com/archlinux/archinstall/blob/master/examples/mac_address_installation.py)
example which will look for a matching profile for the machine it is being run on, based on any local MAC address.
For instance, if the machine the code is executed on has the MAC address `52:54:00:12:34:56` it will look for a profile called
[52-54-00-12-34-56.py](https://github.com/archlinux/archinstall/blob/master/archinstall/default_profiles/tailored.py).
If it's found, the unattended installation will commence and source that profile as its installation procedure.
# Profiles
`archinstall` ships with a set of pre-defined profiles that can be chosen during the installation process.
`archinstall` comes with a set of pre-configured profiles available for selection during the installation process.
- [Desktop](https://github.com/archlinux/archinstall/tree/master/archinstall/default_profiles/desktops)
- [Server](https://github.com/archlinux/archinstall/tree/master/archinstall/default_profiles/servers)
The definitions of the profiles and what packages they will install can be seen directly in the menu or
The profiles' definitions and the packages they will install can be directly viewed in the menu, or
[default profiles](https://github.com/archlinux/archinstall/tree/master/archinstall/default_profiles)
@ -202,19 +155,20 @@ The definitions of the profiles and what packages they will install can be seen
## Using a Live ISO Image
If you want to test a commit, branch or bleeding edge release from the repository using the vanilla Arch Live ISO image,
you can replace the version of archinstall with a new version and run that with the steps described below:
If you want to test a commit, branch, or bleeding edge release from the repository using the standard Arch Linux Live ISO image,
replace the archinstall version with a newer one and execute the subsequent steps defined below.
1. You need a working network connection
2. Install the build requirements with `pacman -Sy; pacman -S git python-pip gcc pkgconf`
*(note that this may or may not work depending on your RAM and current state of the squashfs maximum filesystem free space)*
3. Uninstall the previous version of archinstall with `pip uninstall archinstall`
3. Uninstall the previous version of archinstall with `pip uninstall --break-system-packages archinstall`
4. Now clone the latest repository with `git clone https://github.com/archlinux/archinstall`
5. Enter the repository with `cd archinstall`
*At this stage, you can choose to check out a feature branch for instance with `git checkout v2.3.1-rc1`*
6. Build the project and install it using `pip install --break-operating-system .`
After this, running archinstall with `python -m archinstall` will run against whatever branch you chose in step 5.
6. To run the source code, there are 2 different options:
- Run a specific branch version from source directly using `python -m archinstall`, in most cases this will work just fine, the
rare case it will not work is if the source has introduced any new dependencies that are not installed yet
- Installing the branch version with `pip install --break-system-packages .` and `archinstall`
## Without a Live ISO Image
@ -222,11 +176,10 @@ To test this without a live ISO, the simplest approach is to use a local image a
This can be done by installing `pacman -S arch-install-scripts util-linux` locally and doing the following:
# truncate -s 20G testimage.img
# losetup -fP ./testimage.img
# losetup -a | grep "testimage.img" | awk -F ":" '{print $1}'
# losetup --partscan --show ./testimage.img
# pip install --upgrade archinstall
# python -m archinstall --script guided
# qemu-system-x86_64 -enable-kvm -machine q35,accel=kvm -device intel-iommu -cpu host -m 4096 -boot order=d -drive file=./testimage.img,format=raw -drive if=pflash,format=raw,readonly,file=/usr/share/ovmf/x64/OVMF_CODE.fd -drive if=pflash,format=raw,readonly,file=/usr/share/ovmf/x64/OVMF_VARS.fd
# qemu-system-x86_64 -enable-kvm -machine q35,accel=kvm -device intel-iommu -cpu host -m 4096 -boot order=d -drive file=./testimage.img,format=raw -drive if=pflash,format=raw,readonly,file=/usr/share/edk2/x64/OVMF_CODE.4m.fd -drive if=pflash,format=raw,readonly,file=/usr/share/edk2/x64/OVMF_VARS.4m.fd
This will create a *20 GB* `testimage.img` and create a loop device which we can use to format and install to.<br>
`archinstall` is installed and executed in [guided mode](#docs-todo). Once the installation is complete, ~~you can use qemu/kvm to boot the test media.~~<br>
@ -235,6 +188,81 @@ This will create a *20 GB* `testimage.img` and create a loop device which we can
There's also a [Building and Testing](https://github.com/archlinux/archinstall/wiki/Building-and-Testing) guide.<br>
It will go through everything from packaging, building and running *(with qemu)* the installer against a dev branch.
## Boot an Arch ISO image in a VM
You may want to boot an ISO image in a VM to test `archinstall` in there.
* Download the latest [Arch ISO](https://archlinux.org/download/)
* Use the the below command to boot the ISO in a VM
```
qemu-system-x86_64 -enable-kvm \
-machine q35,accel=kvm -device intel-iommu \
-cpu host -m 4096 -boot order=d \
-drive if=pflash,format=raw,readonly,file=/usr/share/edk2/x64/OVMF_CODE.4m.fd \
-drive if=pflash,format=raw,readonly,file=/usr/share/edk2/x64/OVMF_VARS.4m.fd \
-drive file=./archlinux-2025.12.01-x86_64.iso,format=raw
```
HINT: For espeakup support
```
qemu-system-x86_64 -enable-kvm \
-machine q35,accel=kvm -device intel-iommu \
-cpu host -m 4096 -boot order=d \
-drive if=pflash,format=raw,readonly,file=/usr/share/edk2/x64/OVMF_CODE.4m.fd \
-drive if=pflash,format=raw,readonly,file=/usr/share/edk2/x64/OVMF_VARS.4m.fd \
-drive file=./archlinux-2025.12.01-x86_64.iso,format=raw \
-device intel-hda -device hda-duplex,audiodev=snd0 \
-audiodev pa,id=snd0,server=/run/user/1000/pulse/native
```
# FAQ
## AUR
`archinstall` will not offer or bundle AUR helpers or AUR packages due to a current consensus. This is not any individual developers decision. The reasons and discussions for this stance on the topic can be found on our mailing list thread: [(optional) AUR helper in archinstall](https://lists.archlinux.org/archives/list/arch-dev-public@lists.archlinux.org/thread/VYOULH2GOJLFM2BXOFLWH3D754YXFPSL/).
## Keyring out-of-date
For a description of the problem see https://archinstall.archlinux.page/help/known_issues.html#keyring-is-out-of-date-2213 and discussion in issue https://github.com/archlinux/archinstall/issues/2213.
For a quick fix the below command will install the latest keyrings
```pacman -Sy archlinux-keyring```
## How to dual boot with Windows
To install Arch Linux alongside an existing Windows installation using `archinstall`, follow these steps:
1. Ensure some unallocated space is available for the Linux installation after the Windows installation.
2. Boot into the ISO and run `archinstall`.
3. Choose `Disk configuration` -> `Manual partitioning`.
4. Select the disk on which Windows resides.
5. Select `Create a new partition`.
6. Choose a filesystem type.
7. Determine the start and end sectors for the new partition location (values can be suffixed with various units).
8. Assign the mountpoint `/` to the new partition.
9. Assign the `Boot/ESP` partition the mountpoint `/boot` from the partitioning menu.
10. Confirm your settings and exit to the main menu by choosing `Confirm and exit`.
11. Modify any additional settings for your installation as necessary.
12. Start the installation upon completion of setup.
# Mission Statement
Archinstall promises to ship a [guided installer](https://github.com/archlinux/archinstall/blob/master/archinstall/scripts/guided.py) that follows
the [Arch Linux Principles](https://wiki.archlinux.org/index.php/Arch_Linux#Principles) as well as a library to manage services, packages, and other Arch Linux aspects.
The guided installer ensures a user-friendly experience, offering optional selections throughout the process. Emphasizing its flexible nature, these options are never obligatory.
In addition, the decision to use the guided installer remains entirely with the user, reflecting the Linux philosophy of providing full freedom and flexibility.
---
Archinstall primarily functions as a flexible library for managing services, packages, and other elements within an Arch Linux system.
This core library is the backbone for the guided installer that Archinstall provides. It is also designed to be used by those who wish to script their own custom installations.
Therefore, Archinstall will try its best to not introduce any breaking changes except for major releases which may break backward compatibility after notifying about such changes.
# Contributing

View File

@ -1,288 +1,3 @@
"""Arch Linux installer - guided, templates etc."""
import importlib
import os
from argparse import ArgumentParser, Namespace
from pathlib import Path
from typing import TYPE_CHECKING, Any, Dict, Union
from archinstall.lib.plugins import plugin
from .lib import disk
from .lib import menu
from .lib import models
from .lib import packages
from .lib import exceptions
from .lib import luks
from .lib import locale
from .lib import mirrors
from .lib import networking
from .lib import profile
from .lib import interactions
from . import default_profiles
from .lib.hardware import SysInfo, GfxDriver
from .lib.installer import Installer, accessibility_tools_in_use
from .lib.output import FormattedOutput, log, error, debug, warn, info
from .lib.storage import storage
from .lib.global_menu import GlobalMenu
from .lib.boot import Boot
from .lib.translationhandler import TranslationHandler, Language, DeferredTranslation
from .lib.plugins import plugins, load_plugin
from .lib.configuration import ConfigurationOutput
from .lib.general import (
generate_password, locate_binary, clear_vt100_escape_codes,
JSON, UNSAFE_JSON, SysCommandWorker, SysCommand,
run_custom_user_commands, json_stream_to_structure, secret
)
if TYPE_CHECKING:
_: Any
__version__ = "2.6.0rc1"
storage['__version__'] = __version__
# add the custome _ as a builtin, it can now be used anywhere in the
# project to mark strings as translatable with _('translate me')
DeferredTranslation.install()
# Log various information about hardware before starting the installation. This might assist in troubleshooting
debug(f"Hardware model detected: {SysInfo.sys_vendor()} {SysInfo.product_name()}; UEFI mode: {SysInfo.has_uefi()}")
debug(f"Processor model detected: {SysInfo.cpu_model()}")
debug(f"Memory statistics: {SysInfo.mem_available()} available out of {SysInfo.mem_total()} total installed")
debug(f"Virtualization detected: {SysInfo.virtualization()}; is VM: {SysInfo.is_vm()}")
debug(f"Graphics devices detected: {SysInfo._graphics_devices().keys()}")
# For support reasons, we'll log the disk layout pre installation to match against post-installation layout
debug(f"Disk states before installing: {disk.disk_layouts()}")
if os.getuid() != 0:
print(_("Archinstall requires root privileges to run. See --help for more."))
exit(1)
parser = ArgumentParser()
def define_arguments():
"""
Define which explicit arguments do we allow.
Refer to https://docs.python.org/3/library/argparse.html for documentation and
https://docs.python.org/3/howto/argparse.html for a tutorial
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("--silent", action="store_true",
help="WARNING: Disables all prompts for input and confirmation. If no configuration is provided, this is ignored")
parser.add_argument("--dry-run", "--dry_run", action="store_true",
help="Generates a configuration file and then exits instead of performing an installation")
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, err :bool = False) -> dict:
"""We accept arguments not defined to the parser. (arguments "ad hoc").
Internally argparse return to us a list of words so we have to parse its contents, manually.
We accept following individual syntax for each argument
--argument value
--argument=value
--argument = value
--argument (boolean as default)
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.
To a certain extent, multiple and error are incompatible. In fact, the only error this routine can catch, as of now, is the event
argument value value ...
which isn't am error if multiple is specified
"""
tmp_list = unknowns[:] # wastes a few bytes, but avoids any collateral effect of the destructive nature of the pop method()
config = {}
key = None
last_key = None
while tmp_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)]
config[key] = value
last_key = key # for multiple handling
key = None # we have the kwy value pair we need
else:
key = element[2:]
config[key] = True # every argument starts its lifecycle as boolean
else:
if element == '=':
continue
if key:
config[key] = element
last_key = key # multiple
key = None
else:
if multiple and last_key:
if isinstance(config[last_key],str):
config[last_key] = [config[last_key],element]
else:
config[last_key].append(element)
elif err:
raise ValueError(f"Entry {element} is not related to any argument")
else:
print(f" We ignore the entry {element} as it isn't related to any argument")
return config
def cleanup_empty_args(args: 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:
0) we create a dict to store the arguments and their values
1) preprocess.
We take those arguments which use JSON files, and read them into the argument dict. So each first level entry becomes a argument on it's own right
2) Load.
We convert the predefined argument list directly into the dict via the vars() function. Non specified arguments are loaded with value None or false if they are booleans (action="store_true").
The name is chosen according to argparse conventions. See above (the first text is used as argument name, but underscore substitutes dash)
We then load all the undefined arguments. In this case the names are taken as written.
Important. This way explicit command line arguments take precedence over configuration files.
3) Amend
Change whatever is needed on the configuration dictionary (it could be done in post_process_arguments but this ougth to be left to changes anywhere else in the code, not in the arguments dictionary
"""
config: Dict[str, Any] = {}
args, unknowns = parser.parse_known_args()
# preprocess the JSON files.
# TODO Expand the url access to the other JSON file arguments ?
if args.config is not None:
if not json_stream_to_structure('--config', args.config, config):
exit(1)
if args.creds is not None:
if not json_stream_to_structure('--creds', args.creds, config):
exit(1)
# load the parameters. first the known, then the unknowns
clean_args = cleanup_empty_args(args)
config.update(clean_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 clean_args.get('config') is None:
config["silent"] = False
else:
config["silent"] = clean_args.get('silent')
# avoiding a compatibility issue
if 'dry-run' in config:
del config['dry-run']
return config
def load_config():
"""
refine and set some arguments. Formerly at the scripts
"""
from .lib.models import NetworkConfiguration
arguments['locale_config'] = locale.LocaleConfiguration.parse_arg(arguments)
if (archinstall_lang := arguments.get('archinstall-language', None)) is not None:
arguments['archinstall-language'] = TranslationHandler().get_language_by_name(archinstall_lang)
if disk_config := arguments.get('disk_config', {}):
arguments['disk_config'] = disk.DiskLayoutConfiguration.parse_arg(disk_config)
if profile_config := arguments.get('profile_config', None):
arguments['profile_config'] = profile.ProfileConfiguration.parse_arg(profile_config)
if mirror_config := arguments.get('mirror_config', None):
arguments['mirror_config'] = mirrors.MirrorConfiguration.parse_args(mirror_config)
if arguments.get('servers', None) is not None:
storage['_selected_servers'] = arguments.get('servers', None)
if arguments.get('network_config', None) is not None:
config = NetworkConfiguration.parse_arg(arguments.get('network_config'))
arguments['network_config'] = config
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)
arguments['!users'] = models.User.parse_arguments(users, superusers)
if arguments.get('bootloader', None) is not None:
arguments['bootloader'] = models.Bootloader.from_arg(arguments['bootloader'])
if arguments.get('disk_encryption', None) is not None and disk_config is not None:
password = arguments.get('encryption_password', '')
arguments['disk_encryption'] = disk.DiskEncryption.parse_arg(
arguments['disk_config'],
arguments['disk_encryption'],
password
)
def post_process_arguments(arguments):
storage['arguments'] = arguments
if mountpoint := arguments.get('mount_point', None):
storage['MOUNT_POINT'] = Path(mountpoint)
if arguments.get('debug', False):
warn(f"Warning: --debug mode will write certain credentials to {storage['LOG_PATH']}/{storage['LOG_FILE']}!")
if arguments.get('plugin', None):
path = arguments['plugin']
load_plugin(path)
load_config()
define_arguments()
arguments: Dict[str, Any] = get_arguments()
post_process_arguments(arguments)
# @archinstall.plugin decorator hook to programmatically add
# plugins in runtime. Useful in profiles_bck and other things.
def plugin(f, *args, **kwargs):
plugins[f.__name__] = f
def run_as_a_module():
"""
This can either be run as the compiled and installed application: python setup.py install
OR straight as a module: python -m archinstall
In any case we will be attempting to load the provided script to be run from the scripts/ folder
"""
script = arguments.get('script', None)
if script is None:
print('No script to run provided')
mod_name = f'archinstall.scripts.{script}'
# by loading the module we'll automatically run the script
importlib.import_module(mod_name)
__all__ = ['plugin']

View File

@ -1,19 +1,6 @@
import importlib
import sys
import pathlib
# Load .git version before the builtin version
if pathlib.Path('./archinstall/__init__.py').absolute().exists():
spec = importlib.util.spec_from_file_location("archinstall", "./archinstall/__init__.py")
if spec is None or spec.loader is None:
raise ValueError('Could not retrieve spec from file: archinstall/__init__.py')
archinstall = importlib.util.module_from_spec(spec)
sys.modules["archinstall"] = archinstall
spec.loader.exec_module(archinstall)
else:
import archinstall
from archinstall.main import main
if __name__ == '__main__':
archinstall.run_as_a_module()
sys.exit(main())

View File

@ -0,0 +1,80 @@
from typing import TYPE_CHECKING
from archinstall.lib.hardware import SysInfo
from archinstall.lib.log import debug
from archinstall.lib.models.application import Audio, AudioConfiguration
from archinstall.lib.models.users import User
if TYPE_CHECKING:
from archinstall.lib.installer import Installer
class AudioApp:
@property
def pulseaudio_packages(self) -> list[str]:
return [
'pulseaudio',
]
@property
def pipewire_packages(self) -> list[str]:
return [
'pipewire',
'pipewire-alsa',
'pipewire-jack',
'pipewire-pulse',
'gst-plugin-pipewire',
'libpulse',
'wireplumber',
]
def _enable_pipewire(
self,
install_session: Installer,
users: list[User] | None = None,
) -> None:
if users is None:
return
for user in users:
# Create the full path for enabling the pipewire systemd items
service_dir = install_session.target / 'home' / user.username / '.config' / 'systemd' / 'user' / 'default.target.wants'
service_dir.mkdir(parents=True, exist_ok=True)
# Set ownership of the entire user catalogue
install_session.arch_chroot(f'chown -R {user.username}:{user.username} /home/{user.username}')
# symlink in the correct pipewire systemd items
install_session.arch_chroot(
f'ln -sf /usr/lib/systemd/user/pipewire-pulse.service /home/{user.username}/.config/systemd/user/default.target.wants/pipewire-pulse.service',
run_as=user.username,
)
install_session.arch_chroot(
f'ln -sf /usr/lib/systemd/user/pipewire-pulse.socket /home/{user.username}/.config/systemd/user/default.target.wants/pipewire-pulse.socket',
run_as=user.username,
)
def install(
self,
install_session: Installer,
audio_config: AudioConfiguration,
users: list[User] | None = None,
) -> None:
debug(f'Installing audio server: {audio_config.audio.value}')
if audio_config.audio == Audio.NO_AUDIO:
debug('No audio server selected, skipping installation.')
return
if SysInfo.requires_sof_fw():
install_session.add_additional_packages('sof-firmware')
if SysInfo.requires_alsa_fw():
install_session.add_additional_packages('alsa-firmware')
match audio_config.audio:
case Audio.PIPEWIRE:
install_session.add_additional_packages(self.pipewire_packages)
self._enable_pipewire(install_session, users)
case Audio.PULSEAUDIO:
install_session.add_additional_packages(self.pulseaudio_packages)

View File

@ -0,0 +1,26 @@
from typing import TYPE_CHECKING
from archinstall.lib.log import debug
if TYPE_CHECKING:
from archinstall.lib.installer import Installer
class BluetoothApp:
@property
def packages(self) -> list[str]:
return [
'bluez',
'bluez-utils',
]
@property
def services(self) -> list[str]:
return [
'bluetooth.service',
]
def install(self, install_session: Installer) -> None:
debug('Installing Bluetooth')
install_session.add_additional_packages(self.packages)
install_session.enable_service(self.services)

View File

@ -0,0 +1,52 @@
from typing import TYPE_CHECKING
from archinstall.lib.log import debug
from archinstall.lib.models.application import Firewall, FirewallConfiguration
if TYPE_CHECKING:
from archinstall.lib.installer import Installer
class FirewallApp:
@property
def ufw_packages(self) -> list[str]:
return [
'ufw',
]
@property
def fwd_packages(self) -> list[str]:
return [
'firewalld',
]
@property
def ufw_services(self) -> list[str]:
return [
'ufw.service',
]
@property
def fwd_services(self) -> list[str]:
return [
'firewalld.service',
]
def install(
self,
install_session: Installer,
firewall_config: FirewallConfiguration,
) -> None:
debug(f'Installing firewall: {firewall_config.firewall.value}')
match firewall_config.firewall:
case Firewall.UFW:
install_session.add_additional_packages(self.ufw_packages)
install_session.enable_service(self.ufw_services)
# write default conf file to enabled
ufw_conf = install_session.target / 'etc/ufw/ufw.conf'
ufw_conf.write_text(ufw_conf.read_text().replace('ENABLED=no', 'ENABLED=yes'))
case Firewall.FWD:
install_session.add_additional_packages(self.fwd_packages)
install_session.enable_service(self.fwd_services)

View File

@ -0,0 +1,14 @@
from typing import TYPE_CHECKING
from archinstall.lib.log import debug
from archinstall.lib.models.application import FontsConfiguration
if TYPE_CHECKING:
from archinstall.lib.installer import Installer
class FontsApp:
def install(self, install_session: Installer, fonts_config: FontsConfiguration) -> None:
packages = [f.value for f in fonts_config.fonts]
debug(f'Installing fonts: {packages}')
install_session.add_additional_packages(packages)

View File

@ -0,0 +1,49 @@
from typing import TYPE_CHECKING
from archinstall.lib.log import debug
from archinstall.lib.models.application import PowerManagement, PowerManagementConfiguration
if TYPE_CHECKING:
from archinstall.lib.installer import Installer
class PowerManagementApp:
@property
def ppd_packages(self) -> list[str]:
return [
'power-profiles-daemon',
]
@property
def tuned_packages(self) -> list[str]:
return [
'tuned',
'tuned-ppd',
]
@property
def ppd_services(self) -> list[str]:
return [
'power-profiles-daemon.service',
]
@property
def tuned_services(self) -> list[str]:
return [
'tuned.service',
]
def install(
self,
install_session: Installer,
power_management_config: PowerManagementConfiguration,
) -> None:
debug(f'Installing power management daemon: {power_management_config.power_management.value}')
match power_management_config.power_management:
case PowerManagement.POWER_PROFILES_DAEMON:
install_session.add_additional_packages(self.ppd_packages)
install_session.enable_service(self.ppd_services)
case PowerManagement.TUNED:
install_session.add_additional_packages(self.tuned_packages)
install_session.enable_service(self.tuned_services)

View File

@ -0,0 +1,23 @@
from typing import TYPE_CHECKING
from archinstall.lib.log import debug
if TYPE_CHECKING:
from archinstall.lib.installer import Installer
class PrintServiceApp:
@property
def packages(self) -> list[str]:
return ['cups', 'system-config-printer', 'cups-pk-helper']
@property
def services(self) -> list[str]:
return [
'cups.service',
]
def install(self, install_session: Installer) -> None:
debug('Installing print service')
install_session.add_additional_packages(self.packages)
install_session.enable_service(self.services)

View File

@ -1,40 +0,0 @@
from typing import List, Union, Any, TYPE_CHECKING
import archinstall
from archinstall.default_profiles.profile import Profile, ProfileType
from archinstall.lib.models import User
if TYPE_CHECKING:
from archinstall.lib.installer import Installer
_: Any
class PipewireProfile(Profile):
def __init__(self):
super().__init__('Pipewire', ProfileType.Application)
@property
def packages(self) -> List[str]:
return [
'pipewire',
'pipewire-alsa',
'pipewire-jack',
'pipewire-pulse',
'gst-plugin-pipewire',
'libpulse',
'wireplumber'
]
def _enable_pipewire_for_all(self, install_session: 'Installer'):
users: Union[User, List[User]] = archinstall.arguments.get('!users', [])
if not isinstance(users, list):
users = [users]
for user in users:
install_session.arch_chroot('systemctl enable --user pipewire-pulse.service', run_as=user.username)
def install(self, install_session: 'Installer'):
super().install(install_session)
install_session.add_additional_packages(self.packages)
self._enable_pipewire_for_all(install_session)

View File

@ -1,218 +0,0 @@
# from typing import List, Dict, Optional, TYPE_CHECKING, Any
#
# from ..lib import menu
# from archinstall.lib.output import log, FormattedOutput
# from archinstall.lib.profile.profiles_handler import profile_handler
# from archinstall.default_profiles.profile import Profile, ProfileType, SelectResult, ProfileInfo, TProfile
#
# if TYPE_CHECKING:
# from archinstall.lib.installer import Installer
# _: Any
#
#
# class CustomProfileList(menu.ListManager):
# def __init__(self, prompt: str, profiles: List[TProfile]):
# self._actions = [
# str(_('Add profile')),
# str(_('Edit profile')),
# str(_('Delete profile'))
# ]
# super().__init__(prompt, profiles, [self._actions[0]], self._actions[1:])
#
# def reformat(self, data: List[TProfile]) -> Dict[str, Optional[TProfile]]:
# table = FormattedOutput.as_table(data)
# rows = table.split('\n')
#
# # these are the header rows of the table and do not map to any profile 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[TProfile]] = {f' {rows[0]}': None, f' {rows[1]}': None}
#
# for row, profile in zip(rows[2:], data):
# row = row.replace('|', '\\|')
# display_data[row] = profile
#
# return display_data
#
# def selected_action_display(self, profile: TProfile) -> str:
# return profile.name
#
# def handle_action(
# self,
# action: str,
# entry: Optional['CustomTypeProfile'],
# data: List['CustomTypeProfile']
# ) -> List['CustomTypeProfile']:
# if action == self._actions[0]: # add
# new_profile = self._add_profile()
# if new_profile is not None:
# # in case a profile with the same name as an existing profile
# # was created we'll replace the existing one
# data = [d for d in data if d.name != new_profile.name]
# data += [new_profile]
# elif entry is not None:
# if action == self._actions[1]: # edit
# new_profile = self._add_profile(entry)
# if new_profile is not None:
# # we'll remove the original profile and add the modified version
# data = [d for d in data if d.name != entry.name and d.name != new_profile.name]
# data += [new_profile]
# elif action == self._actions[2]: # delete
# data = [d for d in data if d != entry]
#
# return data
#
# def _is_new_profile_name(self, name: str) -> bool:
# existing_profile = profile_handler.get_profile_by_name(name)
# if existing_profile is not None and existing_profile.profile_type != ProfileType.CustomType:
# return False
# return True
#
# def _add_profile(self, editing: Optional['CustomTypeProfile'] = None) -> Optional['CustomTypeProfile']:
# name_prompt = '\n\n' + str(_('Profile name: '))
#
# while True:
# profile_name = menu.TextInput(name_prompt, editing.name if editing else '').run().strip()
#
# if not profile_name:
# return None
#
# if not self._is_new_profile_name(profile_name):
# error_prompt = str(_("The profile name you entered is already in use. Try again"))
# print(error_prompt)
# else:
# break
#
# packages_prompt = str(_('Packages to be install with this profile (space separated, leave blank to skip): '))
# edit_packages = ' '.join(editing.packages) if editing else ''
# packages = menu.TextInput(packages_prompt, edit_packages).run().strip()
#
# services_prompt = str(_('Services to be enabled with this profile (space separated, leave blank to skip): '))
# edit_services = ' '.join(editing.services) if editing else ''
# services = menu.TextInput(services_prompt, edit_services).run().strip()
#
# choice = menu.Menu(
# str(_('Should this profile be enabled for installation?')),
# menu.Menu.yes_no(),
# skip=False,
# default_option=menu.Menu.no(),
# clear_screen=False,
# show_search_hint=False
# ).run()
#
# enable_profile = True if choice.value == menu.Menu.yes() else False
#
# profile = CustomTypeProfile(
# profile_name,
# enabled=enable_profile,
# packages=packages.split(' '),
# services=services.split(' ')
# )
#
# return profile
#
#
# # TODO
# # Still needs some ironing out
# class CustomProfile():
# def __init__(self):
# super().__init__(
# 'Custom',
# ProfileType.Custom,
# description=str(_('Create your own'))
# )
#
# def json(self) -> Dict[str, Any]:
# data: Dict[str, Any] = {'main': self.name, 'gfx_driver': self.gfx_driver, 'custom': []}
#
# for profile in self._current_selection:
# data['custom'].append({
# 'name': profile.name,
# 'packages': profile.packages,
# 'services': profile.services,
# 'enabled': profile.custom_enabled
# })
#
# return data
#
# def do_on_select(self) -> SelectResult:
# custom_profile_list = CustomProfileList('', profile_handler.get_custom_profiles())
# custom_profiles = custom_profile_list.run()
#
# # we'll first remove existing custom default_profiles with
# # the same name and then add the new ones this
# # will avoid errors of default_profiles with duplicate naming
# profile_handler.remove_custom_profiles(custom_profiles)
# profile_handler.add_custom_profiles(custom_profiles)
#
# self.set_current_selection(custom_profiles)
#
# if custom_profile_list.is_last_choice_cancel():
# return SelectResult.SameSelection
#
# enabled_profiles = [p for p in self._current_selection if p.custom_enabled]
# # in case we only created inactive default_profiles we wanna store them but
# # we want to reset the original setting
# if not enabled_profiles:
# return SelectResult.ResetCurrent
#
# return SelectResult.NewSelection
#
# def post_install(self, install_session: 'Installer'):
# for profile in self._current_selection:
# profile.post_install(install_session)
#
# def install(self, install_session: 'Installer'):
# driver_packages = self.gfx_driver_packages()
# install_session.add_additional_packages(driver_packages)
#
# for profile in self._current_selection:
# if profile.custom_enabled:
# log(f'Installing custom profile {profile.name}...')
#
# install_session.add_additional_packages(profile.packages)
# install_session.enable_service(profile.services)
#
# profile.install(install_session)
#
# def info(self) -> Optional[ProfileInfo]:
# enabled_profiles = [p for p in self._current_selection if p.custom_enabled]
# if enabled_profiles:
# details = ', '.join([p.name for p in enabled_profiles])
# gfx_driver = self.gfx_driver
# return ProfileInfo(self.name, details, gfx_driver)
#
# return None
#
# def reset(self):
# for profile in self._current_selection:
# profile.set_enabled(False)
#
# self.gfx_driver = None
#
#
# class CustomTypeProfile(Profile):
# def __init__(
# self,
# name: str,
# enabled: bool = False,
# packages: List[str] = [],
# services: List[str] = []
# ):
# super().__init__(
# name,
# ProfileType.CustomType,
# packages=packages,
# services=services,
# support_gfx_driver=True
# )
#
# self.custom_enabled = enabled
#
# def json(self) -> Dict[str, Any]:
# return {
# 'name': self.name,
# 'packages': self.packages,
# 'services': self.services,
# 'enabled': self.custom_enabled
# }

View File

@ -1,43 +1,44 @@
from typing import Any, TYPE_CHECKING, List, Optional, Dict
from typing import TYPE_CHECKING, Self, override
from archinstall.lib import menu
from archinstall.lib.output import info
from archinstall.default_profiles.desktops.utils import provision_seat_access
from archinstall.default_profiles.profile import CustomSetting, DisplayServerType, GreeterType, Profile, ProfileType, SelectResult
from archinstall.lib.log import info
from archinstall.lib.menu.helpers import Selection
from archinstall.lib.profile.profiles_handler import profile_handler
from archinstall.default_profiles.profile import Profile, ProfileType, SelectResult, GreeterType
from archinstall.tui.menu_item import MenuItem, MenuItemGroup
from archinstall.tui.result import ResultType
if TYPE_CHECKING:
from archinstall.lib.installer import Installer
_: Any
from archinstall.lib.models.users import User
class DesktopProfile(Profile):
def __init__(self, current_selection: List[Profile] = []):
def __init__(self, current_selection: list[Self] = []) -> None:
super().__init__(
'Desktop',
ProfileType.Desktop,
description=str(_('Provides a selection of desktop environments and tiling window managers, e.g. gnome, kde, sway')),
current_selection=current_selection,
support_greeter=True
support_greeter=True,
)
@property
def packages(self) -> List[str]:
@override
def packages(self) -> list[str]:
return [
'nano',
'vim',
'openssh',
'htop',
'wget',
'iwd',
'wireless_tools',
'wpa_supplicant',
'smartmontools',
'xdg-utils'
'xdg-utils',
]
@property
def default_greeter_type(self) -> Optional[GreeterType]:
combined_greeters: Dict[GreeterType, int] = {}
@override
def default_greeter_type(self) -> GreeterType | None:
combined_greeters: dict[GreeterType, int] = {}
for profile in self.current_selection:
if profile.default_greeter_type:
combined_greeters.setdefault(profile.default_greeter_type, 0)
@ -48,40 +49,70 @@ class DesktopProfile(Profile):
return None
def _do_on_select_profiles(self):
async def _do_on_select_profiles(self) -> None:
for profile in self.current_selection:
profile.do_on_select()
await profile.do_on_select()
def do_on_select(self) -> SelectResult:
choice = profile_handler.select_profile(
profile_handler.get_desktop_profiles(),
self._current_selection,
title=str(_('Select your desired desktop environment')),
multi=True
)
@override
async def do_on_select(self) -> SelectResult:
items = [
MenuItem(
p.name,
value=p,
preview_action=lambda x: x.value.preview_text() if x.value else None,
)
for p in profile_handler.get_desktop_profiles()
]
match choice.type_:
case menu.MenuSelectionType.Selection:
self.set_current_selection(choice.value) # type: ignore
self._do_on_select_profiles()
group = MenuItemGroup(items, sort_items=True, sort_case_sensitive=False)
group.set_selected_by_value(self.current_selection)
result = await Selection[Self](
group,
multi=True,
allow_reset=True,
allow_skip=True,
preview_location='right',
).show()
match result.type_:
case ResultType.Selection:
self.current_selection = result.get_values()
await self._do_on_select_profiles()
return SelectResult.NewSelection
case menu.MenuSelectionType.Skip:
case ResultType.Skip:
return SelectResult.SameSelection
case menu.MenuSelectionType.Reset:
case ResultType.Reset:
return SelectResult.ResetCurrent
def post_install(self, install_session: 'Installer'):
for profile in self._current_selection:
@override
def post_install(self, install_session: Installer) -> None:
for profile in self.current_selection:
profile.post_install(install_session)
def install(self, install_session: 'Installer'):
@override
def provision(self, install_session: Installer, users: list[User]) -> None:
for profile in self.current_selection:
profile.provision(install_session, users)
if seat_access := profile.custom_settings.get(CustomSetting.SeatAccess):
provision_seat_access(install_session, users, seat_access)
@override
def install(self, install_session: Installer) -> None:
# Install common packages for all desktop environments
install_session.add_additional_packages(self.packages)
for profile in self._current_selection:
xorg_installed = False
for profile in self.current_selection:
info(f'Installing profile {profile.name}...')
install_session.add_additional_packages(profile.packages)
install_session.enable_service(profile.services)
if not xorg_installed and profile.display_server == DisplayServerType.Xorg:
install_session.add_additional_packages(['xorg-server', 'xorg-xinit'])
xorg_installed = True
profile.install(install_session)

View File

@ -1,36 +1,67 @@
from typing import List, Optional, Any, TYPE_CHECKING
from typing import TYPE_CHECKING, override
from archinstall.default_profiles.profile import ProfileType
from archinstall.default_profiles.xorg import XorgProfile
from archinstall.default_profiles.profile import DisplayServerType, Profile, ProfileType
if TYPE_CHECKING:
from archinstall.lib.installer import Installer
_: Any
class AwesomeProfile(XorgProfile):
def __init__(self):
super().__init__('Awesome', ProfileType.WindowMgr, description='')
class AwesomeProfile(Profile):
def __init__(self) -> None:
super().__init__(
'Awesome',
ProfileType.WindowMgr,
support_gfx_driver=True,
display_server=DisplayServerType.Xorg,
)
@property
def packages(self) -> List[str]:
return ['alacritty']
@override
def packages(self) -> list[str]:
return [
'awesome',
'alacritty',
'xorg-xrandr',
'xterm',
'feh',
'slock',
'terminus-font',
'gnu-free-fonts',
'ttf-liberation',
'xsel',
]
def preview_text(self) -> Optional[str]:
text = str(_('Environment type: {}')).format(self.profile_type.value)
return text + '\n' + self.packages_text()
def install(self, install_session: 'Installer'):
@override
def install(self, install_session: Installer) -> None:
super().install(install_session)
# TODO: Copy a full configuration to ~/.config/awesome/rc.lua instead.
with open(f"{install_session.target}/etc/xdg/awesome/rc.lua", 'r') as fh:
with open(f'{install_session.target}/etc/xdg/awesome/rc.lua') as fh:
awesome_lua = fh.read()
# Replace xterm with alacritty for a smoother experience.
awesome_lua = awesome_lua.replace('"xterm"', '"alacritty"')
with open(f"{install_session.target}/etc/xdg/awesome/rc.lua", 'w') as fh:
with open(f'{install_session.target}/etc/xdg/awesome/rc.lua', 'w') as fh:
fh.write(awesome_lua)
# TODO: Configure the right-click-menu to contain the above packages that were installed. (as a user config)
# TODO: check if we selected a greeter,
# but for now, awesome is intended to run without one.
with open(f'{install_session.target}/etc/X11/xinit/xinitrc') as xinitrc:
xinitrc_data = xinitrc.read()
for line in xinitrc_data.split('\n'):
if 'twm &' in line:
xinitrc_data = xinitrc_data.replace(line, f'# {line}')
if 'xclock' in line:
xinitrc_data = xinitrc_data.replace(line, f'# {line}')
if 'xterm' in line:
xinitrc_data = xinitrc_data.replace(line, f'# {line}')
xinitrc_data += '\n'
xinitrc_data += 'exec awesome\n'
with open(f'{install_session.target}/etc/X11/xinit/xinitrc', 'w') as xinitrc:
xinitrc.write(xinitrc_data)

View File

@ -1,30 +1,39 @@
from typing import List, Optional, Any, TYPE_CHECKING
from typing import override
from archinstall.default_profiles.profile import ProfileType, GreeterType
from archinstall.default_profiles.xorg import XorgProfile
if TYPE_CHECKING:
_: Any
from archinstall.default_profiles.profile import DisplayServerType, GreeterType, Profile, ProfileType
from archinstall.lib.installer import Installer
from archinstall.lib.models.users import User
class BspwmProfile(XorgProfile):
def __init__(self):
super().__init__('Bspwm', ProfileType.WindowMgr, description='')
class BspwmProfile(Profile):
def __init__(self) -> None:
super().__init__(
'Bspwm',
ProfileType.WindowMgr,
support_gfx_driver=True,
display_server=DisplayServerType.Xorg,
)
@property
def packages(self) -> List[str]:
@override
def packages(self) -> list[str]:
return [
'bspwm',
'sxhkd',
'dmenu',
'xdo',
'rxvt-unicode'
'rxvt-unicode',
]
@property
def default_greeter_type(self) -> Optional[GreeterType]:
@override
def default_greeter_type(self) -> GreeterType:
return GreeterType.Lightdm
def preview_text(self) -> Optional[str]:
text = str(_('Environment type: {}')).format(self.profile_type.value)
return text + '\n' + self.packages_text()
@override
def provision(self, install_session: Installer, users: list[User]) -> None:
for user in users:
install_session.arch_chroot('mkdir -p ~/.config/bspwm ~/.config/sxhkd', run_as=user.username)
install_session.arch_chroot('cp /usr/share/doc/bspwm/examples/bspwmrc ~/.config/bspwm/', run_as=user.username)
install_session.arch_chroot('cp /usr/share/doc/bspwm/examples/sxhkdrc ~/.config/sxhkd/', run_as=user.username)
install_session.arch_chroot('chmod +x ~/.config/bspwm/bspwmrc', run_as=user.username)

View File

@ -1,30 +1,30 @@
from typing import List, Optional, Any, TYPE_CHECKING
from typing import override
from archinstall.default_profiles.profile import ProfileType, GreeterType
from archinstall.default_profiles.xorg import XorgProfile
if TYPE_CHECKING:
_: Any
from archinstall.default_profiles.profile import DisplayServerType, GreeterType, Profile, ProfileType
class BudgieProfile(XorgProfile):
def __init__(self):
super().__init__('Budgie', ProfileType.DesktopEnv, description='')
class BudgieProfile(Profile):
def __init__(self) -> None:
super().__init__(
'Budgie',
ProfileType.DesktopEnv,
support_gfx_driver=True,
display_server=DisplayServerType.Wayland,
)
@property
def packages(self) -> List[str]:
@override
def packages(self) -> list[str]:
return [
"arc-gtk-theme",
"budgie",
"mate-terminal",
"nemo",
"papirus-icon-theme"
'materia-gtk-theme',
'budgie',
'mate-terminal',
'nemo',
'nemo-fileroller',
'papirus-icon-theme',
]
@property
def default_greeter_type(self) -> Optional[GreeterType]:
return GreeterType.Lightdm
def preview_text(self) -> Optional[str]:
text = str(_('Environment type: {}')).format(self.profile_type.value)
return text + '\n' + self.packages_text()
@override
def default_greeter_type(self) -> GreeterType:
return GreeterType.LightdmSlick

View File

@ -1,31 +1,33 @@
from typing import Optional, List, Any, TYPE_CHECKING
from typing import override
from archinstall.default_profiles.profile import ProfileType, GreeterType
from archinstall.default_profiles.xorg import XorgProfile
if TYPE_CHECKING:
_: Any
from archinstall.default_profiles.profile import DisplayServerType, GreeterType, Profile, ProfileType
class CinnamonProfile(XorgProfile):
def __init__(self):
super().__init__('Cinnamon', ProfileType.DesktopEnv, description='')
class CinnamonProfile(Profile):
def __init__(self) -> None:
super().__init__(
'Cinnamon',
ProfileType.DesktopEnv,
support_gfx_driver=True,
display_server=DisplayServerType.Xorg,
)
@property
def packages(self) -> List[str]:
@override
def packages(self) -> list[str]:
return [
"cinnamon",
"system-config-printer",
"gnome-keyring",
"gnome-terminal",
"blueberry",
"metacity"
'cinnamon',
'system-config-printer',
'gnome-keyring',
'gnome-terminal',
'engrampa',
'gnome-screenshot',
'gvfs-smb',
'xed',
'xdg-user-dirs-gtk',
]
@property
def default_greeter_type(self) -> Optional[GreeterType]:
@override
def default_greeter_type(self) -> GreeterType:
return GreeterType.Lightdm
def preview_text(self) -> Optional[str]:
text = str(_('Environment type: {}')).format(self.profile_type.value)
return text + '\n' + self.packages_text()

View File

@ -0,0 +1,26 @@
from typing import override
from archinstall.default_profiles.profile import DisplayServerType, GreeterType, Profile, ProfileType
class CosmicProfile(Profile):
def __init__(self) -> None:
super().__init__(
'Cosmic',
ProfileType.DesktopEnv,
support_gfx_driver=True,
display_server=DisplayServerType.Wayland,
)
@property
@override
def packages(self) -> list[str]:
return [
'cosmic',
'xdg-user-dirs',
]
@property
@override
def default_greeter_type(self) -> GreeterType:
return GreeterType.CosmicSession

View File

@ -1,31 +0,0 @@
from typing import Optional, List, Any, TYPE_CHECKING
from archinstall.default_profiles.profile import ProfileType, GreeterType
from archinstall.default_profiles.xorg import XorgProfile
if TYPE_CHECKING:
from archinstall.lib.installer import Installer
_: Any
class CutefishProfile(XorgProfile):
def __init__(self):
super().__init__('Cutefish', ProfileType.DesktopEnv, description='')
@property
def packages(self) -> List[str]:
return [
"cutefish",
"noto-fonts"
]
@property
def default_greeter_type(self) -> Optional[GreeterType]:
return GreeterType.Sddm
def preview_text(self) -> Optional[str]:
text = str(_('Environment type: {}')).format(self.profile_type.value)
return text + '\n' + self.packages_text()
def install(self, install_session: 'Installer'):
super().install(install_session)

View File

@ -1,28 +1,27 @@
from typing import List, Optional, Any, TYPE_CHECKING
from typing import override
from archinstall.default_profiles.profile import ProfileType, GreeterType
from archinstall.default_profiles.xorg import XorgProfile
if TYPE_CHECKING:
_: Any
from archinstall.default_profiles.profile import DisplayServerType, GreeterType, Profile, ProfileType
class DeepinProfile(XorgProfile):
def __init__(self):
super().__init__('Deepin', ProfileType.DesktopEnv, description='')
class DeepinProfile(Profile):
def __init__(self) -> None:
super().__init__(
'Deepin',
ProfileType.DesktopEnv,
support_gfx_driver=True,
display_server=DisplayServerType.Xorg,
)
@property
def packages(self) -> List[str]:
@override
def packages(self) -> list[str]:
return [
"deepin",
"deepin-terminal",
"deepin-editor"
'deepin',
'deepin-terminal',
'deepin-editor',
]
@property
def default_greeter_type(self) -> Optional[GreeterType]:
@override
def default_greeter_type(self) -> GreeterType:
return GreeterType.Lightdm
def preview_text(self) -> Optional[str]:
text = str(_('Environment type: {}')).format(self.profile_type.value)
return text + '\n' + self.packages_text()

View File

@ -1,27 +1,26 @@
from typing import List, Optional, Any, TYPE_CHECKING
from typing import override
from archinstall.default_profiles.profile import ProfileType, GreeterType
from archinstall.default_profiles.xorg import XorgProfile
if TYPE_CHECKING:
_: Any
from archinstall.default_profiles.profile import DisplayServerType, GreeterType, Profile, ProfileType
class EnlighenmentProfile(XorgProfile):
def __init__(self):
super().__init__('Enlightenment', ProfileType.WindowMgr, description='')
class EnlightenmentProfile(Profile):
def __init__(self) -> None:
super().__init__(
'Enlightenment',
ProfileType.WindowMgr,
support_gfx_driver=True,
display_server=DisplayServerType.Xorg,
)
@property
def packages(self) -> List[str]:
@override
def packages(self) -> list[str]:
return [
"enlightenment",
"terminology"
'enlightenment',
'terminology',
]
@property
def default_greeter_type(self) -> Optional[GreeterType]:
@override
def default_greeter_type(self) -> GreeterType:
return GreeterType.Lightdm
def preview_text(self) -> Optional[str]:
text = str(_('Environment type: {}')).format(self.profile_type.value)
return text + '\n' + self.packages_text()

View File

@ -1,27 +1,26 @@
from typing import List, Optional, Any, TYPE_CHECKING
from typing import override
from archinstall.default_profiles.profile import ProfileType, GreeterType
from archinstall.default_profiles.xorg import XorgProfile
if TYPE_CHECKING:
_: Any
from archinstall.default_profiles.profile import DisplayServerType, GreeterType, Profile, ProfileType
class GnomeProfile(XorgProfile):
def __init__(self):
super().__init__('Gnome', ProfileType.DesktopEnv, description='')
class GnomeProfile(Profile):
def __init__(self) -> None:
super().__init__(
'GNOME',
ProfileType.DesktopEnv,
support_gfx_driver=True,
display_server=DisplayServerType.Wayland,
)
@property
def packages(self) -> List[str]:
@override
def packages(self) -> list[str]:
return [
'gnome',
'gnome-tweaks'
'gnome-tweaks',
]
@property
def default_greeter_type(self) -> Optional[GreeterType]:
@override
def default_greeter_type(self) -> GreeterType:
return GreeterType.Gdm
def preview_text(self) -> Optional[str]:
text = str(_('Environment type: {}')).format(self.profile_type.value)
return text + '\n' + self.packages_text()

View File

@ -1,31 +0,0 @@
from typing import List, Optional, Any, TYPE_CHECKING
from archinstall.default_profiles.profile import ProfileType, GreeterType
from archinstall.default_profiles.xorg import XorgProfile
if TYPE_CHECKING:
_: Any
class HyperlandProfile(XorgProfile):
def __init__(self):
super().__init__('Hyperland', ProfileType.DesktopEnv, description='')
@property
def packages(self) -> List[str]:
return [
"hyprland",
"dunst",
"xdg-desktop-portal-hyprland",
"kitty",
"qt5-wayland",
"qt6-wayland"
]
@property
def default_greeter_type(self) -> Optional[GreeterType]:
return GreeterType.Sddm
def preview_text(self) -> Optional[str]:
text = str(_('Environment type: {}')).format(self.profile_type.value)
return text + '\n' + self.packages_text()

View File

@ -0,0 +1,52 @@
from typing import override
from archinstall.default_profiles.desktops.utils import select_seat_access
from archinstall.default_profiles.profile import CustomSetting, DisplayServerType, GreeterType, Profile, ProfileType
class HyprlandProfile(Profile):
def __init__(self) -> None:
super().__init__(
'Hyprland',
ProfileType.DesktopEnv,
support_gfx_driver=True,
display_server=DisplayServerType.Wayland,
)
self.custom_settings = {CustomSetting.SeatAccess: None}
@property
@override
def packages(self) -> list[str]:
return [
'hyprland',
'dunst',
'kitty',
'uwsm',
'dolphin',
'wofi',
'xdg-desktop-portal-hyprland',
'qt5-wayland',
'qt6-wayland',
'polkit-kde-agent',
'grim',
'slurp',
]
@property
@override
def default_greeter_type(self) -> GreeterType:
return GreeterType.Sddm
@property
@override
def services(self) -> list[str]:
if pref := self.custom_settings.get(CustomSetting.SeatAccess, None):
return [pref]
return []
@override
async def do_on_select(self) -> None:
default = self.custom_settings.get(CustomSetting.SeatAccess, None)
seat_access = await select_seat_access(self.name, default)
self.custom_settings[CustomSetting.SeatAccess] = seat_access.value

View File

@ -1,33 +1,33 @@
from typing import Optional, List, Any, TYPE_CHECKING
from typing import override
from archinstall.default_profiles.profile import ProfileType, GreeterType
from archinstall.default_profiles.xorg import XorgProfile
if TYPE_CHECKING:
_: Any
from archinstall.default_profiles.profile import DisplayServerType, GreeterType, Profile, ProfileType
class I3wmProfile(XorgProfile):
def __init__(self):
super().__init__('i3-wm', ProfileType.WindowMgr, description='')
class I3wmProfile(Profile):
def __init__(self) -> None:
super().__init__(
'i3-wm',
ProfileType.WindowMgr,
support_gfx_driver=True,
display_server=DisplayServerType.Xorg,
)
@property
def packages(self) -> List[str]:
@override
def packages(self) -> list[str]:
return [
'i3-wm',
'i3lock',
'i3status',
'i3blocks',
'xss-lock',
'xterm',
'lightdm-gtk-greeter',
'lightdm',
'dmenu'
'dmenu',
]
@property
def default_greeter_type(self) -> Optional[GreeterType]:
@override
def default_greeter_type(self) -> GreeterType:
return GreeterType.Lightdm
def preview_text(self) -> Optional[str]:
text = str(_('Environment type: {}')).format(self.profile_type.value)
return text + '\n' + self.packages_text()

View File

@ -1,32 +0,0 @@
from typing import List, Optional, Any, TYPE_CHECKING
from archinstall.default_profiles.profile import ProfileType, GreeterType
from archinstall.default_profiles.xorg import XorgProfile
if TYPE_CHECKING:
_: Any
class KdeProfile(XorgProfile):
def __init__(self):
super().__init__('Kde', ProfileType.DesktopEnv, description='')
@property
def packages(self) -> List[str]:
return [
"plasma-meta",
"konsole",
"kwrite",
"dolphin",
"ark",
"plasma-wayland-session",
"egl-wayland"
]
@property
def default_greeter_type(self) -> Optional[GreeterType]:
return GreeterType.Sddm
def preview_text(self) -> Optional[str]:
text = str(_('Environment type: {}')).format(self.profile_type.value)
return text + '\n' + self.packages_text()

View File

@ -0,0 +1,46 @@
from typing import override
from archinstall.default_profiles.desktops.utils import select_seat_access
from archinstall.default_profiles.profile import CustomSetting, DisplayServerType, GreeterType, Profile, ProfileType
class LabwcProfile(Profile):
def __init__(self) -> None:
super().__init__(
'Labwc',
ProfileType.WindowMgr,
support_gfx_driver=True,
display_server=DisplayServerType.Wayland,
)
self.custom_settings = {CustomSetting.SeatAccess: None}
@property
@override
def packages(self) -> list[str]:
additional = []
if seat := self.custom_settings.get(CustomSetting.SeatAccess, None):
additional = [seat]
return [
'alacritty',
'labwc',
] + additional
@property
@override
def default_greeter_type(self) -> GreeterType:
return GreeterType.Lightdm
@property
@override
def services(self) -> list[str]:
if pref := self.custom_settings.get(CustomSetting.SeatAccess, None):
return [pref]
return []
@override
async def do_on_select(self) -> None:
default = self.custom_settings.get(CustomSetting.SeatAccess, None)
seat_access = await select_seat_access(self.name, default)
self.custom_settings[CustomSetting.SeatAccess] = seat_access.value

View File

@ -1,35 +1,34 @@
from typing import List, Optional, Any, TYPE_CHECKING
from typing import override
from archinstall.default_profiles.profile import ProfileType, GreeterType
from archinstall.default_profiles.xorg import XorgProfile
if TYPE_CHECKING:
_: Any
from archinstall.default_profiles.profile import DisplayServerType, GreeterType, Profile, ProfileType
class LxqtProfile(XorgProfile):
def __init__(self):
super().__init__('Lxqt', ProfileType.DesktopEnv, description='')
class LxqtProfile(Profile):
def __init__(self) -> None:
super().__init__(
'Lxqt',
ProfileType.DesktopEnv,
support_gfx_driver=True,
display_server=DisplayServerType.Xorg,
)
# NOTE: SDDM is the only officially supported greeter for LXQt, so unlike other DEs, lightdm is not used here.
# LXQt works with lightdm, but since this is not supported, we will not default to this.
# https://github.com/lxqt/lxqt/issues/795
@property
def packages(self) -> List[str]:
@override
def packages(self) -> list[str]:
return [
"lxqt",
"breeze-icons",
"oxygen-icons",
"xdg-utils",
"ttf-freefont",
"leafpad",
"slock"
'lxqt',
'breeze-icons',
'oxygen-icons',
'xdg-utils',
'ttf-freefont',
'l3afpad',
'slock',
]
@property
def default_greeter_type(self) -> Optional[GreeterType]:
@override
def default_greeter_type(self) -> GreeterType:
return GreeterType.Sddm
def preview_text(self) -> Optional[str]:
text = str(_('Environment type: {}')).format(self.profile_type.value)
return text + '\n' + self.packages_text()

View File

@ -1,27 +1,26 @@
from typing import List, Optional, Any, TYPE_CHECKING
from typing import override
from archinstall.default_profiles.profile import ProfileType, GreeterType
from archinstall.default_profiles.xorg import XorgProfile
if TYPE_CHECKING:
_: Any
from archinstall.default_profiles.profile import DisplayServerType, GreeterType, Profile, ProfileType
class MateProfile(XorgProfile):
def __init__(self):
super().__init__('Mate', ProfileType.DesktopEnv, description='')
class MateProfile(Profile):
def __init__(self) -> None:
super().__init__(
'Mate',
ProfileType.DesktopEnv,
support_gfx_driver=True,
display_server=DisplayServerType.Xorg,
)
@property
def packages(self) -> List[str]:
@override
def packages(self) -> list[str]:
return [
"mate",
"mate-extra"
'mate',
'mate-extra',
]
@property
def default_greeter_type(self) -> Optional[GreeterType]:
@override
def default_greeter_type(self) -> GreeterType:
return GreeterType.Lightdm
def preview_text(self) -> Optional[str]:
text = str(_('Environment type: {}')).format(self.profile_type.value)
return text + '\n' + self.packages_text()

View File

@ -0,0 +1,54 @@
from typing import override
from archinstall.default_profiles.desktops.utils import select_seat_access
from archinstall.default_profiles.profile import CustomSetting, DisplayServerType, GreeterType, Profile, ProfileType
class NiriProfile(Profile):
def __init__(self) -> None:
super().__init__(
'niri',
ProfileType.WindowMgr,
support_gfx_driver=True,
display_server=DisplayServerType.Wayland,
)
self.custom_settings = {CustomSetting.SeatAccess: None}
@property
@override
def packages(self) -> list[str]:
additional = []
if seat := self.custom_settings.get(CustomSetting.SeatAccess, None):
additional = [seat]
return [
'niri',
'alacritty',
'fuzzel',
'mako',
'xorg-xwayland',
'waybar',
'swaybg',
'swayidle',
'swaylock',
'xdg-desktop-portal-gnome',
] + additional
@property
@override
def default_greeter_type(self) -> GreeterType:
return GreeterType.Lightdm
@property
@override
def services(self) -> list[str]:
if pref := self.custom_settings.get(CustomSetting.SeatAccess, None):
return [pref]
return []
@override
async def do_on_select(self) -> None:
default = self.custom_settings.get(CustomSetting.SeatAccess, None)
seat_access = await select_seat_access(self.name, default)
self.custom_settings[CustomSetting.SeatAccess] = seat_access.value

View File

@ -0,0 +1,66 @@
import shutil
from pathlib import Path
from typing import TYPE_CHECKING, override
from archinstall.default_profiles.profile import DisplayServerType, GreeterType, Profile, ProfileType
if TYPE_CHECKING:
from archinstall.lib.installer import Installer
from archinstall.lib.models.users import User
_TERMINAL = 'alacritty'
_ASSETS_DIR = Path(__file__).parent / 'niri_dms_assets'
class NiriDmsProfile(Profile):
def __init__(self) -> None:
super().__init__(
'niri - DankMaterialShell',
ProfileType.WindowMgr,
support_gfx_driver=True,
display_server=DisplayServerType.Wayland,
)
@property
@override
def packages(self) -> list[str]:
return [
'niri',
'dms-shell-niri',
'polkit',
'xdg-desktop-portal-gnome',
'xorg-xwayland',
'matugen',
'cava',
'kimageformats',
'cups-pk-helper',
'tuned-ppd',
_TERMINAL,
]
@property
@override
def default_greeter_type(self) -> GreeterType:
return GreeterType.GreetdDms
@override
def provision(self, install_session: Installer, users: list[User]) -> None:
binds = (_ASSETS_DIR / 'dms/binds.kdl').read_text().replace('{{TERMINAL_COMMAND}}', _TERMINAL)
for user in users:
home = install_session.target / 'home' / user.username
niri_dir = home / '.config/niri'
dms_dir = niri_dir / 'dms'
dms_dir.mkdir(parents=True, exist_ok=True)
shutil.copy(_ASSETS_DIR / 'niri.kdl', niri_dir / 'config.kdl')
for name in ('colors.kdl', 'layout.kdl', 'alttab.kdl', 'outputs.kdl', 'cursor.kdl'):
shutil.copy(_ASSETS_DIR / 'dms' / name, dms_dir / name)
(dms_dir / 'binds.kdl').write_text(binds)
niri_unit_dropin = home / '.config/systemd/user/niri.service.d'
niri_unit_dropin.mkdir(parents=True, exist_ok=True)
(niri_unit_dropin / 'dms.conf').write_text('[Unit]\nWants=dms.service\n')
install_session.arch_chroot(f'chown -R {user.username}:{user.username} /home/{user.username}/.config')

View File

@ -0,0 +1,10 @@
// ! DO NOT EDIT !
// ! AUTO-GENERATED BY DMS !
// ! CHANGES WILL BE OVERWRITTEN !
// ! PLACE YOUR CUSTOM CONFIGURATION ELSEWHERE !
recent-windows {
highlight {
corner-radius 12
}
}

View File

@ -0,0 +1,221 @@
binds {
// === System & Overview ===
Mod+D repeat=false { toggle-overview; }
Mod+Tab repeat=false { toggle-overview; }
Mod+Shift+Slash { show-hotkey-overlay; }
// === Application Launchers ===
Mod+T hotkey-overlay-title="Open Terminal" { spawn "{{TERMINAL_COMMAND}}"; }
Mod+Space hotkey-overlay-title="Application Launcher" {
spawn "dms" "ipc" "call" "spotlight" "toggle";
}
Mod+V hotkey-overlay-title="Clipboard Manager" {
spawn "dms" "ipc" "call" "clipboard" "toggle";
}
Mod+M hotkey-overlay-title="Task Manager" {
spawn "dms" "ipc" "call" "processlist" "focusOrToggle";
}
Super+X hotkey-overlay-title="Power Menu: Toggle" { spawn "dms" "ipc" "call" "powermenu" "toggle"; }
Mod+Comma hotkey-overlay-title="Settings" {
spawn "dms" "ipc" "call" "settings" "focusOrToggle";
}
Mod+Y hotkey-overlay-title="Browse Wallpapers" {
spawn "dms" "ipc" "call" "dankdash" "wallpaper";
}
Mod+N hotkey-overlay-title="Notification Center" { spawn "dms" "ipc" "call" "notifications" "toggle"; }
Mod+Shift+N hotkey-overlay-title="Notepad" { spawn "dms" "ipc" "call" "notepad" "toggle"; }
// === Security ===
Mod+Alt+L hotkey-overlay-title="Lock Screen" {
spawn "dms" "ipc" "call" "lock" "lock";
}
Mod+Shift+E { quit; }
Ctrl+Alt+Delete hotkey-overlay-title="Task Manager" {
spawn "dms" "ipc" "call" "processlist" "focusOrToggle";
}
// === Audio Controls ===
XF86AudioRaiseVolume allow-when-locked=true {
spawn "dms" "ipc" "call" "audio" "increment" "3";
}
XF86AudioLowerVolume allow-when-locked=true {
spawn "dms" "ipc" "call" "audio" "decrement" "3";
}
XF86AudioMute allow-when-locked=true {
spawn "dms" "ipc" "call" "audio" "mute";
}
XF86AudioMicMute allow-when-locked=true {
spawn "dms" "ipc" "call" "audio" "micmute";
}
XF86AudioPause allow-when-locked=true {
spawn "dms" "ipc" "call" "mpris" "playPause";
}
XF86AudioPlay allow-when-locked=true {
spawn "dms" "ipc" "call" "mpris" "playPause";
}
XF86AudioPrev allow-when-locked=true {
spawn "dms" "ipc" "call" "mpris" "previous";
}
XF86AudioNext allow-when-locked=true {
spawn "dms" "ipc" "call" "mpris" "next";
}
Ctrl+XF86AudioRaiseVolume allow-when-locked=true {
spawn "dms" "ipc" "call" "mpris" "increment" "3";
}
Ctrl+XF86AudioLowerVolume allow-when-locked=true {
spawn "dms" "ipc" "call" "mpris" "decrement" "3";
}
// === Brightness Controls ===
XF86MonBrightnessUp allow-when-locked=true {
spawn "dms" "ipc" "call" "brightness" "increment" "5" "";
}
XF86MonBrightnessDown allow-when-locked=true {
spawn "dms" "ipc" "call" "brightness" "decrement" "5" "";
}
// === Window Management ===
Mod+Q repeat=false { close-window; }
Mod+F { maximize-column; }
Mod+Shift+F { fullscreen-window; }
Mod+Shift+T { toggle-window-floating; }
Mod+Shift+V { switch-focus-between-floating-and-tiling; }
Mod+W { toggle-column-tabbed-display; }
Mod+Shift+W hotkey-overlay-title="Create window rule" { spawn "dms" "ipc" "call" "window-rules" "toggle"; }
// === Focus Navigation ===
Mod+Left { focus-column-left; }
Mod+Down { focus-window-down; }
Mod+Up { focus-window-up; }
Mod+Right { focus-column-right; }
Mod+H { focus-column-left; }
Mod+J { focus-window-down; }
Mod+K { focus-window-up; }
Mod+L { focus-column-right; }
// === Window Movement ===
Mod+Shift+Left { move-column-left; }
Mod+Shift+Down { move-window-down; }
Mod+Shift+Up { move-window-up; }
Mod+Shift+Right { move-column-right; }
Mod+Shift+H { move-column-left; }
Mod+Shift+J { move-window-down; }
Mod+Shift+K { move-window-up; }
Mod+Shift+L { move-column-right; }
// === Column Navigation ===
Mod+Home { focus-column-first; }
Mod+End { focus-column-last; }
Mod+Ctrl+Home { move-column-to-first; }
Mod+Ctrl+End { move-column-to-last; }
// === Monitor Navigation ===
Mod+Ctrl+Left { focus-monitor-left; }
//Mod+Ctrl+Down { focus-monitor-down; }
//Mod+Ctrl+Up { focus-monitor-up; }
Mod+Ctrl+Right { focus-monitor-right; }
Mod+Ctrl+H { focus-monitor-left; }
Mod+Ctrl+J { focus-monitor-down; }
Mod+Ctrl+K { focus-monitor-up; }
Mod+Ctrl+L { focus-monitor-right; }
// === Move to Monitor ===
Mod+Shift+Ctrl+Left { move-column-to-monitor-left; }
Mod+Shift+Ctrl+Down { move-column-to-monitor-down; }
Mod+Shift+Ctrl+Up { move-column-to-monitor-up; }
Mod+Shift+Ctrl+Right { move-column-to-monitor-right; }
Mod+Shift+Ctrl+H { move-column-to-monitor-left; }
Mod+Shift+Ctrl+J { move-column-to-monitor-down; }
Mod+Shift+Ctrl+K { move-column-to-monitor-up; }
Mod+Shift+Ctrl+L { move-column-to-monitor-right; }
// === Workspace Navigation ===
Mod+Page_Down { focus-workspace-down; }
Mod+Page_Up { focus-workspace-up; }
Mod+U { focus-workspace-down; }
Mod+I { focus-workspace-up; }
Mod+Ctrl+Down { move-column-to-workspace-down; }
Mod+Ctrl+Up { move-column-to-workspace-up; }
Mod+Ctrl+U { move-column-to-workspace-down; }
Mod+Ctrl+I { move-column-to-workspace-up; }
// === Workspace Management ===
Ctrl+Shift+R hotkey-overlay-title="Rename Workspace" {
spawn "dms" "ipc" "call" "workspace-rename" "open";
}
// === Move Workspaces ===
Mod+Shift+Page_Down { move-workspace-down; }
Mod+Shift+Page_Up { move-workspace-up; }
Mod+Shift+U { move-workspace-down; }
Mod+Shift+I { move-workspace-up; }
// === Mouse Wheel Navigation ===
Mod+WheelScrollDown cooldown-ms=150 { focus-workspace-down; }
Mod+WheelScrollUp cooldown-ms=150 { focus-workspace-up; }
Mod+Ctrl+WheelScrollDown cooldown-ms=150 { move-column-to-workspace-down; }
Mod+Ctrl+WheelScrollUp cooldown-ms=150 { move-column-to-workspace-up; }
Mod+WheelScrollRight { focus-column-right; }
Mod+WheelScrollLeft { focus-column-left; }
Mod+Ctrl+WheelScrollRight { move-column-right; }
Mod+Ctrl+WheelScrollLeft { move-column-left; }
Mod+Shift+WheelScrollDown { focus-column-right; }
Mod+Shift+WheelScrollUp { focus-column-left; }
Mod+Ctrl+Shift+WheelScrollDown { move-column-right; }
Mod+Ctrl+Shift+WheelScrollUp { move-column-left; }
// === Numbered Workspaces ===
Mod+1 { focus-workspace 1; }
Mod+2 { focus-workspace 2; }
Mod+3 { focus-workspace 3; }
Mod+4 { focus-workspace 4; }
Mod+5 { focus-workspace 5; }
Mod+6 { focus-workspace 6; }
Mod+7 { focus-workspace 7; }
Mod+8 { focus-workspace 8; }
Mod+9 { focus-workspace 9; }
// === Move to Numbered Workspaces ===
Mod+Shift+1 { move-column-to-workspace 1; }
Mod+Shift+2 { move-column-to-workspace 2; }
Mod+Shift+3 { move-column-to-workspace 3; }
Mod+Shift+4 { move-column-to-workspace 4; }
Mod+Shift+5 { move-column-to-workspace 5; }
Mod+Shift+6 { move-column-to-workspace 6; }
Mod+Shift+7 { move-column-to-workspace 7; }
Mod+Shift+8 { move-column-to-workspace 8; }
Mod+Shift+9 { move-column-to-workspace 9; }
// === Column Management ===
Mod+BracketLeft { consume-or-expel-window-left; }
Mod+BracketRight { consume-or-expel-window-right; }
Mod+Period { expel-window-from-column; }
// === Sizing & Layout ===
Mod+R { switch-preset-column-width; }
Mod+Shift+R { switch-preset-window-height; }
Mod+Ctrl+R { reset-window-height; }
Mod+Ctrl+F { expand-column-to-available-width; }
Mod+C { center-column; }
Mod+Ctrl+C { center-visible-columns; }
// === Manual Sizing ===
Mod+Minus { set-column-width "-10%"; }
Mod+Equal { set-column-width "+10%"; }
Mod+Shift+Minus { set-window-height "-10%"; }
Mod+Shift+Equal { set-window-height "+10%"; }
// === Screenshots ===
XF86Launch1 { screenshot; }
Ctrl+XF86Launch1 { screenshot-screen; }
Alt+XF86Launch1 { screenshot-window; }
Print { screenshot; }
Ctrl+Print { screenshot-screen; }
Alt+Print { screenshot-window; }
// === System Controls ===
Mod+Escape allow-inhibiting=false { toggle-keyboard-shortcuts-inhibit; }
Mod+Shift+P { power-off-monitors; }
}

View File

@ -0,0 +1,39 @@
// ! Auto-generated file. Do not edit directly.
// Remove `include "dms/colors.kdl"` from your config to override.
layout {
background-color "transparent"
focus-ring {
active-color "#d0bcff"
inactive-color "#948f99"
urgent-color "#f2b8b5"
}
border {
active-color "#d0bcff"
inactive-color "#948f99"
urgent-color "#f2b8b5"
}
shadow {
color "#00000070"
}
tab-indicator {
active-color "#d0bcff"
inactive-color "#948f99"
urgent-color "#f2b8b5"
}
insert-hint {
color "#d0bcff80"
}
}
recent-windows {
highlight {
active-color "#4f378b"
urgent-color "#f2b8b5"
}
}

View File

@ -0,0 +1,6 @@
// Place cursor configuration here.
// Example:
// cursor {
// xcursor-theme "Adwaita"
// xcursor-size 24
// }

View File

@ -0,0 +1,22 @@
// ! DO NOT EDIT !
// ! AUTO-GENERATED BY DMS !
// ! CHANGES WILL BE OVERWRITTEN !
// ! PLACE YOUR CUSTOM CONFIGURATION ELSEWHERE !
layout {
gaps 4
border {
width 2
}
focus-ring {
width 2
}
}
window-rule {
geometry-corner-radius 12
clip-to-geometry true
tiled-state true
draw-border-with-background false
}

View File

@ -0,0 +1,7 @@
// Place per-output configuration here.
// Example:
// output "DP-1" {
// mode "2560x1440@165"
// position x=0 y=0
// scale 1
// }

View File

@ -0,0 +1,279 @@
// This config is in the KDL format: https://kdl.dev
// "/-" comments out the following node.
// Check the wiki for a full description of the configuration:
// https://github.com/YaLTeR/niri/wiki/Configuration:-Introduction
config-notification {
disable-failed
}
gestures {
hot-corners {
off
}
}
// Input device configuration.
// Find the full list of options on the wiki:
// https://github.com/YaLTeR/niri/wiki/Configuration:-Input
input {
keyboard {
xkb {
// You can set rules, model, layout, variant and options.
// For more information, see xkeyboard-config(7).
// For example:
// layout "us,ru"
// options "grp:win_space_toggle,compose:ralt,ctrl:nocaps"
// If this section is empty, niri will fetch xkb settings
// from org.freedesktop.locale1. You can control these using
// localectl set-x11-keymap.
}
// Enable numlock on startup, omitting this setting disables it.
numlock
}
// Next sections include libinput settings.
// Omitting settings disables them, or leaves them at their default values.
// All commented-out settings here are examples, not defaults.
touchpad {
// off
tap
// dwt
// dwtp
// drag false
// drag-lock
natural-scroll
// accel-speed 0.2
// accel-profile "flat"
// scroll-method "two-finger"
// disabled-on-external-mouse
}
mouse {
// off
// natural-scroll
// accel-speed 0.2
// accel-profile "flat"
// scroll-method "no-scroll"
}
trackpoint {
// off
// natural-scroll
// accel-speed 0.2
// accel-profile "flat"
// scroll-method "on-button-down"
// scroll-button 273
// scroll-button-lock
// middle-emulation
}
// Uncomment this to make the mouse warp to the center of newly focused windows.
// warp-mouse-to-focus
// Focus windows and outputs automatically when moving the mouse into them.
// Setting max-scroll-amount="0%" makes it work only on windows already fully on screen.
// focus-follows-mouse max-scroll-amount="0%"
}
// You can configure outputs by their name, which you can find
// by running `niri msg outputs` while inside a niri instance.
// The built-in laptop monitor is usually called "eDP-1".
// Find more information on the wiki:
// https://github.com/YaLTeR/niri/wiki/Configuration:-Outputs
// Remember to uncomment the node by removing "/-"!
/-output "eDP-2" {
mode "2560x1600@239.998993"
position x=2560 y=0
variable-refresh-rate
}
// Settings that influence how windows are positioned and sized.
// Find more information on the wiki:
// https://github.com/YaLTeR/niri/wiki/Configuration:-Layout
layout {
// Set gaps around windows in logical pixels.
background-color "transparent"
// When to center a column when changing focus, options are:
// - "never", default behavior, focusing an off-screen column will keep at the left
// or right edge of the screen.
// - "always", the focused column will always be centered.
// - "on-overflow", focusing a column will center it if it doesn't fit
// together with the previously focused column.
center-focused-column "never"
// You can customize the widths that "switch-preset-column-width" (Mod+R) toggles between.
preset-column-widths {
// Proportion sets the width as a fraction of the output width, taking gaps into account.
// For example, you can perfectly fit four windows sized "proportion 0.25" on an output.
// The default preset widths are 1/3, 1/2 and 2/3 of the output.
proportion 0.33333
proportion 0.5
proportion 0.66667
// Fixed sets the width in logical pixels exactly.
// fixed 1920
}
// You can also customize the heights that "switch-preset-window-height" (Mod+Shift+R) toggles between.
// preset-window-heights { }
// You can change the default width of the new windows.
default-column-width { proportion 0.5; }
// If you leave the brackets empty, the windows themselves will decide their initial width.
// default-column-width {}
// By default focus ring and border are rendered as a solid background rectangle
// behind windows. That is, they will show up through semitransparent windows.
// This is because windows using client-side decorations can have an arbitrary shape.
//
// If you don't like that, you should uncomment `prefer-no-csd` below.
// Niri will draw focus ring and border *around* windows that agree to omit their
// client-side decorations.
//
// Alternatively, you can override it with a window rule called
// `draw-border-with-background`.
border {
off
width 4
active-color "#707070" // Neutral gray
inactive-color "#d0d0d0" // Light gray
urgent-color "#cc4444" // Softer red
}
shadow {
softness 30
spread 5
offset x=0 y=5
color "#0007"
}
struts {
}
}
layer-rule {
match namespace="^quickshell$"
place-within-backdrop true
}
overview {
workspace-shadow {
off
}
}
// Add lines like this to spawn processes at startup.
// Note that running niri as a session supports xdg-desktop-autostart,
// which may be more convenient to use.
// See the binds section below for more spawn examples.
// This line starts waybar, a commonly used bar for Wayland compositors.
environment {
XDG_CURRENT_DESKTOP "niri"
}
hotkey-overlay {
skip-at-startup
}
prefer-no-csd
screenshot-path "~/Pictures/Screenshots/Screenshot from %Y-%m-%d %H-%M-%S.png"
animations {
workspace-switch {
spring damping-ratio=0.80 stiffness=523 epsilon=0.0001
}
window-open {
duration-ms 150
curve "ease-out-expo"
}
window-close {
duration-ms 150
curve "ease-out-quad"
}
horizontal-view-movement {
spring damping-ratio=0.85 stiffness=423 epsilon=0.0001
}
window-movement {
spring damping-ratio=0.75 stiffness=323 epsilon=0.0001
}
window-resize {
spring damping-ratio=0.85 stiffness=423 epsilon=0.0001
}
config-notification-open-close {
spring damping-ratio=0.65 stiffness=923 epsilon=0.001
}
screenshot-ui-open {
duration-ms 200
curve "ease-out-quad"
}
overview-open-close {
spring damping-ratio=0.85 stiffness=800 epsilon=0.0001
}
}
// Window rules let you adjust behavior for individual windows.
// Find more information on the wiki:
// https://github.com/YaLTeR/niri/wiki/Configuration:-Window-Rules
// Work around WezTerm's initial configure bug
// by setting an empty default-column-width.
window-rule {
// This regular expression is intentionally made as specific as possible,
// since this is the default config, and we want no false positives.
// You can get away with just app-id="wezterm" if you want.
match app-id=r#"^org\.wezfurlong\.wezterm$"#
default-column-width {}
}
window-rule {
match app-id=r#"^org\.gnome\."#
draw-border-with-background false
geometry-corner-radius 12
clip-to-geometry true
}
window-rule {
match app-id=r#"^gnome-control-center$"#
match app-id=r#"^pavucontrol$"#
match app-id=r#"^nm-connection-editor$"#
default-column-width { proportion 0.5; }
open-floating false
}
window-rule {
match app-id=r#"^org\.gnome\.Calculator$"#
match app-id=r#"^gnome-calculator$"#
match app-id=r#"^galculator$"#
match app-id=r#"^blueman-manager$"#
match app-id=r#"^org\.gnome\.Nautilus$"#
match app-id=r#"^xdg-desktop-portal$"#
open-floating true
}
window-rule {
match app-id=r#"^steam$"# title=r#"^notificationtoasts_\d+_desktop$"#
default-floating-position x=10 y=10 relative-to="bottom-right"
open-focused false
}
window-rule {
match app-id=r#"^org\.wezfurlong\.wezterm$"#
match app-id="Alacritty"
match app-id="zen"
match app-id="com.mitchellh.ghostty"
match app-id="kitty"
draw-border-with-background false
}
window-rule {
match app-id=r#"firefox$"# title="^Picture-in-Picture$"
match app-id="zoom"
open-floating true
}
// Open dms windows as floating by default
window-rule {
match app-id=r#"org.quickshell$"#
match app-id=r#"com.danklinux.dms$"#
open-floating true
}
debug {
honor-xdg-activation-with-invalid-serial
}
// Override to disable super+tab
recent-windows {
binds {
Alt+Tab { next-window scope="output"; }
Alt+Shift+Tab { previous-window scope="output"; }
Alt+grave { next-window filter="app-id"; }
Alt+Shift+grave { previous-window filter="app-id"; }
}
}
// Include dms files
include "dms/colors.kdl"
include "dms/layout.kdl"
include "dms/alttab.kdl"
include "dms/binds.kdl"
include "dms/outputs.kdl"
include "dms/cursor.kdl"

View File

@ -0,0 +1,120 @@
from enum import StrEnum
from typing import override
from archinstall.default_profiles.profile import CustomSetting, DisplayServerType, GreeterType, Profile, ProfileType
from archinstall.lib.menu.helpers import Selection
from archinstall.lib.packages.packages import available_package, package_group_info
from archinstall.lib.translationhandler import tr
from archinstall.tui.menu_item import MenuItem, MenuItemGroup
from archinstall.tui.result import ResultType
class PlasmaFlavor(StrEnum):
Meta = 'plasma-meta'
Plasma = 'plasma'
Desktop = 'plasma-desktop'
def show(self) -> str:
match self:
case PlasmaFlavor.Meta:
return f'{self.value} ({tr("Recommended")})'
case PlasmaFlavor.Plasma | PlasmaFlavor.Desktop:
return self.value
def package_details(self) -> str:
ty = ''
details = ''
desc = ''
match self:
case PlasmaFlavor.Meta:
ty = tr('Package')
desc = tr('Curated selection of KDE Plasma packages')
info = available_package(self.value)
if info is not None:
details = tr('Dependencies') + '\n'
details += '\n'.join(f'- {entry}' for entry in info.get_depends_on)
case PlasmaFlavor.Plasma:
ty = tr('Package group')
desc = tr('Extensive KDE Plasma installation')
group = package_group_info(self.value)
if group is not None:
details = tr('Packages in group') + '\n'
details += '\n'.join(f'- {entry}' for entry in group.packages)
case PlasmaFlavor.Desktop:
ty = tr('Package group')
desc = tr('Minimal KDE Plasma installation')
info = available_package(self.value)
if info is not None:
details = tr('Dependencies') + '\n'
details += '\n'.join(f'- {entry}' for entry in info.get_depends_on)
return f'{tr("Type")}: {ty}\n{tr("Description")}: {desc}\n\n{details}'
def packages(self) -> list[str]:
match self:
case PlasmaFlavor.Meta:
return ['plasma-meta']
case PlasmaFlavor.Plasma:
return ['plasma']
case PlasmaFlavor.Desktop:
return ['plasma-desktop']
class PlasmaProfile(Profile):
def __init__(self) -> None:
super().__init__(
'KDE Plasma',
ProfileType.DesktopEnv,
support_gfx_driver=True,
display_server=DisplayServerType.Wayland,
)
@property
@override
def packages(self) -> list[str]:
flavor_str = self.custom_settings.get(CustomSetting.PlasmaFlavor)
if flavor_str is not None:
flavor = PlasmaFlavor(flavor_str)
return flavor.packages()
else:
return PlasmaFlavor.Meta.packages() # use plasma-meta as the recommended default
@property
@override
def default_greeter_type(self) -> GreeterType:
return GreeterType.PlasmaLoginManager
async def _select_flavor(self) -> None:
header = tr('Select a flavor of KDE Plasma to install') + '\n'
items = [
MenuItem(
s.show(),
value=s,
preview_action=lambda x: x.value.package_details() if x.value else None,
)
for s in PlasmaFlavor
]
group = MenuItemGroup(items, sort_items=False)
default = self.custom_settings.get(CustomSetting.PlasmaFlavor, None)
group.set_default_by_value(default)
result = await Selection[PlasmaFlavor](
group,
header=header,
allow_skip=False,
preview_location='right',
).show()
if result.type_ == ResultType.Selection:
self.custom_settings[CustomSetting.PlasmaFlavor] = result.get_value().value
@override
async def do_on_select(self) -> None:
await self._select_flavor()

View File

@ -1,27 +1,26 @@
from typing import Optional, List, Any, TYPE_CHECKING
from typing import override
from archinstall.default_profiles.profile import ProfileType, GreeterType
from archinstall.default_profiles.xorg import XorgProfile
if TYPE_CHECKING:
_: Any
from archinstall.default_profiles.profile import DisplayServerType, GreeterType, Profile, ProfileType
class QtileProfile(XorgProfile):
def __init__(self):
super().__init__('Qtile', ProfileType.WindowMgr, description='')
class QtileProfile(Profile):
def __init__(self) -> None:
super().__init__(
'Qtile',
ProfileType.WindowMgr,
support_gfx_driver=True,
display_server=DisplayServerType.Xorg,
)
@property
def packages(self) -> List[str]:
@override
def packages(self) -> list[str]:
return [
'qtile',
'alacritty'
'alacritty',
]
@property
def default_greeter_type(self) -> Optional[GreeterType]:
@override
def default_greeter_type(self) -> GreeterType:
return GreeterType.Lightdm
def preview_text(self) -> Optional[str]:
text = str(_('Environment type: {}')).format(self.profile_type.value)
return text + '\n' + self.packages_text()

View File

@ -0,0 +1,27 @@
from typing import override
from archinstall.default_profiles.profile import DisplayServerType, GreeterType, Profile, ProfileType
class RiverProfile(Profile):
def __init__(self) -> None:
super().__init__(
'River',
ProfileType.WindowMgr,
support_gfx_driver=True,
display_server=DisplayServerType.Wayland,
)
@property
@override
def packages(self) -> list[str]:
return [
'foot',
'xdg-desktop-portal-wlr',
'river',
]
@property
@override
def default_greeter_type(self) -> GreeterType:
return GreeterType.Lightdm

View File

@ -1,81 +1,56 @@
from enum import Enum
from typing import List, Optional, TYPE_CHECKING, Any
from typing import override
from archinstall.default_profiles.profile import ProfileType, GreeterType
from archinstall.default_profiles.xorg import XorgProfile
from archinstall.lib.menu import Menu
if TYPE_CHECKING:
from archinstall.lib.installer import Installer
_: Any
from archinstall.default_profiles.desktops.utils import select_seat_access
from archinstall.default_profiles.profile import CustomSetting, DisplayServerType, GreeterType, Profile, ProfileType
class SeatAccess(Enum):
seatd = 'seatd'
polkit = 'polkit'
class SwayProfile(XorgProfile):
def __init__(self):
class SwayProfile(Profile):
def __init__(self) -> None:
super().__init__(
'Sway',
ProfileType.WindowMgr,
description=''
support_gfx_driver=True,
display_server=DisplayServerType.Wayland,
)
self.custom_settings = {'seat_access': None}
self.custom_settings = {CustomSetting.SeatAccess: None}
@property
def packages(self) -> List[str]:
@override
def packages(self) -> list[str]:
additional = []
if seat := self.custom_settings.get('seat_access', None):
if seat := self.custom_settings.get(CustomSetting.SeatAccess, None):
additional = [seat]
return [
"sway",
"swaybg",
"swaylock",
"swayidle",
"waybar",
"dmenu",
"brightnessctl",
"grim",
"slurp",
"pavucontrol",
"foot",
"xorg-xwayland"
'sway',
'swaybg',
'swaylock',
'swayidle',
'waybar',
'wmenu',
'brightnessctl',
'grim',
'slurp',
'pavucontrol',
'foot',
'xorg-xwayland',
] + additional
@property
def default_greeter_type(self) -> Optional[GreeterType]:
@override
def default_greeter_type(self) -> GreeterType:
return GreeterType.Lightdm
@property
def services(self) -> List[str]:
if pref := self.custom_settings.get('seat_access', None):
return [pref.value]
@override
def services(self) -> list[str]:
if pref := self.custom_settings.get(CustomSetting.SeatAccess, None):
return [pref]
return []
def _ask_seat_access(self):
# need to activate seat service and add to seat group
title = str(_('Sway needs access to your seat (collection of hardware devices i.e. keyboard, mouse, etc)'))
title += str(_('\n\nChoose an option to give Sway access to your hardware'))
options = [e.value for e in SeatAccess]
default = None
if seat := self.custom_settings.get('seat_access', None):
default = seat
choice = Menu(title, options, skip=False, preset_values=default).run()
self.custom_settings['seat_access'] = choice.single_value
def do_on_select(self):
self._ask_seat_access()
def preview_text(self) -> Optional[str]:
text = str(_('Environment type: {}')).format(self.profile_type.value)
return text + '\n' + self.packages_text()
def install(self, install_session: 'Installer'):
super().install(install_session)
@override
async def do_on_select(self) -> None:
default = self.custom_settings.get(CustomSetting.SeatAccess, None)
seat_access = await select_seat_access(self.name, default)
self.custom_settings[CustomSetting.SeatAccess] = seat_access.value

View File

@ -0,0 +1,45 @@
from enum import Enum
from archinstall.lib.installer import Installer
from archinstall.lib.menu.helpers import Selection
from archinstall.lib.models.users import User
from archinstall.lib.translationhandler import tr
from archinstall.tui.menu_item import MenuItem, MenuItemGroup
from archinstall.tui.result import ResultType
class SeatAccess(Enum):
seatd = 'seatd'
polkit = 'polkit'
def provision_seat_access(
install_session: Installer,
users: list[User],
seat_access: str,
) -> None:
if seat_access == SeatAccess.seatd.value:
for user in users:
install_session.arch_chroot(f'usermod -a -G seat {user.username}')
async def select_seat_access(profile_name: str, default: str | None) -> SeatAccess:
header = tr('{} needs access to your seat').format(profile_name)
header += f' ({tr("collection of hardware devices i.e. keyboard, mouse")})' + '\n'
header += tr('Choose an option how to give {} access to your hardware').format(profile_name)
items = [MenuItem(s.value, value=s) for s in SeatAccess]
group = MenuItemGroup(items, sort_items=True)
group.set_default_by_value(default)
result = await Selection[SeatAccess](
group,
header=header,
allow_skip=False,
).show()
if result.type_ == ResultType.Selection:
return result.get_value()
else:
raise ValueError('Unexpected result type from seat access selection')

View File

@ -1,30 +1,29 @@
from typing import List, Optional, Any, TYPE_CHECKING
from typing import override
from archinstall.default_profiles.profile import ProfileType, GreeterType
from archinstall.default_profiles.xorg import XorgProfile
if TYPE_CHECKING:
_: Any
from archinstall.default_profiles.profile import DisplayServerType, GreeterType, Profile, ProfileType
class Xfce4Profile(XorgProfile):
def __init__(self):
super().__init__('Xfce4', ProfileType.DesktopEnv, description='')
class Xfce4Profile(Profile):
def __init__(self) -> None:
super().__init__(
'Xfce4',
ProfileType.DesktopEnv,
support_gfx_driver=True,
display_server=DisplayServerType.Xorg,
)
@property
def packages(self) -> List[str]:
@override
def packages(self) -> list[str]:
return [
"xfce4",
"xfce4-goodies",
"pavucontrol",
"gvfs",
"xarchiver"
'xfce4',
'xfce4-goodies',
'pavucontrol',
'gvfs',
'xarchiver',
]
@property
def default_greeter_type(self) -> Optional[GreeterType]:
@override
def default_greeter_type(self) -> GreeterType:
return GreeterType.Lightdm
def preview_text(self) -> Optional[str]:
text = str(_('Environment type: {}')).format(self.profile_type.value)
return text + '\n' + self.packages_text()

View File

@ -0,0 +1,29 @@
from typing import override
from archinstall.default_profiles.profile import DisplayServerType, GreeterType, Profile, ProfileType
class XmonadProfile(Profile):
def __init__(self) -> None:
super().__init__(
'Xmonad',
ProfileType.WindowMgr,
support_gfx_driver=True,
display_server=DisplayServerType.Xorg,
)
@property
@override
def packages(self) -> list[str]:
return [
'xmonad',
'xmonad-contrib',
'xmonad-extras',
'xterm',
'dmenu',
]
@property
@override
def default_greeter_type(self) -> GreeterType:
return GreeterType.Lightdm

View File

@ -1,15 +1,9 @@
from typing import Any, TYPE_CHECKING
from archinstall.default_profiles.profile import Profile, ProfileType
if TYPE_CHECKING:
_: Any
class MinimalProfile(Profile):
def __init__(self):
def __init__(self) -> None:
super().__init__(
'Minimal',
ProfileType.Minimal,
description=str(_('A very basic installation that allows you to customize Arch Linux as you see fit.'))
)

View File

@ -1,16 +1,16 @@
from __future__ import annotations
from enum import Enum, StrEnum, auto
from typing import TYPE_CHECKING, Self
from enum import Enum, auto
from typing import List, Optional, Any, Dict, TYPE_CHECKING, TypeVar
from archinstall.lib.utils.util import format_cols
from archinstall.lib.translationhandler import tr
if TYPE_CHECKING:
from archinstall.lib.installer import Installer
_: Any
from archinstall.lib.models.users import User
TProfile = TypeVar('TProfile', bound='Profile')
class DisplayServerType(Enum):
Xorg = 'Xorg'
Wayland = 'Wayland'
class ProfileType(Enum):
@ -26,14 +26,18 @@ class ProfileType(Enum):
DesktopEnv = 'Desktop Environment'
CustomType = 'CustomType'
# special things
Tailored = 'Tailored'
Application = 'Application'
class GreeterType(Enum):
Lightdm = 'lightdm'
Lightdm = 'lightdm-gtk-greeter'
LightdmSlick = 'lightdm-slick-greeter'
Sddm = 'sddm'
Gdm = 'gdm'
Ly = 'ly'
CosmicSession = 'cosmic-greeter'
PlasmaLoginManager = 'plasma-login-manager'
GreetdDms = 'dms-greeter'
class SelectResult(Enum):
@ -42,29 +46,34 @@ class SelectResult(Enum):
ResetCurrent = auto()
class CustomSetting(StrEnum):
SeatAccess = 'seat_access'
PlasmaFlavor = 'plasma_flavor'
class Profile:
def __init__(
self,
name: str,
profile_type: ProfileType,
description: str = '',
current_selection: List[TProfile] = [],
packages: List[str] = [],
services: List[str] = [],
current_selection: list[Self] = [],
packages: list[str] = [],
services: list[str] = [],
support_gfx_driver: bool = False,
support_greeter: bool = False
):
support_greeter: bool = False,
display_server: DisplayServerType | None = None,
) -> None:
self.name = name
self.description = description
self.profile_type = profile_type
self.custom_settings: Dict[str, Any] = {}
self.custom_settings: dict[CustomSetting, str | None] = {}
self._support_gfx_driver = support_gfx_driver
self._support_greeter = support_greeter
self._display_server = display_server
# self.gfx_driver: Optional[str] = None
# self.gfx_driver: str | None = None
self._current_selection = current_selection
self.current_selection = current_selection
self._packages = packages
self._services = services
@ -72,19 +81,15 @@ class Profile:
self.custom_enabled = False
@property
def current_selection(self) -> List[TProfile]:
return self._current_selection
@property
def packages(self) -> List[str]:
def packages(self) -> list[str]:
"""
Returns a list of packages that should be installed when
this profile is among the choosen ones
this profile is among the chosen ones
"""
return self._packages
@property
def services(self) -> List[str]:
def services(self) -> list[str]:
"""
Returns a list of services that should be enabled when
this profile is among the chosen ones
@ -92,54 +97,58 @@ class Profile:
return self._services
@property
def default_greeter_type(self) -> Optional[GreeterType]:
def default_greeter_type(self) -> GreeterType | None:
"""
Setting a default greeter type for a desktop profile
"""
return None
def install(self, install_session: 'Installer'):
def install(self, install_session: Installer) -> None:
"""
Performs installation steps when this profile was selected
"""
def post_install(self, install_session: 'Installer'):
def post_install(self, install_session: Installer) -> None:
"""
Hook that will be called when the installation process is
finished and custom installation steps for specific default_profiles
are needed
"""
def json(self) -> Dict:
def provision(self, install_session: Installer, users: list[User]) -> None:
"""
Hook that will be called when the installation process is
finished and user configuration for specific default_profiles
is needed
"""
def json(self) -> dict[str, str]:
"""
Returns a json representation of the profile
"""
return {}
def do_on_select(self) -> SelectResult:
async def do_on_select(self) -> SelectResult | None:
"""
Hook that will be called when a profile is selected
"""
return SelectResult.NewSelection
def set_custom_settings(self, settings: Dict[str, Any]):
def set_custom_settings(self, settings: dict[CustomSetting, str | None]) -> None:
"""
Set the custom settings for the profile.
This is also called when the settings are parsed from the config
and can be overriden to perform further actions based on the profile
and can be overridden to perform further actions based on the profile
"""
self.custom_settings = settings
def current_selection_names(self) -> List[str]:
if self._current_selection:
return [s.name for s in self._current_selection]
def current_selection_names(self) -> list[str]:
if self.current_selection:
return [s.name for s in self.current_selection]
return []
def reset(self):
self.set_current_selection([])
def set_current_selection(self, current_selection: List[TProfile]):
self._current_selection = current_selection
def reset(self) -> None:
self.current_selection = []
def is_top_level_profile(self) -> bool:
top_levels = [ProfileType.Desktop, ProfileType.Server, ProfileType.Xorg, ProfileType.Minimal, ProfileType.Custom]
@ -157,34 +166,53 @@ class Profile:
def is_xorg_type_profile(self) -> bool:
return self.profile_type == ProfileType.Xorg
def is_tailored(self) -> bool:
return self.profile_type == ProfileType.Tailored
def is_custom_type_profile(self) -> bool:
return self.profile_type == ProfileType.CustomType
def is_graphic_driver_supported(self) -> bool:
if not self._current_selection:
if not self.current_selection:
return self._support_gfx_driver
else:
if any([p._support_gfx_driver for p in self._current_selection]):
if any([p._support_gfx_driver for p in self.current_selection]):
return True
return False
def is_greeter_supported(self) -> bool:
return self._support_greeter
def preview_text(self) -> Optional[str]:
"""
Used for preview text in profiles_bck. If a description is set for a
profile it will automatically display that one in the preivew.
If no preview or a different text should be displayed just
"""
if self.description:
return self.description
return None
@property
def display_server(self) -> DisplayServerType | None:
return self._display_server
def packages_text(self) -> str:
header = str(_('Installed packages'))
output = format_cols(self.packages, header)
return output
def preview_text(self) -> str:
"""
Override this method to provide a preview text for the profile
"""
if self.is_desktop_type_profile():
if self._display_server:
text = tr('Environment type: {} {}').format(self._display_server.value, self.profile_type.value)
else:
text = tr('Environment type: {}').format(self.profile_type.value)
if packages := self.packages_text():
text += f'\n{packages}'
return text
return self.packages_text()
def packages_text(self, include_sub_packages: bool = False) -> str:
packages = set()
if self.packages:
packages = set(self.packages)
if include_sub_packages:
for sub_profile in self.current_selection:
if sub_profile.packages:
packages.update(sub_profile.packages)
text = tr('Installed packages') + ':\n'
for pkg in sorted(packages):
text += f' - {pkg}\n'
return text

View File

@ -1,53 +1,74 @@
from typing import Any, TYPE_CHECKING, List
from typing import TYPE_CHECKING, Self, override
from archinstall.lib.output import info
from archinstall.lib.menu import MenuSelectionType
from archinstall.default_profiles.profile import Profile, ProfileType, SelectResult
from archinstall.lib.log import info
from archinstall.lib.menu.helpers import Selection
from archinstall.lib.profile.profiles_handler import profile_handler
from archinstall.default_profiles.profile import ProfileType, Profile, SelectResult, TProfile
from archinstall.tui.menu_item import MenuItem, MenuItemGroup
from archinstall.tui.result import ResultType
if TYPE_CHECKING:
from archinstall.lib.installer import Installer
_: Any
from archinstall.lib.models.users import User
class ServerProfile(Profile):
def __init__(self, current_value: List[TProfile] = []):
def __init__(self, current_value: list[Self] = []):
super().__init__(
'Server',
ProfileType.Server,
description=str(_('Provides a selection of various server packages to install and enable, e.g. httpd, nginx, mariadb')),
current_selection=current_value
current_selection=current_value,
)
def do_on_select(self) -> SelectResult:
available_servers = profile_handler.get_server_profiles()
@override
async def do_on_select(self) -> SelectResult:
items = [
MenuItem(
p.name,
value=p,
preview_action=lambda x: x.value.preview_text() if x.value else None,
)
for p in profile_handler.get_server_profiles()
]
choice = profile_handler.select_profile(
available_servers,
self._current_selection,
title=str(_('Choose which servers to install, if none then a minimal installation will be done')),
multi=True
)
group = MenuItemGroup(items, sort_items=True)
group.set_selected_by_value(self.current_selection)
match choice.type_:
case MenuSelectionType.Selection:
self.set_current_selection(choice.value) # type: ignore
result = await Selection[Self](
group,
allow_reset=True,
allow_skip=True,
multi=True,
preview_location='right',
).show()
match result.type_:
case ResultType.Selection:
selections = result.get_values()
self.current_selection = selections
return SelectResult.NewSelection
case MenuSelectionType.Skip:
case ResultType.Skip:
return SelectResult.SameSelection
case MenuSelectionType.Reset:
case ResultType.Reset:
return SelectResult.ResetCurrent
def post_install(self, install_session: 'Installer'):
for profile in self._current_selection:
@override
def provision(self, install_session: Installer, users: list[User]) -> None:
for profile in self.current_selection:
profile.provision(install_session, users)
@override
def post_install(self, install_session: Installer) -> None:
for profile in self.current_selection:
profile.post_install(install_session)
def install(self, install_session: 'Installer'):
@override
def install(self, install_session: Installer) -> None:
server_info = self.current_selection_names()
details = ', '.join(server_info)
info(f'Now installing the selected servers: {details}')
for server in self._current_selection:
for server in self.current_selection:
info(f'Installing {server.name}...')
install_session.add_additional_packages(server.packages)
install_session.enable_service(server.services)

View File

@ -1,19 +1,21 @@
from typing import List
from typing import override
from archinstall.default_profiles.profile import Profile, ProfileType
class CockpitProfile(Profile):
def __init__(self):
def __init__(self) -> None:
super().__init__(
'Cockpit',
ProfileType.ServerType
ProfileType.ServerType,
)
@property
def packages(self) -> List[str]:
@override
def packages(self) -> list[str]:
return ['cockpit', 'udisks2', 'packagekit']
@property
def services(self) -> List[str]:
@override
def services(self) -> list[str]:
return ['cockpit.socket']

View File

@ -1,33 +1,30 @@
from typing import List, Union, TYPE_CHECKING
import archinstall
from typing import TYPE_CHECKING, override
from archinstall.default_profiles.profile import Profile, ProfileType
from archinstall.lib.models import User
if TYPE_CHECKING:
from archinstall.lib.installer import Installer
from archinstall.lib.models.users import User
class DockerProfile(Profile):
def __init__(self):
def __init__(self) -> None:
super().__init__(
'Docker',
ProfileType.ServerType
ProfileType.ServerType,
)
@property
def packages(self) -> List[str]:
@override
def packages(self) -> list[str]:
return ['docker']
@property
def services(self) -> List[str]:
@override
def services(self) -> list[str]:
return ['docker']
def post_install(self, install_session: 'Installer'):
users: Union[User, List[User]] = archinstall.arguments.get('!users', [])
if not isinstance(users, list):
users = [users]
@override
def provision(self, install_session: Installer, users: list[User]) -> None:
for user in users:
install_session.arch_chroot(f'usermod -a -G docker {user.username}')

View File

@ -1,19 +1,21 @@
from typing import List
from typing import override
from archinstall.default_profiles.profile import Profile, ProfileType
class HttpdProfile(Profile):
def __init__(self):
def __init__(self) -> None:
super().__init__(
'httpd',
ProfileType.ServerType
ProfileType.ServerType,
)
@property
def packages(self) -> List[str]:
@override
def packages(self) -> list[str]:
return ['apache']
@property
def services(self) -> List[str]:
@override
def services(self) -> list[str]:
return ['httpd']

View File

@ -1,19 +1,21 @@
from typing import List
from typing import override
from archinstall.default_profiles.profile import Profile, ProfileType
class LighttpdProfile(Profile):
def __init__(self):
def __init__(self) -> None:
super().__init__(
'Lighttpd',
ProfileType.ServerType
ProfileType.ServerType,
)
@property
def packages(self) -> List[str]:
@override
def packages(self) -> list[str]:
return ['lighttpd']
@property
def services(self) -> List[str]:
@override
def services(self) -> list[str]:
return ['lighttpd']

View File

@ -1,4 +1,4 @@
from typing import List, TYPE_CHECKING
from typing import TYPE_CHECKING, override
from archinstall.default_profiles.profile import Profile, ProfileType
@ -7,19 +7,22 @@ if TYPE_CHECKING:
class MariadbProfile(Profile):
def __init__(self):
def __init__(self) -> None:
super().__init__(
'Mariadb',
ProfileType.ServerType
ProfileType.ServerType,
)
@property
def packages(self) -> List[str]:
@override
def packages(self) -> list[str]:
return ['mariadb']
@property
def services(self) -> List[str]:
@override
def services(self) -> list[str]:
return ['mariadb']
def post_install(self, install_session: 'Installer'):
@override
def post_install(self, install_session: Installer) -> None:
install_session.arch_chroot('mariadb-install-db --user=mysql --basedir=/usr --datadir=/var/lib/mysql')

View File

@ -1,19 +1,21 @@
from typing import List
from typing import override
from archinstall.default_profiles.profile import Profile, ProfileType
class NginxProfile(Profile):
def __init__(self):
def __init__(self) -> None:
super().__init__(
'Nginx',
ProfileType.ServerType
ProfileType.ServerType,
)
@property
def packages(self) -> List[str]:
@override
def packages(self) -> list[str]:
return ['nginx']
@property
def services(self) -> List[str]:
@override
def services(self) -> list[str]:
return ['nginx']

View File

@ -1,4 +1,4 @@
from typing import List, TYPE_CHECKING
from typing import TYPE_CHECKING, override
from archinstall.default_profiles.profile import Profile, ProfileType
@ -7,20 +7,22 @@ if TYPE_CHECKING:
class PostgresqlProfile(Profile):
def __init__(self):
def __init__(self) -> None:
super().__init__(
'Postgresql',
ProfileType.ServerType,
''
)
@property
def packages(self) -> List[str]:
@override
def packages(self) -> list[str]:
return ['postgresql']
@property
def services(self) -> List[str]:
@override
def services(self) -> list[str]:
return ['postgresql']
def post_install(self, install_session: 'Installer'):
install_session.arch_chroot("initdb -D /var/lib/postgres/data", run_as='postgres')
@override
def post_install(self, install_session: Installer) -> None:
install_session.arch_chroot('initdb -D /var/lib/postgres/data', run_as='postgres')

View File

@ -1,19 +1,21 @@
from typing import List
from typing import override
from archinstall.default_profiles.profile import Profile, ProfileType
class SshdProfile(Profile):
def __init__(self):
def __init__(self) -> None:
super().__init__(
'sshd',
ProfileType.ServerType
ProfileType.ServerType,
)
@property
def packages(self) -> List[str]:
@override
def packages(self) -> list[str]:
return ['openssh']
@property
def services(self) -> List[str]:
@override
def services(self) -> list[str]:
return ['sshd']

View File

@ -1,19 +1,21 @@
from typing import List
from typing import override
from archinstall.default_profiles.profile import Profile, ProfileType
class TomcatProfile(Profile):
def __init__(self):
def __init__(self) -> None:
super().__init__(
'Tomcat',
ProfileType.ServerType
ProfileType.ServerType,
)
@property
def packages(self) -> List[str]:
@override
def packages(self) -> list[str]:
return ['tomcat10']
@property
def services(self) -> List[str]:
@override
def services(self) -> list[str]:
return ['tomcat10']

View File

@ -1,21 +0,0 @@
from typing import List, Any, TYPE_CHECKING
from archinstall.default_profiles.profile import ProfileType
from archinstall.default_profiles.xorg import XorgProfile
if TYPE_CHECKING:
from archinstall.lib.installer import Installer
_: Any
class TailoredProfile(XorgProfile):
def __init__(self):
super().__init__('52-54-00-12-34-56', ProfileType.Tailored, description='')
@property
def packages(self) -> List[str]:
return ['nano', 'wget', 'git']
def install(self, install_session: 'Installer'):
super().install(install_session)
# do whatever you like here :)

View File

@ -1,9 +1,9 @@
from typing import Any, TYPE_CHECKING
from typing import TYPE_CHECKING, override
from archinstall.default_profiles.profile import Profile, ProfileType
from archinstall.default_profiles.profile import DisplayServerType, Profile, ProfileType
if TYPE_CHECKING:
_: Any
from archinstall.lib.installer import Installer
class XorgProfile(Profile):
@ -11,11 +11,22 @@ class XorgProfile(Profile):
self,
name: str = 'Xorg',
profile_type: ProfileType = ProfileType.Xorg,
description: str = str(_('Installs a minimal system as well as xorg and graphics drivers.')),
):
super().__init__(
name,
profile_type,
description=description,
support_gfx_driver=True
support_gfx_driver=True,
display_server=DisplayServerType.Xorg,
)
@property
@override
def packages(self) -> list[str]:
return [
'xorg-server',
'xorg-xinit',
]
@override
def install(self, install_session: Installer) -> None:
install_session.add_additional_packages(self.packages)

View File

@ -0,0 +1,51 @@
from typing import TYPE_CHECKING
from archinstall.applications.audio import AudioApp
from archinstall.applications.bluetooth import BluetoothApp
from archinstall.applications.firewall import FirewallApp
from archinstall.applications.fonts import FontsApp
from archinstall.applications.power_management import PowerManagementApp
from archinstall.applications.print_service import PrintServiceApp
from archinstall.lib.models import Audio
from archinstall.lib.models.application import ApplicationConfiguration
from archinstall.lib.models.users import User
if TYPE_CHECKING:
from archinstall.lib.installer import Installer
class ApplicationHandler:
def __init__(self) -> None:
pass
def install_applications(self, install_session: Installer, app_config: ApplicationConfiguration, users: list[User] | None = None) -> None:
if app_config.bluetooth_config and app_config.bluetooth_config.enabled:
BluetoothApp().install(install_session)
if app_config.audio_config and app_config.audio_config.audio != Audio.NO_AUDIO:
AudioApp().install(
install_session,
app_config.audio_config,
users,
)
if app_config.power_management_config:
PowerManagementApp().install(
install_session,
app_config.power_management_config,
)
if app_config.print_service_config and app_config.print_service_config.enabled:
PrintServiceApp().install(install_session)
if app_config.firewall_config:
FirewallApp().install(
install_session,
app_config.firewall_config,
)
if app_config.fonts_config:
FontsApp().install(
install_session,
app_config.fonts_config,
)

View File

@ -0,0 +1,263 @@
from typing import override
from archinstall.lib.hardware import SysInfo
from archinstall.lib.menu.abstract_menu import AbstractSubMenu
from archinstall.lib.menu.helpers import Confirmation, Selection
from archinstall.lib.models.application import (
ApplicationConfiguration,
Audio,
AudioConfiguration,
BluetoothConfiguration,
Firewall,
FirewallConfiguration,
FontPackage,
FontsConfiguration,
PowerManagement,
PowerManagementConfiguration,
PrintServiceConfiguration,
)
from archinstall.lib.translationhandler import tr
from archinstall.tui.menu_item import MenuItem, MenuItemGroup
from archinstall.tui.result import ResultType
class ApplicationMenu(AbstractSubMenu[ApplicationConfiguration]):
def __init__(
self,
preset: ApplicationConfiguration | None = None,
):
if preset:
self._app_config = preset
else:
self._app_config = ApplicationConfiguration()
menu_options = self._define_menu_options()
self._item_group = MenuItemGroup(menu_options, checkmarks=True)
super().__init__(
self._item_group,
config=self._app_config,
allow_reset=True,
)
@override
async def show(self) -> ApplicationConfiguration | None:
_ = await super().show()
return self._app_config
def _define_menu_options(self) -> list[MenuItem]:
return [
MenuItem(
text=tr('Bluetooth'),
action=select_bluetooth,
value=self._app_config.bluetooth_config,
preview_action=self._prev_bluetooth,
key='bluetooth_config',
),
MenuItem(
text=tr('Audio'),
action=select_audio,
preview_action=self._prev_audio,
key='audio_config',
),
MenuItem(
text=tr('Print service'),
action=select_print_service,
preview_action=self._prev_print_service,
key='print_service_config',
),
MenuItem(
text=tr('Power management'),
action=select_power_management,
preview_action=self._prev_power_management,
enabled=SysInfo.has_battery(),
key='power_management_config',
),
MenuItem(
text=tr('Firewall'),
action=select_firewall,
preview_action=self._prev_firewall,
key='firewall_config',
),
MenuItem(
text=tr('Additional fonts'),
action=select_fonts,
value=self._app_config.fonts_config,
preview_action=self._prev_fonts,
key='fonts_config',
),
]
def _prev_power_management(self, item: MenuItem) -> str | None:
if item.value is not None:
config: PowerManagementConfiguration = item.value
return f'{tr("Power management")}: {config.power_management.value}'
return None
def _prev_bluetooth(self, item: MenuItem) -> str | None:
if item.value is not None:
bluetooth_config: BluetoothConfiguration = item.value
output = f'{tr("Bluetooth")}: '
output += tr('Enabled') if bluetooth_config.enabled else tr('Disabled')
return output
return None
def _prev_audio(self, item: MenuItem) -> str | None:
if item.value is not None:
config: AudioConfiguration = item.value
return f'{tr("Audio")}: {config.audio.value}'
return None
def _prev_print_service(self, item: MenuItem) -> str | None:
if item.value is not None:
print_service_config: PrintServiceConfiguration = item.value
output = f'{tr("Print service")}: '
output += tr('Enabled') if print_service_config.enabled else tr('Disabled')
return output
return None
def _prev_firewall(self, item: MenuItem) -> str | None:
if item.value is not None:
config: FirewallConfiguration = item.value
return f'{tr("Firewall")}: {config.firewall.value}'
return None
def _prev_fonts(self, item: MenuItem) -> str | None:
if item.value is not None:
config: FontsConfiguration = item.value
packages = ', '.join(f.value for f in config.fonts)
return f'{tr("Additional fonts")}: {packages}'
return None
async def select_power_management(preset: PowerManagementConfiguration | None = None) -> PowerManagementConfiguration | None:
group = MenuItemGroup.from_enum(PowerManagement)
if preset:
group.set_focus_by_value(preset.power_management)
result = await Selection[PowerManagement](
group,
allow_skip=True,
allow_reset=True,
).show()
match result.type_:
case ResultType.Skip:
return preset
case ResultType.Selection:
return PowerManagementConfiguration(power_management=result.get_value())
case ResultType.Reset:
return None
async def select_bluetooth(preset: BluetoothConfiguration | None) -> BluetoothConfiguration | None:
header = tr('Would you like to configure Bluetooth?') + '\n'
preset_val = preset.enabled if preset else False
result = await Confirmation(
header=header,
allow_skip=True,
preset=preset_val,
).show()
match result.type_:
case ResultType.Selection:
return BluetoothConfiguration(result.get_value())
case ResultType.Skip:
return preset
case _:
raise ValueError('Unhandled result type')
async def select_print_service(preset: PrintServiceConfiguration | None) -> PrintServiceConfiguration | None:
header = tr('Would you like to configure the print service?') + '\n'
preset_val = preset.enabled if preset else False
result = await Confirmation(
header=header,
allow_skip=True,
preset=preset_val,
).show()
match result.type_:
case ResultType.Selection:
result.get_value()
return PrintServiceConfiguration(result.get_value())
case ResultType.Skip:
return preset
case _:
raise ValueError('Unhandled result type')
async def select_audio(preset: AudioConfiguration | None = None) -> AudioConfiguration | None:
items = [MenuItem(a.value, value=a) for a in Audio]
group = MenuItemGroup(items)
if preset:
group.set_focus_by_value(preset.audio)
result = await Selection[Audio](
group,
header=tr('Select audio configuration'),
allow_skip=True,
).show()
match result.type_:
case ResultType.Skip:
return preset
case ResultType.Selection:
return AudioConfiguration(audio=result.get_value())
case ResultType.Reset:
raise ValueError('Unhandled result type')
async def select_firewall(preset: FirewallConfiguration | None = None) -> FirewallConfiguration | None:
group = MenuItemGroup.from_enum(Firewall)
if preset:
group.set_focus_by_value(preset.firewall)
result = await Selection[Firewall](
group,
allow_skip=True,
allow_reset=True,
).show()
match result.type_:
case ResultType.Skip:
return preset
case ResultType.Selection:
return FirewallConfiguration(firewall=result.get_value())
case ResultType.Reset:
return None
async def select_fonts(preset: FontsConfiguration | None = None) -> FontsConfiguration | None:
items = [MenuItem(f'{f.value} ({f.description()})', value=f) for f in FontPackage]
group = MenuItemGroup(items)
if preset:
for f in preset.fonts:
group.set_selected_by_value(f)
result = await Selection[FontPackage](
group,
header=tr('Select font packages to install'),
allow_skip=True,
allow_reset=True,
multi=True,
).show()
match result.type_:
case ResultType.Skip:
return preset
case ResultType.Selection:
selected = result.get_values()
if selected:
return FontsConfiguration(fonts=selected)
return None
case ResultType.Reset:
return None

801
archinstall/lib/args.py Normal file
View File

@ -0,0 +1,801 @@
import argparse
import json
import os
import stat
import sys
import tempfile
import urllib.error
import urllib.parse
from argparse import ArgumentParser, Namespace
from dataclasses import dataclass, field
from enum import Enum, StrEnum
from pathlib import Path
from typing import Any, Self
from urllib.request import Request, urlopen
from pydantic import TypeAdapter
from pydantic.dataclasses import dataclass as p_dataclass
from archinstall.lib.crypt import decrypt, encrypt
from archinstall.lib.log import debug, error, logger, warn
from archinstall.lib.menu.util import get_password
from archinstall.lib.models.application import ApplicationConfiguration, ZramConfiguration
from archinstall.lib.models.authentication import AuthenticationConfiguration
from archinstall.lib.models.bootloader import Bootloader, BootloaderConfiguration
from archinstall.lib.models.config import SubConfig
from archinstall.lib.models.device import DiskEncryption, DiskLayoutConfiguration
from archinstall.lib.models.locale import LocaleConfiguration
from archinstall.lib.models.mirrors import MirrorConfiguration
from archinstall.lib.models.network import NetworkConfiguration
from archinstall.lib.models.package_types import DEFAULT_KERNEL
from archinstall.lib.models.packages import Repository
from archinstall.lib.models.pacman import PacmanConfiguration
from archinstall.lib.models.profile import ProfileConfiguration
from archinstall.lib.models.users import Password, User, UserSerialization
from archinstall.lib.plugins import load_plugin
from archinstall.lib.translationhandler import Language, tr, translation_handler
from archinstall.lib.utils.format import as_key_value_pair
from archinstall.lib.version import get_version
from archinstall.tui.components import tui
class SubCommand(Enum):
SHARE_LOG = 'share-log'
@p_dataclass
class Arguments:
config: Path | None = None
config_url: str | None = None
creds: Path | None = None
creds_url: str | None = None
creds_decryption_key: str | None = None
silent: bool = False
dry_run: bool = False
script: str | None = None
mountpoint: Path = Path('/mnt')
skip_ntp: bool = False
skip_wkd: bool = False
skip_boot: bool = False
debug: bool = False
offline: bool = False
no_pkg_lookups: bool = False
plugin: Path | None = None
plugin_url: str | None = None
skip_version_check: bool = False
skip_wifi_check: bool = False
advanced: bool = False
verbose: bool = False
command: SubCommand | None = None
class ArchConfigType(StrEnum):
VERSION = 'version'
SCRIPT = 'script'
LOCALE_CONFIG = 'locale_config'
ARCHINSTALL_LANGUAGE = 'archinstall_language'
DISK_CONFIG = 'disk_config'
PROFILE_CONFIG = 'profile_config'
MIRROR_CONFIG = 'mirror_config'
NETWORK_CONFIG = 'network_config'
BOOTLOADER_CONFIG = 'bootloader_config'
APP_CONFIG = 'app_config'
AUTH_CONFIG = 'auth_config'
SWAP = 'swap'
USERS = 'users'
ROOT_ENC_PASSWORD = 'root_enc_password'
ENCRYPTION_PASSWORD = 'encryption_password'
HOSTNAME = 'hostname'
KERNELS = 'kernels'
NTP = 'ntp'
TIMEZONE = 'timezone'
SERVICES = 'services'
PACKAGES = 'packages'
PACMAN_CONFIG = 'pacman_config'
CUSTOM_COMMANDS = 'custom_commands'
def text(self) -> str:
match self:
case ArchConfigType.ARCHINSTALL_LANGUAGE:
return tr('ArchInstall Language')
case ArchConfigType.VERSION:
return tr('Version')
case ArchConfigType.SCRIPT:
return tr('Installation Script')
case ArchConfigType.LOCALE_CONFIG:
return tr('Locales')
case ArchConfigType.DISK_CONFIG:
return tr('Disk configuration')
case ArchConfigType.PROFILE_CONFIG:
return tr('Profile')
case ArchConfigType.MIRROR_CONFIG:
return tr('Mirrors and repositories')
case ArchConfigType.NETWORK_CONFIG:
return tr('Network')
case ArchConfigType.BOOTLOADER_CONFIG:
return tr('Bootloader')
case ArchConfigType.APP_CONFIG:
return tr('Application')
case ArchConfigType.AUTH_CONFIG:
return tr('Authentication')
case ArchConfigType.SWAP:
return tr('Swap')
case ArchConfigType.HOSTNAME:
return tr('Hostname')
case ArchConfigType.KERNELS:
return tr('Kernels')
case ArchConfigType.NTP:
return tr('Automatic time sync (NTP)')
case ArchConfigType.TIMEZONE:
return tr('Timezone')
case ArchConfigType.SERVICES:
return tr('Services')
case ArchConfigType.PACKAGES:
return tr('Additional packages')
case ArchConfigType.PACMAN_CONFIG:
return tr('Pacman')
case ArchConfigType.CUSTOM_COMMANDS:
return tr('Custom commands')
case ArchConfigType.USERS:
return tr('Users')
case ArchConfigType.ROOT_ENC_PASSWORD:
return tr('Root encrypted password')
case ArchConfigType.ENCRYPTION_PASSWORD:
return tr('Disk encryption password')
USER_CONFIG_FILE: Path = Path('user_configuration.json')
USER_CREDS_FILE: Path = Path('user_credentials.json')
DEFAULT_SAVE_PATH = logger.directory
@dataclass
class ArchConfig:
version: str | None = None
script: str | None = None
locale_config: LocaleConfiguration | None = None
archinstall_language: Language = field(default_factory=lambda: translation_handler.get_language_by_abbr('en'))
disk_config: DiskLayoutConfiguration | None = None
profile_config: ProfileConfiguration | None = None
mirror_config: MirrorConfiguration | None = None
network_config: NetworkConfiguration | None = None
bootloader_config: BootloaderConfiguration | None = None
app_config: ApplicationConfiguration | None = None
auth_config: AuthenticationConfiguration | None = None
swap: ZramConfiguration | None = None
hostname: str = 'archlinux'
kernels: list[str] = field(default_factory=lambda: [DEFAULT_KERNEL.value])
ntp: bool = True
packages: list[str] = field(default_factory=list)
pacman_config: PacmanConfiguration = field(default_factory=PacmanConfiguration.default)
timezone: str = 'UTC'
services: list[str] = field(default_factory=list)
custom_commands: list[str] = field(default_factory=list)
def unsafe_config(self) -> dict[ArchConfigType, Any]:
config: dict[ArchConfigType, list[UserSerialization] | str | None] = {}
if self.auth_config:
if self.auth_config.users:
config[ArchConfigType.USERS] = [user.json() for user in self.auth_config.users]
if self.auth_config.root_enc_password:
config[ArchConfigType.ROOT_ENC_PASSWORD] = self.auth_config.root_enc_password.enc_password
if self.disk_config:
disk_encryption = self.disk_config.disk_encryption
if disk_encryption and disk_encryption.encryption_password:
config[ArchConfigType.ENCRYPTION_PASSWORD] = disk_encryption.encryption_password.plaintext
return config
def safe_config(self) -> dict[ArchConfigType, Any]:
base_config: dict[ArchConfigType, Any] = {
ArchConfigType.VERSION: self.version,
ArchConfigType.SCRIPT: self.script,
ArchConfigType.ARCHINSTALL_LANGUAGE: self.archinstall_language.json(),
}
base_config.update(self.plain_cfg())
sub_config = self.sub_cfg()
for config_type, value in sub_config.items():
if not hasattr(value, 'json'):
raise ValueError(f'Config value for {config_type} must implement json() method')
base_config[config_type] = value.json()
return base_config
def plain_cfg(self) -> dict[ArchConfigType, str | list[str] | bool]:
return {
ArchConfigType.HOSTNAME: self.hostname,
ArchConfigType.KERNELS: self.kernels,
ArchConfigType.NTP: self.ntp,
ArchConfigType.TIMEZONE: self.timezone,
ArchConfigType.SERVICES: self.services,
ArchConfigType.PACKAGES: self.packages,
ArchConfigType.CUSTOM_COMMANDS: self.custom_commands,
}
def sub_cfg(self) -> dict[ArchConfigType, SubConfig]:
cfg: dict[ArchConfigType, SubConfig] = {
ArchConfigType.PACMAN_CONFIG: self.pacman_config,
}
if self.mirror_config:
cfg[ArchConfigType.MIRROR_CONFIG] = self.mirror_config
if self.bootloader_config:
cfg[ArchConfigType.BOOTLOADER_CONFIG] = self.bootloader_config
if self.disk_config:
cfg[ArchConfigType.DISK_CONFIG] = self.disk_config
if self.swap:
cfg[ArchConfigType.SWAP] = self.swap
if self.auth_config:
cfg[ArchConfigType.AUTH_CONFIG] = self.auth_config
if self.locale_config:
cfg[ArchConfigType.LOCALE_CONFIG] = self.locale_config
if self.profile_config:
cfg[ArchConfigType.PROFILE_CONFIG] = self.profile_config
if self.network_config:
cfg[ArchConfigType.NETWORK_CONFIG] = self.network_config
if self.app_config:
cfg[ArchConfigType.APP_CONFIG] = self.app_config
return cfg
@classmethod
def from_config(cls, args_config: dict[str, Any], args: Arguments) -> Self:
arch_config = cls()
arch_config.locale_config = LocaleConfiguration.parse_arg(args_config)
if script := args_config.get('script', None):
arch_config.script = script
if archinstall_lang := args_config.get('archinstall-language', None):
arch_config.archinstall_language = translation_handler.get_language_by_name(archinstall_lang)
translation_handler.activate(arch_config.archinstall_language, set_font=False)
if disk_config := args_config.get('disk_config', {}):
enc_password = args_config.get('encryption_password', '')
password = Password(plaintext=enc_password) if enc_password else None
arch_config.disk_config = DiskLayoutConfiguration.parse_arg(disk_config, password)
# DEPRECATED
# backwards compatibility for main level disk_encryption entry
disk_encryption: DiskEncryption | None = None
if args_config.get('disk_encryption', None) is not None and arch_config.disk_config is not None:
disk_encryption = DiskEncryption.parse_arg(
arch_config.disk_config,
args_config['disk_encryption'],
Password(plaintext=args_config.get('encryption_password', '')),
)
if disk_encryption:
arch_config.disk_config.disk_encryption = disk_encryption
if profile_config := args_config.get('profile_config', None):
arch_config.profile_config = ProfileConfiguration.parse_arg(profile_config)
if mirror_config := args_config.get('mirror_config', None):
backwards_compatible_repo = []
if additional_repositories := args_config.get('additional-repositories', []):
backwards_compatible_repo = [Repository(r) for r in additional_repositories]
arch_config.mirror_config = MirrorConfiguration.parse_args(
mirror_config,
backwards_compatible_repo,
)
if net_config := args_config.get('network_config', None):
arch_config.network_config = NetworkConfiguration.parse_arg(net_config)
if bootloader_config_dict := args_config.get('bootloader_config', None):
arch_config.bootloader_config = BootloaderConfiguration.parse_arg(bootloader_config_dict, args.skip_boot)
# DEPRECATED: separate bootloader and uki fields (backward compatibility)
elif bootloader_str := args_config.get('bootloader', None):
bootloader = Bootloader.from_arg(bootloader_str, args.skip_boot)
uki = args_config.get('uki', False)
if uki and not bootloader.has_uki_support():
uki = False
arch_config.bootloader_config = BootloaderConfiguration(bootloader=bootloader, uki=uki, removable=True)
# deprecated: backwards compatibility
audio_config_args = args_config.get('audio_config', None)
app_config_args = args_config.get('app_config', None)
if audio_config_args is not None or app_config_args is not None:
arch_config.app_config = ApplicationConfiguration.parse_arg(app_config_args, audio_config_args)
if auth_config_args := args_config.get('auth_config', None):
arch_config.auth_config = AuthenticationConfiguration.parse_arg(auth_config_args)
if hostname := args_config.get('hostname', ''):
arch_config.hostname = hostname
if kernels := args_config.get('kernels', []):
arch_config.kernels = kernels
arch_config.ntp = args_config.get('ntp', True)
if packages := args_config.get('packages', []):
arch_config.packages = packages
if pacman_config := args_config.get('pacman_config', None):
arch_config.pacman_config = PacmanConfiguration.parse_arg(pacman_config)
elif parallel_downloads := args_config.get('parallel_downloads', 0):
arch_config.pacman_config = PacmanConfiguration(parallel_downloads=int(parallel_downloads))
swap_arg = args_config.get('swap')
if swap_arg is not None:
arch_config.swap = ZramConfiguration.parse_arg(swap_arg)
if timezone := args_config.get('timezone', 'UTC'):
arch_config.timezone = timezone
if services := args_config.get('services', []):
arch_config.services = services
# DEPRECATED: backwards compatibility
root_password = None
if root_password := args_config.get('!root-password', None):
root_password = Password(plaintext=root_password)
if enc_password := args_config.get('root_enc_password', None):
root_password = Password(enc_password=enc_password)
if root_password is not None:
if arch_config.auth_config is None:
arch_config.auth_config = AuthenticationConfiguration()
arch_config.auth_config.root_enc_password = root_password
# DEPRECATED: backwards compatibility
users: list[User] = []
if args_users := args_config.get('!users', None):
users = User.parse_arguments(args_users)
if args_users := args_config.get('users', None):
users = User.parse_arguments(args_users)
if users:
if arch_config.auth_config is None:
arch_config.auth_config = AuthenticationConfiguration()
arch_config.auth_config.users = users
if custom_commands := args_config.get('custom_commands', []):
arch_config.custom_commands = custom_commands
return arch_config
def user_config_to_json(self) -> str:
config = self.safe_config()
adapter = TypeAdapter(dict[ArchConfigType, Any])
python_dict = adapter.dump_python(config)
return json.dumps(python_dict, indent=4, sort_keys=True)
def user_credentials_to_json(self) -> str:
cfg = self.unsafe_config()
adapter = TypeAdapter(dict[ArchConfigType, Any])
python_dict = adapter.dump_python(cfg)
return json.dumps(python_dict, indent=4, sort_keys=True)
def write_debug(self) -> None:
debug(' -- Chosen configuration --')
debug(self.user_config_to_json())
def save(
self,
dest_path: Path | None = None,
creds: bool = False,
password: str | None = None,
) -> None:
save_path = dest_path or DEFAULT_SAVE_PATH
if not save_path.is_dir():
warn(
f'Destination directory {save_path} does not exist or is not a directory\n.',
'Configuration files can not be saved',
)
return
self.save_user_config(save_path)
if creds:
self.save_user_creds(save_path, password=password)
def save_user_config(self, dest_path: Path) -> None:
if not dest_path.is_dir():
error(f'Invalid path {dest_path}. User configuration could not be saved.')
return
target = dest_path / USER_CONFIG_FILE
data = self.user_config_to_json()
target.write_text(data)
target.chmod(stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP)
def save_user_creds(
self,
dest_path: Path,
password: str | None = None,
) -> None:
if not dest_path.is_dir():
error(f'Invalid path {dest_path}. User credentials could not be saved.')
return
data = self.user_credentials_to_json()
if password:
data = encrypt(password, data)
target = dest_path / USER_CREDS_FILE
target.write_text(data)
target.chmod(stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP)
def as_summary(self) -> str:
"""
Render a concise two-column summary of the current configuration.
Returns an empty string if nothing meaningful to show.
"""
cfg: dict[str, str | list[str] | bool] = {}
for key, value in self.plain_cfg().items():
cfg[key.text()] = value
for config_type, obj in self.sub_cfg().items():
if not hasattr(obj, 'summary'):
continue
summary = obj.summary()
if summary:
cfg[config_type.text()] = summary
simple_summary = as_key_value_pair(cfg, ignore_empty=True)
return simple_summary
class ArchConfigHandler:
def __init__(self) -> None:
self._parser: ArgumentParser = self._define_arguments()
self._add_sub_parsers()
self._args: Arguments = self._parse_args()
config = self._parse_config()
try:
self._config = ArchConfig.from_config(config, self._args)
self._config.version = get_version()
except ValueError as err:
warn(str(err))
sys.exit(1)
@property
def config(self) -> ArchConfig:
return self._config
@property
def args(self) -> Arguments:
return self._args
def get_script(self) -> str:
if script := self.args.script:
return script
if script := self.config.script:
return script
return 'guided'
def print_help(self) -> None:
self._parser.print_help()
def _add_sub_parsers(self) -> None:
subparsers = self._parser.add_subparsers(dest='command', help='Available subcommands')
_ = subparsers.add_parser(SubCommand.SHARE_LOG.value, help='Upload log file to public server')
def _define_arguments(self) -> ArgumentParser:
parser = ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument(
'-v',
'--version',
action='version',
default=False,
version='%(prog)s ' + get_version(),
)
parser.add_argument(
'--config',
type=Path,
nargs='?',
default=None,
help='JSON configuration file',
)
parser.add_argument(
'--config-url',
type=str,
nargs='?',
default=None,
help='Url to a JSON configuration file',
)
parser.add_argument(
'--creds',
type=Path,
nargs='?',
default=None,
help='JSON credentials configuration file',
)
parser.add_argument(
'--creds-url',
type=str,
nargs='?',
default=None,
help='Url to a JSON credentials configuration file',
)
parser.add_argument(
'--creds-decryption-key',
type=str,
nargs='?',
default=None,
help='Decryption key for credentials file',
)
parser.add_argument(
'--silent',
action='store_true',
default=False,
help='WARNING: Disables all prompts for input and confirmation. If no configuration is provided, this is ignored',
)
parser.add_argument(
'--dry-run',
'--dry_run',
action='store_true',
default=False,
help='Generates a configuration file and then exits instead of performing an installation',
)
parser.add_argument(
'--script',
nargs='?',
help='Script to run for installation',
type=str,
)
parser.add_argument(
'--mountpoint',
type=Path,
nargs='?',
default=Path('/mnt'),
help='Define an alternate mount point for installation',
)
parser.add_argument(
'--skip-ntp',
action='store_true',
help='Disables NTP checks during installation',
default=False,
)
parser.add_argument(
'--skip-wkd',
action='store_true',
help='Disables checking if archlinux keyring wkd sync is complete.',
default=False,
)
parser.add_argument(
'--skip-boot',
action='store_true',
help='Disables installation of a boot loader (note: only use this when problems arise with the boot loader step).',
default=False,
)
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=Path,
default=None,
help='File path to a plugin to load',
)
parser.add_argument(
'--plugin-url',
type=str,
nargs='?',
default=None,
help='Url to a plugin file to load',
)
parser.add_argument(
'--skip-version-check',
action='store_true',
default=False,
help='Skip the version check when running archinstall',
)
parser.add_argument(
'--skip-wifi-check',
action='store_true',
default=False,
help='Skip wifi check when running archinstall',
)
parser.add_argument(
'--advanced',
action='store_true',
default=False,
help='Enabled advanced options',
)
parser.add_argument(
'--verbose',
action='store_true',
default=False,
help='Enabled verbose options',
)
return parser
def _parse_args(self) -> Arguments:
argparse_args = vars(self._parser.parse_args())
args: Arguments = Arguments(**argparse_args)
# amend the parameters (check internal consistency)
# Installation can't be silent if config is not passed
if args.config is None and args.config_url is None:
args.silent = False
if args.debug:
warn(f'Warning: --debug mode will write certain credentials to {logger.path}!')
if args.plugin:
load_plugin(args.plugin)
if args.plugin_url:
plugin_data = self._fetch_from_url(args.plugin_url)
plugin_path = self._write_plugin_to_temp_file(plugin_data)
load_plugin(plugin_path)
if args.creds_decryption_key is None:
if os.environ.get('ARCHINSTALL_CREDS_DECRYPTION_KEY'):
args.creds_decryption_key = os.environ.get('ARCHINSTALL_CREDS_DECRYPTION_KEY')
return args
def _parse_config(self) -> dict[str, Any]:
config: dict[str, Any] = {}
config_data: str | None = None
creds_data: str | None = None
if self._args.config is not None:
config_data = self._read_file(self._args.config)
elif self._args.config_url is not None:
config_data = self._fetch_from_url(self._args.config_url)
if config_data is not None:
config.update(json.loads(config_data))
if self._args.creds is not None:
creds_data = self._read_file(self._args.creds)
elif self._args.creds_url is not None:
creds_data = self._fetch_from_url(self._args.creds_url)
if creds_data is not None:
json_data = self._process_creds_data(creds_data)
if json_data is not None:
config.update(json_data)
config = self._cleanup_config(config)
return config
def _process_creds_data(self, creds_data: str) -> dict[str, Any] | None:
if creds_data.startswith('$'): # encrypted data
if self._args.creds_decryption_key is not None:
try:
creds_data = decrypt(creds_data, self._args.creds_decryption_key)
return json.loads(creds_data)
except ValueError as err:
if 'Invalid password' in str(err):
error(tr('Incorrect credentials file decryption password'))
sys.exit(1)
else:
debug(f'Error decrypting credentials file: {err}')
raise err from err
else:
header = tr('Enter credentials file decryption password')
wrong_pwd_text = tr('Incorrect password')
prompt = header
while True:
decryption_pwd: Password | None = tui.run(
lambda p=prompt: get_password( # type: ignore[misc]
header=p,
allow_skip=False,
no_confirmation=True,
)
)
if not decryption_pwd:
return None
try:
creds_data = decrypt(creds_data, decryption_pwd.plaintext)
break
except ValueError as err:
if 'Invalid password' in str(err):
debug('Incorrect credentials file decryption password')
prompt = f'{header}' + f'\n\n{wrong_pwd_text}'
else:
debug(f'Error decrypting credentials file: {err}')
raise err from err
return json.loads(creds_data)
def _fetch_from_url(self, url: str) -> str:
if urllib.parse.urlparse(url).scheme:
try:
req = Request(url, headers={'User-Agent': 'ArchInstall'})
with urlopen(req) as resp:
return resp.read().decode('utf-8')
except urllib.error.HTTPError as err:
error(f'Could not fetch JSON from {url}: {err}')
else:
error('Not a valid url')
sys.exit(1)
def _write_plugin_to_temp_file(self, plugin_data: str) -> Path:
if not plugin_data.strip():
error('The downloaded plugin is empty')
sys.exit(1)
tmp_file = tempfile.NamedTemporaryFile(
mode='w',
suffix='.py',
prefix='archinstall_plugin_',
delete=False,
)
try:
with tmp_file as f:
f.write(plugin_data)
except OSError as err:
error(f'Could not write the downloaded plugin to a temporary file: {err}')
sys.exit(1)
return Path(tmp_file.name)
def _read_file(self, path: Path) -> str:
if not path.exists():
error(f'Could not find file {path}')
sys.exit(1)
return path.read_text()
def _cleanup_config(self, config: Namespace | dict[str, Any]) -> dict[str, Any]:
clean_args = {}
for key, val in config.items():
if isinstance(val, dict):
val = self._cleanup_config(val)
if val is not None:
clean_args[key] = val
return clean_args

View File

@ -0,0 +1,126 @@
import getpass
from pathlib import Path
from typing import TYPE_CHECKING
from archinstall.lib.command import SysCommandWorker
from archinstall.lib.log import debug, info
from archinstall.lib.models.authentication import AuthenticationConfiguration, U2FLoginConfiguration, U2FLoginMethod
from archinstall.lib.models.users import User
from archinstall.lib.translationhandler import tr
if TYPE_CHECKING:
from archinstall.lib.installer import Installer
class AuthenticationHandler:
def setup_auth(
self,
install_session: Installer,
auth_config: AuthenticationConfiguration,
hostname: str,
) -> None:
if auth_config.u2f_config and auth_config.users is not None:
self._setup_u2f_login(install_session, auth_config.u2f_config, auth_config.users, hostname)
def _setup_u2f_login(self, install_session: Installer, u2f_config: U2FLoginConfiguration, users: list[User], hostname: str) -> None:
self._configure_u2f_mapping(install_session, u2f_config, users, hostname)
self._update_pam_config(install_session, u2f_config)
def _update_pam_config(
self,
install_session: Installer,
u2f_config: U2FLoginConfiguration,
) -> None:
match u2f_config.u2f_login_method:
case U2FLoginMethod.Passwordless:
config_entry = 'auth sufficient pam_u2f.so authfile=/etc/u2f_mappings cue'
case U2FLoginMethod.SecondFactor:
config_entry = 'auth required pam_u2f.so authfile=/etc/u2f_mappings cue'
case _:
raise ValueError(f'Unknown U2F login method: {u2f_config.u2f_login_method}')
debug(f'U2F PAM configuration: {config_entry}')
debug(f'Passwordless sudo enabled: {u2f_config.passwordless_sudo}')
sudo_config = install_session.target / 'etc/pam.d/sudo'
sys_login = install_session.target / 'etc/pam.d/system-login'
if u2f_config.passwordless_sudo:
self._add_u2f_entry(sudo_config, config_entry)
self._add_u2f_entry(sys_login, config_entry)
def _add_u2f_entry(self, file: Path, entry: str) -> None:
if not file.exists():
debug(f'File does not exist: {file}')
return
content = file.read_text().splitlines()
# remove any existing u2f auth entry
content = [line for line in content if 'pam_u2f.so' not in line]
# add the u2f auth entry as the first one after comments
for i, line in enumerate(content):
if not line.startswith('#'):
content.insert(i, entry)
break
else:
content.append(entry)
file.write_text('\n'.join(content) + '\n')
def _configure_u2f_mapping(
self,
install_session: Installer,
u2f_config: U2FLoginConfiguration,
users: list[User],
hostname: str,
) -> None:
debug(f'Setting up U2F login: {u2f_config.u2f_login_method.value}')
install_session.pacman.strap('pam-u2f')
print(tr('Setting up U2F login: {}').format(u2f_config.u2f_login_method.value))
# https://developers.yubico.com/pam-u2f/
u2f_auth_file = install_session.target / 'etc/u2f_mappings'
u2f_auth_file.touch()
existing_keys = u2f_auth_file.read_text()
registered_keys: list[str] = []
for user in users:
print('')
info(tr('Setting up U2F device for user: {}').format(user.username))
info(tr('You may need to enter the PIN and then touch your U2F device to register it'))
cmd = ' '.join(
['arch-chroot', '-S', str(install_session.target), 'pamu2fcfg', '-u', user.username, '-o', f'pam://{hostname}', '-i', f'pam://{hostname}']
)
debug(f'Enrolling U2F device: {cmd}')
worker = SysCommandWorker(cmd, peek_output=True)
pin_inputted = False
while worker.is_alive():
if pin_inputted is False:
if bytes('enter pin for', 'UTF-8') in worker._trace_log.lower():
worker.write(bytes(getpass.getpass(''), 'UTF-8'))
pin_inputted = True
output = worker.decode().strip().splitlines()
debug(f'Output from pamu2fcfg: {output}')
key = output[-1].strip()
registered_keys.append(key)
all_keys = '\n'.join(registered_keys)
if existing_keys:
existing_keys += f'\n{all_keys}'
else:
existing_keys = all_keys
u2f_auth_file.write_text(existing_keys)

View File

@ -0,0 +1,147 @@
from typing import override
from archinstall.lib.disk.fido import Fido2
from archinstall.lib.menu.abstract_menu import AbstractSubMenu
from archinstall.lib.menu.helpers import Confirmation, Selection
from archinstall.lib.menu.util import get_password
from archinstall.lib.models.authentication import AuthenticationConfiguration, U2FLoginConfiguration, U2FLoginMethod
from archinstall.lib.models.users import Password, User
from archinstall.lib.translationhandler import tr
from archinstall.lib.user.user_menu import select_users
from archinstall.lib.utils.format import as_table
from archinstall.tui.menu_item import MenuItem, MenuItemGroup
from archinstall.tui.result import ResultType
class AuthenticationMenu(AbstractSubMenu[AuthenticationConfiguration]):
def __init__(self, preset: AuthenticationConfiguration | None = None):
if preset:
self._auth_config = preset
else:
self._auth_config = AuthenticationConfiguration()
menu_options = self._define_menu_options()
self._item_group = MenuItemGroup(menu_options, checkmarks=True)
super().__init__(
self._item_group,
config=self._auth_config,
allow_reset=True,
)
@override
async def show(self) -> AuthenticationConfiguration | None:
return await super().show()
def _define_menu_options(self) -> list[MenuItem]:
return [
MenuItem(
text=tr('Root password'),
action=lambda x: select_root_password(),
preview_action=self._prev_root_pwd,
key='root_enc_password',
),
MenuItem(
text=tr('User account'),
action=self._create_user_account,
preview_action=self._prev_users,
key='users',
),
MenuItem(
text=tr('U2F login setup'),
action=select_u2f_login,
value=self._auth_config.u2f_config,
preview_action=self._prev_u2f_login,
key='u2f_config',
),
]
async def _create_user_account(self, preset: list[User] | None = None) -> list[User]:
preset = [] if preset is None else preset
users = await select_users(preset=preset)
return users
def _prev_users(self, item: MenuItem) -> str | None:
users: list[User] | None = item.value
if users:
return as_table(users)
return None
def _prev_root_pwd(self, item: MenuItem) -> str | None:
if item.value is not None:
password: Password = item.value
return f'{tr("Root password")}: {password.hidden()}'
return None
def _depends_on_u2f(self) -> bool:
devices = Fido2.get_fido2_devices()
if not devices:
return False
return True
def _prev_u2f_login(self, item: MenuItem) -> str | None:
if item.value is not None:
u2f_config: U2FLoginConfiguration = item.value
login_method = u2f_config.u2f_login_method.display_value()
output = tr('U2F login method: ') + login_method
output += '\n'
output += tr('Passwordless sudo: ') + (tr('Enabled') if u2f_config.passwordless_sudo else tr('Disabled'))
return output
devices = Fido2.get_fido2_devices()
if not devices:
return tr('No U2F devices found')
return None
async def select_root_password() -> Password | None:
password = await get_password(header=tr('Enter root password'), allow_skip=True)
return password
async def select_u2f_login(preset: U2FLoginConfiguration | None) -> U2FLoginConfiguration | None:
devices = Fido2.get_fido2_devices()
if not devices:
return None
items = []
for method in U2FLoginMethod:
items.append(MenuItem(method.display_value(), value=method))
group = MenuItemGroup(items)
if preset is not None:
group.set_selected_by_value(preset.u2f_login_method)
result = await Selection[U2FLoginMethod](
group,
allow_skip=True,
allow_reset=True,
).show()
match result.type_:
case ResultType.Selection:
u2f_method = result.get_value()
header = tr('Enable passwordless sudo?')
result_sudo = await Confirmation(
header=header,
allow_skip=True,
preset=False,
).show()
passwordless_sudo = result_sudo.item() == MenuItem.yes()
return U2FLoginConfiguration(
u2f_login_method=u2f_method,
passwordless_sudo=passwordless_sudo,
)
case ResultType.Skip:
return preset
case ResultType.Reset:
return None

View File

@ -1,37 +1,48 @@
import time
from typing import Iterator, Optional
from .exceptions import SysCallError
from .general import SysCommand, SysCommandWorker, locate_binary
from .installer import Installer
from .output import error
from .storage import storage
from collections.abc import Iterator
from pathlib import Path
from types import TracebackType
from typing import ClassVar, Self
from archinstall.lib.command import SysCommand, SysCommandWorker
from archinstall.lib.exceptions import SysCallError
from archinstall.lib.log import error
class Boot:
def __init__(self, installation: Installer):
self.instance = installation
_active_boot: ClassVar[Self | None] = None
def __init__(self, path: Path | str):
if isinstance(path, Path):
path = str(path)
self.path = path
self.container_name = 'archinstall'
self.session: Optional[SysCommandWorker] = None
self.session: SysCommandWorker | None = None
self.ready = False
def __enter__(self) -> 'Boot':
if (existing_session := storage.get('active_boot', None)) and existing_session.instance != self.instance:
raise KeyError("Archinstall only supports booting up one instance, and a active session is already active and it is not this one.")
def __enter__(self) -> Self:
if Boot._active_boot and Boot._active_boot.path != self.path:
raise KeyError('Archinstall only supports booting up one instance and another session is already active.')
if existing_session:
self.session = existing_session.session
self.ready = existing_session.ready
if Boot._active_boot:
self.session = Boot._active_boot.session
self.ready = Boot._active_boot.ready
else:
# '-P' or --console=pipe could help us not having to do a bunch
# of os.write() calls, but instead use pipes (stdin, stdout and stderr) as usual.
self.session = SysCommandWorker([
'/usr/bin/systemd-nspawn',
'-D', str(self.instance.target),
'--timezone=off',
'-b',
'--no-pager',
'--machine', self.container_name
])
self.session = SysCommandWorker(
[
'systemd-nspawn',
'-D',
self.path,
'--timezone=off',
'-b',
'--no-pager',
'--machine',
self.container_name,
]
)
if not self.ready and self.session:
while self.session.is_alive():
@ -39,21 +50,21 @@ class Boot:
self.ready = True
break
storage['active_boot'] = self
Boot._active_boot = self
return self
def __exit__(self, *args :str, **kwargs :str) -> None:
def __exit__(self, exc_type: type[BaseException] | None, exc_value: BaseException | None, traceback: TracebackType | None) -> None:
# b''.join(sys_command('sync')) # No need to, since the underlying fs() object will call sync.
# TODO: https://stackoverflow.com/questions/28157929/how-to-safely-handle-an-exception-inside-a-context-manager
if len(args) >= 2 and args[1]:
if exc_type is not None:
error(
args[1],
f"The error above occurred in a temporary boot-up of the installation {self.instance}"
str(exc_value),
f'The error above occurred in a temporary boot-up of the installation {self.path!r}',
)
shutdown = None
shutdown_exit_code: Optional[int] = -1
shutdown_exit_code: int | None = -1
try:
shutdown = SysCommand(f'systemd-run --machine={self.container_name} --pty shutdown now')
@ -68,19 +79,18 @@ class Boot:
shutdown_exit_code = shutdown.exit_code
if self.session and (self.session.exit_code == 0 or shutdown_exit_code == 0):
storage['active_boot'] = None
Boot._active_boot = None
else:
session_exit_code = self.session.exit_code if self.session else -1
raise SysCallError(
f"Could not shut down temporary boot of {self.instance}: {session_exit_code}/{shutdown_exit_code}",
exit_code=next(filter(bool, [session_exit_code, shutdown_exit_code]))
f'Could not shut down temporary boot of {self.path!r}: {session_exit_code}/{shutdown_exit_code}',
exit_code=next(filter(bool, [session_exit_code, shutdown_exit_code])),
)
def __iter__(self) -> Iterator[bytes]:
if self.session:
for value in self.session:
yield value
yield from self.session
def __contains__(self, key: bytes) -> bool:
if self.session is None:
@ -94,18 +104,8 @@ class Boot:
return self.session.is_alive()
def SysCommand(self, cmd: list, *args, **kwargs) -> SysCommand:
if cmd[0][0] != '/' and cmd[0][:2] != './':
# This check is also done in SysCommand & SysCommandWorker.
# However, that check is done for `machinectl` and not for our chroot command.
# So this wrapper for SysCommand will do this additionally.
def SysCommand(self, cmd: list[str], *args, **kwargs) -> SysCommand: # type: ignore[no-untyped-def]
return SysCommand(['systemd-run', f'--machine={self.container_name}', '--pty', *cmd], *args, **kwargs)
cmd[0] = locate_binary(cmd[0])
return SysCommand(["systemd-run", f"--machine={self.container_name}", "--pty", *cmd], *args, **kwargs)
def SysCommandWorker(self, cmd: list, *args, **kwargs) -> SysCommandWorker:
if cmd[0][0] != '/' and cmd[0][:2] != './':
cmd[0] = locate_binary(cmd[0])
return SysCommandWorker(["systemd-run", f"--machine={self.container_name}", "--pty", *cmd], *args, **kwargs)
def SysCommandWorker(self, cmd: list[str], *args, **kwargs) -> SysCommandWorker: # type: ignore[no-untyped-def]
return SysCommandWorker(['systemd-run', f'--machine={self.container_name}', '--pty', *cmd], *args, **kwargs)

View File

View File

@ -0,0 +1,281 @@
import textwrap
from typing import override
from archinstall.lib.menu.abstract_menu import AbstractSubMenu
from archinstall.lib.menu.helpers import Confirmation, Selection
from archinstall.lib.models.bootloader import Bootloader, BootloaderConfiguration, PlymouthTheme
from archinstall.lib.translationhandler import tr
from archinstall.tui.menu_item import MenuItem, MenuItemGroup
from archinstall.tui.result import ResultType
class BootloaderMenu(AbstractSubMenu[BootloaderConfiguration]):
def __init__(
self,
bootloader_conf: BootloaderConfiguration,
uefi: bool,
skip_boot: bool = False,
):
self._bootloader_conf = bootloader_conf
self._skip_boot = skip_boot
self._uefi = uefi
menu_options = self._define_menu_options()
self._item_group = MenuItemGroup(menu_options, sort_items=False, checkmarks=True)
super().__init__(
self._item_group,
config=self._bootloader_conf,
allow_reset=False,
)
def _define_menu_options(self) -> list[MenuItem]:
bootloader = self._bootloader_conf.bootloader
# UKI availability
uki_enabled = self._uefi and bootloader.has_uki_support()
if not uki_enabled:
self._bootloader_conf.uki = False
# Removable availability
removable_enabled = self._uefi and bootloader.has_removable_support()
if not removable_enabled:
self._bootloader_conf.removable = False
return [
MenuItem(
text=tr('Bootloader'),
action=self._select_bootloader,
value=self._bootloader_conf.bootloader,
preview_action=self._prev_bootloader,
mandatory=True,
key='bootloader',
),
MenuItem(
text=tr('Unified kernel images'),
action=self._select_uki,
value=self._bootloader_conf.uki,
preview_action=self._prev_uki,
key='uki',
enabled=uki_enabled,
),
MenuItem(
text=tr('Install to removable location'),
action=self._select_removable,
value=self._bootloader_conf.removable,
preview_action=self._prev_removable,
key='removable',
enabled=removable_enabled,
),
MenuItem(
text=tr('Plymouth'),
action=self._select_plymouth,
value=self._bootloader_conf.plymouth,
preview_action=self._prev_plymouth,
key='plymouth',
),
]
def _prev_bootloader(self, item: MenuItem) -> str | None:
if item.value:
return f'{tr("Bootloader")}: {item.value.value}'
return None
def _prev_uki(self, item: MenuItem) -> str | None:
uki_text = f'{tr("Unified kernel images")}'
if item.value:
return f'{uki_text}: {tr("Enabled")}'
else:
return f'{uki_text}: {tr("Disabled")}'
def _prev_removable(self, item: MenuItem) -> str | None:
if item.value:
return tr('Will install to /EFI/BOOT/ (removable location, safe default)')
return tr('Will install to custom location with NVRAM entry')
def _prev_plymouth(self, item: MenuItem) -> str | None:
if item.value:
return f'{tr("Plymouth")}: {item.value.value}'
return None
@override
async def show(self) -> BootloaderConfiguration:
_ = await super().show()
return self._bootloader_conf
async def _select_bootloader(self, preset: Bootloader | None) -> Bootloader | None:
bootloader = await select_bootloader(preset, self._uefi, self._skip_boot)
if bootloader:
# Update UKI option based on bootloader
uki_item = self._menu_item_group.find_by_key('uki')
if not self._uefi or not bootloader.has_uki_support():
uki_item.enabled = False
uki_item.value = False
self._bootloader_conf.uki = False
else:
uki_item.enabled = True
# Update removable option based on bootloader
removable_item = self._menu_item_group.find_by_key('removable')
if not self._uefi or not bootloader.has_removable_support():
removable_item.enabled = False
removable_item.value = False
self._bootloader_conf.removable = False
else:
if not removable_item.enabled:
removable_item.value = True
self._bootloader_conf.removable = True
removable_item.enabled = True
return bootloader
async def _select_plymouth(self, preset: PlymouthTheme | None) -> PlymouthTheme | None:
# Plymouth is purely cosmetic and a frequent source of boot breakage
# (notably with the NVIDIA driver and disk encryption), so confirm before
# enabling it. When it is already enabled the user is only changing the
# theme, so the warning is skipped.
if preset is None:
prompt = (
'[ansi_bright_yellow]'
+ tr('Plymouth adds a cosmetic boot splash but can cause boot problems on some setups:')
+ '\n\n'
+ tr('black screen with the NVIDIA driver')
+ '\n'
+ tr('hidden password prompt with disk encryption (LUKS)')
+ '\n\n'
+ tr('Would you like to enable it?')
+ '[/]\n'
)
result = await Confirmation(header=prompt, allow_skip=True, preset=False).show()
match result.type_:
case ResultType.Skip:
return preset
case ResultType.Selection:
if not result.get_value():
return preset
case ResultType.Reset:
raise ValueError('Unhandled result type')
return await select_plymouth_theme(preset)
async def _select_uki(self, preset: bool) -> bool:
prompt = tr('Would you like to use unified kernel images?') + '\n'
result = await Confirmation(header=prompt, allow_skip=True, preset=preset).show()
match result.type_:
case ResultType.Skip:
return preset
case ResultType.Selection:
return result.item() == MenuItem.yes()
case ResultType.Reset:
raise ValueError('Unhandled result type')
async def _select_removable(self, preset: bool) -> bool:
prompt = (
tr('Would you like to install the bootloader to the default removable media search location?')
+ '\n\n'
+ tr('This installs the bootloader to /EFI/BOOT/BOOTX64.EFI (or similar) which is useful for:')
+ '\n\n'
+ tr('Firmware that does not properly support NVRAM boot entries like most MSI motherboards,')
+ '\n '
+ tr('most Apple Macs, many laptops...')
+ '\n'
+ tr('USB drives or other portable external media.')
+ '\n'
+ tr('Systems where you want the disk to be bootable on any computer.')
+ '\n\n'
+ tr(
textwrap.dedent(
"""\
If you do not know what this means, LEAVE THIS OPTION ENABLED, as it is the safe default.
It is suggested to disable this if none of the above apply, as it makes installing multiple
EFI bootloaders on the same disk easier, and it will not overwrite whatever bootloader
was previously installed at the default removable media search location, if any.
It may also make the installation more resilient in case of dual-booting with Windows,
as Windows is known to sometimes erase or replace the bootloader installed at the removable
location.
"""
)
)
+ '\n'
)
result = await Confirmation(
header=prompt,
allow_skip=True,
preset=preset,
).show()
match result.type_:
case ResultType.Skip:
return preset
case ResultType.Selection:
return result.get_value()
case ResultType.Reset:
raise ValueError('Unhandled result type')
async def select_bootloader(
preset: Bootloader | None,
uefi: bool,
skip_boot: bool = False,
) -> Bootloader | None:
options = []
hidden_options = []
header = tr('Select bootloader to install')
default = Bootloader.get_default(uefi, skip_boot)
if not skip_boot:
hidden_options += [Bootloader.NO_BOOTLOADER]
if not uefi:
options += [Bootloader.Grub, Bootloader.Limine]
header += '\n' + tr('UEFI is not detected and some options are disabled')
else:
options += [b for b in Bootloader if b not in hidden_options]
items = [MenuItem(o.value, value=o) for o in options]
group = MenuItemGroup(items)
group.set_default_by_value(default)
group.set_focus_by_value(preset)
result = await Selection[Bootloader](
group,
header=header,
allow_skip=True,
).show()
match result.type_:
case ResultType.Skip:
return preset
case ResultType.Selection:
return result.get_value()
case ResultType.Reset:
raise ValueError('Unhandled result type')
async def select_plymouth_theme(preset: PlymouthTheme | None = None) -> PlymouthTheme | None:
items = [MenuItem(t.value, value=t) for t in PlymouthTheme]
group = MenuItemGroup(items, sort_items=False)
group.set_focus_by_value(preset)
result = await Selection[PlymouthTheme](
group,
header=tr('Select Plymouth theme'),
allow_reset=True,
allow_skip=True,
).show()
match result.type_:
case ResultType.Skip:
return preset
case ResultType.Reset:
return None
case ResultType.Selection:
return PlymouthTheme(result.get_value())

View File

@ -0,0 +1,86 @@
from dataclasses import dataclass
from enum import Enum, auto
from pathlib import Path
from archinstall.lib.hardware import SysInfo
from archinstall.lib.models.bootloader import Bootloader, BootloaderConfiguration
from archinstall.lib.models.device import DiskLayoutConfiguration
class BootloaderValidationFailureKind(Enum):
LimineNonFatBoot = auto()
LimineLayout = auto()
BootloaderRequiresUefi = auto()
EfistubNonFatBoot = auto()
@dataclass(frozen=True)
class BootloaderValidationFailure:
kind: BootloaderValidationFailureKind
description: str
def validate_bootloader_layout(
bootloader_config: BootloaderConfiguration | None,
disk_config: DiskLayoutConfiguration | None,
) -> BootloaderValidationFailure | None:
"""Validate bootloader configuration against disk layout.
Returns a failure with a human-readable description if the configuration
would produce an unbootable system, or None if it is valid.
"""
if not (bootloader_config and disk_config):
return None
bootloader = bootloader_config.bootloader
if bootloader == Bootloader.NO_BOOTLOADER:
return None
if bootloader.is_uefi_only() and not SysInfo.has_uefi():
return BootloaderValidationFailure(
kind=BootloaderValidationFailureKind.BootloaderRequiresUefi,
description=f'{bootloader.value} requires a UEFI system.',
)
boot_part = next(
(p for m in disk_config.device_modifications if (p := m.get_boot_partition())),
None,
)
if bootloader == Bootloader.Efistub:
# The UEFI firmware reads the kernel directly from the boot partition,
# which must be FAT.
if boot_part and (boot_part.fs_type is None or not boot_part.fs_type.is_fat()):
return BootloaderValidationFailure(
kind=BootloaderValidationFailureKind.EfistubNonFatBoot,
description='Efistub does not support booting with a non-FAT boot partition.',
)
if bootloader == Bootloader.Limine:
# Limine reads its config and kernels from the boot partition, which
# must be FAT.
if boot_part and (boot_part.fs_type is None or not boot_part.fs_type.is_fat()):
return BootloaderValidationFailure(
kind=BootloaderValidationFailureKind.LimineNonFatBoot,
description='Limine does not support booting with a non-FAT boot partition.',
)
# When the ESP is the boot partition but mounted outside /boot and
# UKI is disabled, kernels end up on the root filesystem which
# Limine cannot access.
if not bootloader_config.uki:
efi_part = next(
(p for m in disk_config.device_modifications if (p := m.get_efi_partition())),
None,
)
if efi_part and efi_part == boot_part and efi_part.mountpoint != Path('/boot'):
return BootloaderValidationFailure(
kind=BootloaderValidationFailureKind.LimineLayout,
description=(
f'Limine requires kernels on a FAT partition. The ESP is mounted at {efi_part.mountpoint}, '
'enable UKI or add a separate /boot partition to install Limine.'
),
)
return None

384
archinstall/lib/command.py Normal file
View File

@ -0,0 +1,384 @@
import os
import shlex
import stat
import subprocess
import sys
import time
from collections.abc import Iterator
from select import EPOLLHUP, EPOLLIN, epoll
from shutil import which
from types import TracebackType
from typing import Any, Self, override
from archinstall.lib.exceptions import RequirementError, SysCallError
from archinstall.lib.log import debug, error, logger
from archinstall.lib.utils.encoding import clear_vt100_escape_codes
class SysCommandWorker:
def __init__(
self,
cmd: str | list[str],
peek_output: bool | None = False,
environment_vars: dict[str, str] | None = None,
working_directory: str = './',
remove_vt100_escape_codes_from_lines: bool = True,
):
if isinstance(cmd, str):
cmd = shlex.split(cmd)
if cmd and not cmd[0].startswith(('/', './')): # Path() does not work well
cmd[0] = locate_binary(cmd[0])
self.cmd = cmd
self.peek_output = peek_output
# define the standard locale for command outputs. For now the C ascii one. Can be overridden
self.environment_vars = {'LC_ALL': 'C'}
if environment_vars:
self.environment_vars.update(environment_vars)
self.working_directory = working_directory
self.exit_code: int | None = None
self._trace_log = b''
self._trace_log_pos = 0
self.poll_object = epoll()
self.child_fd: int | None = None
self.started = False
self.ended = False
self.remove_vt100_escape_codes_from_lines: bool = remove_vt100_escape_codes_from_lines
def __contains__(self, key: bytes) -> bool:
"""
Contains will also move the current buffert position forward.
This is to avoid re-checking the same data when looking for output.
"""
assert isinstance(key, bytes)
index = self._trace_log.find(key, self._trace_log_pos)
if index >= 0:
self._trace_log_pos += index + len(key)
return True
return False
def __iter__(self, *args: str, **kwargs: dict[str, Any]) -> Iterator[bytes]:
last_line = self._trace_log.rfind(b'\n')
lines = filter(None, self._trace_log[self._trace_log_pos : last_line].splitlines())
for line in lines:
if self.remove_vt100_escape_codes_from_lines:
line = clear_vt100_escape_codes(line)
yield line + b'\n'
self._trace_log_pos = last_line
@override
def __repr__(self) -> str:
self.make_sure_we_are_executing()
return str(self._trace_log)
@override
def __str__(self) -> str:
try:
return self._trace_log.decode('utf-8')
except UnicodeDecodeError:
return str(self._trace_log)
def __enter__(self) -> Self:
return self
def __exit__(self, exc_type: type[BaseException] | None, exc_value: BaseException | None, traceback: TracebackType | None) -> None:
# b''.join(sys_command('sync')) # No need to, since the underlying fs() object will call sync.
# TODO: https://stackoverflow.com/questions/28157929/how-to-safely-handle-an-exception-inside-a-context-manager
if self.child_fd:
try:
os.close(self.child_fd)
except Exception:
pass
if self.peek_output:
# To make sure any peaked output didn't leave us hanging
# on the same line we were on.
sys.stdout.write('\n')
sys.stdout.flush()
if exc_type is not None:
debug(str(exc_value))
if self.exit_code != 0:
raise SysCallError(
f'{self.cmd} exited with abnormal exit code [{self.exit_code}]: {str(self)[-500:]}',
self.exit_code,
worker_log=self._trace_log,
)
def is_alive(self) -> bool:
self.poll()
if self.started and not self.ended:
return True
return False
def write(self, data: bytes, line_ending: bool = True) -> int:
assert isinstance(data, bytes) # TODO: Maybe we can support str as well and encode it
self.make_sure_we_are_executing()
if self.child_fd:
return os.write(self.child_fd, data + (b'\n' if line_ending else b''))
return 0
def make_sure_we_are_executing(self) -> bool:
if not self.started:
return self.execute()
return True
def tell(self) -> int:
self.make_sure_we_are_executing()
return self._trace_log_pos
def seek(self, pos: int) -> None:
self.make_sure_we_are_executing()
# Safety check to ensure 0 < pos < len(tracelog)
self._trace_log_pos = min(max(0, pos), len(self._trace_log))
def peak(self, output: str | bytes) -> bool:
if self.peek_output:
if isinstance(output, bytes):
try:
output = output.decode('UTF-8')
except UnicodeDecodeError:
return False
_cmd_output(output)
sys.stdout.write(output)
sys.stdout.flush()
return True
def poll(self) -> None:
self.make_sure_we_are_executing()
if self.child_fd:
got_output = False
for _fileno, _event in self.poll_object.poll(0.1):
try:
output = os.read(self.child_fd, 8192)
got_output = True
self.peak(output)
self._trace_log += output
except OSError:
self.ended = True
break
if self.ended or (not got_output and not _pid_exists(self.pid)):
self.ended = True
try:
wait_status = os.waitpid(self.pid, 0)[1]
self.exit_code = os.waitstatus_to_exitcode(wait_status)
except ChildProcessError:
try:
wait_status = os.waitpid(self.child_fd, 0)[1]
self.exit_code = os.waitstatus_to_exitcode(wait_status)
except ChildProcessError:
self.exit_code = 1
def execute(self) -> bool:
import pty
if (old_dir := os.getcwd()) != self.working_directory:
os.chdir(str(self.working_directory))
# 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 losing it.
self.pid, self.child_fd = pty.fork()
# https://stackoverflow.com/questions/4022600/python-pty-fork-how-does-it-work
if not self.pid:
_cmd_history(self.cmd)
try:
os.execve(self.cmd[0], list(self.cmd), {**os.environ, **self.environment_vars})
except FileNotFoundError:
error(f'{self.cmd[0]} does not exist.')
self.exit_code = 1
return False
else:
# Only parent process moves back to the original working directory
os.chdir(old_dir)
self.started = True
self.poll_object.register(self.child_fd, EPOLLIN | EPOLLHUP)
return True
def decode(self, encoding: str = 'UTF-8') -> str:
return self._trace_log.decode(encoding)
class SysCommand:
def __init__(
self,
cmd: str | list[str],
peek_output: bool | None = False,
environment_vars: dict[str, str] | None = None,
working_directory: str = './',
remove_vt100_escape_codes_from_lines: bool = True,
):
self.cmd = cmd
self.peek_output = peek_output
self.environment_vars = environment_vars
self.working_directory = working_directory
self.remove_vt100_escape_codes_from_lines = remove_vt100_escape_codes_from_lines
self.session: SysCommandWorker | None = None
self.create_session()
def __enter__(self) -> SysCommandWorker | None:
return self.session
def __exit__(self, exc_type: type[BaseException] | None, exc_value: BaseException | None, traceback: TracebackType | None) -> None:
# b''.join(sys_command('sync')) # No need to, since the underlying fs() object will call sync.
# TODO: https://stackoverflow.com/questions/28157929/how-to-safely-handle-an-exception-inside-a-context-manager
if exc_type is not None:
error(str(exc_value))
def __iter__(self, *args: list[Any], **kwargs: dict[str, Any]) -> Iterator[bytes]:
if self.session:
yield from self.session
def __getitem__(self, key: slice) -> bytes:
if not self.session:
raise KeyError('SysCommand() does not have an active session.')
elif type(key) is slice:
start = key.start or 0
end = key.stop or len(self.session._trace_log)
return self.session._trace_log[start:end]
else:
raise ValueError("SysCommand() doesn't have key & value pairs, only slices, SysCommand('ls')[:10] as an example.")
@override
def __repr__(self, *args: list[Any], **kwargs: dict[str, Any]) -> str:
return self.decode('UTF-8', errors='backslashreplace') or ''
def create_session(self) -> bool:
"""
Initiates a :ref:`SysCommandWorker` session in this class ``.session``.
It then proceeds to poll the process until it ends, after which it also
clears any printed output if ``.peek_output=True``.
"""
if self.session:
return True
with SysCommandWorker(
self.cmd,
peek_output=self.peek_output,
environment_vars=self.environment_vars,
remove_vt100_escape_codes_from_lines=self.remove_vt100_escape_codes_from_lines,
working_directory=self.working_directory,
) as session:
self.session = session
while not self.session.ended:
self.session.poll()
if self.peek_output:
sys.stdout.write('\n')
sys.stdout.flush()
return True
def decode(self, encoding: str = 'utf-8', errors: str = 'backslashreplace', strip: bool = True) -> str:
if not self.session:
raise ValueError('No session available to decode')
val = self.session._trace_log.decode(encoding, errors=errors)
if strip:
return val.strip()
return val
def output(self, remove_cr: bool = True) -> bytes:
if not self.session:
raise ValueError('No session available')
if remove_cr:
return self.session._trace_log.replace(b'\r\n', b'\n')
return self.session._trace_log
@property
def exit_code(self) -> int | None:
if self.session:
return self.session.exit_code
else:
return None
@property
def trace_log(self) -> bytes | None:
if self.session:
return self.session._trace_log
return None
def run(
cmd: list[str],
input_data: bytes | None = None,
) -> subprocess.CompletedProcess[bytes]:
_cmd_history(cmd)
return subprocess.run(
cmd,
input=input_data,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
check=True,
)
def locate_binary(name: str) -> str:
if path := which(name):
return path
raise RequirementError(f'Binary {name} does not exist.')
def _pid_exists(pid: int) -> bool:
try:
return any(subprocess.check_output(['ps', '--no-headers', '-o', 'pid', '-p', str(pid)]).strip())
except subprocess.CalledProcessError:
return False
def _cmd_history(cmd: list[str]) -> None:
content = f'{time.time()} {cmd}\n'
_append_log('cmd_history.txt', content)
def _cmd_output(output: str) -> None:
_append_log('cmd_output.txt', output)
def _append_log(file: str, content: str) -> None:
path = logger.directory / file
change_perm = not path.exists()
try:
with path.open('a') as f:
f.write(content)
if change_perm:
path.chmod(stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP)
except PermissionError, FileNotFoundError:
# If the file does not exist, ignore the error
pass

View File

@ -1,181 +1,137 @@
import os
import json
import stat
import readline
from pathlib import Path
from typing import Optional, Dict, Any, TYPE_CHECKING
from .menu import Menu, MenuSelectionType
from .storage import storage
from .general import JSON, UNSAFE_JSON
from .output import debug, info, warn
if TYPE_CHECKING:
_: Any
from archinstall.lib.args import USER_CONFIG_FILE, USER_CREDS_FILE, ArchConfig
from archinstall.lib.log import debug
from archinstall.lib.menu.helpers import Confirmation, Selection
from archinstall.lib.menu.util import get_password, prompt_dir
from archinstall.lib.translationhandler import tr
from archinstall.tui.menu_item import MenuItem, MenuItemGroup
from archinstall.tui.result import ResultType
class ConfigurationOutput:
def __init__(self, config: Dict):
"""
Configuration output handler to parse the existing configuration data structure and prepare for output on the
console and for saving it to configuration files
async def confirm_config(config: ArchConfig) -> bool:
header = f'{tr("The specified configuration will be applied")}. '
header += tr('Would you like to continue?') + '\n'
:param config: A dictionary containing configurations (basically archinstall.arguments)
:type config: Dict
"""
self._config = config
self._user_credentials: Dict[str, Any] = {}
self._user_config: Dict[str, Any] = {}
self._default_save_path = storage.get('LOG_PATH', Path('.'))
self._user_config_file = 'user_configuration.json'
self._user_creds_file = "user_credentials.json"
group = MenuItemGroup.yes_no()
group.set_preview_for_all(lambda x: config.user_config_to_json())
self._sensitive = ['!users', '!root-password']
self._ignore = ['abort', 'install', 'config', 'creds', 'dry_run']
result = await Confirmation(
group=group,
header=header,
allow_skip=False,
preset=True,
preview_location='bottom',
preview_header=tr('Configuration preview'),
).show()
self._process_config()
if not result.get_value():
return False
@property
def user_credentials_file(self):
return self._user_creds_file
@property
def user_configuration_file(self):
return self._user_config_file
def _process_config(self):
for key, value in self._config.items():
if key in self._sensitive:
self._user_credentials[key] = value
elif key in self._ignore:
pass
else:
self._user_config[key] = value
# special handling for encryption password
if key == 'disk_encryption' and value:
self._user_credentials['encryption_password'] = value.encryption_password
def user_config_to_json(self) -> str:
return json.dumps({
'config_version': storage['__version__'], # Tells us what version was used to generate the config
**self._user_config, # __version__ will be overwritten by old version definition found in config
'version': storage['__version__']
}, indent=4, sort_keys=True, cls=JSON)
def user_credentials_to_json(self) -> Optional[str]:
if self._user_credentials:
return json.dumps(self._user_credentials, indent=4, sort_keys=True, cls=UNSAFE_JSON)
return None
def show(self):
print(_('\nThis is your chosen configuration:'))
debug(" -- Chosen configuration --")
info(self.user_config_to_json())
print()
def _is_valid_path(self, dest_path: Path) -> bool:
dest_path_ok = dest_path.exists() and dest_path.is_dir()
if not dest_path_ok:
warn(
f'Destination directory {dest_path.resolve()} does not exist or is not a directory\n.',
'Configuration files can not be saved'
)
return dest_path_ok
def save_user_config(self, dest_path: Path):
if self._is_valid_path(dest_path):
target = dest_path / self._user_config_file
target.write_text(self.user_config_to_json())
os.chmod(target, stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP)
def save_user_creds(self, dest_path: Path):
if self._is_valid_path(dest_path):
if user_creds := self.user_credentials_to_json():
target = dest_path / self._user_creds_file
target.write_text(user_creds)
os.chmod(target, stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP)
def save(self, dest_path: Optional[Path] = None):
dest_path = dest_path or self._default_save_path
if self._is_valid_path(dest_path):
self.save_user_config(dest_path)
self.save_user_creds(dest_path)
return True
def save_config(config: Dict):
def preview(selection: str):
match options[selection]:
case "user_config":
serialized = config_output.user_config_to_json()
return f"{config_output.user_configuration_file}\n{serialized}"
case "user_creds":
if maybe_serial := config_output.user_credentials_to_json():
return f"{config_output.user_credentials_file}\n{maybe_serial}"
return str(_("No configuration"))
case "all":
output = [config_output.user_configuration_file]
if config_output.user_credentials_to_json():
output.append(config_output.user_credentials_file)
async def save_config(config: ArchConfig) -> None:
def preview(item: MenuItem) -> str | None:
match item.value:
case 'user_config':
serialized = config.user_config_to_json()
return f'{USER_CONFIG_FILE}\n{serialized}'
case 'user_creds':
if maybe_serial := config.user_credentials_to_json():
return f'{USER_CREDS_FILE}\n{maybe_serial}'
return tr('No configuration')
case 'all':
output = [str(USER_CONFIG_FILE)]
config.user_credentials_to_json()
output.append(str(USER_CREDS_FILE))
return '\n'.join(output)
return None
try:
config_output = ConfigurationOutput(config)
items = [
MenuItem(
tr('Save user configuration (including disk layout)'),
value='user_config',
preview_action=preview,
),
MenuItem(
tr('Save user credentials'),
value='user_creds',
preview_action=preview,
),
MenuItem(
tr('Save all'),
value='all',
preview_action=preview,
),
]
options = {
str(_("Save user configuration (including disk layout)")): "user_config",
str(_("Save user credentials")): "user_creds",
str(_("Save all")): "all",
}
group = MenuItemGroup(items)
result = await Selection[str](
group,
allow_skip=True,
preview_location='right',
).show()
save_choice = Menu(
_("Choose which configuration to save"),
list(options),
sort=False,
skip=True,
preview_size=0.75,
preview_command=preview,
).run()
if save_choice.type_ == MenuSelectionType.Skip:
match result.type_:
case ResultType.Skip:
return
case ResultType.Selection:
save_option = result.get_value()
case _:
raise ValueError('Unhandled return type')
readline.set_completer_delims("\t\n=")
readline.parse_and_bind("tab: complete")
while True:
path = input(
_(
"Enter a directory for the configuration(s) to be saved (tab completion enabled)\nSave directory: "
)
).strip(" ")
dest_path = Path(path)
if dest_path.exists() and dest_path.is_dir():
break
info(_("Not a valid directory: {}").format(dest_path), fg="red")
readline.set_completer_delims('\t\n=')
readline.parse_and_bind('tab: complete')
if not path:
return
dest_path = await prompt_dir(
tr('Enter a directory for the configuration(s) to be saved') + '\n',
allow_skip=True,
)
prompt = _(
"Do you want to save {} configuration file(s) in the following location?\n\n{}"
).format(options[str(save_choice.value)], dest_path.absolute())
save_confirmation = Menu(prompt, Menu.yes_no(), default_option=Menu.yes()).run()
if save_confirmation == Menu.no():
return
debug("Saving {} configuration files to {}".format(options[str(save_choice.value)], dest_path.absolute()))
match options[str(save_choice.value)]:
case "user_config":
config_output.save_user_config(dest_path)
case "user_creds":
config_output.save_user_creds(dest_path)
case "all":
config_output.save(dest_path)
except KeyboardInterrupt:
if not dest_path:
return
header = tr('Do you want to save the configuration file(s) to {}?').format(dest_path)
save_result = await Confirmation(
header=header,
allow_skip=False,
preset=True,
).show()
match save_result.type_:
case ResultType.Selection:
if not save_result.get_value():
return
case _:
return
debug(f'Saving configuration files to {dest_path.absolute()}')
header = tr('Do you want to encrypt the user_credentials.json file?')
enc_result = await Confirmation(
header=header,
allow_skip=False,
preset=False,
).show()
enc_password: str | None = None
if enc_result.type_ == ResultType.Selection:
if enc_result.get_value():
password = await get_password(
header=tr('Credentials file encryption password'),
allow_skip=True,
)
if password:
enc_password = password.plaintext
match save_option:
case 'user_config':
config.save_user_config(dest_path)
case 'user_creds':
config.save_user_creds(dest_path, password=enc_password)
case 'all':
config.save(dest_path, creds=True, password=enc_password)

125
archinstall/lib/crypt.py Normal file
View File

@ -0,0 +1,125 @@
import base64
import ctypes
import os
from pathlib import Path
from cryptography.fernet import Fernet, InvalidToken
from cryptography.hazmat.primitives.kdf.argon2 import Argon2id
from archinstall.lib.log import debug
libcrypt = ctypes.CDLL('libcrypt.so')
libcrypt.crypt.argtypes = [ctypes.c_char_p, ctypes.c_char_p]
libcrypt.crypt.restype = ctypes.c_char_p
libcrypt.crypt_gensalt.argtypes = [ctypes.c_char_p, ctypes.c_ulong, ctypes.c_char_p, ctypes.c_int]
libcrypt.crypt_gensalt.restype = ctypes.c_char_p
LOGIN_DEFS = Path('/etc/login.defs')
def _search_login_defs(key: str) -> str | None:
defs = LOGIN_DEFS.read_text()
for line in defs.split('\n'):
line = line.strip()
if line.startswith('#'):
continue
if line.startswith(key):
value = line.split(' ')[1]
return value
return None
def crypt_gen_salt(prefix: str | bytes, rounds: int) -> bytes:
if isinstance(prefix, str):
prefix = prefix.encode('utf-8')
setting = libcrypt.crypt_gensalt(prefix, rounds, None, 0)
if setting is None:
raise ValueError(f'crypt_gensalt() returned NULL for prefix {prefix!r} and rounds {rounds}')
return setting
def crypt_yescrypt(plaintext: str) -> str:
"""
By default chpasswd in Arch uses PAM to hash the password with crypt_yescrypt
the PAM code https://github.com/linux-pam/linux-pam/blob/master/modules/pam_unix/support.c
shows that the hashing rounds are determined from YESCRYPT_COST_FACTOR in /etc/login.defs
If no value was specified (or commented out) a default of 5 is chosen
"""
value = _search_login_defs('YESCRYPT_COST_FACTOR')
if value is not None:
rounds = int(value)
if rounds < 3:
rounds = 3
elif rounds > 11:
rounds = 11
else:
rounds = 5
debug(f'Creating yescrypt hash with rounds {rounds}')
enc_plaintext = plaintext.encode('utf-8')
salt = crypt_gen_salt('$y$', rounds)
crypt_hash = libcrypt.crypt(enc_plaintext, salt)
if crypt_hash is None:
raise ValueError('crypt() returned NULL')
return crypt_hash.decode('utf-8')
def _get_fernet(salt: bytes, password: str) -> Fernet:
# https://cryptography.io/en/latest/hazmat/primitives/key-derivation-functions/#argon2id
kdf = Argon2id(
salt=salt,
length=32,
iterations=1,
lanes=4,
memory_cost=64 * 1024,
ad=None,
secret=None,
)
key = base64.urlsafe_b64encode(
kdf.derive(
password.encode('utf-8'),
),
)
return Fernet(key)
def encrypt(password: str, data: str) -> str:
salt = os.urandom(16)
f = _get_fernet(salt, password)
token = f.encrypt(data.encode('utf-8'))
encoded_token = base64.urlsafe_b64encode(token).decode('utf-8')
encoded_salt = base64.urlsafe_b64encode(salt).decode('utf-8')
return f'$argon2id${encoded_salt}${encoded_token}'
def decrypt(data: str, password: str) -> str:
_, algo, encoded_salt, encoded_token = data.split('$')
salt = base64.urlsafe_b64decode(encoded_salt)
token = base64.urlsafe_b64decode(encoded_token)
if algo != 'argon2id':
raise ValueError(f'Unsupported algorithm {algo!r}')
f = _get_fernet(salt, password)
try:
decrypted = f.decrypt(token)
except InvalidToken:
raise ValueError('Invalid password')
return decrypted.decode('utf-8')

View File

@ -1,40 +0,0 @@
from .device_handler import device_handler, disk_layouts
from .fido import Fido2
from .filesystem import FilesystemHandler
from .subvolume_menu import SubvolumeMenu
from .partitioning_menu import (
manual_partitioning,
PartitioningList
)
from .device_model import (
_DeviceInfo,
BDevice,
DiskLayoutType,
DiskLayoutConfiguration,
PartitionTable,
Unit,
Size,
SubvolumeModification,
DeviceGeometry,
PartitionType,
PartitionFlag,
FilesystemType,
ModificationStatus,
PartitionModification,
DeviceModification,
EncryptionType,
DiskEncryption,
Fido2Device,
LsblkInfo,
CleanType,
get_lsblk_info,
get_all_lsblk_info,
get_lsblk_by_mountpoint
)
from .encryption_menu import (
select_encryption_type,
select_encrypted_password,
select_hsm,
select_partitions_to_encrypt,
DiskEncryptionMenu,
)

View File

@ -1,81 +1,114 @@
from __future__ import annotations
import json
import logging
import os
import time
from pathlib import Path
from typing import List, Dict, Any, Optional, TYPE_CHECKING
from parted import ( # type: ignore
Disk, Geometry, FileSystem,
PartitionException, DiskLabelException,
getAllDevices, freshDisk, Partition, Device
from parted import Device, Disk, DiskException, FileSystem, Geometry, IOException, Partition, PartitionException, freshDisk, getAllDevices, getDevice, newDisk
from archinstall.lib.command import SysCommand
from archinstall.lib.disk.luks import Luks2, unlock_luks2_dev
from archinstall.lib.disk.utils import (
find_lsblk_info,
get_all_lsblk_info,
get_lsblk_info,
mount,
udev_sync,
umount,
)
from .device_model import (
DeviceModification, PartitionModification,
BDevice, _DeviceInfo, _PartitionInfo,
FilesystemType, Unit, PartitionTable,
ModificationStatus, get_lsblk_info, LsblkInfo,
_BtrfsSubvolumeInfo, get_all_lsblk_info, DiskEncryption
from archinstall.lib.exceptions import DiskError, SysCallError, UnknownFilesystemFormat
from archinstall.lib.log import debug, error, info, log
from archinstall.lib.models.device import (
DEFAULT_ITER_TIME,
BDevice,
BtrfsMountOption,
DeviceModification,
DiskEncryption,
FilesystemType,
LsblkInfo,
ModificationStatus,
PartitionFlag,
PartitionGUID,
PartitionModification,
PartitionTable,
SubvolumeModification,
Unit,
_BtrfsSubvolumeInfo,
_DeviceInfo,
_PartitionInfo,
)
from ..exceptions import DiskError, UnknownFilesystemFormat
from ..general import SysCommand, SysCallError, JSON
from ..luks import Luks2
from ..output import debug, error, info, warn
from ..utils.util import is_subpath
if TYPE_CHECKING:
_: Any
from archinstall.lib.models.users import Password
from archinstall.lib.pathnames import ARCHISO_MOUNTPOINT
class DeviceHandler(object):
class DeviceHandler:
_TMP_BTRFS_MOUNT = Path('/mnt/arch_btrfs')
def __init__(self):
self._devices: Dict[Path, BDevice] = {}
def __init__(self) -> None:
self._devices: dict[Path, BDevice] = {}
self._partition_table = PartitionTable.default()
self.load_devices()
@property
def devices(self) -> List[BDevice]:
def devices(self) -> list[BDevice]:
return list(self._devices.values())
def load_devices(self):
@property
def partition_table(self) -> PartitionTable:
return self._partition_table
def load_devices(self) -> None:
block_devices = {}
for device in getAllDevices():
if get_lsblk_info(device.path).type == 'rom':
udev_sync()
all_lsblk_info = get_all_lsblk_info()
devices = getAllDevices()
devices.extend(self.get_loop_devices())
for device in devices:
dev_lsblk_info = find_lsblk_info(device.path, all_lsblk_info)
if not dev_lsblk_info:
debug(f'Device lsblk info not found: {device.path}')
continue
if dev_lsblk_info.type == 'rom':
continue
# exclude archiso loop device
if dev_lsblk_info.mountpoint == ARCHISO_MOUNTPOINT:
continue
try:
disk = Disk(device)
except DiskLabelException as err:
if 'unrecognised disk label' in getattr(error, 'message', str(err)):
disk = freshDisk(device, PartitionTable.GPT.value)
if dev_lsblk_info.pttype:
disk = newDisk(device)
else:
debug(f'Unable to get disk from device: {device}')
continue
disk = freshDisk(device, self.partition_table.value)
except DiskException as err:
debug(f'Unable to get disk from {device.path}: {err}')
continue
device_info = _DeviceInfo.from_disk(disk)
partition_infos = []
for partition in disk.partitions:
lsblk_info = get_lsblk_info(partition.path)
lsblk_info = find_lsblk_info(partition.path, dev_lsblk_info.children)
if not lsblk_info:
debug(f'Partition lsblk info not found: {partition.path}')
continue
fs_type = self._determine_fs_type(partition, lsblk_info)
subvol_infos = []
if fs_type == FilesystemType.Btrfs:
subvol_infos = self.get_btrfs_info(partition.path)
if fs_type == FilesystemType.BTRFS:
subvol_infos = self.get_btrfs_info(partition.path, lsblk_info)
partition_infos.append(
_PartitionInfo.from_partition(
partition,
lsblk_info,
fs_type,
lsblk_info.partuuid,
lsblk_info.mountpoints,
subvol_infos
)
subvol_infos,
),
)
block_device = BDevice(disk, device_info, partition_infos)
@ -83,13 +116,39 @@ class DeviceHandler(object):
self._devices = block_devices
@staticmethod
def get_loop_devices() -> list[Device]:
devices = []
try:
loop_devices = SysCommand(['losetup', '-a'])
except SysCallError as err:
debug(f'Failed to get loop devices: {err}')
else:
for ld_info in str(loop_devices).splitlines():
try:
loop_device_path, _ = ld_info.split(':', maxsplit=1)
except ValueError:
continue
try:
loop_device = getDevice(loop_device_path)
except IOException as err:
debug(f'Failed to get loop device: {err}')
else:
devices.append(loop_device)
return devices
def _determine_fs_type(
self,
partition: Partition,
lsblk_info: Optional[LsblkInfo] = None
) -> Optional[FilesystemType]:
lsblk_info: LsblkInfo | None = None,
) -> FilesystemType | None:
try:
if partition.fileSystem:
if partition.fileSystem.type == FilesystemType.LINUX_SWAP.parted_value:
return FilesystemType.LINUX_SWAP
return FilesystemType(partition.fileSystem.type)
elif lsblk_info is not None:
return FilesystemType(lsblk_info.fstype) if lsblk_info.fstype else None
@ -99,199 +158,191 @@ class DeviceHandler(object):
return None
def get_device(self, path: Path) -> Optional[BDevice]:
def get_device(self, path: Path) -> BDevice | None:
return self._devices.get(path, None)
def get_device_by_partition_path(self, partition_path: Path) -> Optional[BDevice]:
def get_device_by_partition_path(self, partition_path: Path) -> BDevice | None:
partition = self.find_partition(partition_path)
if partition:
device: Device = partition.disk.device
return self.get_device(Path(device.path))
return None
def find_partition(self, path: Path) -> Optional[_PartitionInfo]:
def find_partition(self, path: Path) -> _PartitionInfo | None:
for device in self._devices.values():
part = next(filter(lambda x: str(x.path) == str(path), device.partition_infos), None)
if part is not None:
return part
return None
def get_uuid_for_path(self, path: Path) -> Optional[str]:
def get_uuid_for_path(self, path: Path) -> str | None:
partition = self.find_partition(path)
return partition.partuuid if partition else None
def get_btrfs_info(self, dev_path: Path) -> List[_BtrfsSubvolumeInfo]:
lsblk_info = get_lsblk_info(dev_path)
subvol_infos: List[_BtrfsSubvolumeInfo] = []
def get_btrfs_info(
self,
dev_path: Path,
lsblk_info: LsblkInfo | None = None,
) -> list[_BtrfsSubvolumeInfo]:
if not lsblk_info:
lsblk_info = get_lsblk_info(dev_path)
subvol_infos: list[_BtrfsSubvolumeInfo] = []
if not lsblk_info.mountpoint:
self.mount(dev_path, self._TMP_BTRFS_MOUNT, create_target_mountpoint=True)
mount(dev_path, self._TMP_BTRFS_MOUNT, create_target_mountpoint=True)
mountpoint = self._TMP_BTRFS_MOUNT
else:
# when multiple subvolumes are mounted then the lsblk output may look like
# "mountpoint": "/mnt/archinstall/.snapshots"
# "mountpoints": ["/mnt/archinstall/.snapshots", "/mnt/archinstall/home", ..]
# "mountpoint": "/mnt/archinstall/var/log"
# "mountpoints": ["/mnt/archinstall/var/log", "/mnt/archinstall/home", ..]
# so we'll determine the minimum common path and assume that's the root
path_strings = [str(m) for m in lsblk_info.mountpoints]
common_prefix = os.path.commonprefix(path_strings)
mountpoint = Path(common_prefix)
try:
common_path = os.path.commonpath(lsblk_info.mountpoints)
except ValueError:
return subvol_infos
mountpoint = Path(common_path)
try:
result = SysCommand(f'btrfs subvolume list {mountpoint}')
result = SysCommand(f'btrfs subvolume list {mountpoint}').decode()
except SysCallError as err:
debug(f'Failed to read btrfs subvolume information: {err}')
return subvol_infos
try:
if decoded := result.decode('utf-8'):
# ID 256 gen 16 top level 5 path @
for line in decoded.splitlines():
# expected output format:
# ID 257 gen 8 top level 5 path @home
name = Path(line.split(' ')[-1])
sub_vol_mountpoint = lsblk_info.btrfs_subvol_info.get(name, None)
subvol_infos.append(_BtrfsSubvolumeInfo(name, sub_vol_mountpoint))
except json.decoder.JSONDecodeError as err:
error(f"Could not decode lsblk JSON: {result}")
raise err
# It is assumed that lsblk will contain the fields as
# "mountpoints": ["/mnt/archinstall/log", "/mnt/archinstall/home", "/mnt/archinstall", ...]
# "fsroots": ["/@log", "/@home", "/@"...]
# we'll thereby map the fsroot, which are the mounted filesystem roots
# to the corresponding mountpoints
btrfs_subvol_info = dict(zip(lsblk_info.fsroots, lsblk_info.mountpoints))
# ID 256 gen 16 top level 5 path @
for line in result.splitlines():
# expected output format:
# ID 257 gen 8 top level 5 path @home
name = Path(line.split(' ')[-1])
sub_vol_mountpoint = btrfs_subvol_info.get('/' / name, None)
subvol_infos.append(_BtrfsSubvolumeInfo(name, sub_vol_mountpoint))
if not lsblk_info.mountpoint:
self.umount(dev_path)
umount(dev_path)
return subvol_infos
def _perform_formatting(
def format(
self,
fs_type: FilesystemType,
path: Path,
additional_parted_options: List[str] = []
):
additional_parted_options: list[str] = [],
) -> None:
mkfs_type = fs_type.value
command = None
options = []
command = ''
match fs_type:
case FilesystemType.Btrfs:
options += ['-f']
command += 'mkfs.btrfs'
case FilesystemType.Fat16:
options += ['-F16']
command += 'mkfs.fat'
case FilesystemType.Fat32:
options += ['-F32']
command += 'mkfs.fat'
case FilesystemType.Ext2:
options += ['-F']
command += 'mkfs.ext2'
case FilesystemType.Ext3:
options += ['-F']
command += 'mkfs.ext3'
case FilesystemType.Ext4:
options += ['-F']
command += 'mkfs.ext4'
case FilesystemType.Xfs:
options += ['-f']
command += 'mkfs.xfs'
case FilesystemType.F2fs:
options += ['-f']
command += 'mkfs.f2fs'
case FilesystemType.Ntfs:
options += ['-f', '-Q']
command += 'mkfs.ntfs'
case FilesystemType.Reiserfs:
command += 'mkfs.reiserfs'
case FilesystemType.BTRFS | FilesystemType.XFS:
# Force overwrite
options.append('-f')
case FilesystemType.F2FS:
options.append('-f')
options.extend(('-O', 'extra_attr'))
case FilesystemType.EXT2 | FilesystemType.EXT3 | FilesystemType.EXT4:
# Force create
options.append('-F')
case _ if fs_type.is_fat():
mkfs_type = 'fat'
# Set FAT size
options.extend(('-F', fs_type.value.removeprefix(mkfs_type)))
case FilesystemType.LINUX_SWAP:
command = 'mkswap'
case _:
raise UnknownFilesystemFormat(f'Filetype "{fs_type.value}" is not supported')
options += additional_parted_options
options_str = ' '.join(options)
if not command:
command = f'mkfs.{mkfs_type}'
info(f'Formatting filesystem: /usr/bin/{command} {options_str} {path}')
cmd = [command, *options, *additional_parted_options, str(path)]
debug('Formatting filesystem:', ' '.join(cmd))
try:
SysCommand(f"/usr/bin/{command} {options_str} {path}")
SysCommand(cmd)
except SysCallError as err:
msg = f'Could not format {path} with {fs_type.value}: {err.message}'
error(msg)
raise DiskError(msg) from err
def _perform_enc_formatting(
def encrypt(
self,
dev_path: Path,
mapper_name: Optional[str],
fs_type: FilesystemType,
enc_conf: DiskEncryption
):
mapper_name: str | None,
enc_password: Password | None,
lock_after_create: bool = True,
iter_time: int = DEFAULT_ITER_TIME,
) -> Luks2:
luks_handler = Luks2(
dev_path,
mapper_name=mapper_name,
password=enc_conf.encryption_password
password=enc_password,
)
key_file = luks_handler.encrypt()
key_file = luks_handler.encrypt(iter_time=iter_time)
udev_sync()
luks_handler.unlock(key_file=key_file)
if not luks_handler.mapper_dev:
raise DiskError('Failed to unlock luks device')
if lock_after_create:
debug(f'luks2 locking device: {dev_path}')
luks_handler.lock()
return luks_handler
def format_encrypted(
self,
dev_path: Path,
mapper_name: str | None,
fs_type: FilesystemType,
enc_conf: DiskEncryption,
) -> None:
if not enc_conf.encryption_password:
raise ValueError('No encryption password provided')
luks_handler = Luks2(
dev_path,
mapper_name=mapper_name,
password=enc_conf.encryption_password,
)
key_file = luks_handler.encrypt(iter_time=enc_conf.iter_time)
udev_sync()
debug(f'Unlocking luks2 device: {dev_path}')
luks_handler.unlock(key_file=key_file)
if not luks_handler.mapper_dev:
raise DiskError('Failed to unlock luks device')
info(f'luks2 formatting mapper dev: {luks_handler.mapper_dev}')
self._perform_formatting(fs_type, luks_handler.mapper_dev)
self.format(fs_type, luks_handler.mapper_dev)
info(f'luks2 locking device: {dev_path}')
luks_handler.lock()
def _validate(self, device_mod: DeviceModification):
checks = {
# verify that all partitions have a path set (which implies that they have been created)
lambda x: x.dev_path is None: ValueError('When formatting, all partitions must have a path set'),
# crypto luks is not a valid file system type
lambda x: x.fs_type is FilesystemType.Crypto_luks: ValueError('Crypto luks cannot be set as a filesystem type'),
# file system type must be set
lambda x: x.fs_type is None: ValueError('File system type must be set for modification')
}
for check, exc in checks.items():
found = next(filter(check, device_mod.partitions), None)
if found is not None:
raise exc
def format(
self,
device_mod: DeviceModification,
enc_conf: Optional['DiskEncryption'] = None
):
"""
Format can be given an overriding path, for instance /dev/null to test
the formatting functionality and in essence the support for the given filesystem.
"""
self._validate(device_mod)
# make sure all devices are unmounted
self._umount_all_existing(device_mod)
for part_mod in device_mod.partitions:
# partition will be encrypted
if enc_conf is not None and part_mod in enc_conf.partitions:
self._perform_enc_formatting(
part_mod.safe_dev_path,
part_mod.mapper_name,
part_mod.safe_fs_type,
enc_conf
)
else:
self._perform_formatting(part_mod.safe_fs_type, part_mod.safe_dev_path)
def _perform_partitioning(
def _setup_partition(
self,
part_mod: PartitionModification,
block_device: BDevice,
disk: Disk,
requires_delete: bool
):
requires_delete: bool,
) -> None:
# when we require a delete and the partition to be (re)created
# already exists then we have to delete it first
if requires_delete and part_mod.status in [ModificationStatus.Modify, ModificationStatus.Delete]:
if requires_delete and part_mod.status in [ModificationStatus.MODIFY, ModificationStatus.DELETE]:
info(f'Delete existing partition: {part_mod.safe_dev_path}')
part_info = self.find_partition(part_mod.safe_dev_path)
@ -299,282 +350,238 @@ class DeviceHandler(object):
raise DiskError(f'No partition for dev path found: {part_mod.safe_dev_path}')
disk.deletePartition(part_info.partition)
disk.commit()
if part_mod.status == ModificationStatus.Delete:
if part_mod.status == ModificationStatus.DELETE:
return
start_sector = part_mod.start.convert(
Unit.sectors,
block_device.device_info.sector_size
block_device.device_info.sector_size,
)
length_sector = part_mod.length.convert(
Unit.sectors,
block_device.device_info.sector_size
block_device.device_info.sector_size,
)
geometry = Geometry(
device=block_device.disk.device,
start=start_sector.value,
length=length_sector.value
length=length_sector.value,
)
filesystem = FileSystem(type=part_mod.safe_fs_type.value, geometry=geometry)
fs_value = part_mod.safe_fs_type.parted_value
filesystem = FileSystem(type=fs_value, geometry=geometry)
partition = Partition(
disk=disk,
type=part_mod.type.get_partition_code(),
fs=filesystem,
geometry=geometry
geometry=geometry,
)
for flag in part_mod.flags:
partition.setFlag(flag.value)
partition.setFlag(flag.flag_id)
debug(f'\tType: {part_mod.type.value}')
debug(f'\tFilesystem: {part_mod.safe_fs_type.value}')
debug(f'\tFilesystem: {fs_value}')
debug(f'\tGeometry: {start_sector.value} start sector, {length_sector.value} length')
try:
disk.addPartition(partition=partition, constraint=disk.device.optimalAlignedConstraint)
disk.commit()
# the creation will take a bit of time
time.sleep(3)
# the partition has a real path now as it was created
part_mod.dev_path = Path(partition.path)
lsblk_info = self._fetch_partuuid(part_mod.dev_path)
part_mod.partuuid = lsblk_info.partuuid
part_mod.uuid = lsblk_info.uuid
except PartitionException as ex:
raise DiskError(f'Unable to add partition, most likely due to overlapping sectors: {ex}') from ex
def _fetch_partuuid(self, path: Path) -> LsblkInfo:
attempts = 3
lsblk_info: Optional[LsblkInfo] = None
if disk.type == PartitionTable.GPT.value:
if part_mod.is_root():
partition.type_uuid = PartitionGUID.LINUX_ROOT_X86_64.bytes
elif PartitionFlag.LINUX_HOME not in part_mod.flags and part_mod.is_home():
partition.setFlag(PartitionFlag.LINUX_HOME.flag_id)
self.partprobe(path)
for attempt_nr in range(attempts):
time.sleep(attempt_nr + 1)
lsblk_info = get_lsblk_info(path)
# the partition has a path now that it has been added
part_mod.dev_path = Path(partition.path)
if lsblk_info.partuuid:
break
def fetch_part_info(self, path: Path) -> LsblkInfo:
lsblk_info = get_lsblk_info(path)
self.partprobe(path)
if not lsblk_info.partn:
debug(f'Unable to determine new partition number: {path}\n{lsblk_info}')
raise DiskError(f'Unable to determine new partition number: {path}')
if not lsblk_info or not lsblk_info.partuuid:
if not lsblk_info.partuuid:
debug(f'Unable to determine new partition uuid: {path}\n{lsblk_info}')
raise DiskError(f'Unable to determine new partition uuid: {path}')
debug(f'partuuid found: {lsblk_info.json()}')
if not lsblk_info.uuid:
debug(f'Unable to determine new uuid: {path}\n{lsblk_info}')
raise DiskError(f'Unable to determine new uuid: {path}')
debug(f'partition information found: {lsblk_info.model_dump_json()}')
return lsblk_info
def create_lvm_btrfs_subvolumes(
self,
path: Path,
btrfs_subvols: list[SubvolumeModification],
mount_options: list[str],
) -> None:
info(f'Creating subvolumes: {path}')
mount(path, self._TMP_BTRFS_MOUNT, create_target_mountpoint=True)
for sub_vol in sorted(btrfs_subvols, key=lambda x: x.name):
debug(f'Creating subvolume: {sub_vol.name}')
subvol_path = self._TMP_BTRFS_MOUNT / sub_vol.name
SysCommand(f'btrfs subvolume create -p {subvol_path}')
if BtrfsMountOption.nodatacow.value in mount_options:
try:
SysCommand(f'chattr +C {subvol_path}')
except SysCallError as err:
raise DiskError(f'Could not set nodatacow attribute at {subvol_path}: {err}')
if BtrfsMountOption.compress.value in mount_options:
try:
SysCommand(f'chattr +c {subvol_path}')
except SysCallError as err:
raise DiskError(f'Could not set compress attribute at {subvol_path}: {err}')
umount(path)
def create_btrfs_volumes(
self,
part_mod: PartitionModification,
enc_conf: Optional['DiskEncryption'] = None
):
enc_conf: DiskEncryption | None = None,
) -> None:
info(f'Creating subvolumes: {part_mod.safe_dev_path}')
luks_handler = None
# unlock the partition first if it's encrypted
if enc_conf is not None and part_mod in enc_conf.partitions:
if not part_mod.mapper_name:
raise ValueError('No device path specified for modification')
luks_handler = self.unlock_luks2_dev(
luks_handler = unlock_luks2_dev(
part_mod.safe_dev_path,
part_mod.mapper_name,
enc_conf.encryption_password
enc_conf.encryption_password,
)
if not luks_handler.mapper_dev:
raise DiskError('Failed to unlock luks device')
self.mount(luks_handler.mapper_dev, self._TMP_BTRFS_MOUNT, create_target_mountpoint=True)
dev_path = luks_handler.mapper_dev
else:
self.mount(part_mod.safe_dev_path, self._TMP_BTRFS_MOUNT, create_target_mountpoint=True)
luks_handler = None
dev_path = part_mod.safe_dev_path
for sub_vol in part_mod.btrfs_subvols:
mount(
dev_path,
self._TMP_BTRFS_MOUNT,
create_target_mountpoint=True,
options=part_mod.mount_options,
)
for sub_vol in sorted(part_mod.btrfs_subvols, key=lambda x: x.name):
debug(f'Creating subvolume: {sub_vol.name}')
if luks_handler is not None:
subvol_path = self._TMP_BTRFS_MOUNT / sub_vol.name
else:
subvol_path = self._TMP_BTRFS_MOUNT / sub_vol.name
subvol_path = self._TMP_BTRFS_MOUNT / sub_vol.name
SysCommand(f"btrfs subvolume create {subvol_path}")
SysCommand(f'btrfs subvolume create -p {subvol_path}')
if sub_vol.nodatacow:
try:
SysCommand(f'chattr +C {subvol_path}')
except SysCallError as err:
raise DiskError(f'Could not set nodatacow attribute at {subvol_path}: {err}')
if sub_vol.compress:
try:
SysCommand(f'chattr +c {subvol_path}')
except SysCallError as err:
raise DiskError(f'Could not set compress attribute at {subvol_path}: {err}')
umount(dev_path)
if luks_handler is not None and luks_handler.mapper_dev is not None:
self.umount(luks_handler.mapper_dev)
luks_handler.lock()
else:
self.umount(part_mod.safe_dev_path)
def unlock_luks2_dev(self, dev_path: Path, mapper_name: str, enc_password: str) -> Luks2:
luks_handler = Luks2(dev_path, mapper_name=mapper_name, password=enc_password)
def umount_all_existing(self, device_path: Path) -> None:
debug(f'Unmounting all existing partitions: {device_path}')
if not luks_handler.is_unlocked():
luks_handler.unlock()
if not luks_handler.is_unlocked():
raise DiskError(f'Failed to unlock luks2 device: {dev_path}')
return luks_handler
def _umount_all_existing(self, modification: DeviceModification):
info(f'Unmounting all partitions: {modification.device_path}')
existing_partitions = self._devices[modification.device_path].partition_infos
existing_partitions = self._devices[device_path].partition_infos
for partition in existing_partitions:
debug(f'Unmounting: {partition.path}')
# un-mount for existing encrypted partitions
if partition.fs_type == FilesystemType.Crypto_luks:
if partition.fs_type == FilesystemType.CRYPTO_LUKS:
Luks2(partition.path).lock()
else:
self.umount(partition.path, recursive=True)
umount(partition.path, recursive=True)
def partition(
self,
modification: DeviceModification,
partition_table: Optional[PartitionTable] = None
):
partition_table: PartitionTable | None = None,
) -> None:
"""
Create a partition table on the block device and create all partitions.
"""
if modification.wipe:
if partition_table is None:
raise ValueError('Modification is marked as wipe but no partitioning table was provided')
if partition_table.MBR and len(modification.partitions) > 3:
raise DiskError('Too many partitions on disk, MBR disks can only have 3 primary partitions')
# make sure all devices are unmounted
self._umount_all_existing(modification)
partition_table = partition_table or self.partition_table
# WARNING: the entire device will be wiped and all data lost
if modification.wipe:
if partition_table.is_mbr() and len(modification.partitions) > 3:
raise DiskError('Too many partitions on disk, MBR disks can only have 3 primary partitions')
self.wipe_dev(modification.device)
part_table = partition_table.value if partition_table else None
disk = freshDisk(modification.device.disk.device, part_table)
disk = freshDisk(modification.device.disk.device, partition_table.value)
else:
info(f'Use existing device: {modification.device_path}')
disk = modification.device.disk
info(f'Creating partitions: {modification.device_path}')
# TODO sort by delete first
for part_mod in modification.partitions:
# don't touch existing partitions
if part_mod.exists():
continue
# don't touch existing partitions
filtered_part = [p for p in modification.partitions if not p.exists()]
for part_mod in filtered_part:
# if the entire disk got nuked then we don't have to delete
# any existing partitions anymore because they're all gone already
requires_delete = modification.wipe is False
self._perform_partitioning(part_mod, modification.device, disk, requires_delete=requires_delete)
self._setup_partition(part_mod, modification.device, disk, requires_delete=requires_delete)
self.partprobe(modification.device.device_info.path)
disk.commit()
def mount(
self,
dev_path: Path,
target_mountpoint: Path,
mount_fs: Optional[str] = None,
create_target_mountpoint: bool = True,
options: List[str] = []
):
if create_target_mountpoint and not target_mountpoint.exists():
target_mountpoint.mkdir(parents=True, exist_ok=True)
# Wipe filesystem/LVM signatures from newly created partitions
# to prevent "signature detected" errors
for part_mod in filtered_part:
if part_mod.dev_path:
debug(f'Wiping signatures from: {part_mod.dev_path}')
SysCommand(f'wipefs --all {part_mod.dev_path}')
if not target_mountpoint.exists():
raise ValueError('Target mountpoint does not exist')
# Sync with udev after wiping signatures
if filtered_part:
udev_sync()
lsblk_info = get_lsblk_info(dev_path)
if target_mountpoint in lsblk_info.mountpoints:
info(f'Device already mounted at {target_mountpoint}')
return
str_options = ','.join(options)
str_options = f'-o {str_options}' if str_options else ''
mount_fs = f'-t {mount_fs}' if mount_fs else ''
command = f'mount {mount_fs} {str_options} {dev_path} {target_mountpoint}'
debug(f'Mounting {dev_path}: command')
try:
SysCommand(command)
except SysCallError as err:
raise DiskError(f'Could not mount {dev_path}: {command}\n{err.message}')
def umount(self, mountpoint: Path, recursive: bool = False):
try:
lsblk_info = get_lsblk_info(mountpoint)
except SysCallError as ex:
# this could happen if before partitioning the device contained 3 partitions
# and after partitioning only 2 partitions were created, then the modifications object
# will have a reference to /dev/sX3 which is being tried to umount here now
if 'not a block device' in ex.message:
return
raise ex
if len(lsblk_info.mountpoints) > 0:
debug(f'Partition {mountpoint} is currently mounted at: {[str(m) for m in lsblk_info.mountpoints]}')
for mountpoint in lsblk_info.mountpoints:
debug(f'Unmounting mountpoint: {mountpoint}')
command = 'umount'
if recursive:
command += ' -R'
SysCommand(f'{command} {mountpoint}')
def detect_pre_mounted_mods(self, base_mountpoint: Path) -> List[DeviceModification]:
part_mods: Dict[Path, List[PartitionModification]] = {}
def detect_pre_mounted_mods(self, base_mountpoint: Path) -> list[DeviceModification]:
part_mods: dict[Path, list[PartitionModification]] = {}
for device in self.devices:
for part_info in device.partition_infos:
for mountpoint in part_info.mountpoints:
if is_subpath(mountpoint, base_mountpoint):
if mountpoint.is_relative_to(base_mountpoint):
path = Path(part_info.disk.device.path)
part_mods.setdefault(path, [])
part_mods[path].append(PartitionModification.from_existing_partition(part_info))
part_mod = PartitionModification.from_existing_partition(part_info)
if part_mod.mountpoint:
part_mod.mountpoint = mountpoint.root / mountpoint.relative_to(base_mountpoint)
else:
for subvol in part_mod.btrfs_subvols:
if sm := subvol.mountpoint:
subvol.mountpoint = sm.root / sm.relative_to(base_mountpoint)
part_mods[path].append(part_mod)
break
device_mods: List[DeviceModification] = []
device_mods: list[DeviceModification] = []
for device_path, mods in part_mods.items():
device_mod = DeviceModification(self._devices[device_path], False, mods)
device_mods.append(device_mod)
return device_mods
def partprobe(self, path: Optional[Path] = None):
def partprobe(self, path: Path | None = None) -> None:
if path is not None:
command = f'partprobe {path}'
else:
@ -584,40 +591,36 @@ class DeviceHandler(object):
debug(f'Calling partprobe: {command}')
SysCommand(command)
except SysCallError as err:
error(f'"{command}" failed to run: {err}')
if 'have been written, but we have been unable to inform the kernel of the change' in str(err):
log(f'Partprobe was not able to inform the kernel of the new disk state (ignoring error): {err}', fg='gray', level=logging.INFO)
else:
error(f'"{command}" failed to run (continuing anyway): {err}')
def _wipe(self, dev_path: Path):
def _wipe(self, dev_path: Path) -> None:
"""
Wipe a device (partition or otherwise) of meta-data, be it file system, LVM, etc.
@param dev_path: Device path of the partition to be wiped.
@type dev_path: str
@param dev_path: Device path of the partition to be wiped.
@type dev_path: str
"""
with open(dev_path, 'wb') as p:
p.write(bytearray(1024))
def wipe_dev(self, block_device: BDevice):
def wipe_dev(self, block_device: BDevice) -> None:
"""
Wipe the block device of meta-data, be it file system, LVM, etc.
This is not intended to be secure, but rather to ensure that
auto-discovery tools don't recognize anything here.
"""
info(f'Wiping partitions and metadata: {block_device.device_info.path}')
for partition in block_device.partition_infos:
luks = Luks2(partition.path)
if luks.isLuks():
luks.erase()
self._wipe(partition.path)
self._wipe(block_device.device_info.path)
device_handler = DeviceHandler()
def disk_layouts() -> str:
try:
lsblk_info = get_all_lsblk_info()
return json.dumps(lsblk_info, indent=4, sort_keys=True, cls=JSON)
except SysCallError as err:
warn(f"Could not return disk layouts: {err}")
return ''
except json.decoder.JSONDecodeError as err:
warn(f"Could not return disk layouts: {err}")
return ''

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More