Example #1
0
File: config.py Project: ldming/pcs
def config_backup(lib, argv, modifiers):
    """
    Options:
      * --force - overwrite file if already exists
    """
    del lib
    modifiers.ensure_only_supported("--force")
    if len(argv) > 1:
        usage.config(["backup"])
        sys.exit(1)

    outfile_name = None
    if argv:
        outfile_name = argv[0]
        if not outfile_name.endswith(".tar.bz2"):
            outfile_name += ".tar.bz2"

    tar_data = config_backup_local()
    if outfile_name:
        ok, message = utils.write_file(outfile_name,
                                       tar_data,
                                       permissions=0o600,
                                       binary=True)
        if not ok:
            utils.err(message)
    else:
        # in python3 stdout accepts str so we need to use buffer
        sys.stdout.buffer.write(tar_data)
Example #2
0
def config_backup(argv):
    if len(argv) > 1:
        usage.config(["backup"])
        sys.exit(1)

    outfile_name = None
    if argv:
        outfile_name = argv[0]
        if not outfile_name.endswith(".tar.bz2"):
            outfile_name += ".tar.bz2"

    tar_data = config_backup_local()
    if outfile_name:
        ok, message = utils.write_file(outfile_name,
                                       tar_data,
                                       permissions=0o600,
                                       binary=True)
        if not ok:
            utils.err(message)
    else:
        # in python3 stdout accepts str so we need to use buffer
        if hasattr(sys.stdout, "buffer"):
            sys.stdout.buffer.write(tar_data)
        else:
            sys.stdout.write(tar_data)
Example #3
0
def config_backup(lib, argv, modifiers):
    """
    Options:
      * --force - overwrite file if already exists
    """
    del lib
    modifiers.ensure_only_supported("--force")
    if len(argv) > 1:
        usage.config(["backup"])
        sys.exit(1)

    outfile_name = None
    if argv:
        outfile_name = argv[0]
        if not outfile_name.endswith(".tar.bz2"):
            outfile_name += ".tar.bz2"

    tar_data = config_backup_local()
    if outfile_name:
        ok, message = utils.write_file(
            outfile_name, tar_data, permissions=0o600, binary=True
        )
        if not ok:
            utils.err(message)
    else:
        # in python3 stdout accepts str so we need to use buffer
        sys.stdout.buffer.write(tar_data)
Example #4
0
def config_checkpoint_view(argv):
    if len(argv) != 1:
        usage.config(["checkpoint", "view"])
        sys.exit(1)

    utils.usefile = True
    utils.filename = os.path.join(settings.cib_dir, "cib-%s.raw" % argv[0])
    if not os.path.isfile(utils.filename):
        utils.err("unable to read the checkpoint")
    config_show_cib()
Example #5
0
def config_checkpoint_view(argv):
    if len(argv) != 1:
        usage.config(["checkpoint", "view"])
        sys.exit(1)

    utils.usefile = True
    utils.filename = os.path.join(settings.cib_dir, "cib-%s.raw" % argv[0])
    if not os.path.isfile(utils.filename):
        utils.err("unable to read the checkpoint")
    config_show_cib()
Example #6
0
def config_checkpoint_diff(lib, argv, modifiers):
    """
    Commandline options:
      * -f - CIB file
    """
    modifiers.ensure_only_supported("-f")
    if len(argv) != 2:
        usage.config(["checkpoint diff"])
        sys.exit(1)

    if argv[0] == argv[1]:
        utils.err("cannot diff a checkpoint against itself")

    errors = []
    checkpoints_lines = []
    for checkpoint in argv:
        if checkpoint == "live":
            lines = _config_show_cib_lines(lib)
            if not lines:
                errors.append("unable to read live configuration")
            else:
                checkpoints_lines.append(lines)
        else:
            loaded, lines = _checkpoint_to_lines(lib, checkpoint)
            if not loaded:
                errors.append(
                    "unable to read checkpoint '{0}'".format(checkpoint)
                )
            else:
                checkpoints_lines.append(lines)

    if errors:
        utils.err("\n".join(errors))

    print(
        "Differences between {0} (-) and {1} (+):".format(
            *[
                "live configuration"
                if label == "live"
                else f"checkpoint {label}"
                for label in argv
            ]
        )
    )
    print(
        "\n".join(
            [
                line.rstrip()
                for line in difflib.Differ().compare(
                    checkpoints_lines[0], checkpoints_lines[1]
                )
            ]
        )
    )
