def run_loop(action, options): assert callable(action) loop = asyncio.new_event_loop() asyncio.set_event_loop(loop) print_header('START {}'.format(action.__name__)) try: config = backend.get_config() cli_delegate = CliDelegate() result = loop.run_until_complete(action(config, block=True, async_delegate=cli_delegate, options=options)) pp = PrettyPrint(result) pp.stage_name = action.__name__ pp.beautify('print_data') finally: loop.close() exitcode = 0 for host_result in result: for command_result in host_result: for host, process_result in command_result.items(): if process_result['returncode'] != 0: exitcode += 1 print_header('ACTION {} COMPLETE'.format(action.__name__)) pp.print_summary() return exitcode
def run_loop(action, options): assert callable(action) loop = asyncio.new_event_loop() asyncio.set_event_loop(loop) print_header('START {}'.format(action.__name__)) try: config = backend.get_config() cli_delegate = CliDelegate() result = loop.run_until_complete( action(config, block=True, async_delegate=cli_delegate, options=options)) pp = PrettyPrint(result) pp.stage_name = action.__name__ pp.beautify('print_data') finally: loop.close() exitcode = 0 for host_result in result: for command_result in host_result: for host, process_result in command_result.items(): if process_result['returncode'] != 0: exitcode += 1 print_header('ACTION {} COMPLETE'.format(action.__name__)) pp.print_summary() return exitcode
def validate_config(args): print_header('VALIDATING CONFIGURATION') log_warn_only() validation_errors = backend.do_validate_gen_config() if validation_errors: print_validation_errors(validation_errors) return 1 return 0
def do_validate_config(args): print_header('VALIDATING CONFIGURATION') log_warn_only() validation_errors = backend.do_validate_gen_config() if validation_errors: print_validation_errors(validation_errors) return 1 return 0
def __init__(self, args=None): """ The web based installer leverages Flask to present end-users of dcos_installer with a clean web interface to configure their site-based installation of DC/OS. """ # If no args are passed to the class, then we're calling this # class from another library or code so we shouldn't execute # parser or anything else if args: options = self.parse_args(args) if len(options.hash_password) > 0: print_header("HASHING PASSWORD TO SHA512") backend.hash_password(options.hash_password) sys.exit(0) make_default_dir() if options.web: print_header("Starting DC/OS installer in web mode") async_server.start(options) if options.validate_config: print_header('VALIDATING CONFIGURATION') log_warn_only() validation_errors = backend.do_validate_gen_config() if validation_errors: print_validation_errors(validation_errors) sys.exit(1) sys.exit(0) if options.genconf: print_header("EXECUTING CONFIGURATION GENERATION") code = backend.do_configure() if code != 0: sys.exit(1) sys.exit(0) validate_ssh_config_or_exit() dispatch_action(options)
def install_prereqs(args): print_header("EXECUTING INSTALL PREREQUISITES") return action_lib.install_prereqs
def uninstall(args): print_header("EXECUTING UNINSTALL") tall_enough_to_ride() return action_lib.uninstall_dcos
def deploy(args): print_header("EXECUTING DC/OS INSTALLATION") return action_lib.install_dcos
def __init__(self, args=None): """ The web based installer leverages Flask to present end-users of dcos_installer with a clean web interface to configure their site-based installation of DC/OS. """ # If no args are passed to the class, then we're calling this # class from another library or code so we shouldn't execute # parser or anything else make_default_dir() if args: options = self.parse_args(args) if len(options.hash_password) > 0: print_header("HASHING PASSWORD TO SHA512") backend.hash_password(options.hash_password) sys.exit(0) if options.web: print_header("Starting DC/OS installer in web mode") async_server.start(options) if options.genconf: print_header("EXECUTING CONFIGURATION GENERATION") code = backend.do_configure() if code != 0: sys.exit(1) sys.exit(0) if options.validate_config: print_header('VALIDATING CONFIGURATION') log_warn_only() validation_errors = backend.do_validate_gen_config() if validation_errors: print_validation_errors(validation_errors) sys.exit(1) sys.exit(0) validate_ssh_config_or_exit() action = None if options.preflight: print_header("EXECUTING PREFLIGHT") action = action_lib.run_preflight if options.deploy: print_header("EXECUTING DC/OS INSTALLATION") action = action_lib.install_dcos if options.postflight: print_header("EXECUTING POSTFLIGHT") action = action_lib.run_postflight if options.uninstall: print_header("EXECUTING UNINSTALL") tall_enough_to_ride() action = action_lib.uninstall_dcos if options.install_prereqs: print_header("EXECUTING INSTALL PREREQUISITES") action = action_lib.install_prereqs sys.exit(run_loop(action, options))
def do_web(args): print_header("Starting DC/OS installer in web mode") import dcos_installer.async_server dcos_installer.async_server.start(args) return 0
def on_done(self, name, result, host_status=None): print_header('STAGE {}'.format(name))
def genconf(args): print_header("EXECUTING CONFIGURATION GENERATION") code = backend.do_configure() if code != 0: return 1 return 0
def hash_password(args): if len(args.hash_password) > 0: print_header("HASHING PASSWORD TO SHA512") backend.hash_password(args.hash_password) return 0
def web(args): print_header("Starting DC/OS installer in web mode") async_server.start(args)
def do_genconf(args): print_header("EXECUTING CONFIGURATION GENERATION") code = backend.do_configure() if code != 0: return 1 return 0
def action_action_name(request): """Return /action/<action_name> :param request: a web requeest object. :type request: request | None """ action_name = request.match_info['action_name'] # Update the global action json_state = read_json_state(action_name) app['current_action'] = action_name if request.method == 'GET': log.info('GET {}'.format(action_name)) if json_state: return web.json_response(json_state) return web.json_response({}) elif request.method == 'POST': log.info('POST {}'.format(action_name)) action = action_map.get(action_name) # If the action name is preflight, attempt to run configuration # generation. If genconf fails, present the UI with a usable error # for the end-user if action_name == 'preflight': try: print_header("GENERATING CONFIGURATION") backend.do_configure() except: genconf_failure = { "errors": "Configuration generation failed, please see command line for details" } return web.json_response(genconf_failure, status=400) params = yield from request.post() if json_state: if action_name == 'deploy' and 'retry' in params: if 'hosts' in json_state: failed_hosts = [] for deploy_host, deploy_params in json_state['hosts'].items(): if deploy_params['host_status'] != 'success': failed_hosts.append(deploy_host) log.debug('failed hosts: {}'.format(failed_hosts)) if failed_hosts: yield from asyncio.async( action( backend.get_config(), state_json_dir=STATE_DIR, hosts=failed_hosts, try_remove_stale_dcos=True, **params)) return web.json_response({'status': 'retried', 'details': sorted(failed_hosts)}) if action_name not in remove_on_done: return web.json_response({'status': '{} was already executed, skipping'.format(action_name)}) running = False for host, attributes in json_state['hosts'].items(): if attributes['host_status'].lower() == 'running': running = True log.debug('is action running: {}'.format(running)) if running: return web.json_response({'status': '{} is running, skipping'.format(action_name)}) else: unlink_state_file(action_name) yield from asyncio.async(action(backend.get_config(), state_json_dir=STATE_DIR, options=options, **params)) return web.json_response({'status': '{} started'.format(action_name)})
def preflight(args): print_header("EXECUTING PREFLIGHT") return action_lib.run_preflight
def postflight(args): print_header("EXECUTING POSTFLIGHT") return action_lib.run_postflight
def action_action_name(request): """Return /action/<action_name> :param request: a web requeest object. :type request: request | None """ action_name = request.match_info['action_name'] # Update the global action json_state = read_json_state(action_name) app['current_action'] = action_name if request.method == 'GET': log.info('GET {}'.format(action_name)) if json_state: return web.json_response(json_state) return web.json_response({}) elif request.method == 'POST': log.info('POST {}'.format(action_name)) action = action_map.get(action_name) # If the action name is preflight, attempt to run configuration # generation. If genconf fails, present the UI with a usable error # for the end-user if action_name == 'preflight': try: print_header("GENERATING CONFIGURATION") backend.do_configure() except: genconf_failure = { "errors": "Configuration generation failed, please see command line for details" } return web.json_response(genconf_failure, status=400) params = yield from request.post() if json_state: if action_name == 'deploy' and 'retry' in params: if 'hosts' in json_state: failed_hosts = [] for deploy_host, deploy_params in json_state['hosts'].items(): if deploy_params['host_status'] != 'success': failed_hosts.append(Node(deploy_host, tags=deploy_params['tags'])) log.debug('failed hosts: {}'.format(failed_hosts)) if failed_hosts: yield from asyncio.async( action( backend.get_config(), state_json_dir=STATE_DIR, hosts=failed_hosts, try_remove_stale_dcos=True, **params)) return web.json_response({ 'status': 'retried', 'details': sorted(['{}:{}'.format(node.ip, node.port) for node in failed_hosts]) }) if action_name not in remove_on_done: return web.json_response({'status': '{} was already executed, skipping'.format(action_name)}) running = False for host, attributes in json_state['hosts'].items(): if attributes['host_status'].lower() == 'running': running = True log.debug('is action running: {}'.format(running)) if running: return web.json_response({'status': '{} is running, skipping'.format(action_name)}) else: unlink_state_file(action_name) yield from asyncio.async(action(backend.get_config(), state_json_dir=STATE_DIR, options=options, **params)) return web.json_response({'status': '{} started'.format(action_name)})