Source code for autopilot.setup.run_script

"""
Run scripts to setup system dependencies and autopilot plugins

::

    > # to list scripts
    > python3 -m autopilot.setup.run_script --list

    > # to execute one script (setup hifiberry soundcard)
    > python3 -m autopilot.setup.run_script hifiberry

    > # to execute multiple scripts
    > python3 -m autopilot.setup.run_script hifiberry jackd

"""
import typing
import subprocess
from autopilot.setup.scripts import SCRIPTS
import argparse
import sys

parser = argparse.ArgumentParser(description="Run autopilot setup script(s)")
parser.add_argument('scripts', nargs='*', type=str)
parser.add_argument('--list', help="list available setup scripts!", action='store_true')


[docs]def call_series(commands, series_name=None): """ Call a series of commands, giving a single return code on completion or failure :param commands: :return: """ if series_name: print('\n\033[1;37;42m Running commands for {}\u001b[0m'.format(series_name)) # have to just combine them -- can't do multiple calls b/c shell doesn't preserve between them combined_calls = "" last_command = len(commands)-1 for i, command in enumerate(commands): join_with = " && " if isinstance(command, str): # just a command, default necessary combined_calls += command elif isinstance(command, dict): combined_calls += command['command'] if command.get('optional', False): join_with = "; " if i < last_command: combined_calls += join_with print('Executing:\n {}'.format(combined_calls)) result = subprocess.run(combined_calls, shell=True, executable='/bin/bash') status = False if result.returncode == 0: status = True if series_name: if status: print('\n\033[1;37;42m {} Successful, you lucky duck\u001b[0m'.format(series_name)) else: print('\n\033[1;37;41m {} Failed, check the error message & ur crystal ball\u001b[0m'.format(series_name)) return status
[docs]def run_script(script_name): if script_name in SCRIPTS.keys(): call_series(SCRIPTS[script_name]['commands'], script_name) else: raise NameError('No script named {}, must be one of {}'.format(script_name, "\n".join(SCRIPTS.keys())))
[docs]def run_scripts(scripts, return_all=False,print_status=True) -> typing.Union[bool, typing.Dict[str,bool]]: """ Run a series of scripts, printing results Args: scripts (list): list of script names Returns: bool: success or failure of scripts - ``True`` if all were successful, ``False`` otherwise. """ env_results = {} for script_name in scripts: commands = SCRIPTS[script_name].get('commands', None) if commands is not None: env_results[script_name] = call_series(commands, script_name) # indicate global success success = True # make results string if print_status: env_result = "\033[0;32;40m\n--------------------------------\nScript Results:\n" for config, result in env_results.items(): if result: env_result += " [ SUCCESS ] " else: env_result += " [ FAILURE ] " success = False env_result += config env_result += '\n' env_result += '--------------------------------\u001b[0m' print(env_result) if return_all: return env_results else: return success
[docs]def list_scripts(): print('\nAvailable Scripts:\n----------------------------') # find longest script name longest_name = 0 for script_name in SCRIPTS.keys(): if len(script_name) > longest_name: longest_name = len(script_name) for script_name in sorted(SCRIPTS.keys()): pad = " " * (longest_name - len(script_name)) print(f'\033[1;37;42m{script_name}{pad}\u001b[0m : {SCRIPTS[script_name]["text"]}')
if __name__ == "__main__": args = parser.parse_args() if args.list: list_scripts() sys.exit() elif args.scripts: res = run_scripts(args.scripts) if res: sys.exit() else: sys.exit(1) else: raise RuntimeError('Need to give name of one or multiple scripts, ')