Send patches - preferably formatted by git format-patch - to patches at archlinux32 dot org.
summaryrefslogtreecommitdiff
path: root/archinstall/__init__.py
diff options
context:
space:
mode:
Diffstat (limited to 'archinstall/__init__.py')
-rw-r--r--archinstall/__init__.py143
1 files changed, 48 insertions, 95 deletions
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)