def config_import_cman(lib, argv, modifiers): """ Options: * --force - skip checks, overwrite files * --interactive - interactive issue resolving * --request-timeout - effective only when ouput is not specified """ # pylint: disable=no-member del lib modifiers.ensure_only_supported( "--force", "interactive", "--request-timeout", ) if no_clufter: utils.err("Unable to perform a CMAN cluster conversion due to missing " "python-clufter package") clufter_supports_corosync3 = hasattr(clufter.facts, "cluster_pcs_camelback") # prepare convertor options cluster_conf = settings.cluster_conf_file dry_run_output = None output_format = "corosync.conf" dist = None invalid_args = False for arg in argv: if "=" in arg: name, value = arg.split("=", 1) if name == "input": cluster_conf = value elif name == "output": dry_run_output = value elif name == "output-format": if value in ( "corosync.conf", "pcs-commands", "pcs-commands-verbose", ): output_format = value else: invalid_args = True elif name == "dist": dist = value else: invalid_args = True else: invalid_args = True if output_format not in ("pcs-commands", "pcs-commands-verbose") and ( dry_run_output and not dry_run_output.endswith(".tar.bz2")): dry_run_output += ".tar.bz2" if invalid_args or not dry_run_output: usage.config(["import-cman"]) sys.exit(1) debug = modifiers.get("--debug") force = modifiers.get("--force") interactive = modifiers.get("--interactive") if dist is not None: if not clufter_supports_corosync3: utils.err( "Unable to perform a CMAN cluster conversion due to clufter " "not supporting Corosync 3. Please, upgrade clufter packages.") if not clufter.facts.cluster_pcs_camelback("linux", dist.split(",")): utils.err("dist does not match output-format") elif output_format == "corosync.conf": dist = _get_linux_dist() else: # for output-format=pcs-command[-verbose] dist = _get_linux_dist() clufter_args = { "input": str(cluster_conf), "cib": { "passin": "bytestring" }, "nocheck": force, "batch": True, "sys": "linux", "dist": dist, } if interactive: if "EDITOR" not in os.environ: utils.err("$EDITOR environment variable is not set") clufter_args["batch"] = False clufter_args["editor"] = os.environ["EDITOR"] if debug: logging.getLogger("clufter").setLevel(logging.DEBUG) if output_format == "corosync.conf": clufter_args["coro"] = {"passin": "struct"} cmd_name = "ccs2pcs-camelback" elif output_format in ("pcs-commands", "pcs-commands-verbose"): clufter_args["output"] = {"passin": "bytestring"} clufter_args["start_wait"] = "60" clufter_args["tmp_cib"] = "tmp-cib.xml" clufter_args["force"] = force clufter_args["text_width"] = "80" clufter_args["silent"] = True clufter_args["noguidance"] = True if output_format == "pcs-commands-verbose": clufter_args["text_width"] = "-1" clufter_args["silent"] = False clufter_args["noguidance"] = False if clufter.facts.cluster_pcs_flatiron("linux", dist.split(",")): cmd_name = "ccs2pcscmd-flatiron" elif clufter.facts.cluster_pcs_needle("linux", dist.split(",")): cmd_name = "ccs2pcscmd-needle" elif clufter_supports_corosync3 and clufter.facts.cluster_pcs_camelback( "linux", dist.split(",")): cmd_name = "ccs2pcscmd-camelback" else: utils.err( "unrecognized dist, try something recognized" + " (e. g. rhel,6.8 or redhat,7.3 or debian,7 or ubuntu,trusty)") clufter_args_obj = type(str("ClufterOptions"), (object, ), clufter_args) # run convertor run_clufter( cmd_name, clufter_args_obj, debug, force, "Error: unable to import cluster configuration", ) # save commands if output_format in ("pcs-commands", "pcs-commands-verbose"): ok, message = utils.write_file( dry_run_output, clufter_args_obj.output["passout"].decode()) if not ok: utils.err(message) return # put new config files into tarball file_list = config_backup_path_list() for file_item in file_list.values(): file_item["attrs"]["uname"] = "root" file_item["attrs"]["gname"] = "root" file_item["attrs"]["uid"] = 0 file_item["attrs"]["gid"] = 0 file_item["attrs"]["mode"] = 0o600 tar_data = BytesIO() try: tarball = tarfile.open(fileobj=tar_data, mode="w|bz2") config_backup_add_version_to_tarball(tarball) utils.tar_add_file_data( tarball, clufter_args_obj.cib["passout"], "cib.xml", **file_list["cib.xml"]["attrs"], ) # put uidgid into separate files fmt_simpleconfig = clufter.format_manager.FormatManager.init_lookup( "simpleconfig").plugins["simpleconfig"] corosync_struct = [] uidgid_list = [] for section in clufter_args_obj.coro["passout"][2]: if section[0] == "uidgid": uidgid_list.append(section[1]) else: corosync_struct.append(section) corosync_conf_data = fmt_simpleconfig( "struct", ("corosync", (), corosync_struct))("bytestring") utils.tar_add_file_data( tarball, corosync_conf_data, "corosync.conf", **file_list["corosync.conf"]["attrs"], ) for uidgid in uidgid_list: uid = "" gid = "" for item in uidgid: if item[0] == "uid": uid = item[1] if item[0] == "gid": gid = item[1] filename = utils.get_uid_gid_file_name(uid, gid) uidgid_data = fmt_simpleconfig( "struct", ("corosync", (), [("uidgid", uidgid, None)]))("bytestring") utils.tar_add_file_data( tarball, uidgid_data, "uidgid.d/" + filename, **file_list["uidgid.d"]["attrs"], ) tarball.close() except (tarfile.TarError, EnvironmentError) as e: utils.err("unable to create tarball: %s" % e) tar_data.seek(0) # save tarball / remote restore if dry_run_output: ok, message = utils.write_file(dry_run_output, tar_data.read(), permissions=0o600, binary=True) if not ok: utils.err(message) else: config_restore_remote(None, tar_data) tar_data.close()
def config_backup_add_version_to_tarball(tarball, version=None): """ Commandline options: no options """ ver = version if version is not None else str(config_backup_version()) return utils.tar_add_file_data(tarball, ver.encode("utf-8"), "version.txt")
def config_import_cman(argv): if no_clufter: utils.err("Unable to perform a CMAN cluster conversion due to missing python-clufter package") # prepare convertor options cluster_conf = settings.cluster_conf_file dry_run_output = None output_format = "cluster.conf" if utils.is_rhel6() else "corosync.conf" dist = None invalid_args = False for arg in argv: if "=" in arg: name, value = arg.split("=", 1) if name == "input": cluster_conf = value elif name == "output": dry_run_output = value elif name == "output-format": if value in ( "cluster.conf", "corosync.conf", "pcs-commands", "pcs-commands-verbose", ): output_format = value else: invalid_args = True elif name == "dist": dist = value else: invalid_args = True else: invalid_args = True if ( output_format not in ("pcs-commands", "pcs-commands-verbose") and (dry_run_output and not dry_run_output.endswith(".tar.bz2")) ): dry_run_output += ".tar.bz2" if invalid_args or not dry_run_output: usage.config(["import-cman"]) sys.exit(1) debug = "--debug" in utils.pcs_options force = "--force" in utils.pcs_options interactive = "--interactive" in utils.pcs_options if dist is not None: if output_format == "cluster.conf": if not clufter.facts.cluster_pcs_flatiron("linux", dist.split(",")): utils.err("dist does not match output-format") elif output_format == "corosync.conf": if not clufter.facts.cluster_pcs_needle("linux", dist.split(",")): utils.err("dist does not match output-format") elif ( (output_format == "cluster.conf" and utils.is_rhel6()) or (output_format == "corosync.conf" and not utils.is_rhel6()) ): dist = ",".join(platform.linux_distribution(full_distribution_name=0)) elif output_format == "cluster.conf": dist = "redhat,6.7,Santiago" elif output_format == "corosync.conf": dist = "redhat,7.1,Maipo" else: # for output-format=pcs-command[-verbose] dist = ",".join(platform.linux_distribution(full_distribution_name=0)) clufter_args = { "input": str(cluster_conf), "cib": {"passin": "bytestring"}, "nocheck": force, "batch": True, "sys": "linux", "dist": dist, # Make it work on RHEL6 as well for sure "color": "always" if sys.stdout.isatty() else "never" } if interactive: if "EDITOR" not in os.environ: utils.err("$EDITOR environment variable is not set") clufter_args["batch"] = False clufter_args["editor"] = os.environ["EDITOR"] if debug: logging.getLogger("clufter").setLevel(logging.DEBUG) if output_format == "cluster.conf": clufter_args["ccs_pcmk"] = {"passin": "bytestring"} cmd_name = "ccs2pcs-flatiron" elif output_format == "corosync.conf": clufter_args["coro"] = {"passin": "struct"} cmd_name = "ccs2pcs-needle" elif output_format in ("pcs-commands", "pcs-commands-verbose"): clufter_args["output"] = {"passin": "bytestring"} clufter_args["start_wait"] = "60" clufter_args["tmp_cib"] = "tmp-cib.xml" clufter_args["force"] = force clufter_args["text_width"] = "80" clufter_args["silent"] = True clufter_args["noguidance"] = True if output_format == "pcs-commands-verbose": clufter_args["text_width"] = "-1" clufter_args["silent"] = False clufter_args["noguidance"] = False if clufter.facts.cluster_pcs_flatiron("linux", dist.split(",")): cmd_name = "ccs2pcscmd-flatiron" elif clufter.facts.cluster_pcs_needle("linux", dist.split(",")): cmd_name = "ccs2pcscmd-needle" else: utils.err( "unrecognized dist, try something recognized" + " (e. g. rhel,6.8 or redhat,7.3 or debian,7 or ubuntu,trusty)" ) clufter_args_obj = type(str("ClufterOptions"), (object, ), clufter_args) # run convertor run_clufter( cmd_name, clufter_args_obj, debug, force, "Error: unable to import cluster configuration" ) # save commands if output_format in ("pcs-commands", "pcs-commands-verbose"): ok, message = utils.write_file( dry_run_output, clufter_args_obj.output["passout"] ) if not ok: utils.err(message) return # put new config files into tarball file_list = config_backup_path_list( force_rhel6=(output_format == "cluster.conf") ) for file_item in file_list.values(): file_item["attrs"]["uname"] = "root" file_item["attrs"]["gname"] = "root" file_item["attrs"]["uid"] = 0 file_item["attrs"]["gid"] = 0 file_item["attrs"]["mode"] = 0o600 tar_data = BytesIO() try: tarball = tarfile.open(fileobj=tar_data, mode="w|bz2") config_backup_add_version_to_tarball(tarball) utils.tar_add_file_data( tarball, clufter_args_obj.cib["passout"].encode("utf-8"), "cib.xml", **file_list["cib.xml"]["attrs"] ) if output_format == "cluster.conf": utils.tar_add_file_data( tarball, clufter_args_obj.ccs_pcmk["passout"].encode("utf-8"), "cluster.conf", **file_list["cluster.conf"]["attrs"] ) else: # put uidgid into separate files fmt_simpleconfig = clufter.format_manager.FormatManager.init_lookup( 'simpleconfig' ).plugins['simpleconfig'] corosync_struct = [] uidgid_list = [] for section in clufter_args_obj.coro["passout"][2]: if section[0] == "uidgid": uidgid_list.append(section[1]) else: corosync_struct.append(section) corosync_conf_data = fmt_simpleconfig( "struct", ("corosync", (), corosync_struct) )("bytestring") utils.tar_add_file_data( tarball, corosync_conf_data.encode("utf-8"), "corosync.conf", **file_list["corosync.conf"]["attrs"] ) for uidgid in uidgid_list: uid = "" gid = "" for item in uidgid: if item[0] == "uid": uid = item[1] if item[0] == "gid": gid = item[1] filename = utils.get_uid_gid_file_name(uid, gid) uidgid_data = fmt_simpleconfig( "struct", ("corosync", (), [("uidgid", uidgid, None)]) )("bytestring") utils.tar_add_file_data( tarball, uidgid_data.encode("utf-8"), "uidgid.d/" + filename, **file_list["uidgid.d"]["attrs"] ) tarball.close() except (tarfile.TarError, EnvironmentError) as e: utils.err("unable to create tarball: %s" % e) tar_data.seek(0) #save tarball / remote restore if dry_run_output: ok, message = utils.write_file( dry_run_output, tar_data.read(), permissions=0o600, binary=True ) if not ok: utils.err(message) else: config_restore_remote(None, tar_data) tar_data.close()
def config_backup_add_version_to_tarball(tarball, version=None): ver = version if version is not None else str(config_backup_version()) return utils.tar_add_file_data(tarball, ver.encode("utf-8"), "version.txt")
def config_import_cman(lib, argv, modifiers): """ Options: * --force - skip checks, overwrite files * --interactive - interactive issue resolving * --request-timeout - effective only when ouput is not specified """ # pylint: disable=no-member del lib modifiers.ensure_only_supported( "--force", "interactive", "--request-timeout", ) if no_clufter: utils.err( "Unable to perform a CMAN cluster conversion due to missing " "python-clufter package" ) clufter_supports_corosync3 = hasattr(clufter.facts, "cluster_pcs_camelback") # prepare convertor options cluster_conf = settings.cluster_conf_file dry_run_output = None output_format = "corosync.conf" dist = None invalid_args = False for arg in argv: if "=" in arg: name, value = arg.split("=", 1) if name == "input": cluster_conf = value elif name == "output": dry_run_output = value elif name == "output-format": if value in ( "corosync.conf", "pcs-commands", "pcs-commands-verbose", ): output_format = value else: invalid_args = True elif name == "dist": dist = value else: invalid_args = True else: invalid_args = True if ( output_format not in ("pcs-commands", "pcs-commands-verbose") and (dry_run_output and not dry_run_output.endswith(".tar.bz2")) ): dry_run_output += ".tar.bz2" if invalid_args or not dry_run_output: usage.config(["import-cman"]) sys.exit(1) debug = modifiers.get("--debug") force = modifiers.get("--force") interactive = modifiers.get("--interactive") if dist is not None: if not clufter_supports_corosync3: utils.err( "Unable to perform a CMAN cluster conversion due to clufter " "not supporting Corosync 3. Please, upgrade clufter packages." ) if not clufter.facts.cluster_pcs_camelback("linux", dist.split(",")): utils.err("dist does not match output-format") elif output_format == "corosync.conf": dist = _get_linux_dist() else: # for output-format=pcs-command[-verbose] dist = _get_linux_dist() clufter_args = { "input": str(cluster_conf), "cib": {"passin": "bytestring"}, "nocheck": force, "batch": True, "sys": "linux", "dist": dist, } if interactive: if "EDITOR" not in os.environ: utils.err("$EDITOR environment variable is not set") clufter_args["batch"] = False clufter_args["editor"] = os.environ["EDITOR"] if debug: logging.getLogger("clufter").setLevel(logging.DEBUG) if output_format == "corosync.conf": clufter_args["coro"] = {"passin": "struct"} cmd_name = "ccs2pcs-camelback" elif output_format in ("pcs-commands", "pcs-commands-verbose"): clufter_args["output"] = {"passin": "bytestring"} clufter_args["start_wait"] = "60" clufter_args["tmp_cib"] = "tmp-cib.xml" clufter_args["force"] = force clufter_args["text_width"] = "80" clufter_args["silent"] = True clufter_args["noguidance"] = True if output_format == "pcs-commands-verbose": clufter_args["text_width"] = "-1" clufter_args["silent"] = False clufter_args["noguidance"] = False if clufter.facts.cluster_pcs_flatiron("linux", dist.split(",")): cmd_name = "ccs2pcscmd-flatiron" elif clufter.facts.cluster_pcs_needle("linux", dist.split(",")): cmd_name = "ccs2pcscmd-needle" elif ( clufter_supports_corosync3 and clufter.facts.cluster_pcs_camelback("linux", dist.split(",")) ): cmd_name = "ccs2pcscmd-camelback" else: utils.err( "unrecognized dist, try something recognized" + " (e. g. rhel,6.8 or redhat,7.3 or debian,7 or ubuntu,trusty)" ) clufter_args_obj = type(str("ClufterOptions"), (object, ), clufter_args) # run convertor run_clufter( cmd_name, clufter_args_obj, debug, force, "Error: unable to import cluster configuration" ) # save commands if output_format in ("pcs-commands", "pcs-commands-verbose"): ok, message = utils.write_file( dry_run_output, clufter_args_obj.output["passout"].decode() ) if not ok: utils.err(message) return # put new config files into tarball file_list = config_backup_path_list() for file_item in file_list.values(): file_item["attrs"]["uname"] = "root" file_item["attrs"]["gname"] = "root" file_item["attrs"]["uid"] = 0 file_item["attrs"]["gid"] = 0 file_item["attrs"]["mode"] = 0o600 tar_data = BytesIO() try: tarball = tarfile.open(fileobj=tar_data, mode="w|bz2") config_backup_add_version_to_tarball(tarball) utils.tar_add_file_data( tarball, clufter_args_obj.cib["passout"], "cib.xml", **file_list["cib.xml"]["attrs"] ) # put uidgid into separate files fmt_simpleconfig = clufter.format_manager.FormatManager.init_lookup( 'simpleconfig' ).plugins['simpleconfig'] corosync_struct = [] uidgid_list = [] for section in clufter_args_obj.coro["passout"][2]: if section[0] == "uidgid": uidgid_list.append(section[1]) else: corosync_struct.append(section) corosync_conf_data = fmt_simpleconfig( "struct", ("corosync", (), corosync_struct) )("bytestring") utils.tar_add_file_data( tarball, corosync_conf_data, "corosync.conf", **file_list["corosync.conf"]["attrs"] ) for uidgid in uidgid_list: uid = "" gid = "" for item in uidgid: if item[0] == "uid": uid = item[1] if item[0] == "gid": gid = item[1] filename = utils.get_uid_gid_file_name(uid, gid) uidgid_data = fmt_simpleconfig( "struct", ("corosync", (), [("uidgid", uidgid, None)]) )("bytestring") utils.tar_add_file_data( tarball, uidgid_data, "uidgid.d/" + filename, **file_list["uidgid.d"]["attrs"] ) tarball.close() except (tarfile.TarError, EnvironmentError) as e: utils.err("unable to create tarball: %s" % e) tar_data.seek(0) #save tarball / remote restore if dry_run_output: ok, message = utils.write_file( dry_run_output, tar_data.read(), permissions=0o600, binary=True ) if not ok: utils.err(message) else: config_restore_remote(None, tar_data) tar_data.close()