Пример #1
0
def location_rule(argv):
    if len(argv) < 3:
        usage.constraint(["location", "rule"])
        sys.exit(1)

    res_name = argv.pop(0)
    resource_valid, resource_error, correct_id \
        = utils.validate_constraint_resource(utils.get_cib_dom(), res_name)
    if "--autocorrect" in utils.pcs_options and correct_id:
        res_name = correct_id
    elif not resource_valid:
        utils.err(resource_error)

    argv.pop(0) # pop "rule"

    options, rule_argv = rule_utils.parse_argv(argv, {"constraint-id": None, "resource-discovery": None,})

    # If resource-discovery is specified, we use it with the rsc_location
    # element not the rule
    if "resource-discovery" in options and options["resource-discovery"]:
        utils.checkAndUpgradeCIB(2,2,0)
        cib, constraints = getCurrentConstraints(utils.get_cib_dom())
        lc = cib.createElement("rsc_location")
        lc.setAttribute("resource-discovery", options.pop("resource-discovery"))
    else:
        cib, constraints = getCurrentConstraints(utils.get_cib_dom())
        lc = cib.createElement("rsc_location")


    constraints.appendChild(lc)
    if options.get("constraint-id"):
        id_valid, id_error = utils.validate_xml_id(
            options["constraint-id"], 'constraint id'
        )
        if not id_valid:
            utils.err(id_error)
        if utils.does_id_exist(cib, options["constraint-id"]):
            utils.err(
                "id '%s' is already in use, please specify another one"
                % options["constraint-id"]
            )
        lc.setAttribute("id", options["constraint-id"])
        del options["constraint-id"]
    else:
        lc.setAttribute("id", utils.find_unique_id(cib, "location-" + res_name))
    lc.setAttribute("rsc", res_name)

    rule_utils.dom_rule_add(lc, options, rule_argv)
    location_rule_check_duplicates(constraints, lc)
    utils.replace_cib_configuration(cib)
Пример #2
0
def location_rule(argv):
    if len(argv) < 3:
        usage.constraint(["location", "rule"])
        sys.exit(1)

    res_name = argv.pop(0)
    resource_valid, resource_error, correct_id \
        = utils.validate_constraint_resource(utils.get_cib_dom(), res_name)
    if "--autocorrect" in utils.pcs_options and correct_id:
        res_name = correct_id
    elif not resource_valid:
        utils.err(resource_error)

    argv.pop(0) # pop "rule"

    options, rule_argv = rule_utils.parse_argv(argv, {"constraint-id": None, "resource-discovery": None,})

    # If resource-discovery is specified, we use it with the rsc_location
    # element not the rule
    if "resource-discovery" in options and options["resource-discovery"]:
        utils.checkAndUpgradeCIB(2,2,0)
        cib, constraints = getCurrentConstraints(utils.get_cib_dom())
        lc = cib.createElement("rsc_location")
        lc.setAttribute("resource-discovery", options.pop("resource-discovery"))
    else:
        cib, constraints = getCurrentConstraints(utils.get_cib_dom())
        lc = cib.createElement("rsc_location")


    constraints.appendChild(lc)
    if options.get("constraint-id"):
        id_valid, id_error = utils.validate_xml_id(
            options["constraint-id"], 'constraint id'
        )
        if not id_valid:
            utils.err(id_error)
        if utils.does_id_exist(cib, options["constraint-id"]):
            utils.err(
                "id '%s' is already in use, please specify another one"
                % options["constraint-id"]
            )
        lc.setAttribute("id", options["constraint-id"])
        del options["constraint-id"]
    else:
        lc.setAttribute("id", utils.find_unique_id(cib, "location-" + res_name))
    lc.setAttribute("rsc", res_name)

    rule_utils.dom_rule_add(lc, options, rule_argv)
    location_rule_check_duplicates(constraints, lc)
    utils.replace_cib_configuration(cib)
Пример #3
0
def run_role_delete(argv):
    if len(argv) < 1:
        usage.acl(["role delete"])
        sys.exit(1)

    role_id = argv.pop(0)
    dom = utils.get_cib_dom()
    found = False
    for elem in dom.getElementsByTagName("acl_role"):
        if elem.getAttribute("id") == role_id:
            found = True
            elem.parentNode.removeChild(elem)
            break
    if not found:
        utils.err("unable to find acl role: %s" % role_id)

    # Remove any references to this role in acl_target or acl_group
    for elem in dom.getElementsByTagName("role"):
        if elem.getAttribute("id") == role_id:
            user_group = elem.parentNode
            user_group.removeChild(elem)
            if "--autodelete" in utils.pcs_options:
                if not user_group.getElementsByTagName("role"):
                    user_group.parentNode.removeChild(user_group)

    utils.replace_cib_configuration(dom)
Пример #4
0
def print_node_utilization(filter_node=None, filter_name=None):
    cib = utils.get_cib_dom()

    node_element_list = cib.getElementsByTagName("node")


    if(
        filter_node
        and
        filter_node not in [
            node_element.getAttribute("uname")
            for node_element in node_element_list
        ]
        and (
            utils.usefile
            or
            filter_node not in [
                node_attrs.name for node_attrs
                in utils.getNodeAttributesFromPacemaker()
            ]
        )
    ):
        utils.err("Unable to find a node: {0}".format(filter_node))

    utilization = {}
    for node_el in node_element_list:
        node = node_el.getAttribute("uname")
        if filter_node is not None and node != filter_node:
            continue
        u = utils.get_utilization_str(node_el, filter_name)
        if u:
            utilization[node] = u
    print("Node Utilization:")
    for node in sorted(utilization):
        print(" {0}: {1}".format(node, utilization[node]))
Пример #5
0
def set_node_utilization(node, argv):
    cib = utils.get_cib_dom()
    node_el = utils.dom_get_node(cib, node)
    if node_el is None:
        if utils.usefile:
            utils.err("Unable to find a node: {0}".format(node))

        for attrs in utils.getNodeAttributesFromPacemaker():
            if attrs.name == node and attrs.type == "remote":
                node_attrs = attrs
                break
        else:
            utils.err("Unable to find a node: {0}".format(node))

        nodes_section_list = cib.getElementsByTagName("nodes")
        if len(nodes_section_list) == 0:
            utils.err("Unable to get nodes section of cib")

        dom = nodes_section_list[0].ownerDocument
        node_el = dom.createElement("node")
        node_el.setAttribute("id", node_attrs.id)
        node_el.setAttribute("type", node_attrs.type)
        node_el.setAttribute("uname", node_attrs.name)
        nodes_section_list[0].appendChild(node_el)

    utils.dom_update_utilization(node_el, prepare_options(argv), "nodes-")
    utils.replace_cib_configuration(cib)
Пример #6
0
def set_node_utilization(node, argv):
    cib = utils.get_cib_dom()
    node_el = utils.dom_get_node(cib, node)
    if node_el is None:
        if utils.usefile:
            utils.err("Unable to find a node: {0}".format(node))

        for attrs in utils.getNodeAttributesFromPacemaker():
            if attrs.name == node and attrs.type == "remote":
                node_attrs = attrs
                break
        else:
            utils.err("Unable to find a node: {0}".format(node))

        nodes_section_list = cib.getElementsByTagName("nodes")
        if len(nodes_section_list) == 0:
            utils.err("Unable to get nodes section of cib")

        dom = nodes_section_list[0].ownerDocument
        node_el = dom.createElement("node")
        node_el.setAttribute("id", node_attrs.id)
        node_el.setAttribute("type", node_attrs.type)
        node_el.setAttribute("uname", node_attrs.name)
        nodes_section_list[0].appendChild(node_el)

    utils.dom_update_utilization(node_el, prepare_options(argv), "nodes-")
    utils.replace_cib_configuration(cib)
Пример #7
0
def stonith_level_add(level, node, devices):
    dom = utils.get_cib_dom()

    if not re.search(r'^\d+$', level) or re.search(r'^0+$', level):
        utils.err("invalid level '{0}', use a positive integer".format(level))
    level = level.lstrip('0')
    if "--force" not in utils.pcs_options:
        for dev in devices.split(","):
            if not utils.is_stonith_resource(dev):
                utils.err("%s is not a stonith id (use --force to override)" % dev)
        if not utils.is_pacemaker_node(node) and not utils.is_corosync_node(node):
            utils.err("%s is not currently a node (use --force to override)" % node)

    ft = dom.getElementsByTagName("fencing-topology")
    if len(ft) == 0:
        conf = dom.getElementsByTagName("configuration")[0]
        ft = dom.createElement("fencing-topology")
        conf.appendChild(ft)
    else:
        ft = ft[0]

    fls = ft.getElementsByTagName("fencing-level")
    for fl in fls:
        if fl.getAttribute("target") == node and fl.getAttribute("index") == level and fl.getAttribute("devices") == devices:
            utils.err("unable to add fencing level, fencing level for node: %s, at level: %s, with device: %s already exists" % (node,level,devices))

    new_fl = dom.createElement("fencing-level")
    ft.appendChild(new_fl)
    new_fl.setAttribute("target", node)
    new_fl.setAttribute("index", level)
    new_fl.setAttribute("devices", devices)
    new_fl.setAttribute("id", utils.find_unique_id(dom, "fl-" + node +"-" + level))

    utils.replace_cib_configuration(dom)
Пример #8
0
def print_node_utilization(filter_node=None, filter_name=None):
    cib = utils.get_cib_dom()

    node_element_list = cib.getElementsByTagName("node")

    if (filter_node and filter_node not in [
            node_element.getAttribute("uname")
            for node_element in node_element_list
    ] and (utils.usefile or filter_node not in [
            node_attrs.name
            for node_attrs in utils.getNodeAttributesFromPacemaker()
    ])):
        utils.err("Unable to find a node: {0}".format(filter_node))

    utilization = {}
    for node_el in node_element_list:
        node = node_el.getAttribute("uname")
        if filter_node is not None and node != filter_node:
            continue
        u = utils.get_utilization_str(node_el, filter_name)
        if u:
            utilization[node] = u
    print("Node Utilization:")
    for node in sorted(utilization):
        print(" {0}: {1}".format(node, utilization[node]))
Пример #9
0
def set_property(lib, argv, modifiers):
    """
    Options:
      * --force - allow unknown options
      * -f - CIB file
    """
    del lib
    modifiers.ensure_only_supported(
        "--force",
        "-f",
        # The hint is defined to print error messages which point users to the
        # changes section in pcs manpage.
        # To be removed in the next significant version.
        hint_syntax_changed=modifiers.is_specified("--node"),
    )
    if not argv:
        raise CmdLineInputError()

    prop_def_dict = utils.get_cluster_properties_definition()
    failed = False
    forced = modifiers.get("--force")
    properties = {}
    for arg in argv:
        args = arg.split("=")
        if len(args) != 2:
            utils.err("invalid property format: '{0}'".format(arg), False)
            failed = True
        elif not args[0]:
            utils.err("empty property name: '{0}'".format(arg), False)
            failed = True
        elif forced or args[1].strip() == "":
            properties[args[0]] = args[1]
        else:
            try:
                if utils.is_valid_cluster_property(prop_def_dict, args[0],
                                                   args[1]):
                    properties[args[0]] = args[1]
                else:
                    utils.err(
                        "invalid value of property: '{0}', (use --force to "
                        "override)".format(arg),
                        False,
                    )
                    failed = True
            except utils.UnknownPropertyException:
                utils.err(
                    "unknown cluster property: '{0}', (use --force to "
                    "override)".format(args[0]),
                    False,
                )
                failed = True

    if failed:
        sys.exit(1)

    cib_dom = utils.get_cib_dom()
    for prop, value in properties.items():
        utils.set_cib_property(prop, value, cib_dom)
    utils.replace_cib_configuration(cib_dom)