Example #7
0
def config_checkpoint_restore(argv):
    if len(argv) != 1:
        usage.config(["checkpoint", "restore"])
        sys.exit(1)

    cib_path = os.path.join(settings.cib_dir, "cib-%s.raw" % argv[0])
    try:
        snapshot_dom = parse(cib_path)
    except Exception as e:
        utils.err("unable to read the checkpoint: %s" % e)
    utils.replace_cib_configuration(snapshot_dom)
Example #8
0
def config_checkpoint_restore(argv):
    if len(argv) != 1:
        usage.config(["checkpoint", "restore"])
        sys.exit(1)

    cib_path = os.path.join(settings.cib_dir, "cib-%s.raw" % argv[0])
    try:
        snapshot_dom = parse(cib_path)
    except Exception as e:
        utils.err("unable to read the checkpoint: %s" % e)
    utils.replace_cib_configuration(snapshot_dom)
Example #9
0
def config_checkpoint_view(lib, argv, modifiers):
    """
    Options: no options
    """
    modifiers.ensure_only_supported()
    if len(argv) != 1:
        usage.config(["checkpoint view"])
        sys.exit(1)

    loaded, lines = _checkpoint_to_lines(lib, argv[0])
    if not loaded:
        utils.err("unable to read the checkpoint")
    print("\n".join(lines))
Example #10
0
File: config.py Project: ldming/pcs
def config_checkpoint_view(lib, argv, modifiers):
    """
    Options: no options
    """
    modifiers.ensure_only_supported()
    if len(argv) != 1:
        usage.config(["checkpoint view"])
        sys.exit(1)

    loaded, lines = _checkpoint_to_lines(lib, argv[0])
    if not loaded:
        utils.err("unable to read the checkpoint")
    print("\n".join(lines))
Example #11
0
def config_checkpoint_view(lib, argv, modifiers):
    """
    Options: no options
    """
    modifiers.ensure_only_supported()
    if len(argv) != 1:
        usage.config(["checkpoint", "view"])
        sys.exit(1)

    utils.usefile = True
    utils.filename = os.path.join(settings.cib_dir, "cib-%s.raw" % argv[0])
    if not os.path.isfile(utils.filename):
        utils.err("unable to read the checkpoint")
    config_show_cib(lib)
Example #12
0
def config_cmd(lib, argv, modifiers):
    create_router(
        {
            "help":
            lambda _lib, _argv, _modifiers: usage.config(_argv),
            "show":
            config_show,
            "backup":
            config_backup,
            "restore":
            config_restore,
            "checkpoint":
            create_router(
                {
                    "list": config_checkpoint_list,
                    "view": config_checkpoint_view,
                    "restore": config_checkpoint_restore,
                    "diff": config_checkpoint_diff,
                }, ["config", "checkpoint"],
                default_cmd="list"),
            "import-cman":
            config_import_cman,
            "export":
            create_router(
                {
                    "pcs-commands":
                    config_export_pcs_commands,
                    "pcs-commands-verbose":
                    lambda _lib, _argv, _modifiers: config_export_pcs_commands(
                        _lib, _argv, _modifiers, verbose=True)
                }, ["config", "export"])
        },
        ["config"],
        default_cmd="show",
    )(lib, argv, modifiers)
