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 pydantic.dataclasses import dataclass as p_dataclass
from archinstall.lib.crypt import decrypt 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.application import ApplicationConfiguration, ZramConfiguration
from archinstall.lib.models.authentication import AuthenticationConfiguration from archinstall.lib.models.authentication import AuthenticationConfiguration
from archinstall.lib.models.bootloader import Bootloader, BootloaderConfiguration 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.output import debug, error, logger, warn
from archinstall.lib.plugins import load_plugin from archinstall.lib.plugins import load_plugin
from archinstall.lib.translationhandler import Language, tr, translation_handler from archinstall.lib.translationhandler import Language, tr, translation_handler
from archinstall.lib.utils.util import get_password
@p_dataclass @p_dataclass

View File

@ -3,12 +3,12 @@ from typing import override
from archinstall.lib.disk.fido import Fido2 from archinstall.lib.disk.fido import Fido2
from archinstall.lib.menu.abstract_menu import AbstractSubMenu from archinstall.lib.menu.abstract_menu import AbstractSubMenu
from archinstall.lib.menu.helpers import Confirmation, Selection 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.authentication import AuthenticationConfiguration, U2FLoginConfiguration, U2FLoginMethod
from archinstall.lib.models.users import Password, User from archinstall.lib.models.users import Password, User
from archinstall.lib.output import FormattedOutput from archinstall.lib.output import FormattedOutput
from archinstall.lib.translationhandler import tr from archinstall.lib.translationhandler import tr
from archinstall.lib.user.user_menu import select_users 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.menu_item import MenuItem, MenuItemGroup
from archinstall.tui.ui.result import ResultType 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 .args import ArchConfig
from .crypt import encrypt from .crypt import encrypt
from .menu.util import get_password, prompt_dir
from .output import debug, logger, warn from .output import debug, logger, warn
from .utils.util import get_password, prompt_dir
class ConfigurationOutput: 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 archinstall.tui.ui.result import ResultType
from ..menu.abstract_menu import AbstractSubMenu from ..menu.abstract_menu import AbstractSubMenu
from ..menu.util import get_password
from ..models.device import DEFAULT_ITER_TIME, Fido2Device from ..models.device import DEFAULT_ITER_TIME, Fido2Device
from ..models.users import Password from ..models.users import Password
from ..output import FormattedOutput from ..output import FormattedOutput
from ..utils.util import get_password
from .fido import Fido2 from .fido import Fido2

View File

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

View File

@ -2,12 +2,12 @@ from pathlib import Path
from typing import assert_never, override from typing import assert_never, override
from archinstall.lib.menu.helpers import Input 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.models.device import SubvolumeModification
from archinstall.lib.translationhandler import tr from archinstall.lib.translationhandler import tr
from archinstall.tui.ui.result import ResultType from archinstall.tui.ui.result import ResultType
from ..menu.list_manager import ListManager from ..menu.list_manager import ListManager
from ..utils.util import prompt_dir
class SubvolumeMenu(ListManager[SubvolumeModification]): 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.device_handler import device_handler
from archinstall.lib.disk.partitioning_menu import manual_partitioning from archinstall.lib.disk.partitioning_menu import manual_partitioning
from archinstall.lib.menu.helpers import Confirmation, Notify, Selection, Table from archinstall.lib.menu.helpers import Confirmation, Notify, Selection, Table
from archinstall.lib.menu.util import prompt_dir
from archinstall.lib.models.device import ( from archinstall.lib.models.device import (
BDevice, BDevice,
BtrfsMountOption, BtrfsMountOption,
@ -32,7 +33,6 @@ from archinstall.tui.ui.menu_item import MenuItem, MenuItemGroup
from archinstall.tui.ui.result import ResultType from archinstall.tui.ui.result import ResultType
from ..output import FormattedOutput from ..output import FormattedOutput
from ..utils.util import prompt_dir
def select_devices(preset: list[BDevice] | None = []) -> list[BDevice] | None: 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 ..command import SysCommand
from ..exceptions import ServiceException, SysCallError from ..exceptions import ServiceException, SysCallError
from ..general import running_from_host
from ..output import error 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 functools import lru_cache
from pathlib import Path
from archinstall.lib.packages.packages import check_package_upgrade from archinstall.lib.packages.packages import check_package_upgrade
from .output import debug from ..output import debug
@lru_cache(maxsize=128) @lru_cache(maxsize=128)
@ -20,14 +19,3 @@ def check_version_upgrade() -> str | None:
debug(f'Archinstall latest: {upgrade}') debug(f'Archinstall latest: {upgrade}')
return 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 archinstall.tui.ui.result import ResultType
from ..menu.list_manager import ListManager from ..menu.list_manager import ListManager
from ..menu.util import get_password
from ..models.users import User from ..models.users import User
from ..utils.util import get_password
class UserList(ListManager[User]): class UserList(ListManager[User]):

View File

@ -2,111 +2,25 @@ import secrets
import string import string
from pathlib import Path 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 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: def generate_password(length: int = 64) -> str:
haystack = string.printable # digits, ascii_letters, punctuation (!"#$[] etc) and whitespace haystack = string.printable # digits, ascii_letters, punctuation (!"#$[] etc) and whitespace
return ''.join(secrets.choice(haystack) for _ in range(length)) 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: def is_subpath(first: Path, second: Path) -> bool:
""" """
Check if _first_ a subpath of _second_ 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.args import arch_config_handler
from archinstall.lib.disk.utils import disk_layouts 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.network.wifi_handler import WifiHandler
from archinstall.lib.networking import ping 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.hardware import SysInfo
from .lib.output import debug, error, info, warn 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.configuration import ConfigurationOutput
from archinstall.lib.disk.filesystem import FilesystemHandler from archinstall.lib.disk.filesystem import FilesystemHandler
from archinstall.lib.disk.utils import disk_layouts 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.global_menu import GlobalMenu
from archinstall.lib.hardware import SysInfo from archinstall.lib.hardware import SysInfo
from archinstall.lib.installer import Installer, accessibility_tools_in_use, run_custom_user_commands 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.models.users import User
from archinstall.lib.network.network_handler import NetworkHandler from archinstall.lib.network.network_handler import NetworkHandler
from archinstall.lib.output import debug, error, info 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.profile.profiles_handler import profile_handler
from archinstall.lib.translationhandler import tr from archinstall.lib.translationhandler import tr