Пример #10
0
def constraint_rule(argv):
    if len(argv) < 2:
        usage.constraint("rule")
        sys.exit(1)

    found = False
    command = argv.pop(0)


    constraint_id = None

    if command == "add":
        constraint_id = argv.pop(0)
        cib = utils.get_cib_dom()
        constraint = utils.dom_get_element_with_id(
            cib.getElementsByTagName("constraints")[0],
            "rsc_location",
            constraint_id
        )
        if not constraint:
            utils.err("Unable to find constraint: " + constraint_id)
        options, rule_argv = rule_utils.parse_argv(argv)
        rule_utils.dom_rule_add(constraint, options, rule_argv)
        location_rule_check_duplicates(cib, constraint)
        utils.replace_cib_configuration(cib)

    elif command in ["remove","delete"]:
        cib = utils.get_cib_etree()
        temp_id = argv.pop(0)
        constraints = cib.find('.//constraints')
        loc_cons = cib.findall(str('.//rsc_location'))

        for loc_con in loc_cons:
            for rule in loc_con:
                if rule.get("id") == temp_id:
                    if len(loc_con) > 1:
                        print("Removing Rule: {0}".format(rule.get("id")))
                        loc_con.remove(rule)
                        found = True
                        break
                    else:
                        print(
                            "Removing Constraint: {0}".format(loc_con.get("id"))
                        )
                        constraints.remove(loc_con)
                        found = True
                        break

            if found == True:
                break

        if found:
            utils.replace_cib_configuration(cib)
        else:
            utils.err("unable to find rule with id: %s" % temp_id)
    else:
        usage.constraint("rule")
        sys.exit(1)
Пример #11
0
def constraint_rule(argv):
    if len(argv) < 2:
        usage.constraint("rule")
        sys.exit(1)

    found = False
    command = argv.pop(0)


    constraint_id = None

    if command == "add":
        constraint_id = argv.pop(0)
        cib = utils.get_cib_dom()
        constraint = utils.dom_get_element_with_id(
            cib.getElementsByTagName("constraints")[0],
            "rsc_location",
            constraint_id
        )
        if not constraint:
            utils.err("Unable to find constraint: " + constraint_id)
        options, rule_argv = rule_utils.parse_argv(argv)
        rule_utils.dom_rule_add(constraint, options, rule_argv)
        location_rule_check_duplicates(cib, constraint)
        utils.replace_cib_configuration(cib)

    elif command in ["remove","delete"]:
        cib = utils.get_cib_etree()
        temp_id = argv.pop(0)
        constraints = cib.find('.//constraints')
        loc_cons = cib.findall(str('.//rsc_location'))

        for loc_con in loc_cons:
            for rule in loc_con:
                if rule.get("id") == temp_id:
                    if len(loc_con) > 1:
                        print("Removing Rule: {0}".format(rule.get("id")))
                        loc_con.remove(rule)
                        found = True
                        break
                    else:
                        print(
                            "Removing Constraint: {0}".format(loc_con.get("id"))
                        )
                        constraints.remove(loc_con)
                        found = True
                        break

            if found == True:
                break

        if found:
            utils.replace_cib_configuration(cib)
        else:
            utils.err("unable to find rule with id: %s" % temp_id)
    else:
        usage.constraint("rule")
        sys.exit(1)
Пример #12
0
def status_stonith_check():
    # We should read the default value from pacemaker. However that may slow
    # pcs down as we need to run 'pengine metadata' to get it.
    stonith_enabled = True
    stonith_devices = []
    stonith_devices_id_action = []
    stonith_devices_id_method_cycle = []
    sbd_running = False

    cib = utils.get_cib_dom()
    for conf in cib.getElementsByTagName("configuration"):
        for crm_config in conf.getElementsByTagName("crm_config"):
            for nvpair in crm_config.getElementsByTagName("nvpair"):
                if (nvpair.getAttribute("name") == "stonith-enabled"
                        and is_false(nvpair.getAttribute("value"))):
                    stonith_enabled = False
                    break
            if not stonith_enabled:
                break
        for resource in conf.getElementsByTagName("primitive"):
            if resource.getAttribute("class") == "stonith":
                stonith_devices.append(resource)
                for attribs in resource.getElementsByTagName(
                        "instance_attributes"):
                    for nvpair in attribs.getElementsByTagName("nvpair"):
                        if (nvpair.getAttribute("name") == "action"
                                and nvpair.getAttribute("value")):
                            stonith_devices_id_action.append(
                                resource.getAttribute("id"))
                        if (nvpair.getAttribute("name") == "method"
                                and nvpair.getAttribute("value") == "cycle"):
                            stonith_devices_id_method_cycle.append(
                                resource.getAttribute("id"))

    if not utils.usefile:
        # check if SBD daemon is running
        try:
            sbd_running = utils.is_service_running(utils.cmd_runner(),
                                                   get_sbd_service_name())
        except LibraryError:
            pass

    if stonith_enabled and not stonith_devices and not sbd_running:
        print("WARNING: no stonith devices and stonith-enabled is not false")

    if stonith_devices_id_action:
        print(
            "WARNING: following stonith devices have the 'action' option set, "
            "it is recommended to set {0} instead: {1}".format(
                ", ".join(
                    ["'{0}'".format(x) for x in _STONITH_ACTION_REPLACED_BY]),
                ", ".join(sorted(stonith_devices_id_action))))
    if stonith_devices_id_method_cycle:
        print(
            "WARNING: following stonith devices have the 'method' option set "
            "to 'cycle' which is potentially dangerous, please consider using "
            "'onoff': {0}".format(", ".join(
                sorted(stonith_devices_id_method_cycle))))
Пример #13
0
def print_node_utilization(node):
    cib = utils.get_cib_dom()
    node_el = utils.dom_get_node(cib, node)
    if node_el is None:
        utils.err("Unable to find a node: {0}".format(node))
    utilization = utils.get_utilization_str(node_el)

    print("Node Utilization:")
    print(" {0}: {1}".format(node, utilization))
Пример #14
0
def print_nodes_utilization():
    cib = utils.get_cib_dom()
    utilization = {}
    for node_el in cib.getElementsByTagName("node"):
        u = utils.get_utilization_str(node_el)
        if u:
            utilization[node_el.getAttribute("uname")] = u
    print("Node Utilization:")
    for node in sorted(utilization):
        print(" {0}: {1}".format(node, utilization[node]))
Пример #15
0
def set_node_utilization(node, argv):
    cib = utils.get_cib_dom()
    node_el = utils.dom_get_node(cib, node)
    if node_el is None:
        utils.err("Unable to find a node: {0}".format(node))

    utils.dom_update_utilization(
        node_el, utils.convert_args_to_tuples(argv), "nodes-"
    )
    utils.replace_cib_configuration(cib)
Пример #16
0
def stonith_level_rm(level, node, devices):
    dom = utils.get_cib_dom()

    if devices != "":
        node_devices_combo = node + "," + devices
    else:
        node_devices_combo = node

    ft = dom.getElementsByTagName("fencing-topology")
    if len(ft) == 0:
        utils.err(
            "unable to remove fencing level, fencing level for node: %s, at level: %s, with device: %s doesn't exist"
            % (node, level, devices))
    else:
        ft = ft[0]

    fls = ft.getElementsByTagName("fencing-level")

    if node != "":
        if devices != "":
            found = False
            for fl in fls:
                if fl.getAttribute("target") == node and fl.getAttribute(
                        "index") == level and fl.getAttribute(
                            "devices") == devices:
                    found = True
                    break

                if fl.getAttribute("index") == level and fl.getAttribute(
                        "devices") == node_devices_combo:
                    found = True
                    break

            if found == False:
                utils.err(
                    "unable to remove fencing level, fencing level for node: %s, at level: %s, with device: %s doesn't exist"
                    % (node, level, devices))

            fl.parentNode.removeChild(fl)
        else:
            for fl in fls:
                if fl.getAttribute("index") == level and (
                        fl.getAttribute("target") == node
                        or fl.getAttribute("devices") == node):
                    fl.parentNode.removeChild(fl)
    else:
        for fl in fls:
            if fl.getAttribute("index") == level:
                parent = fl.parentNode
                parent.removeChild(fl)
                if len(parent.getElementsByTagName("fencing-level")) == 0:
                    parent.parentNode.removeChild(parent)
                    break

    utils.replace_cib_configuration(dom)
Пример #17
0
def set_property(lib, argv, modifiers):
    """
    Options:
      * --force - allow unknown options
      * -f - CIB file
    """
    del lib
    modifiers.ensure_only_supported(
        "--force",
        "-f",
    )
    if not argv:
        raise CmdLineInputError()

    prop_def_dict = utils.get_cluster_properties_definition()
    failed = False
    forced = modifiers.get("--force")
    properties = {}
    for arg in argv:
        args = arg.split("=")
        if len(args) != 2:
            utils.err("invalid property format: '{0}'".format(arg), False)
            failed = True
        elif not args[0]:
            utils.err("empty property name: '{0}'".format(arg), False)
            failed = True
        elif forced or args[1].strip() == "":
            properties[args[0]] = args[1]
        else:
            try:
                if utils.is_valid_cluster_property(prop_def_dict, args[0],
                                                   args[1]):
                    properties[args[0]] = args[1]
                else:
                    utils.err(
                        "invalid value of property: '{0}', (use --force to "
                        "override)".format(arg),
                        False,
                    )
                    failed = True
            except utils.UnknownPropertyException:
                utils.err(
                    "unknown cluster property: '{0}', (use --force to "
                    "override)".format(args[0]),
                    False,
                )
                failed = True

    if failed:
        sys.exit(1)

    cib_dom = utils.get_cib_dom()
    for prop, value in properties.items():
        utils.set_cib_property(prop, value, cib_dom)
    utils.replace_cib_configuration(cib_dom)
Пример #18
0
def find_constraints_containing(resource_id, passed_dom=None):
    """
    Commandline options:
      * -f - CIB file, effective only if passed_dom is None
    """
    if passed_dom:
        dom = passed_dom
    else:
        dom = utils.get_cib_dom()
    constraints_found = []
    set_constraints = []

    resources = dom.getElementsByTagName("primitive")
    resource_match = None
    for res in resources:
        if res.getAttribute("id") == resource_id:
            resource_match = res
            break

    if resource_match:
        if (
            resource_match.parentNode.tagName == "master"
            or
            resource_match.parentNode.tagName == "clone"
        ):
            constraints_found, set_constraints = find_constraints_containing(
                resource_match.parentNode.getAttribute("id"),
                dom
            )

    constraints = dom.getElementsByTagName("constraints")
    if not constraints:
        return [], []

    constraints = constraints[0]
    myConstraints = constraints.getElementsByTagName("rsc_colocation")
    myConstraints += constraints.getElementsByTagName("rsc_location")
    myConstraints += constraints.getElementsByTagName("rsc_order")
    myConstraints += constraints.getElementsByTagName("rsc_ticket")
    attr_to_match = ["rsc", "first", "then", "with-rsc", "first", "then"]
    for c in myConstraints:
        for attr in attr_to_match:
            if c.getAttribute(attr) == resource_id:
                constraints_found.append(c.getAttribute("id"))
                break

    setConstraints = constraints.getElementsByTagName("resource_ref")
    for c in setConstraints:
        if c.getAttribute("id") == resource_id:
            set_constraints.append(c.parentNode.parentNode.getAttribute("id"))

    # Remove duplicates
    set_constraints = list(set(set_constraints))
    return constraints_found, set_constraints