Example #13
0
def config_checkpoint_restore(dummy_lib, argv, modifiers):
    """
    Options:
      * -f - CIB file, a checkpoint will be restored into a specified file
    """
    modifiers.ensure_only_supported("-f")
    if len(argv) != 1:
        usage.config(["checkpoint", "restore"])
        sys.exit(1)

    cib_path = os.path.join(settings.cib_dir, "cib-%s.raw" % argv[0])
    try:
        snapshot_dom = parse(cib_path)
    except Exception as e:
        utils.err("unable to read the checkpoint: %s" % e)
    utils.replace_cib_configuration(snapshot_dom)
Example #14
0
def config_checkpoint_restore(lib, argv, modifiers):
    """
    Options:
      * -f - CIB file, a checkpoint will be restored into a specified file
    """
    # pylint: disable=broad-except
    del lib
    modifiers.ensure_only_supported("-f")
    if len(argv) != 1:
        usage.config(["checkpoint restore"])
        sys.exit(1)

    cib_path = os.path.join(settings.cib_dir, "cib-%s.raw" % argv[0])
    try:
        snapshot_dom = parse(cib_path)
    except Exception as e:
        utils.err("unable to read the checkpoint: %s" % e)
    utils.replace_cib_configuration(snapshot_dom)
Example #15
0
def config_restore(lib, argv, modifiers):
    """
    Options:
      * --local - restore config only on local node
      * --request-timeout - timeout for HTTP requests, used only if --local was
        not defined or user is not root
    """
    del lib
    modifiers.ensure_only_supported("--local", "--request-timeout")
    if len(argv) > 1:
        usage.config(["restore"])
        sys.exit(1)

    infile_name = infile_obj = None
    if argv:
        infile_name = argv[0]
    if not infile_name:
        # in python3 stdin returns str so we need to use buffer
        infile_obj = BytesIO(sys.stdin.buffer.read())

    if os.getuid() == 0:
        if modifiers.get("--local"):
            config_restore_local(infile_name, infile_obj)
        else:
            config_restore_remote(infile_name, infile_obj)
    else:
        new_argv = ["config", "restore"]
        new_stdin = None
        if modifiers.get("--local"):
            new_argv.append("--local")
        if infile_name:
            new_argv.append(os.path.abspath(infile_name))
        else:
            new_stdin = infile_obj.read()
        err_msgs, exitcode, std_out, std_err = utils.call_local_pcsd(
            new_argv, new_stdin
        )
        if err_msgs:
            for msg in err_msgs:
                utils.err(msg, False)
            sys.exit(1)
        print(std_out)
        sys.stderr.write(std_err)
        sys.exit(exitcode)
Example #16
0
def config_restore(lib, argv, modifiers):
    """
    Options:
      * --local - restore config only on local node
      * --request-timeout - timeout for HTTP requests, used only if --local was
        not defined or user is not root
    """
    del lib
    modifiers.ensure_only_supported("--local", "--request-timeout")
    if len(argv) > 1:
        usage.config(["restore"])
        sys.exit(1)

    infile_name = infile_obj = None
    if argv:
        infile_name = argv[0]
    if not infile_name:
        # in python3 stdin returns str so we need to use buffer
        infile_obj = BytesIO(sys.stdin.buffer.read())

    if os.getuid() == 0:
        if modifiers.get("--local"):
            config_restore_local(infile_name, infile_obj)
        else:
            config_restore_remote(infile_name, infile_obj)
    else:
        new_argv = ['config', 'restore']
        new_stdin = None
        if modifiers.get("--local"):
            new_argv.append('--local')
        if infile_name:
            new_argv.append(os.path.abspath(infile_name))
        else:
            new_stdin = infile_obj.read()
        err_msgs, exitcode, std_out, std_err = utils.call_local_pcsd(
            new_argv, new_stdin
        )
        if err_msgs:
            for msg in err_msgs:
                utils.err(msg, False)
            sys.exit(1)
        print(std_out)
        sys.stderr.write(std_err)
        sys.exit(exitcode)
