Hello community, here is the log from the commit of package crmsh for openSUSE:Factory checked in at 2014-02-20 06:21:08 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/crmsh (Old) and /work/SRC/openSUSE:Factory/.crmsh.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "crmsh" Changes: -------- --- /work/SRC/openSUSE:Factory/crmsh/crmsh.changes 2014-02-17 12:52:27.000000000 +0100 +++ /work/SRC/openSUSE:Factory/.crmsh.new/crmsh.changes 2014-02-20 06:21:10.000000000 +0100 @@ -1,0 +2,7 @@ +Wed Feb 19 09:26:01 UTC 2014 - [email protected] + +- high: scripts: Disable strict host key checking (bnc#864268) +- high: parse: Fix resource sets displaying as XML (savannah#41617) (bnc#864563) +- upstream cs: 6daeb2253a4a + +------------------------------------------------------------------- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ crmsh.tar.bz2 ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh/.hg_archival.txt new/crmsh/.hg_archival.txt --- old/crmsh/.hg_archival.txt 2014-02-13 16:16:00.000000000 +0100 +++ new/crmsh/.hg_archival.txt 2014-02-19 10:20:53.000000000 +0100 @@ -1,5 +1,5 @@ repo: 13c3bd69e935090cd25213c474cafc3f01b5910b -node: 364c59ee0612e71579ffacbdf628022043e61ba6 +node: 6daeb2253a4a6e050f41ae1df895eb6b030a5eba branch: default latesttag: 1.2.6-rc1 -latesttagdistance: 425 +latesttagdistance: 427 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh/doc/crm.8.txt new/crmsh/doc/crm.8.txt --- old/crmsh/doc/crm.8.txt 2014-02-13 16:16:00.000000000 +0100 +++ new/crmsh/doc/crm.8.txt 2014-02-19 10:20:53.000000000 +0100 @@ -2118,6 +2118,42 @@ node big_node attributes memory=64 ............... +==== Resource sets + +Using resource sets can be a bit confusing unless one knows the +details of the implementation in Pacemaker as well as how to interpret +the syntax provided by `crmsh`. + +Three different types of resource sets are provided by `crmsh`, and +each one implies different values for the two resource set attributes, +`sequential` and `require-all`. + +`sequential`:: + If true, the resources in the set do not depend on each other + internally. Setting `sequential` to true implies a strict order of + dependency within the set. + +`require-all`:: + If false, only one resource in the set is required to fulfil the + requirements of the set. The set of `A, B and C` with `require-all` + set to `false` is be read as `A OR B OR C` when its dependencies + are resolved. + +The three types of resource sets modify the attributes in the +following way: + +1. Implicit sets (no brackets). `sequential=true`, `require-all=true` +2. Parenthesis set (`( ... )`). `sequential=false`, `require-all=true` +3. Bracket set (`[ ... ]`). `sequential=false`, `require-all=false` + +To create a set with the properties `sequential=true` and +`require-all=false`, explicitly set `sequential` in a bracketed set, +`[ A B C sequential=true ]`. + +To create multiple sets with both `sequential` and `require-all` set to +true, explicitly set `sequential` in a parenthesis set: +`A B ( C D sequential=true )`. + [[cmdhelp_configure_primitive,define a resource]] ==== `primitive` diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh/modules/cliformat.py new/crmsh/modules/cliformat.py --- old/crmsh/modules/cliformat.py 2014-02-13 16:16:00.000000000 +0100 +++ new/crmsh/modules/cliformat.py 2014-02-19 10:20:53.000000000 +0100 @@ -234,18 +234,22 @@ return rsc +def boolean_maybe(v): + "returns True/False or None" + if v is None: + return None + return utils.get_boolean(v) + + def rsc_set_constraint(node, obj_type): col = [] cnt = 0 for n in node.findall("resource_set"): - add_seq = False - sequential = utils.get_boolean(n.get("sequential"), True) - require_all = utils.get_boolean(n.get("require-all"), True) - if not require_all: + sequential = boolean_maybe(n.get("sequential")) + require_all = boolean_maybe(n.get("require-all")) + if require_all is False: col.append("[") - if sequential: - add_seq = True - elif not sequential: + elif sequential is False: col.append("(") role = n.get("role") action = n.get("action") @@ -254,15 +258,18 @@ q = (obj_type == "order") and action or role col.append(q and "%s:%s" % (rsc, q) or rsc) cnt += 1 - if not require_all: - if add_seq: + if require_all is False: + if sequential in (None, True): col.append('sequential="true"') col.append("]") - elif not sequential: + elif sequential is False: + if require_all is False: + col.append('require-all="false"') col.append(")") is_ticket = obj_type == 'rsc_ticket' is_location = obj_type == 'location' - if not is_location and ((sequential and require_all and not is_ticket and cnt <= 2) or + is_seq_all = sequential in (None, True) and require_all in (None, True) + if not is_location and ((is_seq_all and not is_ticket and cnt <= 2) or (is_ticket and cnt <= 1)): # a degenerate thingie col.insert(0, "_rsc_set_") return col diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh/modules/parse.py new/crmsh/modules/parse.py --- old/crmsh/modules/parse.py 2014-02-13 16:16:00.000000000 +0100 +++ new/crmsh/modules/parse.py 2014-02-19 10:20:53.000000000 +0100 @@ -944,6 +944,7 @@ self.tokens = s self.cli_list = [] self.reset_set() + self.opened = '' self.sequential = True self.require_all = True self.fix_parentheses() @@ -965,7 +966,6 @@ self.set_pl = [] self.prev_q = '' # previous qualifier (action or role) self.curr_attr = '' # attribute (action or role) - self.opened = '' # the open paren/bracket def save_set(self): if not self.set_pl: @@ -974,23 +974,21 @@ self.set_pl.insert(0, [self.curr_attr, self.prev_q]) if not self.sequential: self.set_pl.insert(0, ["sequential", "false"]) - elif not self.require_all: - self.set_pl.insert(0, ["sequential", "true"]) if not self.require_all: self.set_pl.insert(0, ["require-all", "false"]) self.cli_list.append(["resource_set", self.set_pl]) self.reset_set() def parseattr(self, p): + attrs = {"sequential": "sequential", + "require-all": "require_all"} l = p.split('=') - if len(l) != 2 or l[0] not in ("sequential", "require-all"): + if len(l) != 2 or l[0] not in attrs: return False - if not verify_boolean(l[1]): + k, v = l + if not verify_boolean(v): return False - if l[0] == "sequential": - self.sequential = get_boolean(l[1]) - else: - self.require_all = get_boolean(l[1]) + setattr(self, attrs[k], get_boolean(v)) return True def splitrsc(self, p): @@ -1017,6 +1015,26 @@ msg=errmsg) raise ParseError + def update_attrs(self, bracket, tokpos): + if bracket in ('(', '['): + if self.opened: + self.err(token=self.tokens[tokpos], + errmsg='Cannot nest resource sets') + self.sequential = False + if bracket == '[': + self.require_all = False + self.opened = bracket + elif bracket in (')', ']'): + if not self.opened: + self.err(token=self.tokens[tokpos], + errmsg='Unmatched closing bracket') + if bracket != self.matching[self.opened]: + self.err(token=self.tokens[tokpos], + errmsg='Mismatched closing bracket') + self.sequential = True + self.require_all = True + self.opened = '' + def parse(self): tokpos = -1 for p in self.tokens: @@ -1024,30 +1042,16 @@ if p == "_rsc_set_": continue # a degenerate resource set if p in self.open_set: - if self.set_pl: # save the set before - self.save_set() - if self.opened: - self.err(token=self.tokens[tokpos], - errmsg='Cannot nest resource sets') - self.sequential = False - if p == '[': - self.require_all = False - self.opened = p + self.save_set() + self.update_attrs(p, tokpos) continue if p in self.close_set: - if not self.opened: - self.err(token=self.tokens[tokpos], - errmsg='Unmatched closing bracket') - if p != self.matching[self.opened]: - self.err(token=self.tokens[tokpos], - errmsg='Mismatched closing bracket') - if not self.set_pl: # empty sets not allowed + # empty sets not allowed + if not self.set_pl: self.err(token=self.tokens[tokpos], errmsg='Empty resource set') self.save_set() - self.sequential = True - if p == ']': - self.require_all = True + self.update_attrs(p, tokpos) continue if '=' in p: if not self.parseattr(p): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh/modules/scripts.py new/crmsh/modules/scripts.py --- old/crmsh/modules/scripts.py 2014-02-13 16:16:00.000000000 +0100 +++ new/crmsh/modules/scripts.py 2014-02-19 10:20:53.000000000 +0100 @@ -244,7 +244,7 @@ 'KbdInteractiveAuthentication=no', 'PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey', 'PasswordAuthentication=no', - #'StrictHostKeyChecking=no', + 'StrictHostKeyChecking=no', 'ControlPersist=no'] if config.core.debug: opts.ssh_extra += ['-vvv'] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh/test/unittests/test_cliformat.py new/crmsh/test/unittests/test_cliformat.py --- old/crmsh/test/unittests/test_cliformat.py 2014-02-13 16:16:00.000000000 +0100 +++ new/crmsh/test/unittests/test_cliformat.py 2014-02-19 10:20:53.000000000 +0100 @@ -56,6 +56,7 @@ if s != cli: print "GOT:", s print "EXP:", cli + assert obj.cli_use_validate() assert s == cli @@ -72,3 +73,23 @@ def test_sequential(): roundtrip('colocation', 'rsc_colocation-master', 'colocation rsc_colocation-master inf: [ vip-master vip-rep sequential="true" ] [ msPostgresql:Master sequential="true" ]') + +def test_broken_colo(): + xml = """<rsc_colocation id="colo-2" score="INFINITY"> + <resource_set id="colo-2-0" require-all="false"> + <resource_ref id="vip1"/> + <resource_ref id="vip2"/> + </resource_set> + <resource_set id="colo-2-1" require-all="false" role="Master"> + <resource_ref id="apache"/> + </resource_set> +</rsc_colocation>""" + from lxml import etree + data = etree.fromstring(xml) + obj = factory.new_object('colocation', 'colo-2') + assert obj is not None + obj.node = data + obj.set_id() + data = obj.repr_cli(format=-1) + print data + assert data == 'colocation colo-2 inf: [ vip1 vip2 sequential="true" ] [ apache:Master sequential="true" ]' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh/test/unittests/test_parse.py new/crmsh/test/unittests/test_parse.py --- old/crmsh/test/unittests/test_parse.py 2014-02-13 16:16:00.000000000 +0100 +++ new/crmsh/test/unittests/test_parse.py 2014-02-19 10:20:53.000000000 +0100 @@ -207,6 +207,8 @@ out = self.parser.parse('colocation col-1 inf: foo:master ( bar wiz sequential=yes )') self.assertEqual(out.id, 'col-1') self.assertEqual(2, sum(1 for s in out.resources if s[0] == 'resource_set')) + self.assertFalse(['sequential', 'true'] in out.resources[0][1]) + self.assertFalse(['sequential', 'false'] in out.resources[0][1]) out = self.parser.parse( 'colocation col-1 -20: foo:Master ( bar wiz ) ( zip zoo ) node-attribute="fiz"') @@ -232,7 +234,8 @@ out = self.parser.parse('order o1 Mandatory: [ A B sequential=true ] C') self.assertEqual(out.resources[0][0], 'resource_set') self.assertTrue(['require-all', 'false'] in out.resources[0][1]) - self.assertTrue(['sequential', 'true'] in out.resources[0][1]) + self.assertFalse(['sequential', 'true'] in out.resources[0][1]) + self.assertFalse(['sequential', 'false'] in out.resources[0][1]) self.assertEqual(out.id, 'o1') out = self.parser.parse('order o1 Mandatory: [ A B sequential=false ] C') @@ -265,10 +268,12 @@ self.assertEqual(out.id, 'o1') self.assertTrue(out.symmetrical) - out = self.parser.parse('colocation rsc_colocation-master INFINITY: [ vip-master vip-rep sequential=true ] [ msPostgresql:Master sequential=true ]') + inp = 'colocation rsc_colocation-master INFINITY: [ vip-master vip-rep sequential=true ] [ msPostgresql:Master sequential=true ]' + out = self.parser.parse(inp) + print inp print out.to_list() self.assertEqual(out.resources[0][0], 'resource_set') - self.assertTrue(['sequential', 'true'] in out.resources[0][1]) + self.assertFalse(['sequential', 'false'] in out.resources[0][1]) self.assertEqual(out.id, 'rsc_colocation-master') out = self.parser.parse('order order_2 Mandatory: [ A B ] C') -- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