Пример #19
0
def set_property(lib, argv, modifiers):
    """
    Options:
      * --force - allow unknown options
      * -f - CIB file
    """
    del lib
    modifiers.ensure_only_supported("--force", "-f")
    if not argv:
        raise CmdLineInputError()

    prop_def_dict = utils.get_cluster_properties_definition()
    failed = False
    forced = modifiers.get("--force")
    properties = {}
    for arg in argv:
        args = arg.split('=')
        if len(args) != 2:
            utils.err("invalid property format: '{0}'".format(arg), False)
            failed = True
        elif not args[0]:
            utils.err("empty property name: '{0}'".format(arg), False)
            failed = True
        elif forced or args[1].strip() == "":
            properties[args[0]] = args[1]
        else:
            try:
                if utils.is_valid_cluster_property(
                    prop_def_dict, args[0], args[1]
                ):
                    properties[args[0]] = args[1]
                else:
                    utils.err(
                        "invalid value of property: '{0}', (use --force to "
                        "override)".format(arg),
                        False
                    )
                    failed = True
            except utils.UnknownPropertyException:
                utils.err(
                    "unknown cluster property: '{0}', (use --force to "
                    "override)".format(args[0]),
                    False
                )
                failed = True

    if failed:
        sys.exit(1)

    cib_dom = utils.get_cib_dom()
    for prop, value in properties.items():
        utils.set_cib_property(prop, value, cib_dom)
    utils.replace_cib_configuration(cib_dom)
Пример #20
0
def stonith_level_verify():
    dom = utils.get_cib_dom()

    fls = dom.getElementsByTagName("fencing-level")
    for fl in fls:
        node = fl.getAttribute("target")
        devices = fl.getAttribute("devices")
        for dev in devices.split(","):
            if not utils.is_stonith_resource(dev):
                utils.err("%s is not a stonith id" % dev)
        if not utils.is_corosync_node(node) and not utils.is_pacemaker_node(node):
            utils.err("%s is not currently a node" % node)
Пример #21
0
def set_property(argv):
    if not argv:
        usage.property(['set'])
        sys.exit(1)

    prop_def_dict = utils.get_cluster_properties_definition()
    nodes_attr = "--node" in utils.pcs_options
    failed = False
    forced = "--force" in utils.pcs_options
    properties = {}
    for arg in argv:
        args = arg.split('=')
        if len(args) != 2:
            utils.err("invalid property format: '{0}'".format(arg), False)
            failed = True
        elif not args[0]:
            utils.err("empty property name: '{0}'".format(arg), False)
            failed = True
        elif nodes_attr or forced or args[1].strip() == "":
            properties[args[0]] = args[1]
        else:
            try:
                if utils.is_valid_cluster_property(
                    prop_def_dict, args[0], args[1]
                ):
                    properties[args[0]] = args[1]
                else:
                    utils.err(
                        "invalid value of property: '{0}', (use --force to "
                        "override)".format(arg),
                        False
                    )
                    failed = True
            except utils.UnknownPropertyException:
                utils.err(
                    "unknown cluster property: '{0}', (use --force to "
                    "override)".format(args[0]),
                    False
                )
                failed = True

    if failed:
        sys.exit(1)

    if nodes_attr:
        for prop, value in properties.items():
            utils.set_node_attribute(prop, value, utils.pcs_options["--node"])
    else:
        cib_dom = utils.get_cib_dom()
        for prop, value in properties.items():
            utils.set_cib_property(prop, value, cib_dom)
        utils.replace_cib_configuration(cib_dom)
Пример #22
0
def set_property(argv):
    if not argv:
        usage.property(['set'])
        sys.exit(1)

    prop_def_dict = utils.get_cluster_properties_definition()
    nodes_attr = "--node" in utils.pcs_options
    failed = False
    forced = "--force" in utils.pcs_options
    properties = {}
    for arg in argv:
        args = arg.split('=')
        if len(args) != 2:
            utils.err("invalid property format: '{0}'".format(arg), False)
            failed = True
        elif not args[0]:
            utils.err("empty property name: '{0}'".format(arg), False)
            failed = True
        elif nodes_attr or forced or args[1].strip() == "":
            properties[args[0]] = args[1]
        else:
            try:
                if utils.is_valid_cluster_property(
                    prop_def_dict, args[0], args[1]
                ):
                    properties[args[0]] = args[1]
                else:
                    utils.err(
                        "invalid value of property: '{0}', (use --force to "
                        "override)".format(arg),
                        False
                    )
                    failed = True
            except utils.UnknownPropertyException:
                utils.err(
                    "unknown cluster property: '{0}', (use --force to "
                    "override)".format(args[0]),
                    False
                )
                failed = True

    if failed:
        sys.exit(1)

    if nodes_attr:
        for prop, value in properties.items():
            utils.set_node_attribute(prop, value, utils.pcs_options["--node"])
    else:
        cib_dom = utils.get_cib_dom()
        for prop, value in properties.items():
            utils.set_cib_property(prop, value, cib_dom)
        utils.replace_cib_configuration(cib_dom)
Пример #23
0
def unset_property(argv):
    if len(argv) < 1:
        usage.property()
        sys.exit(1)

    if "--node" in utils.pcs_options:
        for arg in argv:
            utils.set_node_attribute(arg, "",utils.pcs_options["--node"])
    else:
        cib_dom = utils.get_cib_dom()
        for arg in argv:
            utils.set_cib_property(arg, "", cib_dom)
        utils.replace_cib_configuration(cib_dom)
Пример #24
0
def unset_property(argv):
    if len(argv) < 1:
        usage.property()
        sys.exit(1)

    if "--node" in utils.pcs_options:
        for arg in argv:
            utils.set_node_attribute(arg, "",utils.pcs_options["--node"])
    else:
        cib_dom = utils.get_cib_dom()
        for arg in argv:
            utils.set_cib_property(arg, "", cib_dom)
        utils.replace_cib_configuration(cib_dom)
Пример #25
0
def print_node_utilization(filter_node=None, filter_name=None):
    cib = utils.get_cib_dom()
    utilization = {}
    for node_el in cib.getElementsByTagName("node"):
        node = node_el.getAttribute("uname")
        if filter_node is not None and node != filter_node:
            continue
        u = utils.get_utilization_str(node_el, filter_name)
        if u:
            utilization[node] = u
    print("Node Utilization:")
    for node in sorted(utilization):
        print(" {0}: {1}".format(node, utilization[node]))
Пример #26
0
def unset_property(lib, argv, modifiers):
    """
    Options:
      * --force - no error when removing not existing properties
      * -f - CIB file
    """
    modifiers.ensure_only_supported("--force", "-f")
    if len(argv) < 1:
        raise CmdLineInputError()

    cib_dom = utils.get_cib_dom()
    for arg in argv:
        utils.set_cib_property(arg, "", cib_dom)
    utils.replace_cib_configuration(cib_dom)
Пример #27
0
def acl_show(argv):
    dom = utils.get_cib_dom()

    properties = prop.get_set_properties(defaults=prop.get_default_properties())
    acl_enabled = properties.get("enable-acl", "").lower()
    if is_true(acl_enabled):
        print("ACLs are enabled")
    else:
        print("ACLs are disabled, run 'pcs acl enable' to enable")
    print()

    print_targets(dom)
    print_groups(dom)
    print_roles(dom)
Пример #28
0
def unset_property(lib, argv, modifiers):
    """
    Options:
      * --force - no error when removing not existing properties
      * -f - CIB file
    """
    del lib
    modifiers.ensure_only_supported("--force", "-f")
    if not argv:
        raise CmdLineInputError()

    cib_dom = utils.get_cib_dom()
    for arg in argv:
        utils.set_cib_property(arg, "", cib_dom)
    utils.replace_cib_configuration(cib_dom)
Пример #29
0
def run_permission_delete(argv):
    dom = utils.get_cib_dom()
    if len(argv) < 1:
        usage.acl(["permission delete"])
        sys.exit(1)

    perm_id = argv.pop(0)
    found = False
    for elem in dom.getElementsByTagName("acl_permission"):
        if elem.getAttribute("id") == perm_id:
            elem.parentNode.removeChild(elem)
            found = True
    if not found:
        utils.err("Unable to find permission with id: %s" % perm_id)

    utils.replace_cib_configuration(dom)
Пример #30
0
def stonith_level_verify():
    dom = utils.get_cib_dom()
    corosync_nodes = []
    if utils.hasCorosyncConf():
        corosync_nodes = utils.getNodesFromCorosyncConf()
    pacemaker_nodes = utils.getNodesFromPacemaker()

    fls = dom.getElementsByTagName("fencing-level")
    for fl in fls:
        node = fl.getAttribute("target")
        devices = fl.getAttribute("devices")
        for dev in devices.split(","):
            if not utils.is_stonith_resource(dev):
                utils.err("%s is not a stonith id" % dev)
        if node not in corosync_nodes and node not in pacemaker_nodes:
            utils.err("%s is not currently a node" % node)
Пример #31
0
def stonith_level_verify():
    dom = utils.get_cib_dom()
    corosync_nodes = []
    if utils.hasCorosyncConf():
        corosync_nodes = utils.getNodesFromCorosyncConf()
    pacemaker_nodes = utils.getNodesFromPacemaker()

    fls = dom.getElementsByTagName("fencing-level")
    for fl in fls:
        node = fl.getAttribute("target")
        devices = fl.getAttribute("devices")
        for dev in devices.split(","):
            if not utils.is_stonith_resource(dev):
                utils.err("%s is not a stonith id" % dev)
        if node not in corosync_nodes and node not in pacemaker_nodes:
            utils.err("%s is not currently a node" % node)
Пример #32
0
def stonith_level_rm(level, node, devices):
    dom = utils.get_cib_dom()

    if devices != "":
        node_devices_combo  = node + "," + devices
    else:
        node_devices_combo = node

    ft = dom.getElementsByTagName("fencing-topology")
    if len(ft) == 0:
        utils.err("unable to remove fencing level, fencing level for node: %s, at level: %s, with device: %s doesn't exist" % (node,level,devices))
    else:
        ft = ft[0]

    fls = ft.getElementsByTagName("fencing-level")

    if node != "":
        if devices != "":
            found = False
            for fl in fls:
                if fl.getAttribute("target") == node and fl.getAttribute("index") == level and fl.getAttribute("devices") == devices:
                    found = True
                    break

                if fl.getAttribute("index") == level and fl.getAttribute("devices") == node_devices_combo:
                    found = True
                    break

            if found == False:
                utils.err("unable to remove fencing level, fencing level for node: %s, at level: %s, with device: %s doesn't exist" % (node,level,devices))

            fl.parentNode.removeChild(fl)
        else:
            for fl in fls:
                if fl.getAttribute("index") == level and (fl.getAttribute("target") == node or fl.getAttribute("devices") == node):
                    fl.parentNode.removeChild(fl)
    else:
        for fl in fls:
            if fl.getAttribute("index") == level:
                parent = fl.parentNode
                parent.removeChild(fl)
                if len(parent.getElementsByTagName("fencing-level")) == 0:
                    parent.parentNode.removeChild(parent)
                    break

    utils.replace_cib_configuration(dom)
Пример #33
0
def set_node_utilization(node, argv):
    """
    Commandline options:
      * -f - CIB file
    """
    nvpair_dict = prepare_options(argv)
    if not nvpair_dict:
        return
    only_removing = True
    for value in nvpair_dict.values():
        if value != "":
            only_removing = False
            break

    cib = utils.get_cib_dom()
    node_el = utils.dom_get_node(cib, node)
    if node_el is None:
        if utils.usefile:
            utils.err("Unable to find a node: {0}".format(node))

        for attrs in utils.getNodeAttributesFromPacemaker():
            if attrs.name == node and attrs.type == "remote":
                node_attrs = attrs
                break
        else:
            utils.err("Unable to find a node: {0}".format(node))

        nodes_section_list = cib.getElementsByTagName("nodes")
        if not nodes_section_list:
            utils.err("Unable to get nodes section of cib")

        if only_removing:
            # Do not create new node if we are only removing values from it.
            return

        dom = nodes_section_list[0].ownerDocument
        node_el = dom.createElement("node")
        node_el.setAttribute("id", node_attrs.id)
        node_el.setAttribute("type", node_attrs.type)
        node_el.setAttribute("uname", node_attrs.name)
        nodes_section_list[0].appendChild(node_el)

    utils.dom_update_utilization(node_el, nvpair_dict, "nodes-")
    utils.replace_cib_configuration(cib)
