From 81b7524b53fe21664ec6da3b69e507638b1ed253 Mon Sep 17 00:00:00 2001 From: Anton Hvornum Date: Thu, 12 May 2022 10:46:33 +0200 Subject: Made sure remote sourcing works for --creds, --config and --disk-layout. (#1170) * Made sure remote sourcing works for --creds, --config and --disk-layout. * Spelling error when moving around source code. --- archinstall/__init__.py | 21 ++++++-------------- archinstall/lib/general.py | 49 ++++++++++++++++++++++++++++------------------ 2 files changed, 36 insertions(+), 34 deletions(-) (limited to 'archinstall') diff --git a/archinstall/__init__.py b/archinstall/__init__.py index 536db370..aa644d48 100644 --- a/archinstall/__init__.py +++ b/archinstall/__init__.py @@ -149,22 +149,13 @@ def get_arguments() -> Dict[str, Any]: # preprocess the json files. # TODO Expand the url access to the other JSON file arguments ? if args.config is not None: - try: - # First, let's check if this is a URL scheme instead of a filename - parsed_url = urllib.parse.urlparse(args.config) - - if not parsed_url.scheme: # The Profile was not a direct match on a remote URL, it must be a local file. - if not json_stream_to_structure('--config',args.config,config): - exit(1) - else: # Attempt to load the configuration from the URL. - with urllib.request.urlopen(urllib.request.Request(args.config, headers={'User-Agent': 'ArchInstall'})) as response: - config.update(json.loads(response.read())) - except Exception as e: - raise ValueError(f"Could not load --config because: {e}") + if not json_stream_to_structure('--config', args.config, config): + exit(1) - if args.creds is not None: - if not json_stream_to_structure('--creds',args.creds,config): - exit(1) + if args.creds is not None: + if not json_stream_to_structure('--creds', args.creds, config): + exit(1) + # load the parameters. first the known, then the unknowns config.update(vars(args)) config.update(parse_unspecified_argument_list(unknowns)) diff --git a/archinstall/lib/general.py b/archinstall/lib/general.py index cf925de3..a4e2a365 100644 --- a/archinstall/lib/general.py +++ b/archinstall/lib/general.py @@ -10,6 +10,9 @@ import string import sys import time import re +import urllib.parse +import urllib.request +import pathlib from datetime import datetime, date from typing import Callable, Optional, Dict, Any, List, Union, Iterator, TYPE_CHECKING # https://stackoverflow.com/a/39757388/929999 @@ -532,32 +535,40 @@ def run_custom_user_commands(commands :List[str], installation :Installer) -> No log(execution_output) os.unlink(f"{installation.target}/var/tmp/user-command.{index}.sh") -def json_stream_to_structure(id : str, stream :str, target :dict) -> bool : - """ Function to load a stream (file (as name) or valid JSON string into an existing dictionary +def json_stream_to_structure(configuration_identifier : str, stream :str, target :dict) -> bool : + """ + Function to load a stream (file (as name) or valid JSON string into an existing dictionary Returns true if it could be done Return false if operation could not be executed - +id is just a parameter to get meaningful, but not so long messages + +configuration_identifier is just a parameter to get meaningful, but not so long messages """ - from pathlib import Path - if Path(stream).exists(): - try: - with open(Path(stream)) as fh: - target.update(json.load(fh)) - except Exception as e: - log(f"{id} = {stream} does not contain a valid JSON format: {e}",level=logging.ERROR) - return False + + parsed_url = urllib.parse.urlparse(stream) + + if parsed_url.scheme: # The stream is in fact a URL that should be grabed + with urllib.request.urlopen(urllib.request.Request(stream, headers={'User-Agent': 'ArchInstall'})) as response: + target.update(json.loads(response.read())) else: - log(f"{id} = {stream} does not exists in the filesystem. Trying as JSON stream",level=logging.DEBUG) - # NOTE: failure of this check doesn't make stream 'real' invalid JSON, just it first level entry is not an object (i.e. dict), so it is not a format we handle. - if stream.strip().startswith('{') and stream.strip().endswith('}'): + if pathlib.Path(stream).exists(): try: - target.update(json.loads(stream)) - except Exception as e: - log(f" {id} Contains an invalid JSON format : {e}",level=logging.ERROR) + with pathlib.Path(stream).open() as fh: + target.update(json.load(fh)) + except Exception as error: + log(f"{configuration_identifier} = {stream} does not contain a valid JSON format: {error}", level=logging.ERROR, fg="red") return False else: - log(f" {id} is neither a file nor is a JSON string:",level=logging.ERROR) - return False + # NOTE: This is a rudimentary check if what we're trying parse is a dict structure. + # Which is the only structure we tolerate anyway. + if stream.strip().startswith('{') and stream.strip().endswith('}'): + try: + target.update(json.loads(stream)) + except Exception as e: + log(f" {configuration_identifier} Contains an invalid JSON format : {e}",level=logging.ERROR, fg="red") + return False + else: + log(f" {configuration_identifier} is neither a file nor is a JSON string:",level=logging.ERROR, fg="red") + return False + return True def secret(x :str): -- cgit v1.2.3-70-g09d2