Example #17
0
def config_checkpoint_diff(lib, argv, modifiers):
    """
    Commandline options:
      * -f - CIB file
    """
    modifiers.ensure_only_supported("-f")
    if len(argv) != 2:
        usage.config(["checkpoint diff"])
        sys.exit(1)

    if argv[0] == argv[1]:
        utils.err("cannot diff a checkpoint against itself")

    errors = []
    checkpoints_lines = []
    for checkpoint in argv:
        if checkpoint == "live":
            lines = _config_show_cib_lines(lib)
            if not lines:
                errors.append("unable to read live configuration")
            else:
                checkpoints_lines.append(lines)
        else:
            loaded, lines = _checkpoint_to_lines(lib, checkpoint)
            if not loaded:
                errors.append(
                    "unable to read checkpoint '{0}'".format(checkpoint)
                )
            else:
                checkpoints_lines.append(lines)

    if errors:
        utils.err("\n".join(errors))

    print("Differences between {0} (-) and {1} (+):".format(*[
        "live configuration" if label == "live" else f"checkpoint {label}"
        for label in argv
    ]))
    print("\n".join([
        line.rstrip() for line in difflib.Differ().compare(
            checkpoints_lines[0],
            checkpoints_lines[1]
        )]
    ))
Example #18
0
def config_cmd(lib, argv, modifiers):
    if len(argv) == 0:
        config_show(lib, argv, modifiers)
        return

    try:
        sub_cmd = argv.pop(0)
        if sub_cmd == "help":
            usage.config(argv)
        elif sub_cmd == "show":
            config_show(lib, argv, modifiers)
        elif sub_cmd == "backup":
            config_backup(lib, argv, modifiers)
        elif sub_cmd == "restore":
            config_restore(lib, argv, modifiers)
        elif sub_cmd == "checkpoint":
            if not argv:
                config_checkpoint_list(lib, argv, modifiers)
            elif argv[0] == "view":
                config_checkpoint_view(lib, argv[1:], modifiers)
            elif argv[0] == "restore":
                config_checkpoint_restore(lib, argv[1:], modifiers)
            else:
                raise CmdLineInputError()
        elif sub_cmd == "import-cman":
            config_import_cman(lib, argv, modifiers)
        elif sub_cmd == "export":
            if not argv:
                raise CmdLineInputError()
            elif argv[0] == "pcs-commands":
                config_export_pcs_commands(lib, argv[1:], modifiers)
            elif argv[0] == "pcs-commands-verbose":
                config_export_pcs_commands(lib,
                                           argv[1:],
                                           modifiers,
                                           verbose=True)
            else:
                raise CmdLineInputError()
        else:
            raise CmdLineInputError()
    except LibraryError as e:
        utils.process_library_reports(e.args)
    except CmdLineInputError as e:
        utils.exit_on_cmdline_input_errror(e, "config", sub_cmd)
Example #19
0
def config_cmd(argv):
    if len(argv) == 0:
        config_show(argv)
        return

    sub_cmd = argv.pop(0)
    if sub_cmd == "help":
        usage.config(argv)
    elif sub_cmd == "show":
        config_show(argv)
    elif sub_cmd == "backup":
        config_backup(argv)
    elif sub_cmd == "restore":
        config_restore(argv)
    elif sub_cmd == "checkpoint":
        if not argv:
            config_checkpoint_list()
        elif argv[0] == "view":
            config_checkpoint_view(argv[1:])
        elif argv[0] == "restore":
            config_checkpoint_restore(argv[1:])
        else:
            usage.config(["checkpoint"])
            sys.exit(1)
    elif sub_cmd == "import-cman":
        config_import_cman(argv)
    elif sub_cmd == "export":
        if not argv:
            usage.config(["export"])
            sys.exit(1)
        elif argv[0] == "pcs-commands":
            config_export_pcs_commands(argv[1:])
        elif argv[0] == "pcs-commands-verbose":
            config_export_pcs_commands(argv[1:], True)
        else:
            usage.config(["export"])
            sys.exit(1)
    else:
        usage.config()
        sys.exit(1)
