def read(self, file, variables_cmd): conf = Controller.get().CONF config = configparser.RawConfigParser() config.optionxform = str if not os.path.isfile(file): raise IOError("file {0} not found".format(file)) """ Validate option in answer file""" config.read(file) if not config.has_section('general'): raise KeyError("answer file {0} doesn't have general" " section".format(file)) conf_file = dict(config['general']) conf_file.update(variables_cmd) # override variables conf.update(conf_file) try: Controller.get().validate_groups(conf_file) except Exception as e: raise e all_args = Controller.get().get_all_arguments() for non_supported in (set(conf_file) - set(all_args)): LOG.warn("clearstack: variable {0} is not" " supported yet".format(non_supported))
def transfer_file(self, file, dest_path, ip): try: connection = self.connect(self.ssh_user, self.ssh_private_key, ip) sftp = connection.open_sftp() except paramiko.ssh_exception.SSHException: raise Exception("cannot send {0} to {1}, please check" " your ssh connection".format(file, ip)) if os.path.isdir(file): parent_dir = "/".join(file.split('/')[:-1]) try: sftp.mkdir(dest_path) except IOError: pass for dirpath, dirnames, filenames in os.walk(file): remote_path = dest_path + dirpath.split(parent_dir)[1] try: sftp.mkdir(remote_path) except: LOG.info("clearstack: Directory {0} is already created" "in remote host".format(remote_path)) for filename in filenames: local_path = os.path.join(dirpath, filename) remote_filepath = os.path.join(remote_path, filename) sftp.put(local_path, remote_filepath) else: filename = file.split('/')[-1] sftp.put(file, "{0}/{1}".format(dest_path, filename)) connection.close()
def load_sequences(): load_plugins() for plugin in Controller.get().get_all_plugins(): try: getattr(plugin, "init_sequences")() except AttributeError: LOG.debug("missing attribute: init_sequences in %s", plugin.__file__)
def run(self): LOG.info(self.description) if self.function_args: if not self.function(*self.function_args): raise Exception("error running {0}({1})" .format(self.function.__name__, self.function_args)) else: if not self.function(): raise Exception("error running {0}" .format(self.function.__name__))
def load_plugins(): """ return if plugins already are loaded """ if Controller.get().get_all_plugins(): return path = "plugins" base_module = "clearstack.{0}".format(path) directory = "{0}/{1}".format(os.path.dirname( os.path.realpath(__file__)), path) rx_val = r'^[a-zA-Z]+_[0-9]{3}\.py$' files = [fd for fd in os.listdir(directory) if re.match(rx_val, fd)] for fd in sorted(files, key=_get_weight): plugin = import_module("{0}.{1}".format(base_module, fd.split(".")[0])) Controller.get().add_plugin(plugin) try: getattr(plugin, "init_config")() except AttributeError: LOG.debug("missing attribute: init_config in %s", plugin.__file__)
def get_logs(self, _hosts): hosts = set(_hosts) basename = os.path.splitext(util.LOG_FILE)[0] connection = None util.remove_localhost(hosts) for host in hosts: new_name = "{0}-{1}.log".format(basename, host) try: connection = self.connect(self.ssh_user, self.ssh_private_key, host) sftp = connection.open_sftp() sftp.get(util.HOST_LOG_FILE, new_name) except: LOG.warning("clearstack: cannot get log file from {0}".format( host)) finally: if connection: connection.close()
def run_recipe(self, recipe_file, host): connection = None interpreter = "python3" if recipe_file.endswith('.sh'): interpreter = "bash -f" try: connection = self.connect(self.ssh_user, self.ssh_private_key, host) cmd = "source /root/.bashrc 2> /dev/null;" \ "source /usr/share/defaults/etc/profile 2> /dev/null;" \ "{0} {1}".format(interpreter, recipe_file) stdin, stdout, stderr = self.run_command(connection, cmd) except Exception as e: LOG.error("clearstack: an error has occurred in {0}," " please check logs for more information" .format(host)) raise e finally: if connection: connection.close()
def main(self, argv): self.parser = self.get_base_parser() run_setup.add_arguments(self.parser) (options, args) = self.parser.parse_known_args(argv) utils.setup_debugging(options.debug) LOG.debug('Starting clearstack') if not argv or options.help: self.do_help(options) return 0 if options.gen_keys: LOG.debug('generating ssh keys') utils.generate_ssh_keys(options.gen_keys) # todo: fix # if options.allinone: # LOG.debug('testing root access') # if os.geteuid() != 0: # LOG.error("clearstack: error: you need to have root access") # sys.exit(1) """ Save user's variables, used to read/write answerfile """ variables_cmd = {k: v for (k, v) in options.__dict__.items() if v is not None and k.startswith("CONFIG_")} ansfile = AnswerFile.get() if options.gen_answer_file: LOG.debug('generating answer file') ansfile.generate(options.gen_answer_file, variables_cmd) if options.answer_file: try: LOG.debug('Reading answer file') ansfile.read(options.answer_file, variables_cmd) LOG.debug('Running all sequences') run_setup.run_all_sequences() except Exception as e: LOG.error("clearstack: {0}".format(str(e))) sys.exit(1) LOG.debug('Generating admin-openrc') run_setup.generate_admin_openrc()