Login
[x]
Log in using an account from:
Fedora Account System
Red Hat Associate
Red Hat Customer
Or login using a Red Hat Bugzilla account
Forgot Password
Login:
Hide Forgot
Create an Account
Red Hat Bugzilla – Attachment 929192 Details for
Bug 1108319
cloned group resource ignores 'constraint avoids node'
[?]
New
Simple Search
Advanced Search
My Links
Browse
Requests
Reports
Current State
Search
Tabular reports
Graphical reports
Duplicates
Other Reports
User Changes
Plotly Reports
Bug Status
Bug Severity
Non-Defaults
|
Product Dashboard
Help
Page Help!
Bug Writing Guidelines
What's new
Browser Support Policy
5.0.4.rh83 Release notes
FAQ
Guides index
User guide
Web Services
Contact
Legal
This site requires JavaScript to be enabled to function correctly, please enable it.
[patch]
proposed fix
0001-Fix-constraints-refering-to-cloned-resources.patch (text/plain), 47.10 KB, created by
Tomas Jelinek
on 2014-08-21 12:36:39 UTC
(
hide
)
Description:
proposed fix
Filename:
MIME Type:
Creator:
Tomas Jelinek
Created:
2014-08-21 12:36:39 UTC
Size:
47.10 KB
patch
obsolete
>From 42a2306148260389d9321d3c707dd353f221f913 Mon Sep 17 00:00:00 2001 >From: Tomas Jelinek <tojeline@redhat.com> >Date: Tue, 22 Jul 2014 17:35:24 +0200 >Subject: [PATCH] Fix constraints refering to cloned resources > >* Warn when user tries to create a constraint for a clone > or master/slave child. >* Move the constraints from a group to the clone or master when cloning > the group. Previously worked only for the plain resources. >--- > pcs/constraint.py | 111 ++++++------ > pcs/test/test_constraints.py | 397 ++++++++++++++++++++++++++++++++++++++++--- > pcs/test/test_resource.py | 29 +++- > pcs/test/test_utils.py | 205 +++++++++++++++++++--- > pcs/utils.py | 69 +++++++- > 5 files changed, 706 insertions(+), 105 deletions(-) > >diff --git a/pcs/constraint.py b/pcs/constraint.py >index c8a408c..71e3693 100644 >--- a/pcs/constraint.py >+++ b/pcs/constraint.py >@@ -194,16 +194,18 @@ def colocation_add(argv): > resource1 = argv.pop(0) > resource2 = argv.pop(0) > >- if not utils.is_valid_constraint_resource(resource1): >- utils.err("Resource '" + resource1 + "' does not exist") >+ cib_dom = utils.get_cib_dom() >+ resource_valid, resource_error = utils.validate_constraint_resource( >+ cib_dom, resource1 >+ ) >+ if not resource_valid: >+ utils.err(resource_error) >+ resource_valid, resource_error = utils.validate_constraint_resource( >+ cib_dom, resource2 >+ ) >+ if not resource_valid: >+ utils.err(resource_error) > >- if not utils.is_valid_constraint_resource(resource2): >- utils.err("Resource '" + resource2 + "' does not exist") >- >- if utils.is_resource_masterslave(resource1): >- utils.err(resource1 + " is a master/slave resource, you must use the master id: "+utils.get_resource_master_id(resource1)+ " when adding constraints") >- if utils.is_resource_masterslave(resource2): >- utils.err(resource2 + " is a master/slave resource, you must use the master id: "+utils.get_resource_master_id(resource2)+ " when adding constraints") > score,nv_pairs = parse_score_options(argv) > > (dom,constraintsElement) = getCurrentConstraints() >@@ -244,13 +246,11 @@ def colocation_set(argv): > if a.find('=') == -1: > colocation_id = colocation_id + "_" + a > >- cib = utils.get_cib_etree() >- constraints = cib.find(".//constraints") >- if constraints == None: >- constraints = ET.SubElement(cib, "constraints") >- rsc_colocation = ET.SubElement(constraints,"rsc_colocation") >- rsc_colocation.set("id", utils.find_unique_id(cib,colocation_id)) >- rsc_colocation.set("score","INFINITY") >+ cib, constraints = getCurrentConstraints(utils.get_cib_dom()) >+ rsc_colocation = cib.createElement("rsc_colocation") >+ constraints.appendChild(rsc_colocation) >+ rsc_colocation.setAttribute("id", utils.find_unique_id(cib, colocation_id)) >+ rsc_colocation.setAttribute("score", "INFINITY") > score_options = ("score", "score-attribute", "score-attribute-mangle") > score_specified = False > for opt in setoptions: >@@ -269,7 +269,7 @@ def colocation_set(argv): > "invalid score '%s', use integer or INFINITY or -INFINITY" > % value > ) >- rsc_colocation.set(name,value) >+ rsc_colocation.setAttribute(name, value) > set_add_resource_sets(rsc_colocation, current_set, cib) > utils.replace_cib_configuration(cib) > >@@ -362,7 +362,8 @@ def set_add_resource_sets(elem, sets, cib): > > for o_set in sets: > set_id = "pcs_rsc_set" >- res_set = ET.SubElement(elem,"resource_set") >+ res_set = cib.createElement("resource_set") >+ elem.appendChild(res_set) > for opts in o_set: > if opts.find("=") != -1: > key,val = opts.split("=") >@@ -376,12 +377,18 @@ def set_add_resource_sets(elem, sets, cib): > "invalid value '%s' of option '%s', allowed values are: %s" > % (val, key, ", ".join(allowed_options[key])) > ) >- res_set.set(key,val) >+ res_set.setAttribute(key, val) > else: >- se = ET.SubElement(res_set,"resource_ref") >- se.set("id",opts) >+ res_valid, res_error = utils.validate_constraint_resource( >+ cib, opts >+ ) >+ if not res_valid: >+ utils.err(res_error) >+ se = cib.createElement("resource_ref") >+ res_set.appendChild(se) >+ se.setAttribute("id", opts) > set_id = set_id + "_" + opts >- res_set.set("id", utils.find_unique_id(cib,set_id)) >+ res_set.setAttribute("id", utils.find_unique_id(cib, set_id)) > > def order_set(argv): > current_set = set_args_into_array(argv) >@@ -391,12 +398,10 @@ def order_set(argv): > if a.find('=') == -1: > order_id = order_id + "_" + a > >- cib = utils.get_cib_etree() >- constraints = cib.find(".//constraints") >- if constraints == None: >- constraints = ET.SubElement(cib, "constraints") >- rsc_order = ET.SubElement(constraints,"rsc_order") >- rsc_order.set("id", utils.find_unique_id(cib,order_id)) >+ cib, constraints = getCurrentConstraints(utils.get_cib_dom()) >+ rsc_order = cib.createElement("rsc_order") >+ constraints.appendChild(rsc_order) >+ rsc_order.setAttribute("id", utils.find_unique_id(cib, order_id)) > set_add_resource_sets(rsc_order, current_set, cib) > utils.replace_cib_configuration(cib) > >@@ -466,11 +471,6 @@ def order_start(argv): > sys.exit(1) > resource2 = argv.pop(0) > >- if utils.is_resource_masterslave(resource1): >- utils.err(resource1 + " is a master/slave resource, you must use the master id: "+utils.get_resource_master_id(resource1)+ " when adding constraints") >- if utils.is_resource_masterslave(resource2): >- utils.err(resource2 + " is a master/slave resource, you must use the master id: "+utils.get_resource_master_id(resource2)+ " when adding constraints") >- > order_options = [] > if len(argv) != 0: > order_options = order_options + argv[:] >@@ -487,11 +487,17 @@ def order_add(argv,returnElementOnly=False): > resource1 = argv.pop(0) > resource2 = argv.pop(0) > >- if not utils.is_valid_constraint_resource(resource1): >- utils.err("Resource '" + resource1 + "' does not exist") >- >- if not utils.is_valid_constraint_resource(resource2): >- utils.err("Resource '" + resource2 + "' does not exist") >+ cib_dom = utils.get_cib_dom() >+ resource_valid, resource_error = utils.validate_constraint_resource( >+ cib_dom, resource1 >+ ) >+ if not resource_valid: >+ utils.err(resource_error) >+ resource_valid, resource_error = utils.validate_constraint_resource( >+ cib_dom, resource2 >+ ) >+ if not resource_valid: >+ utils.err(resource_error) > > sym = "true" if (len(argv) == 0 or argv[0] != "nonsymmetrical") else "false" > >@@ -524,7 +530,7 @@ def order_add(argv,returnElementOnly=False): > print "Adding " + resource1 + " " + resource2 + " ("+scorekind+")" + options > > order_id = "order-" + resource1 + "-" + resource2 + "-" + id_suffix >- order_id = utils.find_unique_id(utils.get_cib_dom(), order_id) >+ order_id = utils.find_unique_id(cib_dom, order_id) > > (dom,constraintsElement) = getCurrentConstraints() > element = dom.createElement("rsc_order") >@@ -739,9 +745,11 @@ def location_add(argv,rm=False): > resource_name = argv.pop(0) > node = argv.pop(0) > score = argv.pop(0) >- # If resource doesn't exist, we error out >- if not utils.is_valid_constraint_resource(resource_name): >- utils.err("Resource " + resource_name + "' does not exist") >+ resource_valid, resource_error = utils.validate_constraint_resource( >+ utils.get_cib_dom(), resource_name >+ ) >+ if 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) > >@@ -779,8 +787,11 @@ def location_rule(argv): > sys.exit(1) > > res_name = argv.pop(0) >- if not utils.is_resource(res_name) and not utils.is_group(res_name): >- utils.err("'%s' is not a resource" % res_name) >+ resource_valid, resource_error = utils.validate_constraint_resource( >+ utils.get_cib_dom(), res_name >+ ) >+ if not resource_valid: >+ utils.err(resource_error) > > argv.pop(0) > >@@ -977,17 +988,11 @@ def find_constraints_containing_node(dom, node): > # or master) > def constraint_resource_update(old_id, passed_dom=None): > dom = utils.get_cib_dom() if passed_dom is None else passed_dom >- resources = dom.getElementsByTagName("primitive") >- found_resource = None >- for res in resources: >- if res.getAttribute("id") == old_id: >- found_resource = res >- break > > new_id = None >- if found_resource: >- if found_resource.parentNode.tagName == "master" or found_resource.parentNode.tagName == "clone": >- new_id = found_resource.parentNode.getAttribute("id") >+ 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") >diff --git a/pcs/test/test_constraints.py b/pcs/test/test_constraints.py >index 6561e5d..431741e 100644 >--- a/pcs/test/test_constraints.py >+++ b/pcs/test/test_constraints.py >@@ -66,11 +66,11 @@ class ConstraintTest(unittest.TestCase): > assert returnVal == 0 > assert output == "Warning: invalid score 'pingd', setting score-attribute=pingd instead\n", [output] > >- output, returnVal = pcs(temp_cib, "constraint location D3 rule score=pingd defined pingd") >+ output, returnVal = pcs(temp_cib, "constraint location D3 rule score=pingd defined pingd --force") > assert returnVal == 0 > assert output == "Warning: invalid score 'pingd', setting score-attribute=pingd instead\n", [output] > >- output, returnVal = pcs(temp_cib, "constraint location D4 rule score=INFINITY date start=2005-001 gt") >+ output, returnVal = pcs(temp_cib, "constraint location D4 rule score=INFINITY date start=2005-001 gt --force") > assert returnVal == 0 > assert output == "", [output] > >@@ -82,11 +82,11 @@ class ConstraintTest(unittest.TestCase): > assert output == "", [output] > assert returnVal == 0 > >- output, returnVal = pcs(temp_cib, "constraint location D3 rule score=-INFINITY not_defined pingd or pingd lte 0") >+ output, returnVal = pcs(temp_cib, "constraint location D3 rule score=-INFINITY not_defined pingd or pingd lte 0 --force") > assert returnVal == 0 > assert output == "", [output] > >- output, returnVal = pcs(temp_cib, "constraint location D3 rule score=-INFINITY not_defined pingd and pingd lte 0") >+ output, returnVal = pcs(temp_cib, "constraint location D3 rule score=-INFINITY not_defined pingd and pingd lte 0 --force") > assert returnVal == 0 > assert output == "", [output] > >@@ -317,7 +317,7 @@ Colocation Constraints: > output, returnVal = pcs(temp_cib, line) > assert returnVal == 0 and output == "" > >- o, r = pcs(temp_cib, "constraint colocation add D1 D3") >+ o, r = pcs(temp_cib, "constraint colocation add D1 D3-clone") > assert r == 0 and o == "", o > > o, r = pcs(temp_cib, "constraint colocation add D1 D2 100") >@@ -346,7 +346,7 @@ Colocation Constraints: > > o, r = pcs(temp_cib, "constraint") > assert r == 0 >- ac(o,'Location Constraints:\nOrdering Constraints:\nColocation Constraints:\n D1 with D3 (score:INFINITY)\n D1 with D2 (score:100)\n D1 with D2 (score:-100)\n Master with D5 (score:100)\n M1-master with M2-master (score:INFINITY) (rsc-role:Master) (with-rsc-role:Master)\n M3-master with M4-master (score:INFINITY)\n M5-master with M6-master (score:500) (rsc-role:Slave) (with-rsc-role:Started)\n M7-master with M8-master (score:INFINITY) (rsc-role:Started) (with-rsc-role:Master)\n M9-master with M10-master (score:INFINITY) (rsc-role:Slave) (with-rsc-role:Started)\n') >+ ac(o,'Location Constraints:\nOrdering Constraints:\nColocation Constraints:\n D1 with D3-clone (score:INFINITY)\n D1 with D2 (score:100)\n D1 with D2 (score:-100)\n Master with D5 (score:100)\n M1-master with M2-master (score:INFINITY) (rsc-role:Master) (with-rsc-role:Master)\n M3-master with M4-master (score:INFINITY)\n M5-master with M6-master (score:500) (rsc-role:Slave) (with-rsc-role:Started)\n M7-master with M8-master (score:INFINITY) (rsc-role:Started) (with-rsc-role:Master)\n M9-master with M10-master (score:INFINITY) (rsc-role:Slave) (with-rsc-role:Started)\n') > > def testColocationSets(self): > line = "resource create D7 Dummy" >@@ -676,7 +676,7 @@ Colocation Constraints: > assert r == 1 > > o,r = pcs("constraint location non-existant-resource rule role=master '#uname' eq rh7-1") >- ac (o,"Error: 'non-existant-resource' is not a resource\n") >+ ac (o,"Error: Resource 'non-existant-resource' does not exist\n") > assert r == 1 > > output, returnVal = pcs(temp_cib, "constraint rule add location-D1-rh7-1-INFINITY '#uname' eq rh7-2") >@@ -692,7 +692,7 @@ Colocation Constraints: > ac(o,"") > assert r == 0 > >- o,r = pcs("constraint location stateful0 rule role=master '#uname' eq rh7-1") >+ o,r = pcs("constraint location stateful0 rule role=master '#uname' eq rh7-1 --force") > ac(o,"") > assert r == 0 > >@@ -712,15 +712,15 @@ Colocation Constraints: > ac(o,"") > assert r == 0 > >- o,r = pcs("constraint location stateful1 rule rulename '#uname' eq rh7-1") >+ o,r = pcs("constraint location stateful1 rule rulename '#uname' eq rh7-1 --force") > ac(o,"Error: 'rulename #uname eq rh7-1' is not a valid rule expression: unexpected '#uname'\n") > assert r == 1 > >- o,r = pcs("constraint location stateful1 rule role=master rulename '#uname' eq rh7-1") >+ o,r = pcs("constraint location stateful1 rule role=master rulename '#uname' eq rh7-1 --force") > ac(o,"Error: 'rulename #uname eq rh7-1' is not a valid rule expression: unexpected '#uname'\n") > assert r == 1 > >- o,r = pcs("constraint location stateful1 rule role=master 25") >+ o,r = pcs("constraint location stateful1 rule role=master 25 --force") > ac(o,"Error: '25' is not a valid rule expression: missing one of 'eq', 'ne', 'lt', 'gt', 'lte', 'gte', 'in_range', 'defined', 'not_defined', 'date-spec'\n") > assert r == 1 > >@@ -751,30 +751,225 @@ Colocation Constraints: > ac(o,"") > assert r == 0 > >+ o,r = pcs("resource create stateful2 stateful --group statefulG") >+ ac(o,"") >+ assert r == 0 >+ >+ o,r = pcs("resource master statefulG") >+ ac(o,"") >+ assert r == 0 >+ >+ o,r = pcs("constraint location stateful1 prefers rh7-1") >+ ac(o,"Error: stateful1 is a master/slave resource, you should use the master id: stateful1-master when adding constraints. Use --force to override.\n") >+ assert r == 1 >+ >+ o,r = pcs("constraint location statefulG prefers rh7-1") >+ ac(o,"Error: statefulG is a master/slave resource, you should use the master id: statefulG-master when adding constraints. Use --force to override.\n") >+ assert r == 1 >+ >+ o,r = pcs("constraint location stateful1 rule #uname eq rh7-1") >+ ac(o,"Error: stateful1 is a master/slave resource, you should use the master id: stateful1-master when adding constraints. Use --force to override.\n") >+ assert r == 1 >+ >+ o,r = pcs("constraint location statefulG rule #uname eq rh7-1") >+ ac(o,"Error: statefulG is a master/slave resource, you should use the master id: statefulG-master when adding constraints. Use --force to override.\n") >+ assert r == 1 >+ > o,r = pcs("constraint order stateful1 then dummy1") >- ac(o,"Error: stateful1 is a master/slave resource, you must use the master id: stateful1-master when adding constraints\n") >+ ac(o,"Error: stateful1 is a master/slave resource, you should use the master id: stateful1-master when adding constraints. Use --force to override.\n") > assert r == 1 > >- o,r = pcs("constraint order dummy1 then stateful1") >- ac(o,"Error: stateful1 is a master/slave resource, you must use the master id: stateful1-master when adding constraints\n") >+ o,r = pcs("constraint order dummy1 then statefulG") >+ ac(o,"Error: statefulG is a master/slave resource, you should use the master id: statefulG-master when adding constraints. Use --force to override.\n") >+ assert r == 1 >+ >+ o,r = pcs("constraint order set stateful1 dummy1") >+ ac(o,"Error: stateful1 is a master/slave resource, you should use the master id: stateful1-master when adding constraints. Use --force to override.\n") >+ assert r == 1 >+ >+ o,r = pcs("constraint order set dummy1 statefulG") >+ ac(o,"Error: statefulG is a master/slave resource, you should use the master id: statefulG-master when adding constraints. Use --force to override.\n") > assert r == 1 > > o,r = pcs("constraint colocation add stateful1 with dummy1") >- ac(o,"Error: stateful1 is a master/slave resource, you must use the master id: stateful1-master when adding constraints\n") >+ ac(o,"Error: stateful1 is a master/slave resource, you should use the master id: stateful1-master when adding constraints. Use --force to override.\n") >+ assert r == 1 >+ >+ o,r = pcs("constraint colocation add dummy1 with statefulG") >+ ac(o,"Error: statefulG is a master/slave resource, you should use the master id: statefulG-master when adding constraints. Use --force to override.\n") >+ assert r == 1 >+ >+ o,r = pcs("constraint colocation set dummy1 stateful1") >+ ac(o,"Error: stateful1 is a master/slave resource, you should use the master id: stateful1-master when adding constraints. Use --force to override.\n") >+ assert r == 1 >+ >+ o,r = pcs("constraint colocation set statefulG dummy1") >+ ac(o,"Error: statefulG is a master/slave resource, you should use the master id: statefulG-master when adding constraints. Use --force to override.\n") >+ assert r == 1 >+ >+ o,r = pcs("constraint --full") >+ ac(o,"Location Constraints:\nOrdering Constraints:\nColocation Constraints:\n") >+ assert r == 0 >+ >+ o,r = pcs("constraint location stateful1 prefers rh7-1 --force") >+ ac(o,"") >+ assert r == 0 >+ >+ o,r = pcs("constraint location statefulG rule #uname eq rh7-1 --force") >+ ac(o,"") >+ assert r == 0 >+ >+ o,r = pcs("constraint order stateful1 then dummy1 --force") >+ ac(o,"Adding stateful1 dummy1 (kind: Mandatory) (Options: first-action=start then-action=start)\n") >+ assert r == 0 >+ >+ o,r = pcs("constraint order set stateful1 dummy1 --force") >+ ac(o,"") >+ assert r == 0 >+ >+ o,r = pcs("constraint colocation add stateful1 with dummy1 --force") >+ ac(o,"") >+ assert r == 0 >+ >+ o,r = pcs("constraint colocation set stateful1 dummy1 --force") >+ ac(o,"") >+ assert r == 0 >+ >+ o,r = pcs("constraint --full") >+ ac(o, """\ >+Location Constraints: >+ Resource: stateful1 >+ Enabled on: rh7-1 (score:INFINITY) (id:location-stateful1-rh7-1-INFINITY) >+ Resource: statefulG >+ Constraint: location-statefulG >+ Rule: score=INFINITY (id:location-statefulG-rule) >+ Expression: #uname eq rh7-1 (id:location-statefulG-rule-expr) >+Ordering Constraints: >+ start stateful1 then start dummy1 (kind:Mandatory) (id:order-stateful1-dummy1-mandatory) >+ Resource Sets: >+ set stateful1 dummy1 (id:pcs_rsc_set_stateful1_dummy1) (id:pcs_rsc_order_stateful1_dummy1) >+Colocation Constraints: >+ stateful1 with dummy1 (score:INFINITY) (id:colocation-stateful1-dummy1-INFINITY) >+ Resource Sets: >+ set stateful1 dummy1 (id:pcs_rsc_set_stateful1_dummy1-1) setoptions score=INFINITY (id:pcs_rsc_colocation_stateful1_dummy1) >+""") >+ assert r == 0 >+ >+ def testCloneConstraint(self): >+ os.system("CIB_file="+temp_cib+" cibadmin -R --scope nodes --xml-text '<nodes><node id=\"1\" uname=\"rh7-1\"/><node id=\"2\" uname=\"rh7-2\"/></nodes>'") >+ >+ o,r = pcs("resource create dummy1 dummy") >+ ac(o,"") >+ assert r == 0 >+ >+ o,r = pcs("resource create dummy Dummy --clone") >+ ac(o,"") >+ assert r == 0 >+ >+ o,r = pcs("resource create dummy2 Dummy --group dummyG") >+ ac(o,"") >+ assert r == 0 >+ >+ o,r = pcs("resource clone dummyG") >+ ac(o,"") >+ assert r == 0 >+ >+ o,r = pcs("constraint location dummy prefers rh7-1") >+ ac(o,"Error: dummy is a clone resource, you should use the clone id: dummy-clone when adding constraints. Use --force to override.\n") >+ assert r == 1 >+ >+ o,r = pcs("constraint location dummyG prefers rh7-1") >+ ac(o,"Error: dummyG is a clone resource, you should use the clone id: dummyG-clone when adding constraints. Use --force to override.\n") >+ assert r == 1 >+ >+ o,r = pcs("constraint location dummy rule #uname eq rh7-1") >+ ac(o,"Error: dummy is a clone resource, you should use the clone id: dummy-clone when adding constraints. Use --force to override.\n") >+ assert r == 1 >+ >+ o,r = pcs("constraint location dummyG rule #uname eq rh7-1") >+ ac(o,"Error: dummyG is a clone resource, you should use the clone id: dummyG-clone when adding constraints. Use --force to override.\n") >+ assert r == 1 >+ >+ o,r = pcs("constraint order dummy then dummy1") >+ ac(o,"Error: dummy is a clone resource, you should use the clone id: dummy-clone when adding constraints. Use --force to override.\n") >+ assert r == 1 >+ >+ o,r = pcs("constraint order dummy1 then dummyG") >+ ac(o,"Error: dummyG is a clone resource, you should use the clone id: dummyG-clone when adding constraints. Use --force to override.\n") >+ assert r == 1 >+ >+ o,r = pcs("constraint order set dummy1 dummy") >+ ac(o,"Error: dummy is a clone resource, you should use the clone id: dummy-clone when adding constraints. Use --force to override.\n") >+ assert r == 1 >+ >+ o,r = pcs("constraint order set dummyG dummy1") >+ ac(o,"Error: dummyG is a clone resource, you should use the clone id: dummyG-clone when adding constraints. Use --force to override.\n") > assert r == 1 > >- o,r = pcs("constraint colocation add dummy1 with stateful1") >- ac(o,"Error: stateful1 is a master/slave resource, you must use the master id: stateful1-master when adding constraints\n") >+ o,r = pcs("constraint colocation add dummy with dummy1") >+ ac(o,"Error: dummy is a clone resource, you should use the clone id: dummy-clone when adding constraints. Use --force to override.\n") > assert r == 1 > >- o,r = pcs("constraint order dummy1 then stateful1") >- ac(o,"Error: stateful1 is a master/slave resource, you must use the master id: stateful1-master when adding constraints\n") >+ o,r = pcs("constraint colocation add dummy1 with dummyG") >+ ac(o,"Error: dummyG is a clone resource, you should use the clone id: dummyG-clone when adding constraints. Use --force to override.\n") >+ assert r == 1 >+ >+ o,r = pcs("constraint colocation set dummy1 dummy") >+ ac(o,"Error: dummy is a clone resource, you should use the clone id: dummy-clone when adding constraints. Use --force to override.\n") >+ assert r == 1 >+ >+ o,r = pcs("constraint colocation set dummy1 dummyG") >+ ac(o,"Error: dummyG is a clone resource, you should use the clone id: dummyG-clone when adding constraints. Use --force to override.\n") > assert r == 1 > > o,r = pcs("constraint --full") > ac(o,"Location Constraints:\nOrdering Constraints:\nColocation Constraints:\n") > assert r == 0 > >+ o,r = pcs("constraint location dummy prefers rh7-1 --force") >+ ac(o,"") >+ assert r == 0 >+ >+ o,r = pcs("constraint location dummyG rule #uname eq rh7-1 --force") >+ ac(o,"") >+ assert r == 0 >+ >+ o,r = pcs("constraint order dummy then dummy1 --force") >+ ac(o,"Adding dummy dummy1 (kind: Mandatory) (Options: first-action=start then-action=start)\n") >+ assert r == 0 >+ >+ o,r = pcs("constraint order set dummy1 dummy --force") >+ ac(o,"") >+ assert r == 0 >+ >+ o,r = pcs("constraint colocation add dummy with dummy1 --force") >+ ac(o,"") >+ assert r == 0 >+ >+ o,r = pcs("constraint colocation set dummy1 dummy --force") >+ ac(o,"") >+ assert r == 0 >+ >+ o,r = pcs("constraint --full") >+ ac(o, """\ >+Location Constraints: >+ Resource: dummy >+ Enabled on: rh7-1 (score:INFINITY) (id:location-dummy-rh7-1-INFINITY) >+ Resource: dummyG >+ Constraint: location-dummyG >+ Rule: score=INFINITY (id:location-dummyG-rule) >+ Expression: #uname eq rh7-1 (id:location-dummyG-rule-expr) >+Ordering Constraints: >+ start dummy then start dummy1 (kind:Mandatory) (id:order-dummy-dummy1-mandatory) >+ Resource Sets: >+ set dummy1 dummy (id:pcs_rsc_set_dummy1_dummy) (id:pcs_rsc_order_dummy1_dummy) >+Colocation Constraints: >+ dummy with dummy1 (score:INFINITY) (id:colocation-dummy-dummy1-INFINITY) >+ Resource Sets: >+ set dummy1 dummy (id:pcs_rsc_set_dummy1_dummy-1) setoptions score=INFINITY (id:pcs_rsc_colocation_dummy1_dummy) >+""") >+ assert r == 0 >+ > def testMissingRole(self): > os.system("CIB_file="+temp_cib+" cibadmin -R --scope nodes --xml-text '<nodes><node id=\"1\" uname=\"rh7-1\"/><node id=\"2\" uname=\"rh7-2\"/></nodes>'") > o,r = pcs("resource create stateful0 Stateful --master") >@@ -827,6 +1022,170 @@ Colocation Constraints: > ac(output, "") > assert returnVal == 0 > >+ def testConstraintResourceCloneUpdate(self): >+ output, returnVal = pcs(temp_cib, "constraint location D1 prefers rh7-1") >+ ac(output, "") >+ assert returnVal == 0 >+ >+ output, returnVal = pcs(temp_cib, "constraint colocation add D1 with D5") >+ ac(output, "") >+ assert returnVal == 0 >+ >+ output, returnVal = pcs(temp_cib, "constraint order D1 then D5") >+ ac(output, """\ >+Adding D1 D5 (kind: Mandatory) (Options: first-action=start then-action=start) >+""") >+ assert returnVal == 0 >+ >+ output, returnVal = pcs(temp_cib, "constraint order D6 then D1") >+ ac(output, """\ >+Adding D6 D1 (kind: Mandatory) (Options: first-action=start then-action=start) >+""") >+ assert returnVal == 0 >+ >+ assert returnVal == 0 >+ output, returnVal = pcs(temp_cib, "resource clone D1") >+ ac(output, "") >+ assert returnVal == 0 >+ >+ output, returnVal = pcs(temp_cib, "constraint --full") >+ ac(output, """\ >+Location Constraints: >+ Resource: D1-clone >+ Enabled on: rh7-1 (score:INFINITY) (id:location-D1-rh7-1-INFINITY) >+Ordering Constraints: >+ start D1-clone then start D5 (kind:Mandatory) (id:order-D1-D5-mandatory) >+ start D6 then start D1-clone (kind:Mandatory) (id:order-D6-D1-mandatory) >+Colocation Constraints: >+ D1-clone with D5 (score:INFINITY) (id:colocation-D1-D5-INFINITY) >+""") >+ assert returnVal == 0 >+ >+ def testConstraintResourceMasterUpdate(self): >+ output, returnVal = pcs(temp_cib, "constraint location D1 prefers rh7-1") >+ ac(output, "") >+ assert returnVal == 0 >+ >+ output, returnVal = pcs(temp_cib, "constraint colocation add D1 with D5") >+ ac(output, "") >+ assert returnVal == 0 >+ >+ output, returnVal = pcs(temp_cib, "constraint order D1 then D5") >+ ac(output, """\ >+Adding D1 D5 (kind: Mandatory) (Options: first-action=start then-action=start) >+""") >+ assert returnVal == 0 >+ >+ output, returnVal = pcs(temp_cib, "constraint order D6 then D1") >+ ac(output, """\ >+Adding D6 D1 (kind: Mandatory) (Options: first-action=start then-action=start) >+""") >+ assert returnVal == 0 >+ >+ assert returnVal == 0 >+ output, returnVal = pcs(temp_cib, "resource master D1") >+ ac(output, "") >+ assert returnVal == 0 >+ >+ output, returnVal = pcs(temp_cib, "constraint --full") >+ ac(output, """\ >+Location Constraints: >+ Resource: D1-master >+ Enabled on: rh7-1 (score:INFINITY) (id:location-D1-rh7-1-INFINITY) >+Ordering Constraints: >+ start D1-master then start D5 (kind:Mandatory) (id:order-D1-D5-mandatory) >+ start D6 then start D1-master (kind:Mandatory) (id:order-D6-D1-mandatory) >+Colocation Constraints: >+ D1-master with D5 (score:INFINITY) (id:colocation-D1-D5-INFINITY) >+""") >+ assert returnVal == 0 >+ >+ def testConstraintGroupCloneUpdate(self): >+ output, returnVal = pcs(temp_cib, "resource group add DG D1") >+ ac(output, "") >+ assert returnVal == 0 >+ >+ output, returnVal = pcs(temp_cib, "constraint location DG prefers rh7-1") >+ ac(output, "") >+ assert returnVal == 0 >+ >+ output, returnVal = pcs(temp_cib, "constraint colocation add DG with D5") >+ ac(output, "") >+ assert returnVal == 0 >+ >+ output, returnVal = pcs(temp_cib, "constraint order DG then D5") >+ ac(output, """\ >+Adding DG D5 (kind: Mandatory) (Options: first-action=start then-action=start) >+""") >+ assert returnVal == 0 >+ >+ output, returnVal = pcs(temp_cib, "constraint order D6 then DG") >+ ac(output, """\ >+Adding D6 DG (kind: Mandatory) (Options: first-action=start then-action=start) >+""") >+ assert returnVal == 0 >+ >+ assert returnVal == 0 >+ output, returnVal = pcs(temp_cib, "resource clone DG") >+ ac(output, "") >+ assert returnVal == 0 >+ >+ output, returnVal = pcs(temp_cib, "constraint --full") >+ ac(output, """\ >+Location Constraints: >+ Resource: DG-clone >+ Enabled on: rh7-1 (score:INFINITY) (id:location-DG-rh7-1-INFINITY) >+Ordering Constraints: >+ start DG-clone then start D5 (kind:Mandatory) (id:order-DG-D5-mandatory) >+ start D6 then start DG-clone (kind:Mandatory) (id:order-D6-DG-mandatory) >+Colocation Constraints: >+ DG-clone with D5 (score:INFINITY) (id:colocation-DG-D5-INFINITY) >+""") >+ assert returnVal == 0 >+ >+ def testConstraintGroupMasterUpdate(self): >+ output, returnVal = pcs(temp_cib, "resource group add DG D1") >+ ac(output, "") >+ assert returnVal == 0 >+ >+ output, returnVal = pcs(temp_cib, "constraint location DG prefers rh7-1") >+ ac(output, "") >+ assert returnVal == 0 >+ >+ output, returnVal = pcs(temp_cib, "constraint colocation add DG with D5") >+ ac(output, "") >+ assert returnVal == 0 >+ >+ output, returnVal = pcs(temp_cib, "constraint order DG then D5") >+ ac(output, """\ >+Adding DG D5 (kind: Mandatory) (Options: first-action=start then-action=start) >+""") >+ assert returnVal == 0 >+ >+ output, returnVal = pcs(temp_cib, "constraint order D6 then DG") >+ ac(output, """\ >+Adding D6 DG (kind: Mandatory) (Options: first-action=start then-action=start) >+""") >+ assert returnVal == 0 >+ >+ assert returnVal == 0 >+ output, returnVal = pcs(temp_cib, "resource master DG") >+ ac(output, "") >+ assert returnVal == 0 >+ >+ output, returnVal = pcs(temp_cib, "constraint --full") >+ ac(output, """\ >+Location Constraints: >+ Resource: DG-master >+ Enabled on: rh7-1 (score:INFINITY) (id:location-DG-rh7-1-INFINITY) >+Ordering Constraints: >+ start DG-master then start D5 (kind:Mandatory) (id:order-DG-D5-mandatory) >+ start D6 then start DG-master (kind:Mandatory) (id:order-D6-DG-mandatory) >+Colocation Constraints: >+ DG-master with D5 (score:INFINITY) (id:colocation-DG-D5-INFINITY) >+""") >+ assert returnVal == 0 >+ > def testRemoteNodeConstraintsRemove(self): > output, returnVal = pcs( > temp_cib, >diff --git a/pcs/test/test_resource.py b/pcs/test/test_resource.py >index e51cdbf..0377e23 100644 >--- a/pcs/test/test_resource.py >+++ b/pcs/test/test_resource.py >@@ -863,7 +863,11 @@ class ResourceTest(unittest.TestCase): > assert r == 0 > ac(o,"") > >- o,r = pcs("constraint location D1 prefers rh7-1") >+ o,r = pcs("constraint location D1-clone prefers rh7-1") >+ assert r == 0 >+ ac(o,"") >+ >+ o,r = pcs("constraint location D1 prefers rh7-1 --force") > assert r == 0 > ac(o,"") > >@@ -873,7 +877,11 @@ class ResourceTest(unittest.TestCase): > > o,r = pcs("resource delete D1-clone") > assert r == 0 >- ac(o,"Removing Constraint - location-D1-rh7-1-INFINITY\nDeleting Resource - D1\n") >+ ac(o, """\ >+Removing Constraint - location-D1-clone-rh7-1-INFINITY >+Removing Constraint - location-D1-rh7-1-INFINITY >+Deleting Resource - D1 >+""") > > o,r = pcs("resource --full") > assert r == 0 >@@ -889,17 +897,21 @@ class ResourceTest(unittest.TestCase): > > def testMasterSlaveRemove(self): > self.setupClusterA(temp_cib) >- output, returnVal = pcs(temp_cib, "constraint location ClusterIP5 prefers rh7-1") >+ output, returnVal = pcs(temp_cib, "constraint location ClusterIP5 prefers rh7-1 --force") > assert returnVal == 0 > assert output == "" > >- output, returnVal = pcs(temp_cib, "constraint location ClusterIP5 prefers rh7-2") >+ output, returnVal = pcs(temp_cib, "constraint location Master prefers rh7-2") > assert returnVal == 0 > assert output == "" > > output, returnVal = pcs(temp_cib, "resource delete Master") > assert returnVal == 0 >- ac(output,"Removing Constraint - location-ClusterIP5-rh7-1-INFINITY\nRemoving Constraint - location-ClusterIP5-rh7-2-INFINITY\nDeleting Resource - ClusterIP5\n") >+ ac(output, """\ >+Removing Constraint - location-Master-rh7-2-INFINITY >+Removing Constraint - location-ClusterIP5-rh7-1-INFINITY >+Deleting Resource - ClusterIP5 >+""") > > output, returnVal = pcs(temp_cib, "resource create --no-default-ops ClusterIP5 Dummy") > assert returnVal == 0 >@@ -1723,7 +1735,7 @@ Colocation Constraints: > assert r == 0 > o,r = pcs(temp_cib, "resource master AA") > assert r == 0 >- o,r = pcs(temp_cib, "constraint location AA prefers rh7-1") >+ o,r = pcs(temp_cib, "constraint location AA-master prefers rh7-1") > assert r == 0 > > o,r = pcs(temp_cib, "resource delete A1") >@@ -1731,7 +1743,10 @@ Colocation Constraints: > assert r == 0 > > o,r = pcs(temp_cib, "resource delete A2") >- ac(o,"Deleting Resource (and group and M/S) - A2\n") >+ ac(o,"""\ >+Removing Constraint - location-AA-master-rh7-1-INFINITY >+Deleting Resource (and group and M/S) - A2 >+""") > assert r == 0 > > def testMasteredGroup(self): >diff --git a/pcs/test/test_utils.py b/pcs/test/test_utils.py >index bd880b4..c60b3c8 100644 >--- a/pcs/test/test_utils.py >+++ b/pcs/test/test_utils.py >@@ -8,28 +8,11 @@ import utils > > class UtilsTest(unittest.TestCase): > >- def testDomGetResources(self): >- def test_dom_get(method, dom, ok_ids, bad_ids): >- for element_id in ok_ids: >- self.assert_element_id(method(dom, element_id), element_id) >- for element_id in bad_ids: >- self.assertFalse(method(dom, element_id)) >- >- cib_dom = xml.dom.minidom.parse("empty.xml") >- self.assertFalse(utils.dom_get_resource(cib_dom, "myResource")) >- self.assertFalse( >- utils.dom_get_resource_clone(cib_dom, "myClonedResource") >- ) >- self.assertFalse( >- utils.dom_get_resource_masterslave(cib_dom, "myMasteredResource") >- ) >- self.assertFalse(utils.dom_get_group(cib_dom, "myGroup")) >- self.assertFalse(utils.dom_get_group_clone(cib_dom, "myClonedGroup")) >- self.assertFalse(utils.dom_get_clone(cib_dom, "myClone")) >- self.assertFalse(utils.dom_get_master(cib_dom, "myMaster")) >- self.assertFalse(utils.dom_get_clone_ms_resource(cib_dom, "myClone")) >- self.assertFalse(utils.dom_get_clone_ms_resource(cib_dom, "myMaster")) >+ def get_cib_empty(self): >+ return xml.dom.minidom.parse("empty.xml") > >+ def get_cib_resources(self): >+ cib_dom = self.get_cib_empty() > new_resources = xml.dom.minidom.parseString(""" > <resources> > <primitive id="myResource" >@@ -68,7 +51,40 @@ class UtilsTest(unittest.TestCase): > """).documentElement > resources = cib_dom.getElementsByTagName("resources")[0] > resources.parentNode.replaceChild(new_resources, resources) >+ return cib_dom >+ >+ def testDomGetResources(self): >+ def test_dom_get(method, dom, ok_ids, bad_ids): >+ for element_id in ok_ids: >+ self.assert_element_id(method(dom, element_id), element_id) >+ for element_id in bad_ids: >+ self.assertFalse(method(dom, element_id)) >+ >+ cib_dom = self.get_cib_empty() >+ self.assertFalse(utils.dom_get_resource(cib_dom, "myResource")) >+ self.assertFalse( >+ utils.dom_get_resource_clone(cib_dom, "myClonedResource") >+ ) >+ self.assertFalse( >+ utils.dom_get_resource_masterslave(cib_dom, "myMasteredResource") >+ ) >+ self.assertFalse(utils.dom_get_group(cib_dom, "myGroup")) >+ self.assertFalse(utils.dom_get_group_clone(cib_dom, "myClonedGroup")) >+ self.assertFalse( >+ utils.dom_get_group_masterslave(cib_dom, "myMasteredGroup") >+ ) >+ self.assertFalse(utils.dom_get_clone(cib_dom, "myClone")) >+ self.assertFalse(utils.dom_get_master(cib_dom, "myMaster")) >+ self.assertFalse(utils.dom_get_clone_ms_resource(cib_dom, "myClone")) >+ self.assertFalse(utils.dom_get_clone_ms_resource(cib_dom, "myMaster")) >+ self.assertFalse( >+ utils.dom_get_resource_clone_ms_parent(cib_dom, "myClonedResource") >+ ) >+ self.assertFalse( >+ utils.dom_get_resource_clone_ms_parent(cib_dom, "myMasteredResource") >+ ) > >+ cib_dom = self.get_cib_resources() > all_ids = set([ > "none", "myResource", > "myClone", "myClonedResource", >@@ -117,6 +133,12 @@ class UtilsTest(unittest.TestCase): > clone_ids, all_ids - clone_ids > ) > >+ mastered_group_ids = set(["myMasteredGroup"]) >+ test_dom_get( >+ utils.dom_get_group_masterslave, cib_dom, >+ mastered_group_ids, all_ids - mastered_group_ids >+ ) >+ > master_ids = set(["myMaster", "myGroupMaster"]) > test_dom_get( > utils.dom_get_master, cib_dom, >@@ -141,6 +163,51 @@ class UtilsTest(unittest.TestCase): > "myMasteredGroup" > ) > >+ self.assert_element_id( >+ utils.dom_get_resource_clone_ms_parent(cib_dom, "myClonedResource"), >+ "myClone" >+ ) >+ self.assert_element_id( >+ utils.dom_get_resource_clone_ms_parent(cib_dom, "myClonedGroup"), >+ "myGroupClone" >+ ) >+ self.assert_element_id( >+ utils.dom_get_resource_clone_ms_parent( >+ cib_dom, "myClonedGroupedResource" >+ ), >+ "myGroupClone" >+ ) >+ self.assert_element_id( >+ utils.dom_get_resource_clone_ms_parent( >+ cib_dom, "myMasteredResource" >+ ), >+ "myMaster" >+ ) >+ self.assert_element_id( >+ utils.dom_get_resource_clone_ms_parent( >+ cib_dom, "myMasteredGroup" >+ ), >+ "myGroupMaster" >+ ) >+ self.assert_element_id( >+ utils.dom_get_resource_clone_ms_parent( >+ cib_dom, "myMasteredGroupedResource" >+ ), >+ "myGroupMaster" >+ ) >+ self.assertEquals( >+ None, >+ utils.dom_get_resource_clone_ms_parent(cib_dom, "myResource") >+ ) >+ self.assertEquals( >+ None, >+ utils.dom_get_resource_clone_ms_parent(cib_dom, "myGroup") >+ ) >+ self.assertEquals( >+ None, >+ utils.dom_get_resource_clone_ms_parent(cib_dom, "myGroupedResource") >+ ) >+ > def testDomGetResourceRemoteNodeName(self): > dom = xml.dom.minidom.parse("empty.xml") > new_resources = xml.dom.minidom.parseString(""" >@@ -235,6 +302,102 @@ class UtilsTest(unittest.TestCase): > ) > ) > >+ def testValidateConstraintResource(self): >+ dom = self.get_cib_resources() >+ self.assertEquals( >+ (True, ""), >+ utils.validate_constraint_resource(dom, "myClone") >+ ) >+ self.assertEquals( >+ (True, ""), >+ utils.validate_constraint_resource(dom, "myGroupClone") >+ ) >+ self.assertEquals( >+ (True, ""), >+ utils.validate_constraint_resource(dom, "myMaster") >+ ) >+ self.assertEquals( >+ (True, ""), >+ utils.validate_constraint_resource(dom, "myGroupMaster") >+ ) >+ self.assertEquals( >+ (True, ""), >+ utils.validate_constraint_resource(dom, "myResource") >+ ) >+ self.assertEquals( >+ (True, ""), >+ utils.validate_constraint_resource(dom, "myGroup") >+ ) >+ self.assertEquals( >+ (True, ""), >+ utils.validate_constraint_resource(dom, "myGroupedResource") >+ ) >+ >+ self.assertEquals( >+ (False, "Resource 'myNonexistent' does not exist"), >+ utils.validate_constraint_resource(dom, "myNonexistent") >+ ) >+ >+ message = ( >+ "%s is a clone resource, you should use the clone id: " >+ "%s when adding constraints. Use --force to override." >+ ) >+ self.assertEquals( >+ (False, message % ("myClonedResource", "myClone")), >+ utils.validate_constraint_resource(dom, "myClonedResource") >+ ) >+ self.assertEquals( >+ (False, message % ("myClonedGroup", "myGroupClone")), >+ utils.validate_constraint_resource(dom, "myClonedGroup") >+ ) >+ self.assertEquals( >+ (False, message % ("myClonedGroupedResource", "myGroupClone")), >+ utils.validate_constraint_resource(dom, "myClonedGroupedResource") >+ ) >+ >+ message = ( >+ "%s is a master/slave resource, you should use the master id: " >+ "%s when adding constraints. Use --force to override." >+ ) >+ self.assertEquals( >+ (False, message % ("myMasteredResource", "myMaster")), >+ utils.validate_constraint_resource(dom, "myMasteredResource") >+ ) >+ self.assertEquals( >+ (False, message % ("myMasteredGroup", "myGroupMaster")), >+ utils.validate_constraint_resource(dom, "myMasteredGroup") >+ ) >+ self.assertEquals( >+ (False, message % ("myMasteredGroupedResource", "myGroupMaster")), >+ utils.validate_constraint_resource(dom, "myMasteredGroupedResource") >+ ) >+ >+ utils.pcs_options["--force"] = True >+ self.assertEquals( >+ (True, ""), >+ utils.validate_constraint_resource(dom, "myClonedResource") >+ ) >+ self.assertEquals( >+ (True, ""), >+ utils.validate_constraint_resource(dom, "myClonedGroup") >+ ) >+ self.assertEquals( >+ (True, ""), >+ utils.validate_constraint_resource(dom, "myClonedGroupedResource") >+ ) >+ self.assertEquals( >+ (True, ""), >+ utils.validate_constraint_resource(dom, "myMasteredResource") >+ ) >+ self.assertEquals( >+ (True, ""), >+ utils.validate_constraint_resource(dom, "myMasteredGroup") >+ ) >+ self.assertEquals( >+ (True, ""), >+ utils.validate_constraint_resource(dom, "myMasteredGroupedResource") >+ ) >+ > def testValidateXmlId(self): > self.assertEquals((True, ""), utils.validate_xml_id("dummy")) > self.assertEquals((True, ""), utils.validate_xml_id("DUMMY")) >diff --git a/pcs/utils.py b/pcs/utils.py >index 1da6191..b4f5cf4 100644 >--- a/pcs/utils.py >+++ b/pcs/utils.py >@@ -726,6 +726,20 @@ def dom_get_clone_ms_resource(dom, clone_ms_id): > return child > return None > >+def dom_get_resource_clone_ms_parent(dom, resource_id): >+ resource = ( >+ dom_get_resource(dom, resource_id) >+ or >+ dom_get_group(dom, resource_id) >+ ) >+ clone = resource >+ while True: >+ if not isinstance(clone, xml.dom.minidom.Element): >+ return None >+ if clone.tagName in ["clone", "master"]: >+ return clone >+ clone = clone.parentNode >+ > # deprecated, use dom_get_master > def is_master(ms_id): > return does_exist("//master[@id='"+ms_id+"']") >@@ -767,6 +781,13 @@ def dom_get_group_clone(dom, group_id): > return group > return None > >+def dom_get_group_masterslave(dom, group_id): >+ for master in dom.getElementsByTagName("master"): >+ group = dom_get_group(master, group_id) >+ if group: >+ return group >+ return None >+ > # deprecated, use dom_get_resource > def is_resource(resource_id): > return does_exist("//primitive[@id='"+resource_id+"']") >@@ -802,6 +823,7 @@ def dom_get_resource_masterslave(dom, resource_id): > return resource > return None > >+# deprecated, use dom_get_resource_clone_ms_parent > def get_resource_master_id(resource_id): > dom = get_cib_dom() > primitives = dom.getElementsByTagName("primitive") >@@ -811,11 +833,48 @@ def get_resource_master_id(resource_id): > return p.parentNode.getAttribute("id") > return None > >-def is_valid_constraint_resource(resource_id): >- return does_exist("//primitive[@id='"+resource_id+"']") or \ >- does_exist("//group[@id='"+resource_id+"']") or \ >- does_exist("//clone[@id='"+resource_id+"']") or \ >- does_exist("//master[@id='"+resource_id+"']") >+def validate_constraint_resource(dom, resource_id): >+ resource_el = ( >+ dom_get_clone(dom, resource_id) >+ or >+ dom_get_master(dom, resource_id) >+ ) >+ if resource_el: >+ # clone and master is always valid >+ return True, "" >+ >+ resource_el = ( >+ dom_get_resource(dom, resource_id) >+ or >+ dom_get_group(dom, resource_id) >+ ) >+ if not resource_el: >+ return False, "Resource '%s' does not exist" % resource_id >+ >+ if "--force" in pcs_options: >+ return True, "" >+ >+ clone_el = dom_get_resource_clone_ms_parent(dom, resource_id) >+ if not clone_el: >+ # primitive and group is valid if not in clone nor master >+ return True, "" >+ >+ if clone_el.tagName == "clone": >+ return ( >+ False, >+ "%s is a clone resource, you should use the clone id: %s " >+ "when adding constraints. Use --force to override." >+ % (resource_id, clone_el.getAttribute("id")) >+ ) >+ if clone_el.tagName == "master": >+ return ( >+ False, >+ "%s is a master/slave resource, you should use the master id: %s " >+ "when adding constraints. Use --force to override." >+ % (resource_id, clone_el.getAttribute("id")) >+ ) >+ return True, "" >+ > > def dom_get_resource_remote_node_name(dom_resource): > if dom_resource.tagName != "primitive": >-- >1.9.1 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 1108319
:
907756
| 929192 |
940747