Example #20
0
def config_cmd(argv):
    if len(argv) == 0:
        config_show(argv)
        return

    sub_cmd = argv.pop(0)
    if sub_cmd == "help":
        usage.config(argv)
    elif sub_cmd == "show":
        config_show(argv)
    elif sub_cmd == "backup":
        config_backup(argv)
    elif sub_cmd == "restore":
        config_restore(argv)
    elif sub_cmd == "checkpoint":
        if not argv:
            config_checkpoint_list()
        elif argv[0] == "view":
            config_checkpoint_view(argv[1:])
        elif argv[0] == "restore":
            config_checkpoint_restore(argv[1:])
        else:
            usage.config(["checkpoint"])
            sys.exit(1)
    elif sub_cmd == "import-cman":
        config_import_cman(argv)
    elif sub_cmd == "export":
        if not argv:
            usage.config(["export"])
            sys.exit(1)
        elif argv[0] == "pcs-commands":
            config_export_pcs_commands(argv[1:])
        elif argv[0] == "pcs-commands-verbose":
            config_export_pcs_commands(argv[1:], True)
        else:
            usage.config(["export"])
            sys.exit(1)
    else:
        usage.config()
        sys.exit(1)
Example #21
0
def config_restore(argv):
    if len(argv) > 1:
        usage.config(["restore"])
        sys.exit(1)

    infile_name = infile_obj = None
    if argv:
        infile_name = argv[0]
    if not infile_name:
        # in python3 stdin returns str so we need to use buffer
        if hasattr(sys.stdin, "buffer"):
            infile_obj = BytesIO(sys.stdin.buffer.read())
        else:
            infile_obj = BytesIO(sys.stdin.read())

    if os.getuid() == 0:
        if "--local" in utils.pcs_options:
            config_restore_local(infile_name, infile_obj)
        else:
            config_restore_remote(infile_name, infile_obj)
    else:
        new_argv = ['config', 'restore']
        new_stdin = None
        if '--local' in utils.pcs_options:
            new_argv.append('--local')
        if infile_name:
            new_argv.append(os.path.abspath(infile_name))
        else:
            new_stdin = infile_obj.read()
        err_msgs, exitcode, std_out, std_err = utils.call_local_pcsd(
            new_argv, True, new_stdin
        )
        if err_msgs:
            for msg in err_msgs:
                utils.err(msg, False)
            sys.exit(1)
        print(std_out)
        sys.stderr.write(std_err)
        sys.exit(exitcode)
Example #22
0
def config_restore(argv):
    if len(argv) > 1:
        usage.config(["restore"])
        sys.exit(1)

    infile_name = infile_obj = None
    if argv:
        infile_name = argv[0]
    if not infile_name:
        # in python3 stdin returns str so we need to use buffer
        if hasattr(sys.stdin, "buffer"):
            infile_obj = BytesIO(sys.stdin.buffer.read())
        else:
            infile_obj = BytesIO(sys.stdin.read())

    if os.getuid() == 0:
        if "--local" in utils.pcs_options:
            config_restore_local(infile_name, infile_obj)
        else:
            config_restore_remote(infile_name, infile_obj)
    else:
        new_argv = ['config', 'restore']
        new_stdin = None
        if '--local' in utils.pcs_options:
            new_argv.append('--local')
        if infile_name:
            new_argv.append(os.path.abspath(infile_name))
        else:
            new_stdin = infile_obj.read()
        err_msgs, exitcode, std_out, std_err = utils.call_local_pcsd(
            new_argv, True, new_stdin
        )
        if err_msgs:
            for msg in err_msgs:
                utils.err(msg, False)
            sys.exit(1)
        print(std_out)
        sys.stderr.write(std_err)
        sys.exit(exitcode)
Example #23
0
def config_backup(argv):
    if len(argv) > 1:
        usage.config(["backup"])
        sys.exit(1)

    outfile_name = None
    if argv:
        outfile_name = argv[0]
        if not outfile_name.endswith(".tar.bz2"):
            outfile_name += ".tar.bz2"

    tar_data = config_backup_local()
    if outfile_name:
        ok, message = utils.write_file(
            outfile_name, tar_data, permissions=0o600, binary=True
        )
        if not ok:
            utils.err(message)
    else:
        # in python3 stdout accepts str so we need to use buffer
        if hasattr(sys.stdout, "buffer"):
            sys.stdout.buffer.write(tar_data)
        else:
            sys.stdout.write(tar_data)