Пример #34
0
def set_node_utilization(node, argv):
    """
    Commandline options:
      * -f - CIB file
    """
    nvpair_dict = prepare_options(argv)
    if not nvpair_dict:
        return
    only_removing = True
    for value in nvpair_dict.values():
        if value != "":
            only_removing = False
            break

    cib = utils.get_cib_dom()
    node_el = utils.dom_get_node(cib, node)
    if node_el is None:
        if utils.usefile:
            utils.err("Unable to find a node: {0}".format(node))

        for attrs in utils.getNodeAttributesFromPacemaker():
            if attrs.name == node and attrs.type == "remote":
                node_attrs = attrs
                break
        else:
            utils.err("Unable to find a node: {0}".format(node))

        nodes_section_list = cib.getElementsByTagName("nodes")
        if not nodes_section_list:
            utils.err("Unable to get nodes section of cib")

        if only_removing:
            # Do not create new node if we are only removing values from it.
            return

        dom = nodes_section_list[0].ownerDocument
        node_el = dom.createElement("node")
        node_el.setAttribute("id", node_attrs.id)
        node_el.setAttribute("type", node_attrs.type)
        node_el.setAttribute("uname", node_attrs.name)
        nodes_section_list[0].appendChild(node_el)

    utils.dom_update_utilization(node_el, nvpair_dict, "nodes-")
    utils.replace_cib_configuration(cib)
Пример #35
0
def stonith_level_add(level, node, devices):
    dom = utils.get_cib_dom()

    if not re.search(r'^\d+$', level) or re.search(r'^0+$', level):
        utils.err("invalid level '{0}', use a positive integer".format(level))
    level = level.lstrip('0')
    if "--force" not in utils.pcs_options:
        for dev in devices.split(","):
            if not utils.is_stonith_resource(dev):
                utils.err("%s is not a stonith id (use --force to override)" %
                          dev)
        corosync_nodes = []
        if utils.hasCorosyncConf():
            corosync_nodes = utils.getNodesFromCorosyncConf()
        pacemaker_nodes = utils.getNodesFromPacemaker()
        if node not in corosync_nodes and node not in pacemaker_nodes:
            utils.err("%s is not currently a node (use --force to override)" %
                      node)

    ft = dom.getElementsByTagName("fencing-topology")
    if len(ft) == 0:
        conf = dom.getElementsByTagName("configuration")[0]
        ft = dom.createElement("fencing-topology")
        conf.appendChild(ft)
    else:
        ft = ft[0]

    fls = ft.getElementsByTagName("fencing-level")
    for fl in fls:
        if fl.getAttribute("target") == node and fl.getAttribute(
                "index") == level and fl.getAttribute("devices") == devices:
            utils.err(
                "unable to add fencing level, fencing level for node: %s, at level: %s, with device: %s already exists"
                % (node, level, devices))

    new_fl = dom.createElement("fencing-level")
    ft.appendChild(new_fl)
    new_fl.setAttribute("target", node)
    new_fl.setAttribute("index", level)
    new_fl.setAttribute("devices", devices)
    new_fl.setAttribute("id",
                        utils.find_unique_id(dom, "fl-" + node + "-" + level))

    utils.replace_cib_configuration(dom)
Пример #36
0
def find_constraints_containing(resource_id, passed_dom=None):
    if passed_dom:
        dom = passed_dom
    else:
        dom = utils.get_cib_dom()
    constraints_found = []
    set_constraints = []

    resources = dom.getElementsByTagName("primitive")
    resource_match = None
    for res in resources:
        if res.getAttribute("id") == resource_id:
            resource_match = res
            break

    if resource_match:
        if resource_match.parentNode.tagName == "master" or resource_match.parentNode.tagName == "clone":
            constraints_found,set_constraints = find_constraints_containing(resource_match.parentNode.getAttribute("id"), dom)

    constraints = dom.getElementsByTagName("constraints")
    if len(constraints) == 0:
        return [],[]
    else:
        constraints = constraints[0]

    myConstraints = constraints.getElementsByTagName("rsc_colocation")
    myConstraints += constraints.getElementsByTagName("rsc_location")
    myConstraints += constraints.getElementsByTagName("rsc_order")
    myConstraints += constraints.getElementsByTagName("rsc_ticket")
    attr_to_match = ["rsc", "first", "then", "with-rsc", "first", "then"]
    for c in myConstraints:
        for attr in attr_to_match:
            if c.getAttribute(attr) == resource_id:
                constraints_found.append(c.getAttribute("id"))
                break

    setConstraints = constraints.getElementsByTagName("resource_ref")
    for c in setConstraints:
        if c.getAttribute("id") == resource_id:
            set_constraints.append(c.parentNode.parentNode.getAttribute("id"))

    # Remove duplicates
    set_constraints = list(set(set_constraints))
    return constraints_found,set_constraints
Пример #37
0
def run_role_assign(argv):
    if len(argv) < 2:
        usage.acl(["role assign"])
        sys.exit(1)

    if len(argv) == 2:
        role_id = argv[0]
        ug_id = argv[1]
    elif len(argv) > 2 and argv[1] == "to":
        role_id = argv[0]
        ug_id = argv[2]
    else:
        usage.acl(["role assign"])
        sys.exit(1)

    dom = utils.get_cib_dom()
    found = False
    for role in dom.getElementsByTagName("acl_role"):
        if role.getAttribute("id") == role_id:
            found = True
            break

    if not found:
        utils.err("cannot find role: %s" % role_id)

    found = False
    for ug in dom.getElementsByTagName("acl_target") + dom.getElementsByTagName("acl_group"):
        if ug.getAttribute("id") == ug_id:
            found = True
            break

    if not found:
        utils.err("cannot find user or group: %s" % ug_id)

    for current_role in ug.getElementsByTagName("role"):
        if current_role.getAttribute("id") == role_id:
            utils.err(role_id + " is already assigned to " + ug_id)

    new_role = dom.createElement("role")
    new_role.setAttribute("id", role_id)
    ug.appendChild(new_role)
    utils.replace_cib_configuration(dom)
Пример #38
0
def stonith_level_clear(node = None):
    dom = utils.get_cib_dom()
    ft = dom.getElementsByTagName("fencing-topology")

    if len(ft) == 0:
        return

    if node == None:
        ft = ft[0]
        childNodes = ft.childNodes[:]
        for node in childNodes:
            node.parentNode.removeChild(node)
    else:
        fls = dom.getElementsByTagName("fencing-level")
        if len(fls) == 0:
            return
        for fl in fls:
            if fl.getAttribute("target") == node or fl.getAttribute("devices") == node:
                fl.parentNode.removeChild(fl)

    utils.replace_cib_configuration(dom)
Пример #39
0
def unset_property(lib, argv, modifiers):
    """
    Options:
      * --force - no error when removing not existing properties
      * -f - CIB file
    """
    del lib
    modifiers.ensure_only_supported(
        "--force", "-f",
        # The hint is defined to print error messages which point users to the
        # changes section in pcs manpage.
        # To be removed in the next significant version.
        hint_syntax_changed=modifiers.is_specified("--node")
    )
    if not argv:
        raise CmdLineInputError()

    cib_dom = utils.get_cib_dom()
    for arg in argv:
        utils.set_cib_property(arg, "", cib_dom)
    utils.replace_cib_configuration(cib_dom)
Пример #40
0
def stonith_level_clear(node=None):
    dom = utils.get_cib_dom()
    ft = dom.getElementsByTagName("fencing-topology")

    if len(ft) == 0:
        return

    if node == None:
        ft = ft[0]
        childNodes = ft.childNodes[:]
        for node in childNodes:
            node.parentNode.removeChild(node)
    else:
        fls = dom.getElementsByTagName("fencing-level")
        if len(fls) == 0:
            return
        for fl in fls:
            if fl.getAttribute("target") == node or fl.getAttribute(
                    "devices") == node:
                fl.parentNode.removeChild(fl)

    utils.replace_cib_configuration(dom)
Пример #41
0
def constraint_resource_update(old_id, passed_dom=None):
    dom = utils.get_cib_dom() if passed_dom is None else passed_dom

    new_id = None
    clone_ms_parent = utils.dom_get_resource_clone_ms_parent(dom, old_id)
    if clone_ms_parent:
        new_id = clone_ms_parent.getAttribute("id")

    if new_id:
        constraints = dom.getElementsByTagName("rsc_location")
        constraints += dom.getElementsByTagName("rsc_order")
        constraints += dom.getElementsByTagName("rsc_colocation")
        attrs_to_update = ["rsc", "first", "then", "with-rsc"]
        for constraint in constraints:
            for attr in attrs_to_update:
                if constraint.getAttribute(attr) == old_id:
                    constraint.setAttribute(attr, new_id)

        if passed_dom is None:
            utils.replace_cib_configuration(dom)

    if passed_dom:
        return dom
Пример #42
0
def constraint_resource_update(old_id, passed_dom=None):
    dom = utils.get_cib_dom() if passed_dom is None else passed_dom

    new_id = None
    clone_ms_parent = utils.dom_get_resource_clone_ms_parent(dom, old_id)
    if clone_ms_parent:
        new_id = clone_ms_parent.getAttribute("id")

    if new_id:
        constraints = dom.getElementsByTagName("rsc_location")
        constraints += dom.getElementsByTagName("rsc_order")
        constraints += dom.getElementsByTagName("rsc_colocation")
        attrs_to_update=["rsc","first","then", "with-rsc"]
        for constraint in constraints:
            for attr in attrs_to_update:
                if constraint.getAttribute(attr) == old_id:
                    constraint.setAttribute(attr, new_id)

        if passed_dom is None:
            utils.replace_cib_configuration(dom)

    if passed_dom:
        return dom
Пример #43
0
def stonith_level_show():
    dom = utils.get_cib_dom()

    node_levels = {}
    fls = dom.getElementsByTagName("fencing-level")
    for fl in fls:
        node = fl.getAttribute("target")
        level = fl.getAttribute("index")
        devices = fl.getAttribute("devices")

        if node in node_levels:
            node_levels[node].append((level,devices))
        else:
            node_levels[node] = [(level,devices)]

    if len(node_levels.keys()) == 0:
        return

    nodes = sorted(node_levels.keys())

    for node in nodes:
        print(" Node: " + node)
        for level in sorted(node_levels[node], key=lambda x: int(x[0])):
            print("  Level " + level[0] + " - " + level[1])
Пример #44
0
def stonith_level_show():
    dom = utils.get_cib_dom()

    node_levels = {}
    fls = dom.getElementsByTagName("fencing-level")
    for fl in fls:
        node = fl.getAttribute("target")
        level = fl.getAttribute("index")
        devices = fl.getAttribute("devices")

        if node in node_levels:
            node_levels[node].append((level, devices))
        else:
            node_levels[node] = [(level, devices)]

    if len(node_levels.keys()) == 0:
        return

    nodes = sorted(node_levels.keys())

    for node in nodes:
        print(" Node: " + node)
        for level in sorted(node_levels[node], key=lambda x: int(x[0])):
            print("  Level " + level[0] + " - " + level[1])
