From c599f7ba956cb1ef17566b20e5a053fd6a9b2820 Mon Sep 17 00:00:00 2001 From: Daniel Girtler Date: Sat, 14 Oct 2023 17:27:12 +1100 Subject: [PATCH] Add user information for error --- archinstall/__init__.py | 58 ++++++++++++++++++++++------------ archinstall/lib/global_menu.py | 1 + 2 files changed, 39 insertions(+), 20 deletions(-) diff --git a/archinstall/__init__.py b/archinstall/__init__.py index 11b47c4821..c6b7e909c7 100644 --- a/archinstall/__init__.py +++ b/archinstall/__init__.py @@ -1,6 +1,7 @@ """Arch Linux installer - guided, templates etc.""" import importlib import os +import traceback from argparse import ArgumentParser, Namespace from pathlib import Path from typing import TYPE_CHECKING, Any, Dict, Union @@ -34,15 +35,12 @@ run_custom_user_commands, json_stream_to_structure, secret ) - if TYPE_CHECKING: _: Any - __version__ = "2.6.3" storage['__version__'] = __version__ - # add the custom _ as a builtin, it can now be used anywhere in the # project to mark strings as translatable with _('translate me') DeferredTranslation.install() @@ -57,12 +55,10 @@ # For support reasons, we'll log the disk layout pre installation to match against post-installation layout debug(f"Disk states before installing: {disk.disk_layouts()}") - if os.getuid() != 0: print(_("Archinstall requires root privileges to run. See --help for more.")) exit(1) - parser = ArgumentParser() @@ -82,14 +78,17 @@ def define_arguments(): parser.add_argument("--dry-run", "--dry_run", action="store_true", 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", nargs="?", type=str, help="Define an alternate mount point for installation") + parser.add_argument("--mount-point", "--mount_point", nargs="?", type=str, + help="Define an alternate mount point for installation") 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("--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) -def parse_unspecified_argument_list(unknowns :list, multiple :bool = False, err :bool = False) -> dict: +def parse_unspecified_argument_list(unknowns: list, multiple: bool = False, err: 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. We accept following individual syntax for each argument @@ -105,32 +104,33 @@ def parse_unspecified_argument_list(unknowns :list, multiple :bool = False, err argument value value ... which isn't am error if multiple is specified """ - tmp_list = unknowns[:] # wastes a few bytes, but avoids any collateral effect of the destructive nature of the pop method() + tmp_list = unknowns[ + :] # wastes a few bytes, but avoids any collateral effect of the destructive nature of the pop method() config = {} key = None last_key = None while tmp_list: - element = tmp_list.pop(0) # retrieve an element of the list - if element.startswith('--'): # is an argument ? - if '=' in element: # uses the arg=value syntax ? + element = tmp_list.pop(0) # retrieve an element of the list + if element.startswith('--'): # is an argument ? + if '=' in element: # uses the arg=value syntax ? key, value = [x.strip() for x in element[2:].split('=', 1)] config[key] = value - last_key = key # for multiple handling - key = None # we have the kwy value pair we need + last_key = key # for multiple handling + key = None # we have the kwy value pair we need else: key = element[2:] - config[key] = True # every argument starts its lifecycle as boolean + config[key] = True # every argument starts its lifecycle as boolean else: if element == '=': continue if key: config[key] = element - last_key = key # multiple + last_key = key # multiple key = None else: if multiple and last_key: - if isinstance(config[last_key],str): - config[last_key] = [config[last_key],element] + if isinstance(config[last_key], str): + config[last_key] = [config[last_key], element] else: config[last_key].append(element) elif err: @@ -158,6 +158,7 @@ def cleanup_empty_args(args: Union[Namespace, Dict]) -> Dict: return clean_args + def get_arguments() -> Dict[str, Any]: """ The handling of parameters from the command line Is done on following steps: @@ -275,7 +276,7 @@ def plugin(f, *args, **kwargs): plugins[f.__name__] = f -def run_as_a_module(): +def main(): """ This can either be run as the compiled and installed application: python setup.py install OR straight as a module: python -m archinstall @@ -289,3 +290,20 @@ def run_as_a_module(): mod_name = f'archinstall.scripts.{script}' # by loading the module we'll automatically run the script importlib.import_module(mod_name) + + +def run_as_a_module(): + try: + main() + except Exception as e: + err = ''.join(traceback.format_exception(e)) + error(err) + + text = ( + 'Archinstall experienced the above error. If you think this is a bug, please report it to\n' + 'https://github.com/archlinux/archinstall and include the log file "/var/log/archinstall/install.log".\n\n' + 'Hint: To extract the log from a live ISO \ncurl -F\'file=@/var/log/archinstall/install.log\' https://0x0.st\n' + ) + + warn(text) + exit(1) diff --git a/archinstall/lib/global_menu.py b/archinstall/lib/global_menu.py index 86c341a70a..a17df0dec1 100644 --- a/archinstall/lib/global_menu.py +++ b/archinstall/lib/global_menu.py @@ -243,6 +243,7 @@ def _disk_encryption(self, preset: Optional[disk.DiskEncryption]) -> Optional[di def _locale_selection(self, preset: LocaleConfiguration) -> LocaleConfiguration: data_store: Dict[str, Any] = {} + raise ValueError('not good') locale_config = LocaleMenu(data_store, preset).run() return locale_config