Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for role in location_prefers and location_add #242

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 46 additions & 11 deletions pcs/constraint.py
Original file line number Diff line number Diff line change
Expand Up @@ -853,6 +853,15 @@ def _verify_score(score):
% score
)

def _verify_and_prepare_role(role):
role_cleaned = role.lower().capitalize()
if role_cleaned not in ["Master", "Slave"]:
utils.err(
"invalid role '%s', use 'master' or 'slave'"
% role
)
return role_cleaned

def _get_rule_status(rule_id, cib):
_, _, retval = utils.cmd_runner().run(
[settings.crm_rule, "--check", "--rule=" + rule_id, "-X-"],
Expand All @@ -873,14 +882,24 @@ def location_prefer(lib, argv, modifiers):
"""
modifiers.ensure_only_supported("--force", "-f")
rsc = argv.pop(0)
prefer_option = argv.pop(0)

dummy_rsc_type, rsc_value = parse_args.parse_typed_arg(
rsc,
[RESOURCE_TYPE_RESOURCE, RESOURCE_TYPE_REGEXP],
RESOURCE_TYPE_RESOURCE
)

role = None
if (
argv[0].lower() in ["master", "slave"]
or
argv[1].lower() in ["prefers", "avoids"]
):
role = argv.pop(0)
if len(argv) < 2:
raise CmdLineInputError()
role = _verify_and_prepare_role(role)

prefer_option = argv.pop(0)
if prefer_option == "prefers":
prefer = True
elif prefer_option == "avoids":
Expand Down Expand Up @@ -922,12 +941,21 @@ def location_prefer(lib, argv, modifiers):
else:
score = "-" + score

parameters_list.append([
sanitize_id(f"location-{rsc_value}-{node}-{score}"),
rsc,
node,
score
])
if role is None:
parameters_list.append([
sanitize_id(f"location-{rsc_value}-{node}-{score}"),
rsc,
node,
score
])
else:
parameters_list.append([
sanitize_id(f"location-{rsc_value}-{node}-{score}-{role}"),
rsc,
node,
score,
"role=" + role
])

if report_list:
process_library_reports(report_list)
Expand Down Expand Up @@ -958,14 +986,17 @@ def location_add(lib, argv, modifiers, skip_score_and_node_check=False):
node = argv.pop(0)
score = argv.pop(0)
options = []
# For now we only allow setting resource-discovery
role = ""
# For now we allow setting role=<role> and resource-discovery=<option>
if argv:
for arg in argv:
if '=' in arg:
options.append(arg.split('=', 1))
else:
raise CmdLineInputError(f"bad option '{arg}'")
if (
if options[-1][0] == "role":
role = _verify_and_prepare_role(options.pop(-1)[1])
elif (
options[-1][0] != "resource-discovery"
and
not modifiers.get("--force")
Expand Down Expand Up @@ -1015,7 +1046,7 @@ def location_add(lib, argv, modifiers, skip_score_and_node_check=False):
# 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
# If the id matches, or the rsc & node & role match, then we replace/remove
for rsc_loc in constraintsElement.getElementsByTagName('rsc_location'):
# pylint: disable=too-many-boolean-expressions
if (
Expand All @@ -1037,6 +1068,8 @@ def location_add(lib, argv, modifiers, skip_score_and_node_check=False):
rsc_loc.getAttribute("rsc-pattern") == rsc_value
)
)
and
rsc_loc.getAttribute("role") == role
)
):
elementsToRemove.append(rsc_loc)
Expand All @@ -1051,6 +1084,8 @@ def location_add(lib, argv, modifiers, skip_score_and_node_check=False):
element.setAttribute("rsc-pattern", rsc_value)
element.setAttribute("node", node)
element.setAttribute("score", score)
if role != "":
element.setAttribute("role", role)
for option in options:
element.setAttribute(option[0], option[1])
constraintsElement.appendChild(element)
Expand Down
25 changes: 14 additions & 11 deletions pcs/usage.py
Original file line number Diff line number Diff line change
Expand Up @@ -1291,17 +1291,19 @@ def constraint(args=(), pout=True):
is specified also show expired constraints. If --full is specified
also list the constraint ids.

location <resource> prefers <node>[=<score>] [<node>[=<score>]]...
Create a location constraint on a resource to prefer the specified node
with score (default score: INFINITY). Resource may be either a resource
id <resource_id> or %<resource_id> or resource%<resource_id>, or a
resource name regular expression regexp%<resource_pattern>.
location <resource> [<role>] prefers <node>[=<score>] [<node>[=<score>]]...
Create a location constraint on a resource with role (can be master or
slave) to prefer the specified node with score (default: INFINITY).
Resource may be either a resource id <resource_id> or %<resource_id> or
resource%<resource_id>, or a resource name regular expression
regexp%<resource_pattern>.

location <resource> avoids <node>[=<score>] [<node>[=<score>]]...
Create a location constraint on a resource to avoid the specified node
with score (default score: INFINITY). Resource may be either a resource
id <resource_id> or %<resource_id> or resource%<resource_id>, or a
resource name regular expression regexp%<resource_pattern>.
location <resource> [<role>] avoids <node>[=<score>] [<node>[=<score>]]...
Create a location constraint on a resource with role (can be master or
slave) to avoid the specified node with score (default: INFINITY).
Resource may be either a resource id <resource_id> or %<resource_id> or
resource%<resource_id>, or a resource name regular expression
regexp%<resource_pattern>.

location <resource> rule [id=<rule id>] [resource-discovery=<option>]
[role=master|slave] [constraint-id=<id>]
Expand Down Expand Up @@ -1336,7 +1338,8 @@ def constraint(args=(), pout=True):
is specified show the internal constraint id's. If --all is
specified show the expired constraints.

location add <id> <resource> <node> <score> [resource-discovery=<option>]
location add <id> <resource> <node> <score> [role=master|slave]
[resource-discovery=<option>]
Add a location constraint with the appropriate id for the specified
resource, node name and score. Resource may be either a resource id
<resource_id> or %<resource_id> or resource%<resource_id>, or a
Expand Down