def finish(self): if app.argv.model: app.current_model = app.argv.model else: app.current_model = utils.gen_model() if not app.argv.controller: app.current_controller = "conjure-up-{}-{}".format( app.current_cloud, utils.gen_hash()) return controllers.use('newcloud').render() app.current_controller = app.argv.controller if not self.__controller_exists(app.current_controller): return controllers.use('newcloud').render() else: utils.info("Using controller '{}'".format(app.current_controller)) utils.info("Creating new model named '{}', " "please wait.".format(app.current_model)) app.loop.create_task( juju.add_model(app.current_model, app.current_controller, app.current_cloud, allow_exists=True)) return controllers.use('deploy').render() utils.error("Something happened with the controller or model, " "please check the logs.") events.Shutdown.set(1)
def finish(self): if app.argv.cloud == "localhost": if not utils.check_bridge_exists(): back = "{} to localhost".format(app.argv.config['spell']) os.execl("/usr/share/conjure-up/run-lxd-config", "/usr/share/conjure-up/run-lxd-config", back) if app.argv.controller: existing_controller = app.argv.controller if juju.get_controller(existing_controller) is None: utils.error("Specified controller '{}' " "could not be found in cloud '{}'.".format( existing_controller, app.argv.cloud)) sys.exit(1) else: existing_controller = juju.get_controller_in_cloud(app.argv.cloud) if existing_controller is None: return controllers.use('newcloud').render(app.argv.cloud) utils.info("Using controller '{}'".format(existing_controller)) app.current_controller = existing_controller app.current_model = petname.Name() utils.info("Creating new juju model named '{}', " "please wait.".format(app.current_model)) juju.add_model(app.current_model, app.current_controller) return controllers.use('deploy').render()
def render(self, cloud): self.cloud = cloud if app.current_controller is None: app.current_controller = petname.Name() if app.current_model is None: app.current_model = 'conjure-up' if self.cloud != 'localhost': if not common.try_get_creds(self.cloud): utils.warning("You attempted to do an install against a cloud " "that requires credentials that could not be " "found. If you wish to supply those " "credentials please run " "`juju add-credential {}`.".format(self.cloud)) sys.exit(1) if self.cloud == 'localhost': if not utils.check_bridge_exists(): return controllers.use('lxdsetup').render() app.log.debug("Found an IPv4 address, " "assuming LXD is configured.") utils.info("Bootstrapping Juju controller") juju.bootstrap(controller=app.current_controller, cloud=self.cloud, credential=common.try_get_creds(self.cloud)) self.do_post_bootstrap() self.finish()
def do_pre_deploy(self): """ runs pre deploy script if exists """ # Set provider type for post-bootstrap app.env['JUJU_PROVIDERTYPE'] = model_info('default')['provider-type'] pre_deploy_sh = os.path.join(app.config['spell-dir'], 'conjure/steps/00_pre-deploy') if os.path.isfile(pre_deploy_sh) \ and os.access(pre_deploy_sh, os.X_OK): utils.pollinate(app.session_id, 'J001') utils.info("Running pre deployment tasks.") try: sh = run(pre_deploy_sh, shell=True, stdout=PIPE, stderr=PIPE, env=app.env) result = json.loads(sh.stdout.decode('utf8')) if result['returnCode'] > 0: utils.error("Failed to run pre-deploy task: " "{}".format(result['message'])) sys.exit(1) utils.info("Finished pre deploy task: {}".format( result['message'])) except Exception as e: utils.error( "Failed to run pre deploy task: {}".format(e)) sys.exit(1)
def do_post_bootstrap(self): """ runs post bootstrap script if exists """ # Set provider type for post-bootstrap app.env['JUJU_PROVIDERTYPE'] = model_info('default')['provider-type'] post_bootstrap_sh = os.path.join(app.config['spell-dir'], 'steps/00_post-bootstrap') if os.path.isfile(post_bootstrap_sh) \ and os.access(post_bootstrap_sh, os.X_OK): utils.pollinate(app.session_id, 'J001') utils.info("Running post-bootstrap tasks.") try: sh = utils.run(post_bootstrap_sh, shell=True, stdout=PIPE, stderr=PIPE, env=app.env) result = json.loads(sh.stdout.decode('utf8')) utils.info("Finished post bootstrap task: {}".format( result['message'])) except Exception as e: utils.warning( "Failed to run post bootstrap task: {}".format(e)) sys.exit(1)
def do_post_bootstrap(self): """ runs post bootstrap script if exists """ # Set provider type for post-bootstrap info = model_info(app.current_model) app.env['JUJU_PROVIDERTYPE'] = info['provider-type'] app.env['JUJU_CONTROLLER'] = app.current_controller app.env['JUJU_MODEL'] = app.current_model post_bootstrap_sh = os.path.join(app.config['spell-dir'], 'steps/00_post-bootstrap') if os.path.isfile(post_bootstrap_sh) \ and os.access(post_bootstrap_sh, os.X_OK): utils.info("Running post-bootstrap tasks.") try: sh = utils.run(post_bootstrap_sh, shell=True, stdout=PIPE, stderr=PIPE, env=app.env) result = json.loads(sh.stdout.decode('utf8')) utils.info("Finished post bootstrap task: {}".format( result['message'])) except Exception as e: utils.warning( "Failed to run post bootstrap task: {}".format(e)) sys.exit(1)
def render(self, cloud): self.cloud = cloud if app.current_controller is None: app.current_controller = petname.Name() if app.current_model is None: app.current_model = 'default' if self.cloud != 'localhost': if not common.try_get_creds(self.cloud): utils.warning("You attempted to do an install against a cloud " "that requires credentials that could not be " "found. If you wish to supply those " "credentials please run " "`juju add-credential {}`.".format(self.cloud)) sys.exit(1) if self.cloud == 'localhost': if not utils.check_bridge_exists(): return controllers.use('lxdsetup').render() app.log.debug("Found an IPv4 address, " "assuming LXD is configured.") utils.info("Bootstrapping Juju controller") juju.bootstrap(controller=app.current_controller, cloud=self.cloud, credential=common.try_get_creds(self.cloud)) self.do_post_bootstrap() self.finish()
async def do_destroy(self, model, controller): track_event("Destroying model", "Destroy", "") utils.info("Destroying model {} in controller {}".format( model, controller)) await juju.destroy_model(controller, model) utils.info("Model has been removed") events.Shutdown.set(0)
def finish(self): app.current_cloud = app.argv.cloud if app.argv.model: app.current_model = app.argv.model else: app.current_model = "conjure-up-{}-{}".format( app.env['CONJURE_UP_SPELL'], utils.gen_hash()) if not app.argv.controller: app.current_controller = "conjure-up-{}-{}".format( app.current_cloud, utils.gen_hash()) return controllers.use('newcloud').render() app.current_controller = app.argv.controller if self.__get_existing_controller(app.current_controller) is None: return controllers.use('newcloud').render() else: utils.info("Using controller '{}'".format(app.current_controller)) utils.info("Creating new deployment named '{}', " "please wait.".format(app.current_model)) juju.add_model(app.current_model, app.current_controller) return controllers.use('deploy').render() utils.error("Something happened with the controller or model, " "please check the logs.") sys.exit(1)
def render(self): cloud = juju.get_cloud(app.current_cloud) if cloud['type'] != 'lxd': if not common.try_get_creds(app.current_cloud): utils.warning("You attempted to do an install against a cloud " "that requires credentials that could not be " "found. If you wish to supply those " "credentials please run " "`juju add-credential " "{}`.".format(app.current_cloud)) sys.exit(1) if cloud['type'] == 'lxd': lxd = common.is_lxd_ready() if not lxd['ready']: return controllers.use('lxdsetup').render(lxd['msg']) utils.info("Bootstrapping Juju controller \"{}\" " "with deployment \"{}\"".format(app.current_controller, app.current_model)) p = juju.bootstrap(controller=app.current_controller, cloud=app.current_cloud, model=app.current_model, credential=common.try_get_creds(app.current_cloud)) if p.returncode != 0: pathbase = os.path.join(app.config['spell-dir'], '{}-bootstrap').format( app.current_controller) with open(pathbase + ".err") as errf: utils.error("Error bootstrapping controller: " "{}".format("".join(errf.readlines()))) sys.exit(1) self.do_post_bootstrap() self.finish()
def show_summary(self): utils.info("Post-Deployment Step Results") table = PrettyTable() table.field_names = ["Application", "Result"] for step in app.steps: table.add_row(self._format_step_result(step)) print(table)
def render(self): utils.info( "Summoning {} to {}".format(app.argv.spell, app.provider.cloud)) if app.provider.cloud_type == cloud_types.LOCALHOST: if not Path('/snap/bin/lxc').exists(): utils.error("Unable to find lxc executable, please make " "sure LXD is installed: `sudo snap install lxd`") events.Shutdown.set(1) self.finish()
def render(self): if app.argv.cloud not in juju.get_clouds().keys(): formatted_clouds = ", ".join(juju.get_clouds().keys()) utils.warning("Unknown Cloud: {}, please choose " "from one of the following: {}".format( app.argv.cloud, formatted_clouds)) sys.exit(1) utils.info("Summoning {} to {}".format(app.argv.spell, app.argv.cloud)) self.finish()
def render(self): if app.current_cloud not in juju.get_clouds().keys(): formatted_clouds = ", ".join(juju.get_clouds().keys()) utils.error("Unknown Cloud: {}, please choose " "from one of the following: {}".format( app.current_cloud, formatted_clouds)) events.Shutdown.set(1) return utils.info("Summoning {} to {}".format(app.argv.spell, app.argv.cloud)) self.finish()
def render(self, results): common.write_results(results, self.save_path) utils.info("Summary") table = PrettyTable() table.field_names = ["Application", "Result"] for k, v in results.items(): application_name = colored(k, 'blue', attrs=['bold']) result = colored(v, 'green', attrs=['bold']) table.add_row([application_name, result]) print(table) utils.info("Installation of your big software is now complete.")
def render(self): if app.argv.cloud not in juju.get_clouds().keys(): formatted_clouds = ", ".join(juju.get_clouds().keys()) utils.warning( "Unknown Cloud: {}, please choose " "from one of the following: {}".format(app.argv.cloud, formatted_clouds)) sys.exit(1) utils.info( "Summoning {} to {}".format(app.argv.spell, app.argv.cloud)) self.finish()
async def run_steps(self): utils.info("Running post-deployment steps") for step in app.steps: step.result = await common.do_step(step, utils.info) common.save_step_results() self.show_summary() utils.info("Installation of your big software is now complete.") events.PostDeployComplete.set() events.Shutdown.set(0)
async def run_steps(self): utils.info("Running post-deployment steps") for step in app.all_steps: if not step.has_after_deploy: continue step.result = await step.after_deploy(utils.info) common.save_step_results() self.show_summary() utils.info("Installation of your big software is now complete.") events.PostDeployComplete.set() events.Shutdown.set(0)
async def _check_lxd_compat(self): utils.info("Summoning {} to {}".format(app.conjurefile['spell'], app.provider.cloud)) if app.provider.cloud_type == cloud_types.LOCALHOST: app.provider._set_lxd_dir_env() client_compatible = await app.provider.is_client_compatible() server_compatible = await app.provider.is_server_compatible() if client_compatible and server_compatible: return self.finish() else: utils.error("LXD Server or LXC client not compatible") events.Shutdown.set(1) self.finish()
async def run_steps(self): utils.info("Running post-deployment steps") # technically, you can't currently select addons in headless, # but let's go ahead and be future-proof steps = app.steps + AddonModel.selected_addons_steps() for step in steps: step.result = await step.run(utils.info) common.save_step_results() self.show_summary() utils.info("Installation of your big software is now complete.") events.PostDeployComplete.set() events.Shutdown.set(0)
async def _check_lxd_compat(self): utils.info("Summoning {} to {}".format(app.argv.spell, app.provider.cloud)) if app.provider.cloud_type == cloud_types.LOCALHOST: try: app.provider._set_lxd_dir_env() client_compatible = await app.provider.is_client_compatible() server_compatible = await app.provider.is_server_compatible() if client_compatible and server_compatible: return self.finish() else: utils.error("LXD Server or LXC client not compatible") events.Shutdown.set(1) except app.provider.LocalhostError: raise self.finish()
def finish(self): if app.argv.cloud == "localhost": if not utils.check_bridge_exists(): back = "{} to localhost".format(app.argv.config['spell']) os.execl("/usr/share/conjure-up/run-lxd-config", "/usr/share/conjure-up/run-lxd-config", back) existing_controller = juju.get_controller_in_cloud(app.argv.cloud) if existing_controller is None: return controllers.use('newcloud').render(app.argv.cloud) app.current_controller = existing_controller app.current_model = petname.Name() utils.info("Creating new juju model named '{}', " "please wait.".format(app.current_model)) juju.add_model(app.current_model, app.current_controller) return controllers.use('deploy').render()
def finish(self): if app.argv.cloud == "localhost": if not utils.check_bridge_exists(): back = "{} to localhost".format(app.argv.config['spell']) os.execl("/usr/share/conjure-up/run-lxd-config", "/usr/share/conjure-up/run-lxd-config", back) existing_controller = get_controller_in_cloud(app.argv.cloud) if existing_controller is None: return controllers.use('newcloud').render(app.argv.cloud) app.current_controller = existing_controller juju.switch_controller(app.current_controller) app.current_model = petname.Name() utils.info("Creating new juju model named '{}', " "please wait.".format(app.current_model)) juju.add_model(app.current_model) juju.switch_model(app.current_model) return controllers.use('deploy').render()
def render(self): if app.current_controller is None: app.current_controller = petname.Name() if app.current_model is None: app.current_model = 'conjure-up' if app.current_cloud != 'localhost': if not common.try_get_creds(app.current_cloud): utils.warning("You attempted to do an install against a cloud " "that requires credentials that could not be " "found. If you wish to supply those " "credentials please run " "`juju add-credential " "{}`.".format(app.current_cloud)) sys.exit(1) if app.current_cloud == 'localhost': if not utils.check_bridge_exists(): return controllers.use('lxdsetup').render() app.log.debug("Found an IPv4 address, " "assuming LXD is configured.") utils.info("Bootstrapping Juju controller") p = juju.bootstrap(controller=app.current_controller, cloud=app.current_cloud, credential=common.try_get_creds(app.current_cloud)) if p.returncode != 0: pathbase = os.path.join( app.config['spell-dir'], '{}-bootstrap').format(app.current_controller) with open(pathbase + ".err") as errf: utils.error("Error bootstrapping controller: " "{}".format("".join(errf.readlines()))) sys.exit(1) self.do_post_bootstrap() self.finish()
def render(self, cloud): self.cloud = cloud if app.current_controller is None: app.current_controller = petname.Name() if app.current_model is None: app.current_model = 'conjure-up' if self.cloud != 'localhost': if not common.try_get_creds(self.cloud): utils.warning("You attempted to do an install against a cloud " "that requires credentials that could not be " "found. If you wish to supply those " "credentials please run " "`juju add-credential {}`.".format(self.cloud)) sys.exit(1) if self.cloud == 'localhost': if not utils.check_bridge_exists(): return controllers.use('lxdsetup').render() app.log.debug("Found an IPv4 address, " "assuming LXD is configured.") utils.info("Bootstrapping Juju controller") p = juju.bootstrap(controller=app.current_controller, cloud=self.cloud, credential=common.try_get_creds(self.cloud)) if p.returncode != 0: pathbase = os.path.join(app.config['spell-dir'], '{}-bootstrap').format( app.current_controller) with open(pathbase + ".err") as errf: utils.error("Error bootstrapping controller: " "{}".format("".join(errf.readlines()))) sys.exit(1) self.do_post_bootstrap() self.finish()
def do_pre_deploy(self): """ runs pre deploy script if exists """ # Set provider type for post-bootstrap app.env['JUJU_PROVIDERTYPE'] = model_info( app.current_model)['provider-type'] app.env['JUJU_CONTROLLER'] = app.current_controller app.env['JUJU_MODEL'] = app.current_model app.env['CONJURE_UP_SPELLSDIR'] = app.argv.spells_dir pre_deploy_sh = os.path.join(app.config['spell-dir'], 'steps/00_pre-deploy') if os.path.isfile(pre_deploy_sh) \ and os.access(pre_deploy_sh, os.X_OK): utils.info("Running pre deployment tasks.") try: sh = utils.run(pre_deploy_sh, shell=True, stdout=PIPE, stderr=PIPE, env=app.env) try: result = json.loads(sh.stdout.decode('utf8')) except json.decoder.JSONDecodeError as e: utils.error(sh.stdout.decode()) utils.error(sh.stderr.decode()) sys.exit(1) if result['returnCode'] > 0: utils.error("Failed to run pre-deploy task: " "{}".format(result['message'])) sys.exit(1) utils.info("Finished pre deploy task: {}".format( result['message'])) except Exception as e: utils.error("Failed to run pre deploy task: {}".format(e)) sys.exit(1)
def render(self, cloud): self.cloud = cloud if app.current_controller is None: app.current_controller = petname.Name() if app.current_model is None: app.current_model = 'default' if self.cloud != 'localhost': if not common.try_get_creds(self.cloud): utils.warning("You attempted to do an install against a cloud " "that requires credentials that could not be " "found. If you wish to supply those " "credentials please run " "`juju add-credential {}`.".format(self.cloud)) sys.exit(1) utils.info("Bootstrapping Juju controller") juju.bootstrap(controller=app.current_controller, cloud=self.cloud, credential=common.try_get_creds(self.cloud)) self.do_post_bootstrap() self.finish()
def finish(self): if app.argv.controller: existing_controller = app.argv.controller if juju.get_controller(existing_controller) is None: utils.error("Specified controller '{}' " "could not be found in cloud '{}'.".format( existing_controller, app.argv.cloud)) sys.exit(1) else: existing_controller = juju.get_controller_in_cloud(app.argv.cloud) if existing_controller is None: app.current_cloud = app.argv.cloud return controllers.use('newcloud').render() utils.info("Using controller '{}'".format(existing_controller)) app.current_controller = existing_controller app.current_model = petname.Name() utils.info("Creating new juju model named '{}', " "please wait.".format(app.current_model)) juju.add_model(app.current_model, app.current_controller) return controllers.use('deploy').render()
def main(): opts = parse_options(sys.argv[1:]) if os.geteuid() == 0: utils.info("") utils.info("This should _not_ be run as root or with sudo.") utils.info("") sys.exit(1) if not os.path.isdir(opts.cache_dir): os.makedirs(opts.cache_dir) # Application Config app.config = {'metadata': None} app.argv = opts app.log = setup_logging(app, os.path.join(opts.cache_dir, 'conjure-down.log'), opts.debug) # Make sure juju paths are setup juju.set_bin_path() app.env = os.environ.copy() app.loop = asyncio.get_event_loop() app.loop.add_signal_handler(signal.SIGINT, events.Shutdown.set) app.loop.create_task(events.shutdown_watcher()) app.loop.create_task(_start()) try: if app.argv.controller and app.argv.model: app.headless = True app.ui = None app.env['CONJURE_UP_HEADLESS'] = "1" app.loop.run_forever() else: app.ui = ConjureUI() EventLoop.build_loop(app.ui, STYLES, unhandled_input=events.unhandled_input) EventLoop.run() finally: # explicitly close aysncio event loop to avoid hitting the # following issue due to signal handlers added by # asyncio.create_subprocess_exec being cleaned up during final # garbage collection: https://github.com/python/asyncio/issues/396 app.loop.close()
def render(self, results): common.write_results(results, self.save_path) utils.info("Installation of your big software is now complete.")
def main(): opts = parse_options(sys.argv[1:]) opt_defaults = parse_options([]) if os.geteuid() == 0: utils.info("") utils.info("This should _not_ be run as root or with sudo.") utils.info("") sys.exit(1) if not os.path.isdir(opts.cache_dir): os.makedirs(opts.cache_dir) # Application Config app.config = {'metadata': None} # Load conjurefile, merge any overridding options from argv if not opts.conf_file: opts.conf_file = [] if pathlib.Path('~/.config/conjure-up.conf').expanduser().exists(): opts.conf_file.insert( 0, pathlib.Path('~/.config/conjure-up.conf').expanduser()) if (pathlib.Path('.') / 'Conjurefile').exists(): opts.conf_file.insert(0, pathlib.Path('.') / 'Conjurefile') for conf in opts.conf_file: if not conf.exists(): print("Unable to locate config {} for processing.".format( str(conf))) sys.exit(1) app.conjurefile = Conjurefile.load(opts.conf_file) app.conjurefile.merge_argv(opts, opt_defaults) app.log = setup_logging(app, os.path.join(opts.cache_dir, 'conjure-down.log'), opts.debug) app.no_track = app.conjurefile['no-track'] app.no_report = app.conjurefile['no-report'] app.env = os.environ.copy() # Make sure juju paths are setup juju.set_bin_path() app.loop = asyncio.get_event_loop() app.loop.add_signal_handler(signal.SIGINT, events.Shutdown.set) app.loop.create_task(events.shutdown_watcher()) app.loop.create_task(_start()) try: if app.conjurefile['controller'] and app.conjurefile['model']: app.headless = True app.ui = None app.env['CONJURE_UP_HEADLESS'] = "1" app.loop.run_forever() else: app.ui = ConjureUI() EventLoop.build_loop(app.ui, STYLES, unhandled_input=events.unhandled_input) EventLoop.run() finally: # explicitly close aysncio event loop to avoid hitting the # following issue due to signal handlers added by # asyncio.create_subprocess_exec being cleaned up during final # garbage collection: https://github.com/python/asyncio/issues/396 app.loop.close()
def main(): opts = parse_options(sys.argv[1:]) if os.geteuid() == 0: utils.info("") utils.info("This should _not_ be run as root or with sudo.") utils.info("") sys.exit(1) if not os.path.isdir('conjure'): utils.error('Unable to find required conjure directory for spell.' 'Please make sure you are in the correct directory.') sys.exit(1) if not os.path.isfile('conjure/metadata.json'): utils.error('Unable to find conjure metadata.') sys.exit(1) # Application Config app.argv = opts app.log = setup_logging("conjure-up/craft", opts.debug) app.env = os.environ.copy() utils.info("Pushing spell to registry") try: spell = charm.push(opts.path) utils.info("Applying conjure-up metadata") charm.publish(spell) charm.grant(spell) with open('conjure/metadata.json') as fp: metadata = json.load(fp) charm.set_metadata(spell, metadata) utils.info("Success.") except Exception as e: utils.error("Unable to push to registry: {}".format(e)) sys.exit(1)
def main(): opts = parse_options(sys.argv[1:]) spell = os.path.basename(os.path.abspath(opts.spell)) if not os.path.isdir(opts.cache_dir): os.makedirs(opts.cache_dir) if os.geteuid() == 0: utils.info("") utils.info("This should _not_ be run as root or with sudo.") utils.info("") sys.exit(1) # Application Config app.config = {'metadata': None} app.argv = opts app.log = setup_logging("conjure-up/{}".format(spell), os.path.join(opts.cache_dir, 'conjure-up.log'), opts.debug) # Setup proxy apply_proxy() app.session_id = os.getenv('CONJURE_TEST_SESSION_ID', '{}/{}'.format( spell, str(uuid.uuid4()))) global_config_filename = app.argv.global_config_file if not os.path.exists(global_config_filename): # fallback to source tree location global_config_filename = os.path.join(os.path.dirname(__file__), "../etc/conjure-up.conf") if not os.path.exists(global_config_filename): utils.error("Could not find {}.".format(global_config_filename)) sys.exit(1) with open(global_config_filename) as fp: global_conf = yaml.safe_load(fp.read()) app.global_config = global_conf spells_dir = app.argv.spells_dir if not os.path.exists(spells_dir): spells_dir = os.path.join(os.path.dirname(__file__), "../spells") app.config['spells-dir'] = spells_dir spells_index_path = os.path.join(app.config['spells-dir'], 'spells-index.yaml') with open(spells_index_path) as fp: app.spells_index = yaml.safe_load(fp.read()) spell_name = spell app.endpoint_type = detect_endpoint(opts.spell) if app.endpoint_type == EndpointType.LOCAL_SEARCH: spells = utils.find_spells_matching(opts.spell) if len(spells) == 0: utils.error("Can't find a spell matching '{}'".format(opts.spell)) sys.exit(1) # One result means it was a direct match and we can copy it # now. Changing the endpoint type then stops us from showing # the picker UI. More than one result means we need to show # the picker UI and will defer the copy to # SpellPickerController.finish(), so nothing to do here. if len(spells) == 1: print("found spell {}".format(spells[0])) utils.set_chosen_spell(spell_name, os.path.join(opts.cache_dir, spell_name)) download_local(os.path.join(app.config['spells-dir'], spell_name), app.config['spell-dir']) utils.set_spell_metadata() app.endpoint_type = EndpointType.LOCAL_DIR # download spell if necessary elif app.endpoint_type == EndpointType.LOCAL_DIR: if not os.path.isdir(opts.spell): utils.warning("Could not find spell {}".format(opts.spell)) sys.exit(1) spell_name = os.path.basename(os.path.abspath(spell)) utils.set_chosen_spell(spell_name, path.join(opts.cache_dir, spell_name)) download_local(opts.spell, app.config['spell-dir']) utils.set_spell_metadata() elif app.endpoint_type in [EndpointType.VCS, EndpointType.HTTP]: utils.set_chosen_spell(spell, path.join(opts.cache_dir, spell)) remote = get_remote_url(opts.spell) if remote is None: utils.warning("Can't guess URL matching '{}'".format(opts.spell)) sys.exit(1) download(remote, app.config['spell-dir'], True) utils.set_spell_metadata() if app.argv.status_only: if not juju.model_available(): utils.error("Attempted to access the status screen without " "an available Juju model.\n" "Please select a model using 'juju switch' or " "create a new controller using 'juju bootstrap'.") sys.exit(1) app.env = os.environ.copy() app.env['CONJURE_UP_SPELL'] = spell_name if app.argv.cloud: if app.endpoint_type in [None, EndpointType.LOCAL_SEARCH]: utils.error("Please specify a spell for headless mode.") sys.exit(1) app.headless = True app.ui = None app.env['CONJURE_UP_HEADLESS'] = "1" _start() else: app.ui = ConjureUI() EventLoop.build_loop(app.ui, STYLES, unhandled_input=unhandled_input) EventLoop.set_alarm_in(0.05, _start) EventLoop.run()
def main(): if os.geteuid() == 0: utils.info("") utils.info("This should _not_ be run as root or with sudo.") utils.info("") sys.exit(1) utils.set_terminal_title("conjure-up") opts = parse_options(sys.argv[1:]) spell = os.path.basename(os.path.abspath(opts.spell)) if not os.path.isdir(opts.cache_dir): os.makedirs(opts.cache_dir) # Application Config app.config = {'metadata': None} app.argv = opts app.log = setup_logging(app, os.path.join(opts.cache_dir, 'conjure-up.log'), opts.debug) # Grab current LXD and Juju versions app.log.debug("LXD version: {}, " "Juju version: {}, " "conjure-up version: {}".format( utils.lxd_version(), utils.juju_version(), VERSION)) # Setup proxy apply_proxy() app.session_id = os.getenv('CONJURE_TEST_SESSION_ID', str(uuid.uuid4())) spells_dir = app.argv.spells_dir app.config['spells-dir'] = spells_dir spells_index_path = os.path.join(app.config['spells-dir'], 'spells-index.yaml') spells_registry_branch = os.getenv('CONJUREUP_REGISTRY_BRANCH', 'stable') if not app.argv.nosync: if not os.path.exists(spells_dir): utils.info("No spells found, syncing from registry, please wait.") try: download_or_sync_registry( app.argv.registry, spells_dir, branch=spells_registry_branch) except subprocess.CalledProcessError as e: if not os.path.exists(spells_dir): utils.error("Could not load from registry") sys.exit(1) app.log.debug( 'Could not sync spells from github: {}'.format(e)) else: if not os.path.exists(spells_index_path): utils.error( "You opted to not sync from the spells registry, however, " "we could not find any suitable spells in: " "{}".format(spells_dir)) sys.exit(1) with open(spells_index_path) as fp: app.spells_index = yaml.safe_load(fp.read()) spell_name = spell app.endpoint_type = detect_endpoint(opts.spell) app.env = os.environ.copy() if app.endpoint_type == EndpointType.LOCAL_SEARCH: spells = utils.find_spells_matching(opts.spell) if len(spells) == 0: utils.error("Can't find a spell matching '{}'".format(opts.spell)) sys.exit(1) # One result means it was a direct match and we can copy it # now. Changing the endpoint type then stops us from showing # the picker UI. More than one result means we need to show # the picker UI and will defer the copy to # SpellPickerController.finish(), so nothing to do here. if len(spells) == 1: app.log.debug("found spell {}".format(spells[0][1])) spell = spells[0][1] utils.set_chosen_spell(spell_name, os.path.join(opts.cache_dir, spell['key'])) download_local(os.path.join(app.config['spells-dir'], spell['key']), app.config['spell-dir']) utils.set_spell_metadata() app.endpoint_type = EndpointType.LOCAL_DIR # download spell if necessary elif app.endpoint_type == EndpointType.LOCAL_DIR: if not os.path.isdir(opts.spell): utils.warning("Could not find spell {}".format(opts.spell)) sys.exit(1) if not os.path.exists(os.path.join(opts.spell, "metadata.yaml")): utils.warning("'{}' does not appear to be a spell. " "{}/metadata.yaml was not found.".format( opts.spell, opts.spell)) sys.exit(1) spell_name = os.path.basename(os.path.abspath(spell)) utils.set_chosen_spell(spell_name, path.join(opts.cache_dir, spell_name)) download_local(opts.spell, app.config['spell-dir']) utils.set_spell_metadata() elif app.endpoint_type in [EndpointType.VCS, EndpointType.HTTP]: utils.set_chosen_spell(spell, path.join(opts.cache_dir, spell)) remote = get_remote_url(opts.spell) if remote is None: utils.warning("Can't guess URL matching '{}'".format(opts.spell)) sys.exit(1) download(remote, app.config['spell-dir'], True) utils.set_spell_metadata() app.env['CONJURE_UP_CACHEDIR'] = app.argv.cache_dir if app.argv.show_env: if not app.argv.cloud: utils.error("You must specify a cloud for headless mode.") sys.exit(1) if app.endpoint_type in [None, EndpointType.LOCAL_SEARCH]: utils.error("Please specify a spell for headless mode.") sys.exit(1) show_env() track_screen("Application Start") track_event("OS", platform.platform(), "") app.loop = asyncio.get_event_loop() app.loop.add_signal_handler(signal.SIGINT, events.Shutdown.set) try: if app.argv.cloud: if '/' in app.argv.cloud: parse_cli_cloud = app.argv.cloud.split('/') app.current_cloud, app.current_region = parse_cli_cloud app.log.debug( "Region found {} for cloud {}".format(app.current_cloud, app.current_region)) else: app.current_cloud = app.argv.cloud if app.endpoint_type in [None, EndpointType.LOCAL_SEARCH]: utils.error("Please specify a spell for headless mode.") sys.exit(1) app.headless = True app.ui = None app.env['CONJURE_UP_HEADLESS'] = "1" app.loop.create_task(events.shutdown_watcher()) app.loop.create_task(_start()) app.loop.run_forever() else: app.ui = ConjureUI() EventLoop.build_loop(app.ui, STYLES, unhandled_input=events.unhandled_input) app.loop.create_task(events.shutdown_watcher()) app.loop.create_task(_start()) EventLoop.run() finally: # explicitly close asyncio event loop to avoid hitting the # following issue due to signal handlers added by # asyncio.create_subprocess_exec being cleaned up during final # garbage collection: https://github.com/python/asyncio/issues/396 app.loop.close() sys.exit(app.exit_code)
def main(): opts = parse_options(sys.argv[1:]) spell = os.path.basename(os.path.abspath(opts.spell)) if not os.path.isdir(opts.cache_dir): os.makedirs(opts.cache_dir) if os.geteuid() == 0: utils.info("") utils.info("This should _not_ be run as root or with sudo.") utils.info("") sys.exit(1) # Application Config app.config = {'metadata': None} app.argv = opts app.log = setup_logging("conjure-up/{}".format(spell), os.path.join(opts.cache_dir, 'conjure-up.log'), opts.debug) # Setup proxy apply_proxy() app.session_id = os.getenv('CONJURE_TEST_SESSION_ID', '{}/{}'.format(spell, str(uuid.uuid4()))) global_config_filename = app.argv.global_config_file if not os.path.exists(global_config_filename): # fallback to source tree location global_config_filename = os.path.join(os.path.dirname(__file__), "../etc/conjure-up.conf") if not os.path.exists(global_config_filename): utils.error("Could not find {}.".format(global_config_filename)) sys.exit(1) with open(global_config_filename) as fp: global_conf = yaml.safe_load(fp.read()) app.global_config = global_conf spells_dir = app.argv.spells_dir if not os.path.exists(spells_dir): spells_dir = os.path.join(os.path.dirname(__file__), "../spells") app.config['spells-dir'] = spells_dir spells_index_path = os.path.join(app.config['spells-dir'], 'spells-index.yaml') with open(spells_index_path) as fp: app.spells_index = yaml.safe_load(fp.read()) spell_name = spell app.endpoint_type = detect_endpoint(opts.spell) if app.endpoint_type == EndpointType.LOCAL_SEARCH: spells = utils.find_spells_matching(opts.spell) if len(spells) == 0: utils.error("Can't find a spell matching '{}'".format(opts.spell)) sys.exit(1) # One result means it was a direct match and we can copy it # now. Changing the endpoint type then stops us from showing # the picker UI. More than one result means we need to show # the picker UI and will defer the copy to # SpellPickerController.finish(), so nothing to do here. if len(spells) == 1: app.log.debug("found spell {}".format(spells[0])) spell = spells[0] utils.set_chosen_spell(spell_name, os.path.join(opts.cache_dir, spell['key'])) download_local( os.path.join(app.config['spells-dir'], spell['key']), app.config['spell-dir']) utils.set_spell_metadata() app.endpoint_type = EndpointType.LOCAL_DIR # download spell if necessary elif app.endpoint_type == EndpointType.LOCAL_DIR: if not os.path.isdir(opts.spell): utils.warning("Could not find spell {}".format(opts.spell)) sys.exit(1) spell_name = os.path.basename(os.path.abspath(spell)) utils.set_chosen_spell(spell_name, path.join(opts.cache_dir, spell_name)) download_local(opts.spell, app.config['spell-dir']) utils.set_spell_metadata() elif app.endpoint_type in [EndpointType.VCS, EndpointType.HTTP]: utils.set_chosen_spell(spell, path.join(opts.cache_dir, spell)) remote = get_remote_url(opts.spell) if remote is None: utils.warning("Can't guess URL matching '{}'".format(opts.spell)) sys.exit(1) download(remote, app.config['spell-dir'], True) utils.set_spell_metadata() if app.argv.status_only: if not juju.model_available(): utils.error("Attempted to access the status screen without " "an available Juju model.\n" "Please select a model using 'juju switch' or " "create a new controller using 'juju bootstrap'.") sys.exit(1) app.env = os.environ.copy() app.env['CONJURE_UP_SPELL'] = spell_name if app.argv.cloud: if app.endpoint_type in [None, EndpointType.LOCAL_SEARCH]: utils.error("Please specify a spell for headless mode.") sys.exit(1) app.headless = True app.ui = None app.env['CONJURE_UP_HEADLESS'] = "1" _start() else: app.ui = ConjureUI() EventLoop.build_loop(app.ui, STYLES, unhandled_input=unhandled_input) EventLoop.set_alarm_in(0.05, _start) EventLoop.run()
def main(): if os.geteuid() == 0: print("") print(" !! This should _not_ be run as root or with sudo. !!") print("") sys.exit(1) # Verify we can access ~/.local/share/juju if it exists juju_dir = pathlib.Path('~/.local/share/juju').expanduser() if juju_dir.exists(): try: for f in juju_dir.iterdir(): if f.is_file(): f.read_text() except PermissionError: print("") print(" !! Unable to read from ~/.local/share/juju, please " "double check your permissions on that directory " "and its files. !!") print("") sys.exit(1) utils.set_terminal_title("conjure-up") opts = parse_options(sys.argv[1:]) spell = os.path.basename(os.path.abspath(opts.spell)) if not os.path.isdir(opts.cache_dir): os.makedirs(opts.cache_dir) # Application Config os.environ['UNIT_STATE_DB'] = os.path.join(opts.cache_dir, '.state.db') app.state = unitdata.kv() app.env = os.environ.copy() app.config = {'metadata': None} app.argv = opts app.log = setup_logging(app, os.path.join(opts.cache_dir, 'conjure-up.log'), opts.debug) if app.argv.conf_file.expanduser().exists(): conf = configparser.ConfigParser() conf.read_string(app.argv.conf_file.expanduser().read_text()) app.notrack = conf.getboolean('REPORTING', 'notrack', fallback=False) app.noreport = conf.getboolean('REPORTING', 'noreport', fallback=False) if app.argv.notrack: app.notrack = True if app.argv.noreport: app.noreport = True # Grab current LXD and Juju versions app.log.debug("Juju version: {}, " "conjure-up version: {}".format(utils.juju_version(), VERSION)) # Setup proxy apply_proxy() app.session_id = os.getenv('CONJURE_TEST_SESSION_ID', str(uuid.uuid4())) spells_dir = app.argv.spells_dir app.config['spells-dir'] = spells_dir spells_index_path = os.path.join(app.config['spells-dir'], 'spells-index.yaml') spells_registry_branch = os.getenv('CONJUREUP_REGISTRY_BRANCH', 'stable') if not app.argv.nosync: if not os.path.exists(spells_dir): utils.info("No spells found, syncing from registry, please wait.") try: download_or_sync_registry(app.argv.registry, spells_dir, branch=spells_registry_branch) except subprocess.CalledProcessError as e: if not os.path.exists(spells_dir): utils.error("Could not load from registry") sys.exit(1) app.log.debug('Could not sync spells from github: {}'.format(e)) else: if not os.path.exists(spells_index_path): utils.error( "You opted to not sync from the spells registry, however, " "we could not find any suitable spells in: " "{}".format(spells_dir)) sys.exit(1) with open(spells_index_path) as fp: app.spells_index = yaml.safe_load(fp.read()) spell_name = spell app.endpoint_type = detect_endpoint(opts.spell) if app.endpoint_type == EndpointType.LOCAL_SEARCH: spells = utils.find_spells_matching(opts.spell) if len(spells) == 0: utils.error("Can't find a spell matching '{}'".format(opts.spell)) sys.exit(1) # One result means it was a direct match and we can copy it # now. Changing the endpoint type then stops us from showing # the picker UI. More than one result means we need to show # the picker UI and will defer the copy to # SpellPickerController.finish(), so nothing to do here. if len(spells) == 1: app.log.debug("found spell {}".format(spells[0][1])) spell = spells[0][1] utils.set_chosen_spell(spell_name, os.path.join(opts.cache_dir, spell['key'])) download_local( os.path.join(app.config['spells-dir'], spell['key']), app.config['spell-dir']) utils.set_spell_metadata() StepModel.load_spell_steps() AddonModel.load_spell_addons() app.endpoint_type = EndpointType.LOCAL_DIR # download spell if necessary elif app.endpoint_type == EndpointType.LOCAL_DIR: if not os.path.isdir(opts.spell): utils.warning("Could not find spell {}".format(opts.spell)) sys.exit(1) if not os.path.exists(os.path.join(opts.spell, "metadata.yaml")): utils.warning("'{}' does not appear to be a spell. " "{}/metadata.yaml was not found.".format( opts.spell, opts.spell)) sys.exit(1) spell_name = os.path.basename(os.path.abspath(spell)) utils.set_chosen_spell(spell_name, path.join(opts.cache_dir, spell_name)) download_local(opts.spell, app.config['spell-dir']) utils.set_spell_metadata() StepModel.load_spell_steps() AddonModel.load_spell_addons() elif app.endpoint_type in [EndpointType.VCS, EndpointType.HTTP]: utils.set_chosen_spell(spell, path.join(opts.cache_dir, spell)) remote = get_remote_url(opts.spell) if remote is None: utils.warning("Can't guess URL matching '{}'".format(opts.spell)) sys.exit(1) download(remote, app.config['spell-dir'], True) utils.set_spell_metadata() StepModel.load_spell_steps() AddonModel.load_spell_addons() app.env['CONJURE_UP_CACHEDIR'] = app.argv.cache_dir if app.argv.show_env: if app.endpoint_type in [None, EndpointType.LOCAL_SEARCH]: utils.error("Please specify a spell for headless mode.") sys.exit(1) show_env() app.sentry = raven.Client( dsn=SENTRY_DSN, release=VERSION, transport=RequestsHTTPTransport, processors=('conjureup.utils.SanitizeDataProcessor', )) track_screen("Application Start") track_event("OS", platform.platform(), "") app.loop = asyncio.get_event_loop() app.loop.add_signal_handler(signal.SIGINT, events.Shutdown.set) try: if app.argv.cloud: cloud = None region = None if '/' in app.argv.cloud: parse_cli_cloud = app.argv.cloud.split('/') cloud, region = parse_cli_cloud app.log.debug("Region found {} for cloud {}".format( cloud, region)) else: cloud = app.argv.cloud cloud_types = juju.get_cloud_types_by_name() if cloud not in cloud_types: utils.error('Unknown cloud: {}'.format(cloud)) sys.exit(1) if app.endpoint_type in [None, EndpointType.LOCAL_SEARCH]: utils.error("Please specify a spell for headless mode.") sys.exit(1) app.provider = load_schema(cloud_types[cloud]) try: app.provider.load(cloud) except SchemaErrorUnknownCloud as e: utils.error(e) sys.exit(1) if region: app.provider.region = region app.headless = True app.ui = None app.env['CONJURE_UP_HEADLESS'] = "1" app.loop.create_task(events.shutdown_watcher()) app.loop.create_task(_start()) app.loop.run_forever() else: app.ui = ConjureUI() EventLoop.build_loop(app.ui, STYLES, unhandled_input=events.unhandled_input) app.loop.create_task(events.shutdown_watcher()) app.loop.create_task(_start()) EventLoop.run() finally: # explicitly close asyncio event loop to avoid hitting the # following issue due to signal handlers added by # asyncio.create_subprocess_exec being cleaned up during final # garbage collection: https://github.com/python/asyncio/issues/396 app.loop.close() sys.exit(app.exit_code)
def render(self): utils.info("Waiting for bootstrap to finish") self.finish()
def main(): opts = parse_options(sys.argv[1:]) if os.geteuid() == 0: utils.info("") utils.info("This should _not_ be run as root or with sudo.") utils.info("") sys.exit(1) if not os.path.isdir('conjure'): utils.error('Unable to find required conjure directory for spell.' 'Please make sure you are in the correct directory.') sys.exit(1) if not os.path.isfile('metadata.yaml'): utils.error('Unable to find conjure metadata.') sys.exit(1) # Application Config app.argv = opts app.log = setup_logging("conjure-up/craft", opts.debug) app.env = os.environ.copy() utils.info("Pushing spell to registry") try: spell = charm.push(opts.path) utils.info("Applying conjure-up metadata") charm.publish(spell) charm.grant(spell) with open('conjure/metadata.yaml') as fp: metadata = yaml.safe_load(fp.read()) charm.set_metadata(spell, metadata) utils.info("Success.") except Exception as e: utils.error("Unable to push to registry: {}".format(e)) sys.exit(1)
def render(self): utils.info("") utils.info("Unable to find a LXD bridge, please run `lxd init` " "and then re-run conjure-up.") utils.info("") sys.exit(1)
def main(): if os.geteuid() == 0: print("") print(" !! This should _not_ be run as root or with sudo. !!") print("") sys.exit(1) # Verify we can access ~/.local/share/juju if it exists juju_dir = pathlib.Path('~/.local/share/juju').expanduser() if juju_dir.exists(): try: for f in juju_dir.iterdir(): if f.is_file(): f.read_text() except PermissionError: print("") print(" !! Unable to read from ~/.local/share/juju, please " "double check your permissions on that directory " "and its files. !!") print("") sys.exit(1) utils.set_terminal_title("conjure-up") opts = parse_options(sys.argv[1:]) opt_defaults = parse_options([]) # Load conjurefile, merge any overridding options from argv if not opts.conf_file: opts.conf_file = [] if pathlib.Path('~/.config/conjure-up.conf').expanduser().exists(): opts.conf_file.insert( 0, pathlib.Path('~/.config/conjure-up.conf').expanduser()) if (pathlib.Path('.') / 'Conjurefile').exists(): opts.conf_file.insert(0, pathlib.Path('.') / 'Conjurefile') for conf in opts.conf_file: if not conf.exists(): print("Unable to locate config {} for processing.".format( str(conf))) sys.exit(1) try: app.conjurefile = Conjurefile.load(opts.conf_file) except ValueError as e: print(str(e)) sys.exit(1) app.conjurefile.merge_argv(opts, opt_defaults) if app.conjurefile['gen-config']: Conjurefile.print_tpl() sys.exit(0) spell = os.path.basename(os.path.abspath(app.conjurefile['spell'])) if not os.path.isdir(app.conjurefile['cache-dir']): os.makedirs(app.conjurefile['cache-dir']) # Application Config kv_db = os.path.join(app.conjurefile['cache-dir'], '.state.db') app.state = KV(kv_db) app.env = os.environ.copy() app.env['KV_DB'] = kv_db app.config = {'metadata': None} app.log = setup_logging(app, os.path.join(app.conjurefile['cache-dir'], 'conjure-up.log'), app.conjurefile.get('debug', False)) # Make sure juju paths are setup juju.set_bin_path() juju.set_wait_path() app.no_track = app.conjurefile['no-track'] app.no_report = app.conjurefile['no-report'] # Grab current LXD and Juju versions app.log.debug("Juju version: {}, " "conjure-up version: {}".format( utils.juju_version(), VERSION)) # Setup proxy apply_proxy() app.session_id = os.getenv('CONJURE_TEST_SESSION_ID', str(uuid.uuid4())) spells_dir = app.conjurefile['spells-dir'] app.config['spells-dir'] = spells_dir spells_index_path = os.path.join(app.config['spells-dir'], 'spells-index.yaml') spells_registry_branch = os.getenv('CONJUREUP_REGISTRY_BRANCH', 'master') if not app.conjurefile['no-sync']: if not os.path.exists(spells_dir): utils.info("No spells found, syncing from registry, please wait.") try: download_or_sync_registry( app.conjurefile['registry'], spells_dir, branch=spells_registry_branch) except subprocess.CalledProcessError as e: if not os.path.exists(spells_dir): utils.error("Could not load from registry") sys.exit(1) app.log.debug( 'Could not sync spells from github: {}'.format(e)) else: if not os.path.exists(spells_index_path): utils.error( "You opted to not sync from the spells registry, however, " "we could not find any suitable spells in: " "{}".format(spells_dir)) sys.exit(1) with open(spells_index_path) as fp: app.spells_index = yaml.safe_load(fp.read()) addons_aliases_index_path = os.path.join(app.config['spells-dir'], 'addons-aliases.yaml') if os.path.exists(addons_aliases_index_path): with open(addons_aliases_index_path) as fp: app.addons_aliases = yaml.safe_load(fp.read()) spell_name = spell app.endpoint_type = detect_endpoint(app.conjurefile['spell']) if app.conjurefile['spell'] != consts.UNSPECIFIED_SPELL: app.spell_given = True # Check if spell is actually an addon addon = utils.find_addons_matching(app.conjurefile['spell']) if addon: app.log.debug("addon found, setting required spell") utils.set_chosen_spell(addon['spell'], os.path.join(app.conjurefile['cache-dir'], addon['spell'])) download_local(os.path.join(app.config['spells-dir'], addon['spell']), app.config['spell-dir']) utils.set_spell_metadata() StepModel.load_spell_steps() AddonModel.load_spell_addons() app.selected_addons = addon['addons'] app.alias_given = True controllers.setup_metadata_controller() app.endpoint_type = EndpointType.LOCAL_DIR elif app.endpoint_type == EndpointType.LOCAL_SEARCH: spells = utils.find_spells_matching(app.conjurefile['spell']) if len(spells) == 0: utils.error("Can't find a spell matching '{}'".format( app.conjurefile['spell'])) sys.exit(1) # One result means it was a direct match and we can copy it # now. Changing the endpoint type then stops us from showing # the picker UI. More than one result means we need to show # the picker UI and will defer the copy to # SpellPickerController.finish(), so nothing to do here. if len(spells) == 1: app.log.debug("found spell {}".format(spells[0][1])) spell = spells[0][1] utils.set_chosen_spell(spell_name, os.path.join(app.conjurefile['cache-dir'], spell['key'])) download_local(os.path.join(app.config['spells-dir'], spell['key']), app.config['spell-dir']) utils.set_spell_metadata() StepModel.load_spell_steps() AddonModel.load_spell_addons() app.endpoint_type = EndpointType.LOCAL_DIR # download spell if necessary elif app.endpoint_type == EndpointType.LOCAL_DIR: if not os.path.isdir(app.conjurefile['spell']): utils.warning("Could not find spell {}".format( app.conjurefile['spell'])) sys.exit(1) if not os.path.exists(os.path.join(app.conjurefile['spell'], "metadata.yaml")): utils.warning("'{}' does not appear to be a spell. " "{}/metadata.yaml was not found.".format( app.conjurefile['spell'], app.conjurefile['spell'])) sys.exit(1) spell_name = os.path.basename(os.path.abspath(spell)) utils.set_chosen_spell(spell_name, path.join(app.conjurefile['cache-dir'], spell_name)) download_local(app.conjurefile['spell'], app.config['spell-dir']) utils.set_spell_metadata() StepModel.load_spell_steps() AddonModel.load_spell_addons() elif app.endpoint_type in [EndpointType.VCS, EndpointType.HTTP]: utils.set_chosen_spell(spell, path.join( app.conjurefile['cache-dir'], spell)) remote = get_remote_url(app.conjurefile['spell']) if remote is None: utils.warning("Can't guess URL matching '{}'".format( app.conjurefile['spell'])) sys.exit(1) download(remote, app.config['spell-dir'], True) utils.set_spell_metadata() StepModel.load_spell_steps() AddonModel.load_spell_addons() app.env['CONJURE_UP_CACHEDIR'] = app.conjurefile['cache-dir'] app.env['PATH'] = "/snap/bin:{}".format(app.env['PATH']) if app.conjurefile['show-env']: if app.endpoint_type in [None, EndpointType.LOCAL_SEARCH]: utils.error("Please specify a spell for headless mode.") sys.exit(1) show_env() app.sentry = raven.Client( dsn=SENTRY_DSN, release=VERSION, transport=RequestsHTTPTransport, processors=( 'conjureup.utils.SanitizeDataProcessor', ) ) track_screen("Application Start") track_event("OS", platform.platform(), "") app.loop = asyncio.get_event_loop() app.loop.add_signal_handler(signal.SIGINT, events.Shutdown.set) # Enable charmstore querying app.juju.charmstore = CharmStore(app.loop) try: if app.conjurefile.is_valid: cloud = None region = None if '/' in app.conjurefile['cloud']: parse_cli_cloud = app.conjurefile['cloud'].split('/') cloud, region = parse_cli_cloud app.log.debug( "Region found {} for cloud {}".format(cloud, region)) else: cloud = app.conjurefile['cloud'] cloud_types = juju.get_cloud_types_by_name() if cloud not in cloud_types: utils.error('Unknown cloud: {}'.format(cloud)) sys.exit(1) if app.endpoint_type in [None, EndpointType.LOCAL_SEARCH]: utils.error("Please specify a spell for headless mode.") sys.exit(1) app.provider = load_schema(cloud_types[cloud]) try: app.provider.load(cloud) except errors.SchemaCloudError as e: utils.error(e) sys.exit(1) if region: app.provider.region = region app.headless = True app.ui = None app.env['CONJURE_UP_HEADLESS'] = "1" app.loop.create_task(events.shutdown_watcher()) app.loop.create_task(_start()) app.loop.run_forever() else: app.ui = ConjureUI() app.ui.set_footer('Press ? for help') EventLoop.build_loop(app.ui, STYLES, unhandled_input=events.unhandled_input, handle_mouse=False) app.loop.create_task(events.shutdown_watcher()) app.loop.create_task(_start()) EventLoop.run() finally: # explicitly close asyncio event loop to avoid hitting the # following issue due to signal handlers added by # asyncio.create_subprocess_exec being cleaned up during final # garbage collection: https://github.com/python/asyncio/issues/396 app.loop.close() sys.exit(app.exit_code)