Example #24
0
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()
Example #25
0
def config_export_pcs_commands(lib, argv, modifiers, verbose=False):
    """
    Options:
      * --force - skip checks, overwrite files
      * --interactive - interactive issue resolving
      * -f - CIB file
      * --corosync_conf
    """
    del lib
    modifiers.ensure_only_supported(
        "--force", "--interactive", "-f", "--corosync_conf"
    )
    if no_clufter:
        utils.err(
            "Unable to perform export due to missing python-clufter package"
        )

    # parse options
    debug = modifiers.get("--debug")
    force = modifiers.get("--force")
    interactive = modifiers.get("--interactive")
    invalid_args = False
    output_file = None
    dist = None
    for arg in argv:
        if "=" in arg:
            name, value = arg.split("=", 1)
            if name == "output":
                output_file = value
            elif name == "dist":
                dist = value
            else:
                invalid_args = True
        else:
            invalid_args = True
    # check options
    if invalid_args:
        usage.config(["export pcs-commands"])
        sys.exit(1)
    # complete optional options
    if dist is None:
        dist = _get_linux_dist()

    # prepare convertor options
    clufter_args = {
        "nocheck": force,
        "batch": True,
        "sys": "linux",
        "dist": dist,
        "coro": settings.corosync_conf_file,
        "start_wait": "60",
        "tmp_cib": "tmp-cib.xml",
        "force": force,
        "text_width": "80",
        "silent": True,
        "noguidance": True,
    }
    if output_file:
        clufter_args["output"] = {"passin": "bytestring"}
    else:
        clufter_args["output"] = "-"
    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 utils.usefile:
        clufter_args["cib"] = os.path.abspath(utils.filename)
    else:
        clufter_args["cib"] = ("bytestring", utils.get_cib())
    if verbose:
        clufter_args["text_width"] = "-1"
        clufter_args["silent"] = False
        clufter_args["noguidance"] = False
    clufter_args_obj = type(str("ClufterOptions"), (object, ), clufter_args)
    cmd_name = "pcs2pcscmd-camelback"

    # run convertor
    run_clufter(
        cmd_name, clufter_args_obj, debug, force,
        "Error: unable to export cluster configuration"
    )

    # save commands if not printed to stdout by clufter
    if output_file:
        # pylint: disable=no-member
        ok, message = utils.write_file(
            output_file,
            clufter_args_obj.output["passout"].decode()
        )
        if not ok:
            utils.err(message)
Example #26
0
def config_export_pcs_commands(argv, verbose=False):
    if no_clufter:
        utils.err(
            "Unable to perform export due to missing python-clufter package")

    # parse options
    debug = "--debug" in utils.pcs_options
    force = "--force" in utils.pcs_options
    interactive = "--interactive" in utils.pcs_options
    invalid_args = False
    output_file = None
    dist = None
    for arg in argv:
        if "=" in arg:
            name, value = arg.split("=", 1)
            if name == "output":
                output_file = value
            elif name == "dist":
                dist = value
            else:
                invalid_args = True
        else:
            invalid_args = True
    # check options
    if invalid_args:
        usage.config(["export", "pcs-commands"])
        sys.exit(1)
    # complete optional options
    if dist is None:
        dist = ",".join(platform.linux_distribution(full_distribution_name=0))

    # prepare convertor options
    clufter_args = {
        "nocheck": force,
        "batch": True,
        "sys": "linux",
        "dist": dist,
        "coro": settings.corosync_conf_file,
        "ccs": settings.cluster_conf_file,
        "start_wait": "60",
        "tmp_cib": "tmp-cib.xml",
        "force": force,
        "text_width": "80",
        "silent": True,
        "noguidance": True,
    }
    if output_file:
        clufter_args["output"] = {"passin": "bytestring"}
    else:
        clufter_args["output"] = "-"
    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 utils.usefile:
        clufter_args["cib"] = os.path.abspath(utils.filename)
    else:
        clufter_args["cib"] = ("bytestring", utils.get_cib())
    if verbose:
        clufter_args["text_width"] = "-1"
        clufter_args["silent"] = False
        clufter_args["noguidance"] = False
    clufter_args_obj = type(str("ClufterOptions"), (object, ), clufter_args)
    cmd_name = "pcs2pcscmd-flatiron" if utils.is_rhel6(
    ) else "pcs2pcscmd-needle"

    # run convertor
    run_clufter(cmd_name, clufter_args_obj, debug, force,
                "Error: unable to export cluster configuration")

    # save commands if not printed to stdout by clufter
    if output_file:
        ok, message = utils.write_file(
            output_file, clufter_args_obj.output["passout"].decode())
        if not ok:
            utils.err(message)
