Hello community,

here is the log from the commit of package crmsh for openSUSE:Factory checked 
in at 2014-05-17 21:43:24
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
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-05-15 
19:10:29.000000000 +0200
+++ /work/SRC/openSUSE:Factory/.crmsh.new/crmsh.changes 2014-05-17 
21:43:25.000000000 +0200
@@ -1,0 +2,9 @@
+Fri May 16 11:31:42 UTC 2014 - kgronl...@suse.com
+
+- high: xmlutil: Include remote nodes in nodelist (bnc#877962)
+- high: cibconfig: Ban containers stealing children (bnc#878112)
+- high: parse: Allow role in rule-based location constraints (bnc#878128)
+- low: command: Add -h and --help as aliases to help
+- upstream: 2.0.0-85-g5c9da05
+
+-------------------------------------------------------------------

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ crmsh.spec ++++++
--- /var/tmp/diff_new_pack.faZxQZ/_old  2014-05-17 21:43:26.000000000 +0200
+++ /var/tmp/diff_new_pack.faZxQZ/_new  2014-05-17 21:43:26.000000000 +0200
@@ -41,7 +41,7 @@
 Summary:        High Availability cluster command-line interface
 License:        GPL-2.0+
 Group:          %{pkg_group}
-Version:        2.0+git73
+Version:        2.0+git85
 Release:        %{?crmsh_release}%{?dist}
 Url:            http://crmsh.github.io
 Source0:        crmsh.tar.bz2

++++++ crmsh.tar.bz2 ++++++
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-05-14 16:04:21.000000000 +0200
+++ new/crmsh/doc/crm.8.txt     2014-05-16 13:20:50.000000000 +0200
@@ -2406,9 +2406,9 @@
 
 Usage:
 ...............
-location <id> <rsc> {node_pref|rules}
+location <id> <rsc> [role=<role>] {node_pref|rules}
 
-node_pref :: <score>: <node> [role=<role>]
+node_pref :: <score>: <node>
 
 rules ::
   rule [id_spec] [$role=<role>] <score>: <expression>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/crmsh/modules/cibconfig.py 
new/crmsh/modules/cibconfig.py
--- old/crmsh/modules/cibconfig.py      2014-05-14 16:04:21.000000000 +0200
+++ new/crmsh/modules/cibconfig.py      2014-05-16 13:20:50.000000000 +0200
@@ -1621,16 +1621,16 @@
         s = clidisplay.keyword(self.obj_type)
         id = clidisplay.id(self.obj_id)
         s = "%s %s %s" % (s, id, rsc)
+
+        role = self.node.get("role")
+        if role is not None:
+            s += " role=%s" % (role)
+
         pref_node = self.node.get("node")
         score = clidisplay.score(get_score(self.node))
         if pref_node is not None:
-            ret = "%s %s: %s" % (s, score, pref_node)
-            role = self.node.get("role")
-            if role is not None:
-                ret += " role=%s" % (role)
-            return ret
-        else:
-            return s
+            s = "%s %s: %s" % (s, score, pref_node)
+        return s
 
     def _repr_cli_child(self, c, format):
         if c.tag == "rule":
@@ -2352,6 +2352,7 @@
         properties and rsc/op_defaults hold stuff in a
         meta_attributes child.
         '''
+        assert node is not None
         if pnode is None:
             pnode = node
         obj = cib_object_map[pnode.tag][1](pnode.tag)
@@ -2954,7 +2955,8 @@
         if oldnode.getparent() is not None:
             oldnode.getparent().replace(oldnode, newnode)
         obj.nocli = False  # try again after update
-        self._adjust_children(obj)
+        if not self._adjust_children(obj):
+            return False
         if not obj.cli_use_validate():
             common_debug("update_element: validation failed (%s, %s)" % (obj, 
etree.tostring(newnode)))
             obj.nocli_warn = True
@@ -3070,33 +3072,56 @@
         '''
         new_children_ids = get_rsc_children_ids(obj.node)
         if not new_children_ids:
-            return
+            return True
         old_children = [x for x in obj.children if x.parent == obj]
         obj.children = [self.find_object(x) for x in new_children_ids]
         # relink orphans to top
         for child in set(old_children) - set(obj.children):
             common_debug("relink child %s to top" % str(child))
             self._relink_child_to_top(child)
-        self._update_children(obj)
+        if not self._are_children_orphans(obj):
+            return False
+        return self._update_children(obj)
 
     def _relink_child_to_top(self, obj):
         'Relink a child to the top node.'
         get_topnode(self.cib_elem, obj.parent_type).append(obj.node)
         obj.parent = None
 
+    def _are_children_orphans(self, obj):
+        """
+        Check if we're adding a container containing objects
+        we've already added to a different container
+        """
+        for child in obj.children:
+            if not child.parent:
+                continue
+            if child.parent == obj or child.parent.obj_id == obj.obj_id:
+                continue
+            if child.parent.obj_type in constants.container_tags:
+                common_err("Cannot create %s: Child %s already in %s" % (obj, 
child, child.parent))
+                return False
+        return True
+
     def _update_children(self, obj):
         '''For composite objects: update all children nodes.
         '''
         # unlink all and find them in the new node
         for child in obj.children:
             oldnode = child.node
-            child.node = obj.find_child_in_node(child)
+            newnode = obj.find_child_in_node(child)
+            if newnode is None:
+                common_err("Child found in children list but not in node: %s, 
%s" % (obj, child))
+                return False
+            child.node = newnode
             if child.children:  # and children of children
-                self._update_children(child)
+                if not self._update_children(child):
+                    return False
             rmnode(oldnode)
-            if child.parent and child.parent != obj:
-                child.parent.updated = True  # the other parent updated
+            if child.parent:
+                child.parent.updated = True
             child.parent = obj
+        return True
 
     def test_element(self, obj):
         if not obj.xml_obj_type in constants.defaults_tags:
@@ -3127,12 +3152,14 @@
                     child.node = c
 
     def _add_element(self, obj, node):
+        assert node is not None
         obj.node = node
         obj.set_id()
         pnode = get_topnode(self.cib_elem, obj.parent_type)
         common_debug("_add_element: append child %s to %s" % (obj.obj_id, 
pnode.tag))
+        if not self._adjust_children(obj):
+            return None
         pnode.append(node)
-        self._adjust_children(obj)
         self._redirect_children_constraints(obj)
         if not obj.cli_use_validate():
             self.nocli_warn = True
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/crmsh/modules/command.py new/crmsh/modules/command.py
--- old/crmsh/modules/command.py        2014-05-14 16:04:21.000000000 +0200
+++ new/crmsh/modules/command.py        2014-05-16 13:20:50.000000000 +0200
@@ -322,7 +322,7 @@
     def do_quit(self, context):
         context.quit()
 
-    @alias('?')
+    @alias('?', '-h', '--help')
     @help('''show help (help topics for list of topics)
 The help subsystem consists of the command reference and a list
 of topics. The former is what you need in order to get the
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/crmsh/modules/idmgmt.py new/crmsh/modules/idmgmt.py
--- old/crmsh/modules/idmgmt.py 2014-05-14 16:04:21.000000000 +0200
+++ new/crmsh/modules/idmgmt.py 2014-05-16 13:20:50.000000000 +0200
@@ -59,7 +59,7 @@
     '''
     Create a unique id for the xml node.
     '''
-    common_debug("idmgmt.new: node=%s, pfx=%s" % (etree.tostring(node), pfx))
+    #common_debug("idmgmt.new: node=%s, pfx=%s" % (etree.tostring(node), pfx))
     name = node.get("name")
     if node.tag == "nvpair":
         node_id = "%s-%s" % (pfx, name)
@@ -151,7 +151,7 @@
 def save(node_id):
     if not node_id:
         return
-    common_debug("id_store: saved %s" % node_id)
+    #common_debug("id_store: saved %s" % node_id)
     _id_store[node_id] = 1
 
 
@@ -171,7 +171,7 @@
         return
     try:
         del _id_store[node_id]
-        common_debug("id_store: removed %s" % node_id)
+        #common_debug("id_store: removed %s" % node_id)
     except KeyError:
         pass
 
@@ -194,10 +194,8 @@
     '''
     old_id = oldnode.get("id") if oldnode is not None else None
     new_id = node.get("id") or old_id or node.get("uname")
-    from msg import common_debug
-    from lxml import etree
-    common_debug("idmgmt.set: node=%s, new_id=%s, old_id=%s, id_hint=%s" %
-                 (etree.tostring(node), new_id, old_id, id_hint))
+    #common_debug("idmgmt.set: node=%s, new_id=%s, old_id=%s, id_hint=%s" %
+    #             (etree.tostring(node), new_id, old_id, id_hint))
     if new_id:
         save(new_id)
     elif id_required:
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-05-14 16:04:21.000000000 +0200
+++ new/crmsh/modules/parse.py  2014-05-16 13:20:50.000000000 +0200
@@ -698,7 +698,7 @@
     def parse_location(self):
         """
         location <id> rsc <score>: <node> [role=<role>]
-        location <id> rsc [rule ...]
+        location <id> rsc [role=<role>] [rule ...]
         rsc :: /<rsc-pattern>/
             | { <rsc-set> }
             | <rsc>
@@ -716,12 +716,20 @@
                 out.append(rscset)
         else:
             out.set('rsc', self.match_resource())
+
+        if self.try_match(self._ROLE_RE) or self.try_match(self._ROLE2_RE):
+            out.set('role', self.matched(1))
+
+        score = False
         if self.try_match(self._SCORE_RE):
+            score = True
             out.set(*self.validate_score(self.matched(1)))
             out.set('node', self.match_identifier())
-            if self.try_match(self._ROLE_RE) or self.try_match(self._ROLE2_RE):
-                out.set('role', self.matched(1))
-        else:
+            # backwards compatibility: role used to be read here
+            if 'role' not in out:
+                if self.try_match(self._ROLE_RE) or 
self.try_match(self._ROLE2_RE):
+                    out.set('role', self.matched(1))
+        if not score:
             for rule in self.match_rules():
                 out.append(rule)
         return out
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/crmsh/modules/ui_configure.py 
new/crmsh/modules/ui_configure.py
--- old/crmsh/modules/ui_configure.py   2014-05-14 16:04:21.000000000 +0200
+++ new/crmsh/modules/ui_configure.py   2014-05-16 13:20:50.000000000 +0200
@@ -550,8 +550,7 @@
                 not cib_factory.is_elem_supported(cmd):
             common_err("%s not supported by the RNG schema" % cmd)
             return False
-        f = lambda: cib_factory.create_object(cmd, *args)
-        return f()
+        return cib_factory.create_object(cmd, *args)
 
     @command.skill_level('administrator')
     @command.completers(_node_id_list, 
compl.choice(constants.node_attributes_keyw))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/crmsh/modules/xmlutil.py new/crmsh/modules/xmlutil.py
--- old/crmsh/modules/xmlutil.py        2014-05-14 16:04:21.000000000 +0200
+++ new/crmsh/modules/xmlutil.py        2014-05-16 13:20:50.000000000 +0200
@@ -332,17 +332,20 @@
 
 
 def listnodes():
-    nodes_elem = cibdump2elem("nodes")
-    if nodes_elem is None:
+    cib = cibdump2elem()
+    if cib is None:
         return []
-    return [x.get("uname") for x in nodes_elem.iterchildren("node")
-            if is_normal_node(x)]
+    local_nodes = cib.xpath('/cib/configuration/nodes/node/@uname')
+    remote_nodes = 
cib.xpath('/cib/status/node_state[@remote_node="true"]/@uname')
+    return list(set([n for n in local_nodes + remote_nodes if n]))
 
 
 def is_our_node(s):
     '''
     Check if s is in a list of our nodes (ignore case).
     This is not fast, perhaps should be cached.
+
+    Includes remote nodes as well
     '''
     for n in listnodes():
         if n.lower() == s.lower():
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/crmsh/test/cibtests/003.exp.xml 
new/crmsh/test/cibtests/003.exp.xml
--- old/crmsh/test/cibtests/003.exp.xml 2014-05-14 16:04:21.000000000 +0200
+++ new/crmsh/test/cibtests/003.exp.xml 2014-05-16 13:20:50.000000000 +0200
@@ -1,4 +1,4 @@
-<cib epoch="3" num_updates="1" admin_epoch="0" validate-with="pacemaker-1.0" 
cib-last-written="Tue Mar 31 14:52:24 2009">
+<cib epoch="4" num_updates="1" admin_epoch="0" validate-with="pacemaker-1.0" 
cib-last-written="Tue Mar 31 14:52:24 2009">
   <configuration>
     <crm_config>
       <cluster_property_set id="cib-bootstrap-options">
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/crmsh/test/cibtests/004.exp.xml 
new/crmsh/test/cibtests/004.exp.xml
--- old/crmsh/test/cibtests/004.exp.xml 2014-05-14 16:04:21.000000000 +0200
+++ new/crmsh/test/cibtests/004.exp.xml 2014-05-16 13:20:50.000000000 +0200
@@ -1,4 +1,4 @@
-<cib epoch="3" num_updates="1" admin_epoch="0" validate-with="pacemaker-1.0" 
cib-last-written="Tue Mar 31 14:52:24 2009">
+<cib epoch="4" num_updates="1" admin_epoch="0" validate-with="pacemaker-1.0" 
cib-last-written="Tue Mar 31 14:52:24 2009">
   <configuration>
     <crm_config>
       <cluster_property_set id="cib-bootstrap-options">
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/crmsh/test/testcases/edit.exp 
new/crmsh/test/testcases/edit.exp
--- old/crmsh/test/testcases/edit.exp   2014-05-14 16:04:21.000000000 +0200
+++ new/crmsh/test/testcases/edit.exp   2014-05-16 13:20:50.000000000 +0200
@@ -29,6 +29,7 @@
 .INP: primitive d3 ocf:heartbeat:Dummy
 .INP: group g2 d1 d2
 .INP: filter "sed '/g2/s/d1/p1/;/g1/s/p1/d1/'"
+ERROR: 27: Cannot create group:g2: Child primitive:p1 already in group:g1
 .INP: filter "sed '/g1/s/d1/p1/;/g2/s/p1/d1/'"
 .INP: filter "sed '$alocation loc-d1 d1 rule $id=r1 -inf: not_defined 
webserver rule $id=r2 webserver: defined webserver'"
 .INP: filter "sed 's/not_defined webserver/& or mem number:lte 0/'" loc-d1
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/crmsh/test/unittests/test_bugs.py 
new/crmsh/test/unittests/test_bugs.py
--- old/crmsh/test/unittests/test_bugs.py       2014-05-14 16:04:21.000000000 
+0200
+++ new/crmsh/test/unittests/test_bugs.py       2014-05-16 13:20:50.000000000 
+0200
@@ -234,3 +234,39 @@
     print "AFTER:", etree.tostring(elem)
 
     assert len(elem.xpath(".//meta_attributes/nvpair[@name='target-role']")) 
== 1
+
+
+def test_bnc878128():
+    """
+    L3: "crm configure show" displays XML information instead of typical crm 
output.
+    """
+    xml = """<rsc_location id="cli-prefer-dummy-resource" rsc="dummy-resource"
+role="Started">
+  <rule id="cli-prefer-rule-dummy-resource" score="INFINITY">
+    <expression id="cli-prefer-expr-dummy-resource" attribute="#uname"
+operation="eq" value="x64-4"/>
+    <date_expression id="cli-prefer-lifetime-end-dummy-resource" operation="lt"
+end="2014-05-17 17:56:11Z"/>
+  </rule>
+</rsc_location>"""
+    data = etree.fromstring(xml)
+    obj = factory.create_from_node(data)
+    assert obj is not None
+    data = obj.repr_cli(format=-1)
+    print "OUTPUT:", data
+    exp = 'location cli-prefer-dummy-resource dummy-resource role=Started rule 
#uname eq x64-4 and date lt "2014-05-17 17:56:11Z"'
+    assert data == exp
+    assert obj.cli_use_validate()
+
+
+def test_bnc878112():
+    """
+    crm configure group can hijack a cloned primitive (and then crash)
+    """
+    obj1 = factory.create_object('primitive', 'p1', 'Dummy')
+    assert obj1 is not None
+    obj2 = factory.create_object('group', 'g1', 'p1')
+    assert obj2 is not None
+    obj3 = factory.create_object('group', 'g2', 'p1')
+    print obj3
+    assert obj3 is False
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-05-14 16:04:21.000000000 
+0200
+++ new/crmsh/test/unittests/test_cliformat.py  2014-05-16 13:20:50.000000000 
+0200
@@ -25,9 +25,7 @@
 
 
 def assert_is_not_none(thing):
-    if thing is None:
-        message = "%s was None" % (thing)
-        raise AssertionError(message)
+    assert thing is not None, "Expected non-None value"
 
 
 def roundtrip(cli, debug=False):

-- 
To unsubscribe, e-mail: opensuse-commit+unsubscr...@opensuse.org
For additional commands, e-mail: opensuse-commit+h...@opensuse.org

Reply via email to