index : archinstall32 | |
Archlinux32 installer | gitolite user |
summaryrefslogtreecommitdiff |
author | Daniel Girtler <blackrabbit256@gmail.com> | 2023-04-19 20:55:42 +1000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-04-19 12:55:42 +0200 |
commit | 00b0ae7ba439a5a420095175b3bedd52c569db51 (patch) | |
tree | f02d081e361d5e65603f74dea3873dcc6606cf7c /archinstall/__init__.py | |
parent | 5253e57e9f26cf3e59cb2460544af13f56e485bb (diff) |
-rw-r--r-- | archinstall/__init__.py | 143 |
diff --git a/archinstall/__init__.py b/archinstall/__init__.py index 9de4a3ec..8cb6ced9 100644 --- a/archinstall/__init__.py +++ b/archinstall/__init__.py @@ -1,8 +1,12 @@ """Arch Linux installer - guided, templates etc.""" -import typing +import importlib from argparse import ArgumentParser, Namespace -from .lib.disk import * +from .lib import disk +from .lib import menu +from .lib import models as models +from .lib import packages + from .lib.exceptions import * from .lib.general import * from .lib.hardware import * @@ -10,41 +14,20 @@ from .lib.installer import __packages__, Installer, accessibility_tools_in_use from .lib.locale_helpers import * from .lib.luks import * from .lib.mirrors import * -from .lib.models.network_configuration import NetworkConfigurationHandler -from .lib.models.users import User from .lib.networking import * from .lib.output import * -from .lib.models.dataclasses import ( - VersionDef, - PackageSearchResult, - PackageSearch, - LocalPackage -) -from .lib.packages.packages import ( - group_search, - package_search, - find_package, - find_packages, - installed_package, - validate_package_list, -) -from .lib.profiles import * +from archinstall.lib.profile.profiles_handler import ProfileHandler, profile_handler +from .lib.profile.profile_menu import ProfileConfiguration from .lib.services import * from .lib.storage import * from .lib.systemd import * from .lib.user_interaction import * -from .lib.menu import Menu -from .lib.menu.list_manager import ListManager -from .lib.menu.text_input import TextInput -from .lib.menu.global_menu import GlobalMenu -from .lib.menu.abstract_menu import ( - Selector, - AbstractMenu -) +from .lib.global_menu import GlobalMenu from .lib.translationhandler import TranslationHandler, DeferredTranslation -from .lib.plugins import plugins, load_plugin # This initiates the plugin loading ceremony +from .lib.plugins import plugins, load_plugin # This initiates the plugin loading ceremony from .lib.configuration import * -from .lib.udev import udevadm_info + + parser = ArgumentParser() __version__ = "2.5.4" @@ -66,8 +49,6 @@ def define_arguments(): parser.add_argument("-v", "--version", action="version", version="%(prog)s " + __version__) parser.add_argument("--config", nargs="?", help="JSON configuration file or URL") parser.add_argument("--creds", nargs="?", help="JSON credentials configuration file") - parser.add_argument("--disk_layouts","--disk_layout","--disk-layouts","--disk-layout",nargs="?", - help="JSON disk layout 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", @@ -79,6 +60,7 @@ def define_arguments(): parser.add_argument("--no-pkg-lookups", action="store_true", default=False, help="Disabled package validation specifically prior to starting installation.") parser.add_argument("--plugin", nargs="?", type=str) + def parse_unspecified_argument_list(unknowns :list, multiple :bool = False, error :bool = False) -> dict: """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. @@ -129,7 +111,8 @@ def parse_unspecified_argument_list(unknowns :list, multiple :bool = False, erro print(f" We ignore the entry {element} as it isn't related to any argument") return config -def cleanup_empty_args(args :typing.Union[Namespace, dict]) -> dict: + +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) @@ -161,7 +144,7 @@ def get_arguments() -> Dict[str, Any]: 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 = {} + 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 ? @@ -174,15 +157,15 @@ def get_arguments() -> Dict[str, Any]: exit(1) # load the parameters. first the known, then the unknowns - args = cleanup_empty_args(args) - config.update(args) + 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 args.get('config') is None: + if clean_args.get('config') is None: config["silent"] = False else: - config["silent"] = args.get('silent') + config["silent"] = clean_args.get('silent') # avoiding a compatibility issue if 'dry-run' in config: @@ -190,29 +173,24 @@ def get_arguments() -> Dict[str, Any]: return config + def load_config(): """ refine and set some arguments. Formerly at the scripts """ from .lib.models import NetworkConfiguration + arguments.setdefault('sys-language', 'en_US') + arguments.setdefault('sys-encoding', 'utf-8') + if (archinstall_lang := arguments.get('archinstall-language', None)) is not None: arguments['archinstall-language'] = TranslationHandler().get_language_by_name(archinstall_lang) - if arguments.get('harddrives', None) is not None: - if type(arguments['harddrives']) is str: - arguments['harddrives'] = arguments['harddrives'].split(',') - arguments['harddrives'] = [BlockDevice(BlockDev) for BlockDev in arguments['harddrives']] - # Temporarily disabling keep_partitions if config file is loaded - # Temporary workaround to make Desktop Environments work - - if arguments.get('profile', None) is not None: - if type(arguments.get('profile', None)) is dict: - arguments['profile'] = Profile(None, arguments.get('profile', None)['path']) - else: - arguments['profile'] = Profile(None, arguments.get('profile', None)) + if disk_config := arguments.get('disk_config', {}): + arguments['disk_config'] = disk.DiskLayoutConfiguration.parse_arg(disk_config) - storage['_desktop_profile'] = arguments.get('desktop-environment', None) + if profile_config := arguments.get('profile_config', None): + arguments['profile_config'] = ProfileConfiguration.parse_arg(profile_config) if arguments.get('mirror-region', None) is not None: if type(arguments.get('mirror-region', None)) is dict: @@ -221,12 +199,6 @@ def load_config(): selected_region = arguments.get('mirror-region', None) arguments['mirror-region'] = {selected_region: list_mirrors()[selected_region]} - arguments.setdefault('sys-language', 'en_US') - arguments.setdefault('sys-encoding', 'utf-8') - - if arguments.get('gfx_driver', None) is not None: - storage['gfx_driver_packages'] = AVAILABLE_GFX_DRIVERS.get(arguments.get('gfx_driver', None), None) - if arguments.get('servers', None) is not None: storage['_selected_servers'] = arguments.get('servers', None) @@ -240,10 +212,13 @@ def load_config(): superusers = arguments.get('!superusers', None) arguments['!users'] = User.parse_arguments(users, superusers) - if arguments.get('disk_encryption', None) is not None and arguments.get('disk_layouts', None) is not None: + if arguments.get('bootloader', None) is not None: + arguments['bootloader'] = 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'] = DiskEncryption.parse_arg( - arguments['disk_layouts'], + arguments['disk_encryption'] = disk.DiskEncryption.parse_arg( + arguments['disk_config'], arguments['disk_encryption'], password ) @@ -251,8 +226,8 @@ def load_config(): def post_process_arguments(arguments): storage['arguments'] = arguments - if arguments.get('mount_point'): - storage['MOUNT_POINT'] = arguments['mount_point'] + if mountpoint := arguments.get('mount_point', None): + storage['MOUNT_POINT'] = Path(mountpoint) if arguments.get('debug', False): log(f"Warning: --debug mode will write certain credentials to {storage['LOG_PATH']}/{storage['LOG_FILE']}!", fg="red", level=logging.WARNING) @@ -260,53 +235,31 @@ def post_process_arguments(arguments): if arguments.get('plugin', None): load_plugin(arguments['plugin']) - if arguments.get('disk_layouts', None) is not None: - layout_storage = {} - if not json_stream_to_structure('--disk_layouts',arguments['disk_layouts'],layout_storage): - exit(1) - else: - if arguments.get('harddrives') is None: - arguments['harddrives'] = [disk for disk in layout_storage] - # backward compatibility. Change partition.format for partition.wipe - for disk in layout_storage: - for i, partition in enumerate(layout_storage[disk].get('partitions',[])): - if 'format' in partition: - partition['wipe'] = partition['format'] - del partition['format'] - elif 'btrfs' in partition: - partition['btrfs']['subvolumes'] = Subvolume.parse_arguments(partition['btrfs']['subvolumes']) - arguments['disk_layouts'] = layout_storage - load_config() define_arguments() -arguments = get_arguments() +arguments: Dict[str, Any] = get_arguments() post_process_arguments(arguments) + # @archinstall.plugin decorator hook to programmatically add -# plugins in runtime. Useful in profiles and other things. +# plugins in runtime. Useful in profiles_bck and other things. def plugin(f, *args, **kwargs): plugins[f.__name__] = f def run_as_a_module(): """ - Since we're running this as a 'python -m archinstall' module OR - a nuitka3 compiled version of the project. - This function and the file __main__ acts as a entry point. + 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) - # Add another path for finding profiles, so that list_profiles() in Script() can find guided.py, unattended.py etc. - storage['PROFILE_PATH'].append(os.path.abspath(f'{os.path.dirname(__file__)}/examples')) - try: - script = Script(arguments.get('script', None)) - except ProfileNotFound as err: - print(f"Couldn't find file: {err}") - sys.exit(1) - - os.chdir(os.path.abspath(os.path.dirname(__file__))) + if script is None: + print('No script to run provided') - # Remove the example directory from the PROFILE_PATH, to avoid guided.py etc shows up in user input questions. - storage['PROFILE_PATH'].pop() - script.execute() + mod_name = f'archinstall.scripts.{script}' + # by loading the module we'll automatically run the script + importlib.import_module(mod_name) |