Пример #45
0
def run_role_unassign(argv):
    if len(argv) < 2:
        usage.acl(["role unassign"])
        sys.exit(1)

    role_id = argv.pop(0)
    if len(argv) > 1 and argv[0] == "from":
        ug_id = argv[1]
    else:
        ug_id = argv[0]

    dom = utils.get_cib_dom()
    found = False
    for ug in dom.getElementsByTagName("acl_target") + dom.getElementsByTagName("acl_group"):
        if ug.getAttribute("id") == ug_id:
            found = True
            break

    if not found:
        utils.err("cannot find user or group: %s" % ug_id)

    found = False
    for current_role in ug.getElementsByTagName("role"):
        if current_role.getAttribute("id") == role_id:
            found = True
            current_role.parentNode.removeChild(current_role)
            break

    if not found:
        utils.err("cannot find role: %s, assigned to user/group: %s" % (role_id, ug_id))

    if "--autodelete" in utils.pcs_options:
        if not ug.getElementsByTagName("role"):
            ug.parentNode.removeChild(ug)

    utils.replace_cib_configuration(dom)
Пример #46
0
def location_add(argv,rm=False):
    if len(argv) < 4 and (rm == False or len(argv) < 1):
        usage.constraint()
        sys.exit(1)

    constraint_id = argv.pop(0)

    # If we're removing, we only care about the id
    if (rm == True):
        resource_name = ""
        node = ""
        score = ""
    else:
        id_valid, id_error = utils.validate_xml_id(constraint_id, 'constraint id')
        if not id_valid:
            utils.err(id_error)
        resource_name = argv.pop(0)
        node = argv.pop(0)
        score = argv.pop(0)
        options = []
        # For now we only allow setting resource-discovery
        if len(argv) > 0:
            for arg in argv:
                if '=' in arg:
                    options.append(arg.split('=',1))
                else:
                    print("Error: bad option '%s'" % arg)
                    usage.constraint(["location add"])
                    sys.exit(1)
                if options[-1][0] != "resource-discovery" and "--force" not in utils.pcs_options:
                    utils.err("bad option '%s', use --force to override" % options[-1][0])


        resource_valid, resource_error, correct_id \
            = utils.validate_constraint_resource(
                utils.get_cib_dom(), resource_name
            )
        if "--autocorrect" in utils.pcs_options and correct_id:
            resource_name = correct_id
        elif not resource_valid:
            utils.err(resource_error)
        if not utils.is_score(score):
            utils.err("invalid score '%s', use integer or INFINITY or -INFINITY" % score)

    # Verify current constraint doesn't already exist
    # If it does we replace it with the new constraint
    (dom,constraintsElement) = getCurrentConstraints()
    elementsToRemove = []

    # If the id matches, or the rsc & node match, then we replace/remove
    for rsc_loc in constraintsElement.getElementsByTagName('rsc_location'):
        if (constraint_id == rsc_loc.getAttribute("id")) or \
                (rsc_loc.getAttribute("rsc") == resource_name and \
                rsc_loc.getAttribute("node") == node and not rm):
            elementsToRemove.append(rsc_loc)

    for etr in elementsToRemove:
        constraintsElement.removeChild(etr)

    if (rm == True and len(elementsToRemove) == 0):
        utils.err("resource location id: " + constraint_id + " not found.")

    if (not rm):
        element = dom.createElement("rsc_location")
        element.setAttribute("id",constraint_id)
        element.setAttribute("rsc",resource_name)
        element.setAttribute("node",node)
        element.setAttribute("score",score)
        for option in options:
            element.setAttribute(option[0], option[1])
        constraintsElement.appendChild(element)

    utils.replace_cib_configuration(dom)
Пример #47
0
def location_add(argv, rm=False):
    if rm:
        location_remove(argv)
        return

    if len(argv) < 4:
        usage.constraint(["location add"])
        sys.exit(1)

    constraint_id = argv.pop(0)
    rsc_type, rsc_value = parse_args.parse_typed_arg(
        argv.pop(0), [RESOURCE_TYPE_RESOURCE, RESOURCE_TYPE_REGEXP],
        RESOURCE_TYPE_RESOURCE)
    node = argv.pop(0)
    score = argv.pop(0)
    options = []
    # For now we only allow setting resource-discovery
    if len(argv) > 0:
        for arg in argv:
            if '=' in arg:
                options.append(arg.split('=', 1))
            else:
                print("Error: bad option '%s'" % arg)
                usage.constraint(["location add"])
                sys.exit(1)
            if options[-1][
                    0] != "resource-discovery" and "--force" not in utils.pcs_options:
                utils.err("bad option '%s', use --force to override" %
                          options[-1][0])

    id_valid, id_error = utils.validate_xml_id(constraint_id, 'constraint id')
    if not id_valid:
        utils.err(id_error)

    if not utils.is_score(score):
        utils.err("invalid score '%s', use integer or INFINITY or -INFINITY" %
                  score)

    required_version = None
    if [x for x in options if x[0] == "resource-discovery"]:
        required_version = 2, 2, 0
    if rsc_type == RESOURCE_TYPE_REGEXP:
        required_version = 2, 6, 0

    if required_version:
        dom = utils.cluster_upgrade_to_version(required_version)
    else:
        dom = utils.get_cib_dom()

    if rsc_type == RESOURCE_TYPE_RESOURCE:
        rsc_valid, rsc_error, correct_id = utils.validate_constraint_resource(
            dom, rsc_value)
        if "--autocorrect" in utils.pcs_options and correct_id:
            rsc_value = correct_id
        elif not rsc_valid:
            utils.err(rsc_error)

    # Verify current constraint doesn't already exist
    # If it does we replace it with the new constraint
    dummy_dom, constraintsElement = getCurrentConstraints(dom)
    elementsToRemove = []
    # If the id matches, or the rsc & node match, then we replace/remove
    for rsc_loc in constraintsElement.getElementsByTagName('rsc_location'):
        if (rsc_loc.getAttribute("id") == constraint_id
                or (rsc_loc.getAttribute("node") == node and
                    ((RESOURCE_TYPE_RESOURCE == rsc_type
                      and rsc_loc.getAttribute("rsc") == rsc_value) or
                     (RESOURCE_TYPE_REGEXP == rsc_type
                      and rsc_loc.getAttribute("rsc-pattern") == rsc_value)))):
            elementsToRemove.append(rsc_loc)
    for etr in elementsToRemove:
        constraintsElement.removeChild(etr)

    element = dom.createElement("rsc_location")
    element.setAttribute("id", constraint_id)
    if rsc_type == RESOURCE_TYPE_RESOURCE:
        element.setAttribute("rsc", rsc_value)
    elif rsc_type == RESOURCE_TYPE_REGEXP:
        element.setAttribute("rsc-pattern", rsc_value)
    element.setAttribute("node", node)
    element.setAttribute("score", score)
    for option in options:
        element.setAttribute(option[0], option[1])
    constraintsElement.appendChild(element)

    utils.replace_cib_configuration(dom)
Пример #48
0
def status_stonith_check(modifiers):
    """
    Commandline options:
      * -f - CIB file, to get stonith devices and cluster property
        stonith-enabled from CIB, to determine whenever we are working with
        files or cluster
    """
    # pylint: disable=too-many-nested-blocks
    # We should read the default value from pacemaker. However that may slow
    # pcs down as we need to run 'pacemaker-schedulerd metadata' to get it.
    warnings = []
    stonith_enabled = True
    stonith_devices = []
    stonith_devices_id_action = []
    stonith_devices_id_method_cycle = []
    sbd_running = False

    cib = utils.get_cib_dom()
    for conf in cib.getElementsByTagName("configuration"):
        for crm_config in conf.getElementsByTagName("crm_config"):
            for nvpair in crm_config.getElementsByTagName("nvpair"):
                if (nvpair.getAttribute("name") == "stonith-enabled"
                        and is_false(nvpair.getAttribute("value"))):
                    stonith_enabled = False
                    break
            if not stonith_enabled:
                break
        for resource_el in conf.getElementsByTagName("primitive"):
            if resource_el.getAttribute("class") == "stonith":
                stonith_devices.append(resource_el)
                for attribs in resource_el.getElementsByTagName(
                        "instance_attributes"):
                    for nvpair in attribs.getElementsByTagName("nvpair"):
                        if (nvpair.getAttribute("name") == "action"
                                and nvpair.getAttribute("value")):
                            stonith_devices_id_action.append(
                                resource_el.getAttribute("id"))
                        if (nvpair.getAttribute("name") == "method"
                                and nvpair.getAttribute("value") == "cycle"):
                            stonith_devices_id_method_cycle.append(
                                resource_el.getAttribute("id"))

    if not modifiers.is_specified("-f"):
        # check if SBD daemon is running
        try:
            sbd_running = utils.is_service_running(utils.cmd_runner(),
                                                   get_sbd_service_name())
        except LibraryError:
            pass

    if stonith_enabled and not stonith_devices and not sbd_running:
        warnings.append("No stonith devices and stonith-enabled is not false")

    if stonith_devices_id_action:
        warnings.append(
            "Following stonith devices have the 'action' option set, "
            "it is recommended to set {0} instead: {1}".format(
                ", ".join(
                    ["'{0}'".format(x) for x in _STONITH_ACTION_REPLACED_BY]),
                ", ".join(sorted(stonith_devices_id_action))))
    if stonith_devices_id_method_cycle:
        warnings.append(
            "Following stonith devices have the 'method' option set "
            "to 'cycle' which is potentially dangerous, please consider using "
            "'onoff': {0}".format(", ".join(
                sorted(stonith_devices_id_method_cycle))))
    return warnings
Пример #49
0
def _config_show_cib_lines(lib):
    """
    Commandline options:
      * -f - CIB file
    """
    # update of pcs_options will change output of constraint show
    utils.pcs_options["--full"] = 1
    # get latest modifiers object after updating pcs_options
    modifiers = utils.get_input_modifiers()
    cib_xml = utils.get_cib()
    cib_etree = utils.get_cib_etree(cib_xml=cib_xml)
    cib_dom = utils.get_cib_dom(cib_xml=cib_xml)

    resource_lines = []
    stonith_lines = []
    for resource_el in cib_etree.find(".//resources"):
        is_stonith = ("class" in resource_el.attrib
                      and resource_el.attrib["class"] == "stonith")
        resource_el_lines = resource.resource_node_lines(resource_el)
        if is_stonith:
            stonith_lines += resource_el_lines
        else:
            resource_lines += resource_el_lines

    all_lines = []

    all_lines.append("Resources:")
    all_lines.extend(indent(resource_lines, indent_step=1))
    all_lines.append("")
    all_lines.append("Stonith Devices:")
    all_lines.extend(indent(stonith_lines, indent_step=1))
    all_lines.append("Fencing Levels:")
    levels_lines = stonith.stonith_level_config_to_str(
        lib.fencing_topology.get_config())
    if levels_lines:
        all_lines.extend(indent(levels_lines, indent_step=2))

    all_lines.append("")
    constraints_element = cib_dom.getElementsByTagName("constraints")[0]
    all_lines.extend(
        constraint.location_lines(
            constraints_element,
            showDetail=True,
            show_expired=True,
            verify_expiration=False,
        ))
    all_lines.extend(
        constraint_command.show(
            "Ordering Constraints:",
            lib.constraint_order.show,
            constraints_reports.order_plain,
            modifiers.get_subset("-f", "--full"),
        ))
    all_lines.extend(
        constraint_command.show(
            "Colocation Constraints:",
            lib.constraint_colocation.show,
            constraints_reports.colocation_plain,
            modifiers.get_subset("-f", "--full"),
        ))
    all_lines.extend(
        constraint_command.show(
            "Ticket Constraints:",
            lib.constraint_ticket.show,
            constraints_reports.ticket_plain,
            modifiers.get_subset("-f", "--full"),
        ))

    all_lines.append("")
    all_lines.extend(alert.alert_config_lines(lib))

    all_lines.append("")
    all_lines.append("Resources Defaults:")
    all_lines.extend(
        indent(resource.show_defaults(cib_dom, "rsc_defaults"), indent_step=1))
    all_lines.append("Operations Defaults:")
    all_lines.extend(
        indent(resource.show_defaults(cib_dom, "op_defaults"), indent_step=1))

    all_lines.append("")
    all_lines.append("Cluster Properties:")
    properties = utils.get_set_properties()
    all_lines.extend(
        indent(
            [
                "{0}: {1}".format(prop, val)
                for prop, val in sorted(properties.items())
            ],
            indent_step=1,
        ))
    all_lines.append("")
    all_lines.append("Tags:")
    tags = lib.tag.config([])
    if not tags:
        all_lines.append(" No tags defined")
    tag_lines = []
    for tag in tags:
        tag_lines.append(tag["tag_id"])
        tag_lines.extend(indent(tag["idref_list"]))
    all_lines.extend(indent(tag_lines, indent_step=1))
    return all_lines
