def start_initialize(scripts_detector, cron_path): cron_schedule_content = CRON_TEMPLATE % os.environ[CRON_BACKUP_SCHEDULE] with open(cron_path, 'w') as cron_file: cron_file.write(cron_schedule_content) try: run_scripts(scripts_detector, scripts_detector.install_dependencies, 'install_dependencies') except ScriptErrorOccurred as e: # int the dependency install phase it is important to fail and do not boot the container print_logger(e) raise e
def start_run(scripts_detector): # always clean storage before and after usage, we do not want to leave unattended data between calls clear_storage() try: run_scripts(scripts_detector, scripts_detector.before_backups, 'before_backups') run_scripts(scripts_detector, scripts_detector.backups, 'backups') run_scripts(scripts_detector, scripts_detector.after_backups, 'after_backups') except ScriptErrorOccurred as e: print_logger(e) finally: clear_storage()
def run_scripts(scripts_detector, path, hook_name): """ Will run scripts in a given directory, if an error occurs it will launch on_error scripts. If an error occurs during an on_error script, the entire chain of scripts will stop. """ print_logger("Hook: '%s'" % hook_name) try: for script in path: run_single_script(script) except SubprocessErrorDuringExecutionException as e: print_logger(e) # run on_error callbacks and do not rejigger on_error for error_script in scripts_detector.on_error: run_single_script(error_script, skip_error=True, error=str(e)) raise ScriptErrorOccurred( "Script execution finished due to errors. Look at logs for details" )
def run_single_script(script, skip_error=False, **kwargs): print_logger("Starting '%s'" % script) cmd = [script] + list(kwargs.values()) print_logger(cmd) process = subprocess.Popen(cmd, stdout=subprocess.PIPE) for c in iter(lambda: process.stdout.read(1), b''): sys.stdout.write(c.decode('utf-8')) process.communicate() exit_code = process.returncode if exit_code != 0: error_message = "Script '%s' finished with exit code '%s'" % ( script, exit_code) if skip_error: print_logger(error_message) else: raise SubprocessErrorDuringExecutionException(error_message)
def main(): if TARGET_CONTAINER not in os.environ: print_logger("Could not find '%s' in the environment variables" % TARGET_CONTAINER) exit(1) if POD_NAME not in os.environ: print_logger("Could not find '%s' in the environment variables" % POD_NAME) exit(1) cli_arguments = sys.argv[1:] if len(cli_arguments) < 1: print_logger( "You must provide a command to be executed in the target container" ) exit(1) command = " ".join(cli_arguments) run_in_container(command)
def main(): parser = argparse.ArgumentParser( description='Tool for running and initializing backup container') parser.add_argument('-i', '--initialize', action='store_true', help='configure cron and install dependencies') parser.add_argument('-r', '--run', action='store_true', help='runs scrips following the lifecycle') parser.add_argument('-csp', '--container-scripts-path', default='/scripts', help='path to scripts folder, default /scripts') parser.add_argument( '-c', '--cron-path', default='/etc/crontabs/root', help='path to scripts folder, default /etc/crontabs/root') arguments = parser.parse_args() if CRON_BACKUP_SCHEDULE not in os.environ: print_logger("Could not find '%s' in the environment variables" % CRON_BACKUP_SCHEDULE) exit(1) if not croniter.is_valid(os.environ[CRON_BACKUP_SCHEDULE]): print_logger("Provided cron schedule '%s' is not valid" % os.environ[CRON_BACKUP_SCHEDULE]) exit(1) # check if provided directory exists if not os.path.isdir(arguments.container_scripts_path): print_logger("The following path '%s' is not a valid directory" % arguments.container_scripts_path) exit(1) if not arguments.initialize and not arguments.run: print_logger( "Nothing to do.\nPlease run: 'fridge --help' to see possible options" ) exit(1) scripts_detector = ScriptsDetector(arguments.container_scripts_path) scripts_detector.list_detected_scripts() if arguments.initialize: print_logger("Initializing...") start_initialize(scripts_detector, arguments.cron_path) print_logger("Initialization complete.") if arguments.run: print_logger("Running...") start_run(scripts_detector) print_logger("Finished running.")
def main(): """ Generates all needed configurations for k8s after providing a scripts directory and some other parameters """ parser = argparse.ArgumentParser( description='Tool for running and initializing backup container') parser.add_argument('namespace', type=str, help='the k8s namespace') parser.add_argument('project_name', type=str, help='the current project name') parser.add_argument( 'container_name', type=str, help='container name where volumeMounts and volumes are to be used') parser.add_argument('in_dir', type=str, help='path to your directory containing the hooks') parser.add_argument('out_dir', type=str, help='directory for k8s configuration file output') parser.add_argument( '-csp', '--container-scripts-path', default='/scripts', help='path to scripts folder inside the container, default /scripts') arguments = parser.parse_args() # check if provided directory exists if not os.path.isdir(arguments.in_dir): print_logger("The following path '%s' is not a valid directory" % arguments.in_dir) exit(1) # check if provided directory exists if not os.path.isdir(arguments.out_dir): print_logger("The following path '%s' is not a valid directory" % arguments.out_dir) exit(1) scripts_detector = ScriptsDetector(arguments.in_dir) # store yaml files in output directory assemble_config_yaml(scripts_detector=scripts_detector, namespace=arguments.namespace, project_name=arguments.project_name, container_name=arguments.container_name, output_path=arguments.out_dir) assemble_service_account_name_volumes_partial( scripts_detector=scripts_detector, namespace=arguments.namespace, project_name=arguments.project_name, container_name=arguments.container_name, output_path=arguments.out_dir) assemble_volume_mounts_partial( namespace=arguments.namespace, project_name=arguments.project_name, container_name=arguments.container_name, output_path=arguments.out_dir, container_scripts_path=arguments.container_scripts_path) assemble_service_account_role_role_binding( namespace=arguments.namespace, project_name=arguments.project_name, output_path=arguments.out_dir)
def list_detected_scripts(self): message = "\n** Detected scripts **\n" for category, scripts in self.detected_scripts: message += "-- %s --\n" % category message += "%s\n" % scripts print_logger(message)