Refactor general utility functions (#4212)

This commit is contained in:
Daniel Girtler 2026-02-26 08:45:21 +11:00 committed by GitHub
parent 3447d2f47d
commit 4f87ccba28
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
14 changed files with 124 additions and 121 deletions

View File

@ -14,6 +14,7 @@ from urllib.request import Request, urlopen
from pydantic.dataclasses import dataclass as p_dataclass
from archinstall.lib.crypt import decrypt
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
@ -27,7 +28,6 @@ from archinstall.lib.models.users import Password, User, UserSerialization
from archinstall.lib.output import debug, error, logger, warn
from archinstall.lib.plugins import load_plugin
from archinstall.lib.translationhandler import Language, tr, translation_handler
from archinstall.lib.utils.util import get_password
@p_dataclass

View File

@ -3,12 +3,12 @@ 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.output import FormattedOutput
from archinstall.lib.translationhandler import tr
from archinstall.lib.user.user_menu import select_users
from archinstall.lib.utils.util import get_password
from archinstall.tui.ui.menu_item import MenuItem, MenuItemGroup
from archinstall.tui.ui.result import ResultType

View File

@ -13,8 +13,8 @@ from archinstall.tui.ui.result import ResultType
from .args import ArchConfig
from .crypt import encrypt
from .menu.util import get_password, prompt_dir
from .output import debug, logger, warn
from .utils.util import get_password, prompt_dir
class ConfigurationOutput:

View File

@ -16,10 +16,10 @@ from archinstall.tui.ui.menu_item import MenuItem, MenuItemGroup
from archinstall.tui.ui.result import ResultType
from ..menu.abstract_menu import AbstractSubMenu
from ..menu.util import get_password
from ..models.device import DEFAULT_ITER_TIME, Fido2Device
from ..models.users import Password
from ..output import FormattedOutput
from ..utils.util import get_password
from .fido import Fido2

View File

@ -3,6 +3,7 @@ from pathlib import Path
from typing import override
from archinstall.lib.menu.helpers import Confirmation, Input, Selection
from archinstall.lib.menu.util import prompt_dir
from archinstall.lib.models.device import (
BtrfsMountOption,
DeviceModification,
@ -22,7 +23,6 @@ from archinstall.tui.ui.result import ResultType
from ..menu.list_manager import ListManager
from ..output import FormattedOutput
from ..utils.util import prompt_dir
from .subvolume_menu import SubvolumeMenu

View File

@ -2,12 +2,12 @@ from pathlib import Path
from typing import assert_never, override
from archinstall.lib.menu.helpers import Input
from archinstall.lib.menu.util import prompt_dir
from archinstall.lib.models.device import SubvolumeModification
from archinstall.lib.translationhandler import tr
from archinstall.tui.ui.result import ResultType
from ..menu.list_manager import ListManager
from ..utils.util import prompt_dir
class SubvolumeMenu(ListManager[SubvolumeModification]):

View File

@ -4,6 +4,7 @@ from archinstall.lib.args import arch_config_handler
from archinstall.lib.disk.device_handler import device_handler
from archinstall.lib.disk.partitioning_menu import manual_partitioning
from archinstall.lib.menu.helpers import Confirmation, Notify, Selection, Table
from archinstall.lib.menu.util import prompt_dir
from archinstall.lib.models.device import (
BDevice,
BtrfsMountOption,
@ -32,7 +33,6 @@ from archinstall.tui.ui.menu_item import MenuItem, MenuItemGroup
from archinstall.tui.ui.result import ResultType
from ..output import FormattedOutput
from ..utils.util import prompt_dir
def select_devices(preset: list[BDevice] | None = []) -> list[BDevice] | None:

View File

@ -1,6 +1,7 @@
from archinstall.lib.utils.util import running_from_host
from ..command import SysCommand
from ..exceptions import ServiceException, SysCallError
from ..general import running_from_host
from ..output import error

View File

@ -0,0 +1,99 @@
from pathlib import Path
from archinstall.lib.menu.helpers import Input
from archinstall.lib.translationhandler import tr
from archinstall.tui.ui.result import ResultType
from ..models.users import Password
def get_password(
header: str | None = None,
allow_skip: bool = False,
preset: str | None = None,
skip_confirmation: bool = False,
) -> Password | None:
while True:
result = Input(
header=header,
allow_skip=allow_skip,
default_value=preset,
password=True,
).show()
if result.type_ == ResultType.Skip:
if allow_skip:
return None
else:
continue
elif result.type_ == ResultType.Selection:
if not result.get_value():
if allow_skip:
return None
else:
continue
password = Password(plaintext=result.get_value())
break
if skip_confirmation:
return password
confirmation_header = f'{tr("Password")}: {password.hidden()}\n\n'
confirmation_header += tr('Confirm password')
def _validate(value: str) -> str | None:
if value != password._plaintext:
return tr('The password did not match, please try again')
return None
_ = Input(
header=confirmation_header,
allow_skip=False,
password=True,
validator_callback=_validate,
).show()
return password
def prompt_dir(
header: str | None = None,
validate: bool = True,
must_exist: bool = True,
allow_skip: bool = False,
preset: str | None = None,
) -> Path | None:
def validate_path(path: str | None) -> str | None:
if path:
dest_path = Path(path)
if must_exist:
if dest_path.exists() and dest_path.is_dir():
return None
else:
return None
return tr('Not a valid directory')
if validate:
validate_func = validate_path
else:
validate_func = None
result = Input(
header=header,
allow_skip=allow_skip,
validator_callback=validate_func,
default_value=preset,
).show()
match result.type_:
case ResultType.Skip:
return None
case ResultType.Selection:
if not result.get_value():
return None
return Path(result.get_value())
case _:
return None

View File

@ -1,9 +1,8 @@
from functools import lru_cache
from pathlib import Path
from archinstall.lib.packages.packages import check_package_upgrade
from .output import debug
from ..output import debug
@lru_cache(maxsize=128)
@ -20,14 +19,3 @@ def check_version_upgrade() -> str | None:
debug(f'Archinstall latest: {upgrade}')
return upgrade
def running_from_host() -> bool:
"""
Check if running from an installed system.
Returns True if running from installed system (host mode) for host-to-target install.
Returns False if /run/archiso exists (ISO mode).
"""
is_host = not Path('/run/archiso').exists()
return is_host

View File

@ -7,8 +7,8 @@ from archinstall.tui.ui.menu_item import MenuItem
from archinstall.tui.ui.result import ResultType
from ..menu.list_manager import ListManager
from ..menu.util import get_password
from ..models.users import User
from ..utils.util import get_password
class UserList(ListManager[User]):

View File

@ -2,111 +2,25 @@ import secrets
import string
from pathlib import Path
from archinstall.lib.menu.helpers import Input
from archinstall.lib.translationhandler import tr
from archinstall.tui.ui.result import ResultType
from ..models.users import Password
from ..output import FormattedOutput
def running_from_host() -> bool:
"""
Check if running from an installed system.
Returns True if running from installed system (host mode) for host-to-target install.
Returns False if /run/archiso exists (ISO mode).
"""
is_host = not Path('/run/archiso').exists()
return is_host
def generate_password(length: int = 64) -> str:
haystack = string.printable # digits, ascii_letters, punctuation (!"#$[] etc) and whitespace
return ''.join(secrets.choice(haystack) for _ in range(length))
def get_password(
header: str | None = None,
allow_skip: bool = False,
preset: str | None = None,
skip_confirmation: bool = False,
) -> Password | None:
while True:
result = Input(
header=header,
allow_skip=allow_skip,
default_value=preset,
password=True,
).show()
if result.type_ == ResultType.Skip:
if allow_skip:
return None
else:
continue
elif result.type_ == ResultType.Selection:
if not result.get_value():
if allow_skip:
return None
else:
continue
password = Password(plaintext=result.get_value())
break
if skip_confirmation:
return password
confirmation_header = f'{tr("Password")}: {password.hidden()}\n\n'
confirmation_header += tr('Confirm password')
def _validate(value: str) -> str | None:
if value != password._plaintext:
return tr('The password did not match, please try again')
return None
_ = Input(
header=confirmation_header,
allow_skip=False,
password=True,
validator_callback=_validate,
).show()
return password
def prompt_dir(
header: str | None = None,
validate: bool = True,
must_exist: bool = True,
allow_skip: bool = False,
preset: str | None = None,
) -> Path | None:
def validate_path(path: str | None) -> str | None:
if path:
dest_path = Path(path)
if must_exist:
if dest_path.exists() and dest_path.is_dir():
return None
else:
return None
return tr('Not a valid directory')
if validate:
validate_func = validate_path
else:
validate_func = None
result = Input(
header=header,
allow_skip=allow_skip,
validator_callback=validate_func,
default_value=preset,
).show()
match result.type_:
case ResultType.Skip:
return None
case ResultType.Selection:
if not result.get_value():
return None
return Path(result.get_value())
case _:
return None
def is_subpath(first: Path, second: Path) -> bool:
"""
Check if _first_ a subpath of _second_

View File

@ -10,9 +10,10 @@ from pathlib import Path
from archinstall.lib.args import arch_config_handler
from archinstall.lib.disk.utils import disk_layouts
from archinstall.lib.general import check_version_upgrade, running_from_host
from archinstall.lib.network.wifi_handler import WifiHandler
from archinstall.lib.networking import ping
from archinstall.lib.packages.util import check_version_upgrade
from archinstall.lib.utils.util import running_from_host
from .lib.hardware import SysInfo
from .lib.output import debug, error, info, warn

View File

@ -8,7 +8,6 @@ from archinstall.lib.authentication.authentication_handler import Authentication
from archinstall.lib.configuration import ConfigurationOutput
from archinstall.lib.disk.filesystem import FilesystemHandler
from archinstall.lib.disk.utils import disk_layouts
from archinstall.lib.general import check_version_upgrade
from archinstall.lib.global_menu import GlobalMenu
from archinstall.lib.hardware import SysInfo
from archinstall.lib.installer import Installer, accessibility_tools_in_use, run_custom_user_commands
@ -22,6 +21,7 @@ from archinstall.lib.models.device import (
from archinstall.lib.models.users import User
from archinstall.lib.network.network_handler import NetworkHandler
from archinstall.lib.output import debug, error, info
from archinstall.lib.packages.util import check_version_upgrade
from archinstall.lib.profile.profiles_handler import profile_handler
from archinstall.lib.translationhandler import tr