Example #27
0
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()
Example #28
0
File: config.py Project: ldming/pcs
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()
Example #29
0
from pcs import (
    config,
    usage,
)
from pcs.cli.common.routing import create_router

config_cmd = create_router(
    {
        "help":
        lambda lib, argv, modifiers: usage.config(argv),
        "show":
        config.config_show,
        "backup":
        config.config_backup,
        "restore":
        config.config_restore,
        "checkpoint":
        create_router(
            {
                "list": config.config_checkpoint_list,
                "view": config.config_checkpoint_view,
                "restore": config.config_checkpoint_restore,
                "diff": config.config_checkpoint_diff,
            }, ["config", "checkpoint"],
            default_cmd="list"),
        "import-cman":
        config.config_import_cman,
        "export":
        create_router(
            {
                "pcs-commands":
Example #30
0
def config_export_pcs_commands(argv, verbose=False):
    if no_clufter:
        utils.err(
            "Unable to perform export due to missing python-clufter package"
        )

    # parse options
    debug = "--debug" in utils.pcs_options
    force = "--force" in utils.pcs_options
    interactive = "--interactive" in utils.pcs_options
    invalid_args = False
    output_file = None
    dist = None
    for arg in argv:
        if "=" in arg:
            name, value = arg.split("=", 1)
            if name == "output":
                output_file = value
            elif name == "dist":
                dist = value
            else:
                invalid_args = True
        else:
            invalid_args = True
    # check options
    if invalid_args:
        usage.config(["export", "pcs-commands"])
        sys.exit(1)
    # complete optional options
    if dist is None:
        dist = ",".join(platform.linux_distribution(full_distribution_name=0))

    # prepare convertor options
    clufter_args = {
        "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",
        "coro": settings.corosync_conf_file,
        "ccs": settings.cluster_conf_file,
        "start_wait": "60",
        "tmp_cib": "tmp-cib.xml",
        "force": force,
        "text_width": "80",
        "silent": True,
        "noguidance": True,
    }
    if output_file:
        clufter_args["output"] = {"passin": "bytestring"}
    else:
        clufter_args["output"] = "-"
    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 utils.usefile:
        clufter_args["cib"] = os.path.abspath(utils.filename)
    else:
        clufter_args["cib"] = ("bytestring", utils.get_cib())
    if verbose:
        clufter_args["text_width"] = "-1"
        clufter_args["silent"] = False
        clufter_args["noguidance"] = False
    clufter_args_obj = type(str("ClufterOptions"), (object, ), clufter_args)
    cmd_name = "pcs2pcscmd-flatiron" if utils.is_rhel6() else "pcs2pcscmd-needle"

    # run convertor
    run_clufter(
        cmd_name, clufter_args_obj, debug, force,
        "Error: unable to export cluster configuration"
    )

    # save commands if not printed to stdout by clufter
    if output_file:
        ok, message = utils.write_file(
            output_file,
            clufter_args_obj.output["passout"]
        )
        if not ok:
            utils.err(message)
Example #31
0
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()
Example #32
0
from pcs import (
    config,
    usage,
)
from pcs.cli.common.routing import create_router


config_cmd = create_router(
    {
        "help": lambda lib, argv, modifiers: usage.config(argv),
        "show": config.config_show,
        "backup": config.config_backup,
        "restore": config.config_restore,
        "checkpoint": create_router(
            {
                "list": config.config_checkpoint_list,
                "view": config.config_checkpoint_view,
                "restore": config.config_checkpoint_restore,
                "diff": config.config_checkpoint_diff,
            },
            ["config", "checkpoint"],
            default_cmd="list"
        ),
        "import-cman": config.config_import_cman,
        "export": create_router(
            {
                "pcs-commands": config.config_export_pcs_commands,
                "pcs-commands-verbose": lambda lib, argv, modifiers:
                    config.config_export_pcs_commands(
                        lib, argv, modifiers, verbose=True
                    )
Example #33
0
File: config.py Project: ldming/pcs
def config_export_pcs_commands(lib, argv, modifiers, verbose=False):
    """
    Options:
      * --force - skip checks, overwrite files
      * --interactive - interactive issue resolving
      * -f - CIB file
      * --corosync_conf
    """
    del lib
    modifiers.ensure_only_supported("--force", "--interactive", "-f",
                                    "--corosync_conf")
    if no_clufter:
        utils.err(
            "Unable to perform export due to missing python-clufter package")

    # parse options
    debug = modifiers.get("--debug")
    force = modifiers.get("--force")
    interactive = modifiers.get("--interactive")
    invalid_args = False
    output_file = None
    dist = None
    for arg in argv:
        if "=" in arg:
            name, value = arg.split("=", 1)
            if name == "output":
                output_file = value
            elif name == "dist":
                dist = value
            else:
                invalid_args = True
        else:
            invalid_args = True
    # check options
    if invalid_args:
        usage.config(["export pcs-commands"])
        sys.exit(1)
    # complete optional options
    if dist is None:
        dist = _get_linux_dist()

    # prepare convertor options
    clufter_args = {
        "nocheck": force,
        "batch": True,
        "sys": "linux",
        "dist": dist,
        "coro": settings.corosync_conf_file,
        "start_wait": "60",
        "tmp_cib": "tmp-cib.xml",
        "force": force,
        "text_width": "80",
        "silent": True,
        "noguidance": True,
    }
    if output_file:
        clufter_args["output"] = {"passin": "bytestring"}
    else:
        clufter_args["output"] = "-"
    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 utils.usefile:
        clufter_args["cib"] = os.path.abspath(utils.filename)
    else:
        clufter_args["cib"] = ("bytestring", utils.get_cib())
    if verbose:
        clufter_args["text_width"] = "-1"
        clufter_args["silent"] = False
        clufter_args["noguidance"] = False
    clufter_args_obj = type(str("ClufterOptions"), (object, ), clufter_args)
    cmd_name = "pcs2pcscmd-camelback"

    # run convertor
    run_clufter(
        cmd_name,
        clufter_args_obj,
        debug,
        force,
        "Error: unable to export cluster configuration",
    )

    # save commands if not printed to stdout by clufter
    if output_file:
        # pylint: disable=no-member
        ok, message = utils.write_file(
            output_file, clufter_args_obj.output["passout"].decode())
        if not ok:
            utils.err(message)
Example #34
0
from pcs import (
    config,
    usage,
)
from pcs.cli.common.routing import create_router

config_cmd = create_router(
    {
        "help":
        lambda lib, argv, modifiers: print(usage.config(argv)),
        "show":
        config.config_show,
        "backup":
        config.config_backup,
        "restore":
        config.config_restore,
        "checkpoint":
        create_router(
            {
                "list": config.config_checkpoint_list,
                "view": config.config_checkpoint_view,
                "restore": config.config_checkpoint_restore,
                "diff": config.config_checkpoint_diff,
            },
            ["config", "checkpoint"],
            default_cmd="list",
        ),
    },
    ["config"],
    default_cmd="show",
)