Dataclasses for args and config (#2936)
* Introduce dataclass for arguments and configuration * Update * Update
This commit is contained in:
parent
f2bc5ff280
commit
e51f7adf21
|
|
@ -32,7 +32,7 @@ from .lib.output import FormattedOutput, debug, error, info, log, warn
|
|||
from .lib.pacman import Pacman
|
||||
from .lib.plugins import load_plugin, plugins
|
||||
from .lib.storage import storage
|
||||
from .lib.translationhandler import DeferredTranslation, Language, TranslationHandler
|
||||
from .lib.translationhandler import DeferredTranslation, Language, translation_handler
|
||||
from .tui import Tui
|
||||
|
||||
if TYPE_CHECKING:
|
||||
|
|
@ -224,7 +224,7 @@ def load_config() -> None:
|
|||
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)
|
||||
arguments['archinstall-language'] = translation_handler.get_language_by_name(archinstall_lang)
|
||||
|
||||
if disk_config := arguments.get('disk_config', {}):
|
||||
arguments['disk_config'] = disk.DiskLayoutConfiguration.parse_arg(disk_config)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,341 @@
|
|||
import argparse
|
||||
import json
|
||||
import urllib.error
|
||||
import urllib.parse
|
||||
from argparse import ArgumentParser, Namespace
|
||||
from dataclasses import dataclass, field
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
from urllib.request import Request, urlopen
|
||||
|
||||
from pydantic.dataclasses import dataclass as p_dataclass
|
||||
|
||||
from .disk import DiskEncryption, DiskLayoutConfiguration
|
||||
from .locale import LocaleConfiguration
|
||||
from .mirrors import MirrorConfiguration
|
||||
from .models import AudioConfiguration, Bootloader, NetworkConfiguration, User
|
||||
from .output import error, warn
|
||||
from .plugins import load_plugin
|
||||
from .profile import ProfileConfiguration
|
||||
from .storage import storage
|
||||
from .translationhandler import Language, translation_handler
|
||||
|
||||
|
||||
@p_dataclass
|
||||
class Arguments:
|
||||
config: Path | None = None
|
||||
config_url: str | None = None
|
||||
creds: Path | None = None
|
||||
creds_url: str | None = None
|
||||
silent: bool = False
|
||||
dry_run: bool = False
|
||||
script: str = 'guided'
|
||||
mount_point: Path | None = Path('/mnt')
|
||||
skip_ntp: bool = False
|
||||
debug: bool = False
|
||||
offline: bool = False
|
||||
no_pkg_lookups: bool = False
|
||||
plugin: str | None = None
|
||||
skip_version_check: bool = False
|
||||
advanced: bool = False
|
||||
|
||||
|
||||
@dataclass
|
||||
class ArchConfig:
|
||||
version: str = field(default_factory=lambda: storage['__version__'])
|
||||
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: Bootloader = field(default=Bootloader.get_default())
|
||||
uki: bool = False
|
||||
audio_config: AudioConfiguration | None = None
|
||||
hostname: str = 'archlinux'
|
||||
kernels: list[str] = field(default_factory=lambda: ['linux'])
|
||||
ntp: bool = False
|
||||
packages: list[str] = field(default_factory=list)
|
||||
parallel_downloads: int = 0
|
||||
swap: bool = True
|
||||
timezone: str = 'UTC'
|
||||
additional_repositories: list[str] = field(default_factory=list)
|
||||
|
||||
# Special fields that should be handle with care due to security implications
|
||||
_users: list[User] = field(default_factory=list)
|
||||
_disk_encryption: DiskEncryption | None = None
|
||||
|
||||
@classmethod
|
||||
def from_config(cls, args_config: dict[str, Any]) -> 'ArchConfig':
|
||||
arch_config = ArchConfig()
|
||||
|
||||
arch_config.locale_config = LocaleConfiguration.parse_arg(args_config)
|
||||
|
||||
if archinstall_lang := args_config.get('archinstall-language', None):
|
||||
arch_config.archinstall_language = translation_handler.get_language_by_name(archinstall_lang)
|
||||
|
||||
if disk_config := args_config.get('disk_config', {}):
|
||||
arch_config.disk_config = DiskLayoutConfiguration.parse_arg(disk_config)
|
||||
|
||||
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):
|
||||
arch_config.mirror_config = MirrorConfiguration.parse_args(mirror_config)
|
||||
|
||||
if net_config := args_config.get('network_config', None):
|
||||
arch_config.network_config = NetworkConfiguration.parse_arg(net_config)
|
||||
|
||||
users = args_config.get('!users', None)
|
||||
superusers = args_config.get('!superusers', None)
|
||||
if users is not None or superusers is not None:
|
||||
arch_config._users = User.parse_arguments(users, superusers)
|
||||
|
||||
if bootloader_config := args_config.get('bootloader', None):
|
||||
arch_config.bootloader = Bootloader.from_arg(bootloader_config)
|
||||
|
||||
if args_config.get('uki', False) and not arch_config.bootloader.has_uki_support():
|
||||
arch_config.uki = False
|
||||
|
||||
if audio_config := args_config.get('audio_config', None):
|
||||
arch_config.audio_config = AudioConfiguration.parse_arg(audio_config)
|
||||
|
||||
if args_config.get('disk_encryption', None) is not None and arch_config.disk_config is not None:
|
||||
arch_config._disk_encryption = DiskEncryption.parse_arg(
|
||||
arch_config.disk_config,
|
||||
args_config['disk_encryption'],
|
||||
args_config.get('encryption_password', '')
|
||||
)
|
||||
|
||||
if hostname := args_config.get('hostname', ''):
|
||||
arch_config.hostname = hostname
|
||||
|
||||
if kernels := args_config.get('kernels', []):
|
||||
arch_config.kernels = kernels
|
||||
|
||||
if ntp := args_config.get('ntp', False):
|
||||
arch_config.ntp = ntp
|
||||
|
||||
if packages := args_config.get('packages', []):
|
||||
arch_config.packages = packages
|
||||
|
||||
if parallel_downloads := args_config.get('parallel_downloads', 0):
|
||||
arch_config.parallel_downloads = parallel_downloads
|
||||
|
||||
arch_config.swap = args_config.get('swap', True)
|
||||
|
||||
if timezone := args_config.get('timezone', 'UTC'):
|
||||
arch_config.timezone = timezone
|
||||
|
||||
if additional_repositories := args_config.get('additional-repositories', []):
|
||||
arch_config.additional_repositories = additional_repositories
|
||||
|
||||
return arch_config
|
||||
|
||||
|
||||
class ArchConfigHandler:
|
||||
def __init__(self) -> None:
|
||||
self._parser: ArgumentParser = self._define_arguments()
|
||||
self._args: Arguments = self._parse_args()
|
||||
|
||||
config = self._parse_config()
|
||||
self._arch_config = ArchConfig.from_config(config)
|
||||
|
||||
@property
|
||||
def arch_config(self) -> ArchConfig:
|
||||
return self._arch_config
|
||||
|
||||
@property
|
||||
def args(self) -> Arguments:
|
||||
return self._args
|
||||
|
||||
def print_help(self) -> None:
|
||||
self._parser.print_help()
|
||||
|
||||
def _define_arguments(self) -> ArgumentParser:
|
||||
parser = ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter)
|
||||
parser.add_argument(
|
||||
"-v",
|
||||
"--version",
|
||||
action="version",
|
||||
default=False,
|
||||
version="%(prog)s " + storage['__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(
|
||||
"--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",
|
||||
default="guided",
|
||||
nargs="?",
|
||||
help="Script to run for installation",
|
||||
type=str
|
||||
)
|
||||
parser.add_argument(
|
||||
"--mount-point",
|
||||
"--mount_point",
|
||||
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(
|
||||
"--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,
|
||||
default=None,
|
||||
help='File path to a plugin to load'
|
||||
)
|
||||
parser.add_argument(
|
||||
"--skip-version-check",
|
||||
action="store_true",
|
||||
default=False,
|
||||
help="Skip the version check when running archinstall"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--advanced",
|
||||
action="store_true",
|
||||
default=False,
|
||||
help="Enabled advanced 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:
|
||||
args.silent = False
|
||||
|
||||
if args.mount_point is not None:
|
||||
storage['MOUNT_POINT'] = Path(args.mount_point)
|
||||
|
||||
if args.debug:
|
||||
warn(f"Warning: --debug mode will write certain credentials to {storage['LOG_PATH']}/{storage['LOG_FILE']}!")
|
||||
|
||||
if args.plugin:
|
||||
plugin_path = Path(args.plugin)
|
||||
load_plugin(plugin_path)
|
||||
|
||||
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:
|
||||
config.update(json.loads(creds_data))
|
||||
|
||||
config = self._cleanup_config(config)
|
||||
|
||||
return config
|
||||
|
||||
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()
|
||||
except urllib.error.HTTPError as err:
|
||||
error(f"Could not fetch JSON from {url}: {err}")
|
||||
else:
|
||||
error('Not a valid url')
|
||||
|
||||
exit(1)
|
||||
|
||||
def _read_file(self, path: Path) -> str:
|
||||
if not path.exists():
|
||||
error(f"Could not find file {path}")
|
||||
exit(1)
|
||||
|
||||
return path.read_text()
|
||||
|
||||
def _cleanup_config(self, config: Namespace | dict) -> 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
|
||||
|
|
@ -32,7 +32,7 @@ from .models.bootloader import Bootloader
|
|||
from .models.users import User
|
||||
from .output import FormattedOutput
|
||||
from .profile.profile_menu import ProfileConfiguration
|
||||
from .translationhandler import Language, TranslationHandler
|
||||
from .translationhandler import Language, translation_handler
|
||||
from .utils.util import format_cols, get_password
|
||||
|
||||
if TYPE_CHECKING:
|
||||
|
|
@ -46,10 +46,9 @@ if TYPE_CHECKING:
|
|||
class GlobalMenu(AbstractMenu):
|
||||
def __init__(self, data_store: dict[str, Any]):
|
||||
self._data_store = data_store
|
||||
self._translation_handler = TranslationHandler()
|
||||
|
||||
if 'archinstall-language' not in data_store:
|
||||
data_store['archinstall-language'] = self._translation_handler.get_language_by_abbr('en')
|
||||
data_store['archinstall-language'] = translation_handler.get_language_by_abbr('en')
|
||||
|
||||
menu_optioons = self._get_menu_options(data_store)
|
||||
self._item_group = MenuItemGroup(
|
||||
|
|
@ -263,8 +262,8 @@ class GlobalMenu(AbstractMenu):
|
|||
|
||||
def _select_archinstall_language(self, preset: Language) -> Language:
|
||||
from .interactions.general_conf import select_archinstall_language
|
||||
language = select_archinstall_language(self._translation_handler.translated_languages, preset)
|
||||
self._translation_handler.activate(language)
|
||||
language = select_archinstall_language(translation_handler.translated_languages, preset)
|
||||
translation_handler.activate(language)
|
||||
|
||||
self._upate_lang_text()
|
||||
|
||||
|
|
|
|||
|
|
@ -206,3 +206,6 @@ class DeferredTranslation:
|
|||
def install(cls) -> None:
|
||||
import builtins
|
||||
builtins._ = cls # type: ignore
|
||||
|
||||
|
||||
translation_handler = TranslationHandler()
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ dev = [
|
|||
"ruff==0.8.0",
|
||||
"pylint==3.3.1",
|
||||
"pylint-pydantic==0.3.2",
|
||||
"pytest==6.2.5",
|
||||
]
|
||||
doc = ["sphinx"]
|
||||
|
||||
|
|
@ -114,6 +115,10 @@ warn_unreachable = false
|
|||
module = "archinstall.tui.*"
|
||||
warn_unreachable = false
|
||||
|
||||
[[tool.mypy.overrides]]
|
||||
module = "tests.*"
|
||||
ignore_errors = true
|
||||
|
||||
[[tool.mypy.overrides]]
|
||||
module = [
|
||||
"parted",
|
||||
|
|
@ -124,6 +129,11 @@ ignore_missing_imports = true
|
|||
targets = ["archinstall"]
|
||||
exclude = ["/tests"]
|
||||
|
||||
[tool.pytest.ini_options]
|
||||
pythonpath = ["."]
|
||||
addopts = "-s"
|
||||
testpaths = ["tests"]
|
||||
|
||||
[tool.pylint.main]
|
||||
ignore-paths = [
|
||||
"^build/",
|
||||
|
|
|
|||
|
|
@ -0,0 +1,13 @@
|
|||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
@pytest.fixture(scope='session')
|
||||
def config_fixture() -> Path:
|
||||
return Path(__file__).parent / 'data' / 'test_config.json'
|
||||
|
||||
|
||||
@pytest.fixture(scope='session')
|
||||
def creds_fixture() -> Path:
|
||||
return Path(__file__).parent / 'data' / 'test_creds.json'
|
||||
|
|
@ -0,0 +1,135 @@
|
|||
{
|
||||
"additional-repositories": ["testing"],
|
||||
"archinstall-language": "English",
|
||||
"audio_config": {"audio": "pipewire"},
|
||||
"bootloader": "Systemd-boot",
|
||||
"disk_config": {
|
||||
"config_type": "default_layout",
|
||||
"device_modifications": [
|
||||
{
|
||||
"device": "/dev/sda",
|
||||
"partitions": [
|
||||
{
|
||||
"btrfs": [],
|
||||
"flags": [
|
||||
"boot"
|
||||
],
|
||||
"fs_type": "fat32",
|
||||
"size": {
|
||||
"sector_size": null,
|
||||
"unit": "MiB",
|
||||
"value": 512
|
||||
},
|
||||
"mount_options": [],
|
||||
"mountpoint": "/boot",
|
||||
"obj_id": "2c3fa2d5-2c79-4fab-86ec-22d0ea1543c0",
|
||||
"start": {
|
||||
"sector_size": null,
|
||||
"unit": "MiB",
|
||||
"value": 1
|
||||
},
|
||||
"status": "create",
|
||||
"type": "primary"
|
||||
},
|
||||
{
|
||||
"btrfs": [],
|
||||
"flags": [],
|
||||
"fs_type": "ext4",
|
||||
"size": {
|
||||
"sector_size": null,
|
||||
"unit": "GiB",
|
||||
"value": 20
|
||||
},
|
||||
"mount_options": [],
|
||||
"mountpoint": "/",
|
||||
"obj_id": "3e7018a0-363b-4d05-ab83-8e82d13db208",
|
||||
"start": {
|
||||
"sector_size": null,
|
||||
"unit": "MiB",
|
||||
"value": 513
|
||||
},
|
||||
"status": "create",
|
||||
"type": "primary"
|
||||
},
|
||||
{
|
||||
"btrfs": [],
|
||||
"flags": [],
|
||||
"fs_type": "ext4",
|
||||
"size": {
|
||||
"sector_size": null,
|
||||
"unit": "Percent",
|
||||
"value": 100
|
||||
},
|
||||
"mount_options": [],
|
||||
"mountpoint": "/home",
|
||||
"obj_id": "ce58b139-f041-4a06-94da-1f8bad775d3f",
|
||||
"start": {
|
||||
"sector_size": null,
|
||||
"unit": "GiB",
|
||||
"value": 20
|
||||
},
|
||||
"status": "create",
|
||||
"type": "primary"
|
||||
}
|
||||
],
|
||||
"wipe": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"hostname": "archy",
|
||||
"kernels": [
|
||||
"linux-zen"
|
||||
],
|
||||
"locale_config": {
|
||||
"kb_layout": "us",
|
||||
"sys_enc": "UTF-8",
|
||||
"sys_lang": "en_US"
|
||||
},
|
||||
"mirror_config": {
|
||||
"mirror-regions": {
|
||||
"Australia": [
|
||||
"http://archlinux.mirror.digitalpacific.com.au/$repo/os/$arch"
|
||||
]
|
||||
}
|
||||
},
|
||||
"network_config": {
|
||||
"type": "manual",
|
||||
"nics": [
|
||||
{
|
||||
"iface": "eno1",
|
||||
"ip": "192.168.1.15/24",
|
||||
"dhcp": true,
|
||||
"gateway": "192.168.1.1",
|
||||
"dns": [
|
||||
"192.168.1.1",
|
||||
"9.9.9.9"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"ntp": true,
|
||||
"packages": ["firefox"],
|
||||
"parallel_downloads": 66,
|
||||
"profile_config": {
|
||||
"gfx_driver": "All open-source",
|
||||
"greeter": "lightdm-gtk-greeter",
|
||||
"profile": {
|
||||
"custom_settings": {
|
||||
"Hyprland": {
|
||||
"seat_access": "polkit"
|
||||
},
|
||||
"Sway": {
|
||||
"seat_access": "seatd"
|
||||
}
|
||||
},
|
||||
"details": [
|
||||
"Sway",
|
||||
"Hyprland"
|
||||
],
|
||||
"main": "Desktop"
|
||||
}
|
||||
},
|
||||
"swap": false,
|
||||
"timezone": "UTC",
|
||||
"version": "2.8.6"
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"!root-password": "super_pwd",
|
||||
"!users": [
|
||||
{
|
||||
"!password": "user_pwd",
|
||||
"sudo": true,
|
||||
"username": "user_name"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,171 @@
|
|||
from pathlib import Path
|
||||
|
||||
from pytest import MonkeyPatch
|
||||
|
||||
from archinstall.default_profiles.profile import GreeterType
|
||||
from archinstall.lib.args import ArchConfig, ArchConfigHandler, Arguments
|
||||
from archinstall.lib.disk import DiskLayoutConfiguration, DiskLayoutType
|
||||
from archinstall.lib.hardware import GfxDriver
|
||||
from archinstall.lib.locale import LocaleConfiguration
|
||||
from archinstall.lib.mirrors import MirrorConfiguration
|
||||
from archinstall.lib.models import Audio, AudioConfiguration, Bootloader, NetworkConfiguration, User
|
||||
from archinstall.lib.models.network_configuration import Nic, NicType
|
||||
from archinstall.lib.profile.profile_model import ProfileConfiguration
|
||||
from archinstall.lib.profile.profiles_handler import profile_handler
|
||||
from archinstall.lib.translationhandler import translation_handler
|
||||
|
||||
|
||||
def test_default_args(monkeypatch):
|
||||
monkeypatch.setattr('sys.argv', ['archinstall'])
|
||||
handler = ArchConfigHandler()
|
||||
args = handler.args
|
||||
assert args == Arguments(
|
||||
config=None,
|
||||
config_url=None,
|
||||
creds=None,
|
||||
silent=False,
|
||||
dry_run=False,
|
||||
script='guided',
|
||||
mount_point=Path('/mnt'),
|
||||
skip_ntp=False,
|
||||
debug=False,
|
||||
offline=False,
|
||||
no_pkg_lookups=False,
|
||||
plugin=None,
|
||||
skip_version_check=False,
|
||||
advanced=False
|
||||
)
|
||||
|
||||
|
||||
def test_correct_parsing_args(
|
||||
monkeypatch: MonkeyPatch,
|
||||
config_fixture: Path,
|
||||
creds_fixture: Path
|
||||
) -> None:
|
||||
monkeypatch.setattr('sys.argv', [
|
||||
'archinstall',
|
||||
'--config',
|
||||
str(config_fixture),
|
||||
'--config-url',
|
||||
'https://example.com',
|
||||
'--creds',
|
||||
str(creds_fixture),
|
||||
'--script',
|
||||
'execution_script',
|
||||
'--mount-point',
|
||||
'/tmp',
|
||||
'--skip-ntp',
|
||||
'--debug',
|
||||
'--offline',
|
||||
'--no-pkg-lookups',
|
||||
'--plugin',
|
||||
'pytest_plugin.py',
|
||||
'--skip-version-check',
|
||||
'--advanced',
|
||||
'--dry-run',
|
||||
'--silent'
|
||||
])
|
||||
|
||||
handler = ArchConfigHandler()
|
||||
args = handler.args
|
||||
|
||||
assert args == Arguments(
|
||||
config=config_fixture,
|
||||
config_url='https://example.com',
|
||||
creds=creds_fixture,
|
||||
silent=True,
|
||||
dry_run=True,
|
||||
script='execution_script',
|
||||
mount_point=Path('/tmp'),
|
||||
skip_ntp=True,
|
||||
debug=True,
|
||||
offline=True,
|
||||
no_pkg_lookups=True,
|
||||
plugin='pytest_plugin.py',
|
||||
skip_version_check=True,
|
||||
advanced=True
|
||||
)
|
||||
|
||||
|
||||
def test_config_file_parsing(
|
||||
monkeypatch: MonkeyPatch,
|
||||
config_fixture: Path,
|
||||
creds_fixture: Path
|
||||
) -> None:
|
||||
monkeypatch.setattr('sys.argv', [
|
||||
'archinstall',
|
||||
'--config',
|
||||
str(config_fixture),
|
||||
'--creds',
|
||||
str(creds_fixture),
|
||||
])
|
||||
|
||||
handler = ArchConfigHandler()
|
||||
arch_config = handler.arch_config
|
||||
|
||||
assert arch_config == ArchConfig(
|
||||
version='3.0.0',
|
||||
locale_config=LocaleConfiguration(
|
||||
kb_layout='us',
|
||||
sys_lang='en_US',
|
||||
sys_enc='UTF-8'
|
||||
),
|
||||
archinstall_language=translation_handler.get_language_by_abbr('en'),
|
||||
disk_config=DiskLayoutConfiguration(
|
||||
config_type=DiskLayoutType.Default,
|
||||
device_modifications=[],
|
||||
lvm_config=None,
|
||||
mountpoint=None
|
||||
),
|
||||
profile_config=ProfileConfiguration(
|
||||
profile=profile_handler.parse_profile_config({
|
||||
"custom_settings": {
|
||||
"Hyprland": {
|
||||
"seat_access": "polkit"
|
||||
},
|
||||
"Sway": {
|
||||
"seat_access": "seatd"
|
||||
}
|
||||
},
|
||||
"details": [
|
||||
"Sway",
|
||||
"Hyprland"
|
||||
],
|
||||
"main": "Desktop"
|
||||
}),
|
||||
gfx_driver=GfxDriver.AllOpenSource,
|
||||
greeter=GreeterType.Lightdm
|
||||
),
|
||||
mirror_config=MirrorConfiguration(
|
||||
mirror_regions={},
|
||||
custom_mirrors=[]
|
||||
),
|
||||
network_config=NetworkConfiguration(
|
||||
type=NicType.MANUAL,
|
||||
nics=[
|
||||
Nic(
|
||||
iface='eno1',
|
||||
ip='192.168.1.15/24',
|
||||
dhcp=True,
|
||||
gateway='192.168.1.1',
|
||||
dns=[
|
||||
'192.168.1.1',
|
||||
'9.9.9.9'
|
||||
]
|
||||
)
|
||||
]
|
||||
),
|
||||
bootloader=Bootloader.Systemd,
|
||||
uki=False,
|
||||
audio_config=AudioConfiguration(Audio.Pipewire),
|
||||
hostname='archy',
|
||||
kernels=['linux-zen'],
|
||||
ntp=True,
|
||||
packages=["firefox"],
|
||||
parallel_downloads=66,
|
||||
swap=False,
|
||||
timezone='UTC',
|
||||
additional_repositories=["testing"],
|
||||
_users=[User(username='user_name', password='user_pwd', sudo=True)],
|
||||
_disk_encryption=None
|
||||
)
|
||||
Loading…
Reference in New Issue