Пример #50
0
def cluster_remote_node(argv):
    usage_add = """\
    remote-node add <hostname> <resource id> [options]
        Enables the specified resource as a remote-node resource on the
        specified hostname (hostname should be the same as 'uname -n')."""
    usage_remove = """\
    remote-node remove <hostname>
        Disables any resources configured to be remote-node resource on the
        specified hostname (hostname should be the same as 'uname -n')."""

    if len(argv) < 1:
        print("\nUsage: pcs cluster remote-node...")
        print(usage_add)
        print()
        print(usage_remove)
        print()
        sys.exit(1)

    command = argv.pop(0)
    if command == "add":
        if len(argv) < 2:
            print("\nUsage: pcs cluster remote-node add...")
            print(usage_add)
            print()
            sys.exit(1)
        if "--force" in utils.pcs_options:
            warn(
                "this command is deprecated, use 'pcs cluster node add-guest'")
        else:
            raise error(
                "this command is deprecated, use 'pcs cluster node add-guest'"
                ", use --force to override")
        hostname = argv.pop(0)
        rsc = argv.pop(0)
        if not utils.dom_get_resource(utils.get_cib_dom(), rsc):
            utils.err("unable to find resource '%s'" % rsc)
        resource.resource_update(rsc,
                                 ["meta", "remote-node=" + hostname] + argv,
                                 deal_with_guest_change=False)

    elif command in ["remove", "delete"]:
        if len(argv) < 1:
            print("\nUsage: pcs cluster remote-node remove...")
            print(usage_remove)
            print()
            sys.exit(1)
        if "--force" in utils.pcs_options:
            warn("this command is deprecated, use"
                 " 'pcs cluster node remove-guest'")
        else:
            raise error("this command is deprecated, use 'pcs cluster node"
                        " remove-guest', use --force to override")
        hostname = argv.pop(0)
        dom = utils.get_cib_dom()
        nvpairs = dom.getElementsByTagName("nvpair")
        nvpairs_to_remove = []
        for nvpair in nvpairs:
            if nvpair.getAttribute(
                    "name") == "remote-node" and nvpair.getAttribute(
                        "value") == hostname:
                for np in nvpair.parentNode.getElementsByTagName("nvpair"):
                    if np.getAttribute("name").startswith("remote-"):
                        nvpairs_to_remove.append(np)

        if len(nvpairs_to_remove) == 0:
            utils.err("unable to remove: cannot find remote-node '%s'" %
                      hostname)

        for nvpair in nvpairs_to_remove[:]:
            nvpair.parentNode.removeChild(nvpair)
        dom = constraint.remove_constraints_containing_node(dom, hostname)
        utils.replace_cib_configuration(dom)
        if not utils.usefile:
            output, retval = utils.run(
                ["crm_node", "--force", "--remove", hostname])
            if retval != 0:
                utils.err("unable to remove: {0}".format(output))
    else:
        print("\nUsage: pcs cluster remote-node...")
        print(usage_add)
        print()
        print(usage_remove)
        print()
        sys.exit(1)
Пример #51
0
def _config_show_cib_lines(lib):
    """
    Commandline options:
      * -f - CIB file
    """
    # update of pcs_options will change output of constraint show and
    # displaying resources and operations defaults
    utils.pcs_options["--full"] = 1
    # get latest modifiers object after updating pcs_options
    modifiers = utils.get_input_modifiers()
    cib_dom = utils.get_cib_dom()

    resources_facade = ResourcesConfigurationFacade.from_resources_dto(
        lib.resource.get_configured_resources())

    all_lines = []

    all_lines.append("Resources:")
    all_lines.extend(
        smart_wrap_text(
            indent(
                resources_to_text(resources_facade.filter_stonith(False)),
                indent_step=INDENT_STEP,
            )))
    all_lines.append("")
    all_lines.append("Stonith Devices:")
    all_lines.extend(
        smart_wrap_text(
            indent(
                resources_to_text(resources_facade.filter_stonith(True)),
                indent_step=INDENT_STEP,
            )))
    all_lines.append("Fencing Levels:")
    levels_lines = stonith.stonith_level_config_to_str(
        lib.fencing_topology.get_config())
    if levels_lines:
        all_lines.extend(indent(levels_lines, indent_step=2))

    all_lines.append("")
    constraints_element = cib_dom.getElementsByTagName("constraints")[0]
    all_lines.extend(
        constraint.location_lines(
            constraints_element,
            showDetail=True,
            show_expired=True,
            verify_expiration=False,
        ))
    all_lines.extend(
        constraint_command.config_cmd(
            "Ordering Constraints:",
            lib.constraint_order.config,
            constraints_reports.order_plain,
            modifiers.get_subset("-f", "--full"),
        ))
    all_lines.extend(
        constraint_command.config_cmd(
            "Colocation Constraints:",
            lib.constraint_colocation.config,
            constraints_reports.colocation_plain,
            modifiers.get_subset("-f", "--full"),
        ))
    all_lines.extend(
        constraint_command.config_cmd(
            "Ticket Constraints:",
            lib.constraint_ticket.config,
            constraints_reports.ticket_plain,
            modifiers.get_subset("-f", "--full"),
        ))

    all_lines.append("")
    all_lines.extend(alert.alert_config_lines(lib))

    all_lines.append("")
    all_lines.append("Resources Defaults:")
    all_lines.extend(
        indent(
            nvset_dto_list_to_lines(
                lib.cib_options.resource_defaults_config(
                    evaluate_expired=False).meta_attributes,
                nvset_label="Meta Attrs",
                with_ids=modifiers.get("--full"),
                text_if_empty="No defaults set",
            )))
    all_lines.append("Operations Defaults:")
    all_lines.extend(
        indent(
            nvset_dto_list_to_lines(
                lib.cib_options.operation_defaults_config(
                    evaluate_expired=False).meta_attributes,
                nvset_label="Meta Attrs",
                with_ids=modifiers.get("--full"),
                text_if_empty="No defaults set",
            )))

    all_lines.append("")
    all_lines.append("Cluster Properties:")
    properties = utils.get_set_properties()
    all_lines.extend(
        indent(
            [
                "{0}: {1}".format(prop, val)
                for prop, val in sorted(properties.items())
            ],
            indent_step=1,
        ))
    all_lines.append("")
    all_lines.append("Tags:")
    tags = lib.tag.config([])
    if not tags:
        all_lines.append(" No tags defined")
    tag_lines = []
    for tag in tags:
        tag_lines.append(tag["tag_id"])
        tag_lines.extend(indent(tag["idref_list"]))
    all_lines.extend(indent(tag_lines, indent_step=1))
    return all_lines
Пример #52
0
def location_add(lib, argv, modifiers):
    """
    Options:
      * --force - allow unknown options, allow constraint for any resource type
      * -f - CIB file
    """
    del lib
    modifiers.ensure_only_supported("--force", "-f")
    if len(argv) < 4:
        raise CmdLineInputError()

    constraint_id = argv.pop(0)
    rsc_type, rsc_value = parse_args.parse_typed_arg(
        argv.pop(0), [RESOURCE_TYPE_RESOURCE, RESOURCE_TYPE_REGEXP],
        RESOURCE_TYPE_RESOURCE)
    node = argv.pop(0)
    score = argv.pop(0)
    options = []
    # For now we only allow setting resource-discovery
    if argv:
        for arg in argv:
            if '=' in arg:
                options.append(arg.split('=', 1))
            else:
                raise CmdLineInputError(f"bad option '{arg}'")
            if (options[-1][0] != "resource-discovery"
                    and not modifiers.get("--force")):
                utils.err("bad option '%s', use --force to override" %
                          options[-1][0])

    id_valid, id_error = utils.validate_xml_id(constraint_id, 'constraint id')
    if not id_valid:
        utils.err(id_error)

    if not utils.is_score(score):
        utils.err("invalid score '%s', use integer or INFINITY or -INFINITY" %
                  score)

    required_version = None
    if [x for x in options if x[0] == "resource-discovery"]:
        required_version = 2, 2, 0
    if rsc_type == RESOURCE_TYPE_REGEXP:
        required_version = 2, 6, 0

    if required_version:
        dom = utils.cluster_upgrade_to_version(required_version)
    else:
        dom = utils.get_cib_dom()

    if rsc_type == RESOURCE_TYPE_RESOURCE:
        rsc_valid, rsc_error, dummy_correct_id = (
            utils.validate_constraint_resource(dom, rsc_value))
        if not rsc_valid:
            utils.err(rsc_error)

    # Verify that specified node exists in the cluster
    if not (modifiers.is_specified("-f") or modifiers.get("--force")):
        lib_env = utils.get_lib_env()
        existing_nodes = get_existing_nodes_names(
            corosync_conf=lib_env.get_corosync_conf(),
            cib=lib_env.get_cib(),
        )
        if node not in existing_nodes:
            raise error(f"Node '{node}' does not seem to be in the cluster"
                        ", use --force to override")
    else:
        warn(LOCATION_NODE_VALIDATION_SKIP_MSG)

    # Verify current constraint doesn't already exist
    # If it does we replace it with the new constraint
    dummy_dom, constraintsElement = getCurrentConstraints(dom)
    elementsToRemove = []
    # If the id matches, or the rsc & node match, then we replace/remove
    for rsc_loc in constraintsElement.getElementsByTagName('rsc_location'):
        # pylint: disable=too-many-boolean-expressions
        if (rsc_loc.getAttribute("id") == constraint_id
                or (rsc_loc.getAttribute("node") == node and
                    ((RESOURCE_TYPE_RESOURCE == rsc_type
                      and rsc_loc.getAttribute("rsc") == rsc_value) or
                     (RESOURCE_TYPE_REGEXP == rsc_type
                      and rsc_loc.getAttribute("rsc-pattern") == rsc_value)))):
            elementsToRemove.append(rsc_loc)
    for etr in elementsToRemove:
        constraintsElement.removeChild(etr)

    element = dom.createElement("rsc_location")
    element.setAttribute("id", constraint_id)
    if rsc_type == RESOURCE_TYPE_RESOURCE:
        element.setAttribute("rsc", rsc_value)
    elif rsc_type == RESOURCE_TYPE_REGEXP:
        element.setAttribute("rsc-pattern", rsc_value)
    element.setAttribute("node", node)
    element.setAttribute("score", score)
    for option in options:
        element.setAttribute(option[0], option[1])
    constraintsElement.appendChild(element)

    utils.replace_cib_configuration(dom)
Пример #53
0
def location_rule(lib, argv, modifiers):
    """
    Options:
      * -f - CIB file
      * --force - allow constraint on any resource type, allow duplicate
        constraints
    """
    del lib
    modifiers.ensure_only_supported("-f", "--force")
    if len(argv) < 3:
        usage.constraint(["location", "rule"])
        sys.exit(1)

    rsc_type, rsc_value = parse_args.parse_typed_arg(
        argv.pop(0), [RESOURCE_TYPE_RESOURCE, RESOURCE_TYPE_REGEXP],
        RESOURCE_TYPE_RESOURCE)
    argv.pop(0)  # pop "rule"
    options, rule_argv = rule_utils.parse_argv(argv, {
        "constraint-id": None,
        "resource-discovery": None,
    })
    resource_discovery = ("resource-discovery" in options
                          and options["resource-discovery"])

    required_version = None
    if resource_discovery:
        required_version = 2, 2, 0
    if rsc_type == RESOURCE_TYPE_REGEXP:
        required_version = 2, 6, 0

    if required_version:
        dom = utils.cluster_upgrade_to_version(required_version)
    else:
        dom = utils.get_cib_dom()

    if rsc_type == RESOURCE_TYPE_RESOURCE:
        rsc_valid, rsc_error, dummy_correct_id = (
            utils.validate_constraint_resource(dom, rsc_value))
        if not rsc_valid:
            utils.err(rsc_error)

    cib, constraints = getCurrentConstraints(dom)
    lc = cib.createElement("rsc_location")

    # If resource-discovery is specified, we use it with the rsc_location
    # element not the rule
    if resource_discovery:
        lc.setAttribute("resource-discovery",
                        options.pop("resource-discovery"))

    constraints.appendChild(lc)
    if options.get("constraint-id"):
        id_valid, id_error = utils.validate_xml_id(options["constraint-id"],
                                                   'constraint id')
        if not id_valid:
            utils.err(id_error)
        if utils.does_id_exist(dom, options["constraint-id"]):
            utils.err("id '%s' is already in use, please specify another one" %
                      options["constraint-id"])
        lc.setAttribute("id", options["constraint-id"])
        del options["constraint-id"]
    else:
        lc.setAttribute(
            "id",
            utils.find_unique_id(dom, sanitize_id("location-" + rsc_value)))
    if rsc_type == RESOURCE_TYPE_RESOURCE:
        lc.setAttribute("rsc", rsc_value)
    elif rsc_type == RESOURCE_TYPE_REGEXP:
        lc.setAttribute("rsc-pattern", rsc_value)

    rule_utils.dom_rule_add(lc, options, rule_argv)
    location_rule_check_duplicates(constraints, lc, modifiers.get("--force"))
    utils.replace_cib_configuration(cib)
Пример #54
0
def order_add(argv, modifiers):
    """
    Commandline options:
      * -f - CIB file
      * --force - allow constraint for any resource, allow duplicate constraints
    """
    if len(argv) < 2:
        raise CmdLineInputError()

    resource1 = argv.pop(0)
    resource2 = argv.pop(0)

    cib_dom = utils.get_cib_dom()
    resource_valid, resource_error, dummy_correct_id \
        = utils.validate_constraint_resource(cib_dom, resource1)
    if not resource_valid:
        utils.err(resource_error)
    resource_valid, resource_error, dummy_correct_id \
        = utils.validate_constraint_resource(cib_dom, resource2)
    if not resource_valid:
        utils.err(resource_error)

    order_options = []
    id_specified = False
    sym = None
    for arg in argv:
        if arg == "symmetrical":
            sym = "true"
        elif arg == "nonsymmetrical":
            sym = "false"
        elif "=" in arg:
            name, value = arg.split("=", 1)
            if name == "id":
                id_valid, id_error = utils.validate_xml_id(
                    value, 'constraint id')
                if not id_valid:
                    utils.err(id_error)
                if utils.does_id_exist(cib_dom, value):
                    utils.err(
                        "id '%s' is already in use, please specify another one"
                        % value)
                id_specified = True
                order_options.append((name, value))
            elif name == "symmetrical":
                if value.lower() in OPTIONS_SYMMETRICAL:
                    sym = value.lower()
                else:
                    utils.err(
                        "invalid symmetrical value '%s', allowed values are: %s"
                        % (value, ", ".join(OPTIONS_SYMMETRICAL)))
            else:
                order_options.append((name, value))
    if sym:
        order_options.append(("symmetrical", sym))

    options = ""
    if order_options:
        options = " (Options: %s)" % " ".join([
            "%s=%s" % (name, value)
            for name, value in order_options if name not in ("kind", "score")
        ])

    scorekind = "kind: Mandatory"
    id_suffix = "mandatory"
    for opt in order_options:
        if opt[0] == "score":
            scorekind = "score: " + opt[1]
            id_suffix = opt[1]
            break
        if opt[0] == "kind":
            scorekind = "kind: " + opt[1]
            id_suffix = opt[1]
            break

    if not id_specified:
        order_id = "order-" + resource1 + "-" + resource2 + "-" + id_suffix
        order_id = utils.find_unique_id(cib_dom, order_id)
        order_options.append(("id", order_id))

    (dom, constraintsElement) = getCurrentConstraints()
    element = dom.createElement("rsc_order")
    element.setAttribute("first", resource1)
    element.setAttribute("then", resource2)
    for order_opt in order_options:
        element.setAttribute(order_opt[0], order_opt[1])
    constraintsElement.appendChild(element)
    if not modifiers.get("--force"):
        duplicates = order_find_duplicates(constraintsElement, element)
        if duplicates:
            utils.err(
                "duplicate constraint already exists, use --force to override\n"
                + "\n".join([
                    "  " + constraint_order.console_report.constraint_plain(
                        {"options": dict(dup.attributes.items())}, True)
                    for dup in duplicates
                ]))
    print("Adding " + resource1 + " " + resource2 + " (" + scorekind + ")" +
          options)

    utils.replace_cib_configuration(dom)
Пример #55
0
def colocation_add(argv):
    if len(argv) < 2:
        usage.constraint()
        sys.exit(1)

    role1 = ""
    role2 = ""
    if len(argv) > 2:
        if not utils.is_score_or_opt(argv[2]):
            if argv[2] == "with":
                role1 = argv.pop(0).lower().capitalize()
                resource1 = argv.pop(0)
            else:
                resource1 = argv.pop(0)

            argv.pop(0) # Pop 'with'

            if len(argv) == 1:
                resource2 = argv.pop(0)
            else:
                if utils.is_score_or_opt(argv[1]):
                    resource2 = argv.pop(0)
                else:
                    role2 = argv.pop(0).lower().capitalize()
                    resource2 = argv.pop(0)
        else:
            resource1 = argv.pop(0)
            resource2 = argv.pop(0)
    else:
        resource1 = argv.pop(0)
        resource2 = argv.pop(0)

    cib_dom = utils.get_cib_dom()
    resource_valid, resource_error, correct_id \
        = utils.validate_constraint_resource(cib_dom, resource1)
    if "--autocorrect" in utils.pcs_options and correct_id:
        resource1 = correct_id
    elif not resource_valid:
        utils.err(resource_error)
    resource_valid, resource_error, correct_id \
        = utils.validate_constraint_resource(cib_dom, resource2)
    if "--autocorrect" in utils.pcs_options and correct_id:
        resource2 = correct_id
    elif not resource_valid:
        utils.err(resource_error)

    score,nv_pairs = parse_score_options(argv)
    id_in_nvpairs = None
    for name, value in nv_pairs:
        if name == "id":
            id_valid, id_error = utils.validate_xml_id(value, 'constraint id')
            if not id_valid:
                utils.err(id_error)
            if utils.does_id_exist(cib_dom, value):
                utils.err(
                    "id '%s' is already in use, please specify another one"
                    % value
                )
            id_in_nvpairs = True
    if not id_in_nvpairs:
        nv_pairs.append((
            "id",
            utils.find_unique_id(
                cib_dom,
                "colocation-%s-%s-%s" % (resource1, resource2, score)
            )
        ))

    (dom,constraintsElement) = getCurrentConstraints(cib_dom)

# If one role is specified, the other should default to "started"
    if role1 != "" and role2 == "":
        role2 = DEFAULT_ROLE
    if role2 != "" and role1 == "":
        role1 = DEFAULT_ROLE
    element = dom.createElement("rsc_colocation")
    element.setAttribute("rsc",resource1)
    element.setAttribute("with-rsc",resource2)
    element.setAttribute("score",score)
    if role1 != "":
        element.setAttribute("rsc-role", role1)
    if role2 != "":
        element.setAttribute("with-rsc-role", role2)
    for nv_pair in nv_pairs:
        element.setAttribute(nv_pair[0], nv_pair[1])
    if "--force" not in utils.pcs_options:
        duplicates = colocation_find_duplicates(constraintsElement, element)
        if duplicates:
            utils.err(
                "duplicate constraint already exists, use --force to override\n"
                + "\n".join([
                    "  " + constraint_colocation.console_report.constraint_plain(
                            {"options": dict(dup.attributes.items())},
                            True
                        )
                    for dup in duplicates
                ])
            )
    constraintsElement.appendChild(element)
    utils.replace_cib_configuration(dom)
Пример #56
0
def constraint_rule(lib, argv, modifiers):
    """
    Options:
      * -f - CIB file
      * --force - allow duplicate constraints, only for add command

    NOTE: modifiers check is in subcommand
    """
    del lib
    if len(argv) < 2:
        raise CmdLineInputError()

    found = False
    command = argv.pop(0)

    constraint_id = None

    if command == "add":
        modifiers.ensure_only_supported("-f", "--force")
        constraint_id = argv.pop(0)
        cib = utils.get_cib_dom()
        constraint = utils.dom_get_element_with_id(
            cib.getElementsByTagName("constraints")[0], "rsc_location",
            constraint_id)
        if not constraint:
            utils.err("Unable to find constraint: " + constraint_id)
        options, rule_argv = rule_utils.parse_argv(argv)
        rule_utils.dom_rule_add(constraint, options, rule_argv)
        location_rule_check_duplicates(cib, constraint,
                                       modifiers.get("--force"))
        utils.replace_cib_configuration(cib)

    elif command in ["remove", "delete"]:
        modifiers.ensure_only_supported("-f")
        cib = utils.get_cib_etree()
        temp_id = argv.pop(0)
        constraints = cib.find('.//constraints')
        loc_cons = cib.findall(str('.//rsc_location'))

        for loc_con in loc_cons:
            for rule in loc_con:
                if rule.get("id") == temp_id:
                    if len(loc_con) > 1:
                        print("Removing Rule: {0}".format(rule.get("id")))
                        loc_con.remove(rule)
                        found = True
                        break
                    else:
                        print("Removing Constraint: {0}".format(
                            loc_con.get("id")))
                        constraints.remove(loc_con)
                        found = True
                        break

            if found:
                break

        if found:
            utils.replace_cib_configuration(cib)
        else:
            utils.err("unable to find rule with id: %s" % temp_id)
    else:
        raise CmdLineInputError()
Пример #57
0
def order_add(argv,returnElementOnly=False):
    if len(argv) < 2:
        usage.constraint()
        sys.exit(1)

    resource1 = argv.pop(0)
    resource2 = argv.pop(0)

    cib_dom = utils.get_cib_dom()
    resource_valid, resource_error, correct_id \
        = utils.validate_constraint_resource(cib_dom, resource1)
    if "--autocorrect" in utils.pcs_options and correct_id:
        resource1 = correct_id
    elif not resource_valid:
        utils.err(resource_error)
    resource_valid, resource_error, correct_id \
        = utils.validate_constraint_resource(cib_dom, resource2)
    if "--autocorrect" in utils.pcs_options and correct_id:
        resource2 = correct_id
    elif not resource_valid:
        utils.err(resource_error)

    order_options = []
    id_specified = False
    sym = None
    for arg in argv:
        if arg == "symmetrical":
            sym = "true"
        elif arg == "nonsymmetrical":
            sym = "false"
        elif "=" in arg:
            name, value = arg.split("=", 1)
            if name == "id":
                id_valid, id_error = utils.validate_xml_id(value, 'constraint id')
                if not id_valid:
                    utils.err(id_error)
                if utils.does_id_exist(cib_dom, value):
                    utils.err(
                        "id '%s' is already in use, please specify another one"
                        % value
                    )
                id_specified = True
                order_options.append((name, value))
            elif name == "symmetrical":
                if value.lower() in OPTIONS_SYMMETRICAL:
                    sym = value.lower()
                else:
                    utils.err(
                        "invalid symmetrical value '%s', allowed values are: %s"
                        % (value, ", ".join(OPTIONS_SYMMETRICAL))
                    )
            else:
                order_options.append((name, value))
    if sym:
        order_options.append(("symmetrical", sym))

    options = ""
    if order_options:
        options = " (Options: %s)" % " ".join([
            "%s=%s" % (name, value)
                for name, value in order_options
                    if name not in ("kind", "score")
        ])

    scorekind = "kind: Mandatory"
    id_suffix = "mandatory"
    for opt in order_options:
        if opt[0] == "score":
            scorekind = "score: " + opt[1]
            id_suffix = opt[1]
            break
        if opt[0] == "kind":
            scorekind = "kind: " + opt[1]
            id_suffix = opt[1]
            break

    if not id_specified:
        order_id = "order-" + resource1 + "-" + resource2 + "-" + id_suffix
        order_id = utils.find_unique_id(cib_dom, order_id)
        order_options.append(("id", order_id))

    (dom,constraintsElement) = getCurrentConstraints()
    element = dom.createElement("rsc_order")
    element.setAttribute("first",resource1)
    element.setAttribute("then",resource2)
    for order_opt in order_options:
        element.setAttribute(order_opt[0], order_opt[1])
    constraintsElement.appendChild(element)
    if "--force" not in utils.pcs_options:
        duplicates = order_find_duplicates(constraintsElement, element)
        if duplicates:
            utils.err(
                "duplicate constraint already exists, use --force to override\n"
                + "\n".join([
                    "  " + constraint_order.console_report.constraint_plain(
                            {"options": dict(dup.attributes.items())},
                            True
                        ) for dup in duplicates
                ])
            )
    print(
        "Adding " + resource1 + " " + resource2 + " ("+scorekind+")" + options
    )

    if returnElementOnly == False:
        utils.replace_cib_configuration(dom)
    else:
        return element.toxml()
Пример #58
0
def acl_target(argv,group=False):
    if len(argv) < 2:
        if group:
            usage.acl(["group"])
            sys.exit(1)
        else:
            usage.acl(["user"])
            sys.exit(1)

    dom = utils.get_cib_dom()
    acls = utils.get_acls(dom)

    command = argv.pop(0)
    tug_id = argv.pop(0)
    if command == "create":
        # pcsd parses the error message in order to determine whether the id is
        # assigned to user/group or some other cib element
        if group and utils.dom_get_element_with_id(dom, "acl_group", tug_id):
            utils.err("group %s already exists" % tug_id)
        if not group and utils.dom_get_element_with_id(dom, "acl_target", tug_id):
            utils.err("user %s already exists" % tug_id)
        if utils.does_id_exist(dom,tug_id):
            utils.err(tug_id + " already exists")

        if group:
            element = dom.createElement("acl_group")
        else:
            element = dom.createElement("acl_target")
        element.setAttribute("id", tug_id)

        acls.appendChild(element)
        for role in argv:
            if not utils.dom_get_element_with_id(acls, "acl_role", role):
                utils.err("cannot find acl role: %s" % role)
            r = dom.createElement("role")
            r.setAttribute("id", role)
            element.appendChild(r)

        utils.replace_cib_configuration(dom)
    elif command == "delete":
        found = False
        if group:
            elist = dom.getElementsByTagName("acl_group")
        else:
            elist = dom.getElementsByTagName("acl_target")

        for elem in elist:
            if elem.getAttribute("id") == tug_id:
                found = True
                elem.parentNode.removeChild(elem)
                break
        if not found:
            if group:
                utils.err("unable to find acl group: %s" % tug_id)
            else:
                utils.err("unable to find acl target/user: %s" % tug_id)
        utils.replace_cib_configuration(dom)
    else:
        if group:
            usage.acl(["group"])
        else:
            usage.acl(["user"])
        sys.exit(1)
Пример #59
0
def colocation_add(lib, argv, modifiers):
    """
    Options:
      * -f - CIB file
      * --force - allow constraint on any resource, allow duplicate constraints
    """
    del lib
    modifiers.ensure_only_supported("-f", "--force")
    if len(argv) < 3:
        raise CmdLineInputError()

    role1 = ""
    role2 = ""

    if argv[2] == "with":
        role1 = argv.pop(0).lower().capitalize()
        resource1 = argv.pop(0)
    elif argv[1] == "with":
        resource1 = argv.pop(0)
    else:
        raise CmdLineInputError()

    argv.pop(0)  # Pop 'with'

    if not argv:
        raise CmdLineInputError()
    elif len(argv) == 1:
        resource2 = argv.pop(0)
    else:
        if utils.is_score_or_opt(argv[1]):
            resource2 = argv.pop(0)
        else:
            role2 = argv.pop(0).lower().capitalize()
            resource2 = argv.pop(0)

    score, nv_pairs = parse_score_options(argv)

    cib_dom = utils.get_cib_dom()
    resource_valid, resource_error, dummy_correct_id \
        = utils.validate_constraint_resource(cib_dom, resource1)
    if not resource_valid:
        utils.err(resource_error)
    resource_valid, resource_error, dummy_correct_id \
        = utils.validate_constraint_resource(cib_dom, resource2)
    if not resource_valid:
        utils.err(resource_error)

    id_in_nvpairs = None
    for name, value in nv_pairs:
        if name == "id":
            id_valid, id_error = utils.validate_xml_id(value, 'constraint id')
            if not id_valid:
                utils.err(id_error)
            if utils.does_id_exist(cib_dom, value):
                utils.err(
                    "id '%s' is already in use, please specify another one" %
                    value)
            id_in_nvpairs = True
    if not id_in_nvpairs:
        nv_pairs.append(
            ("id",
             utils.find_unique_id(
                 cib_dom,
                 "colocation-%s-%s-%s" % (resource1, resource2, score))))

    (dom, constraintsElement) = getCurrentConstraints(cib_dom)

    # If one role is specified, the other should default to "started"
    if role1 != "" and role2 == "":
        role2 = DEFAULT_ROLE
    if role2 != "" and role1 == "":
        role1 = DEFAULT_ROLE
    element = dom.createElement("rsc_colocation")
    element.setAttribute("rsc", resource1)
    element.setAttribute("with-rsc", resource2)
    element.setAttribute("score", score)
    if role1 != "":
        element.setAttribute("rsc-role", role1)
    if role2 != "":
        element.setAttribute("with-rsc-role", role2)
    for nv_pair in nv_pairs:
        element.setAttribute(nv_pair[0], nv_pair[1])
    if not modifiers.get("--force"):
        duplicates = colocation_find_duplicates(constraintsElement, element)
        if duplicates:
            utils.err(
                "duplicate constraint already exists, use --force to override\n"
                + "\n".join([
                    "  " +
                    constraint_colocation.console_report.constraint_plain(
                        {"options": dict(dup.attributes.items())}, True)
                    for dup in duplicates
                ]))
    constraintsElement.appendChild(element)
    utils.replace_cib_configuration(dom)
Пример #60
0
def colocation_add(lib, argv, modifiers):
    """
    Options:
      * -f - CIB file
      * --force - allow constraint on any resource, allow duplicate constraints
    """
    def _parse_score_options(argv):
        # When passed an array of arguments if the first argument doesn't have
        # an '=' then it's the score, otherwise they're all arguments. Return a
        # tuple with the score and array of name,value pairs
        """
        Commandline options: no options
        """
        if not argv:
            return SCORE_INFINITY, []
        score = SCORE_INFINITY if "=" in argv[0] else argv.pop(0)
        # create a list of 2-tuples (name, value)
        arg_array = [
            parse_args.split_option(arg, allow_empty_value=False)
            for arg in argv
        ]
        return score, arg_array

    def _validate_and_prepare_role(role):
        role_cleaned = role.lower().capitalize()
        if role_cleaned not in RESOURCE_ROLES:
            utils.err(
                "invalid role value '{0}', allowed values are: '{1}'".format(
                    role, "', '".join(RESOURCE_ROLES)))
        return role_cleaned

    del lib
    modifiers.ensure_only_supported("-f", "--force")
    if len(argv) < 3:
        raise CmdLineInputError()

    role1 = ""
    role2 = ""

    if argv[2] == "with":
        role1 = _validate_and_prepare_role(argv.pop(0))
        resource1 = argv.pop(0)
    elif argv[1] == "with":
        resource1 = argv.pop(0)
    else:
        raise CmdLineInputError()

    if argv.pop(0) != "with":
        raise CmdLineInputError()
    if "with" in argv:
        raise CmdLineInputError(
            message="Multiple 'with's cannot be specified.",
            hint=(
                "Use the 'pcs constraint colocation set' command if you want "
                "to create a constraint for more than two resources."),
            show_both_usage_and_message=True)

    if not argv:
        raise CmdLineInputError()
    if len(argv) == 1:
        resource2 = argv.pop(0)
    else:
        if utils.is_score_or_opt(argv[1]):
            resource2 = argv.pop(0)
        else:
            role2 = _validate_and_prepare_role(argv.pop(0))
            resource2 = argv.pop(0)

    score, nv_pairs = _parse_score_options(argv)

    cib_dom = utils.get_cib_dom()
    _validate_constraint_resource(cib_dom, resource1)
    _validate_constraint_resource(cib_dom, resource2)

    id_in_nvpairs = None
    for name, value in nv_pairs:
        if name == "id":
            id_valid, id_error = utils.validate_xml_id(value, 'constraint id')
            if not id_valid:
                utils.err(id_error)
            if utils.does_id_exist(cib_dom, value):
                utils.err(
                    "id '%s' is already in use, please specify another one" %
                    value)
            id_in_nvpairs = True
    if not id_in_nvpairs:
        nv_pairs.append(
            ("id",
             utils.find_unique_id(
                 cib_dom,
                 "colocation-%s-%s-%s" % (resource1, resource2, score))))

    (dom, constraintsElement) = getCurrentConstraints(cib_dom)

    # If one role is specified, the other should default to "started"
    if role1 != "" and role2 == "":
        role2 = DEFAULT_ROLE
    if role2 != "" and role1 == "":
        role1 = DEFAULT_ROLE
    element = dom.createElement("rsc_colocation")
    element.setAttribute("rsc", resource1)
    element.setAttribute("with-rsc", resource2)
    element.setAttribute("score", score)
    if role1 != "":
        element.setAttribute("rsc-role", role1)
    if role2 != "":
        element.setAttribute("with-rsc-role", role2)
    for nv_pair in nv_pairs:
        element.setAttribute(nv_pair[0], nv_pair[1])
    if not modifiers.get("--force"):
        duplicates = colocation_find_duplicates(constraintsElement, element)
        if duplicates:
            utils.err(
                "duplicate constraint already exists, use --force to override\n"
                + "\n".join([
                    "  " +
                    constraint_colocation.console_report.constraint_plain(
                        {"options": dict(dup.attributes.items())}, True)
                    for dup in duplicates
                ]))
    constraintsElement.appendChild(element)
    utils.replace_cib_configuration(dom)