Hello community,

here is the log from the commit of package crmsh for openSUSE:Factory checked 
in at 2015-10-12 10:02:35
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
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      2015-10-02 
09:23:51.000000000 +0200
+++ /work/SRC/openSUSE:Factory/.crmsh.new/crmsh.changes 2015-10-12 
10:02:44.000000000 +0200
@@ -1,0 +2,25 @@
+Thu Oct 08 21:44:06 UTC 2015 - kgronl...@suse.com
+
+- Update to version 2.2.0~rc3+git.1444340345.59850ca:
+  + high: utils: Fix cluster_copy_file error when nodes provided (bsc#949603)
+  + low: xmlutil: More informative message when updating resource references 
after rename
+  + doc: fix some command syntax grammar in the man page
+  + doc: resource-discovery for location constraints
+
+-------------------------------------------------------------------
+Tue Oct 06 12:22:30 UTC 2015 - kgronl...@suse.com
+
+- Update to version 2.2.0~rc3+git.1444133917.3f7f79f:
+  + high: cibconfig: Fix bug in is_edit_valid (bsc#948547)
+  + high: cibconfig: Delete constraints before resources
+
+-------------------------------------------------------------------
+Tue Oct 06 09:14:24 UTC 2015 - kgronl...@suse.com
+
+- Update to version 2.2.0~rc3+git.1444122392.193bf69:
+  + high: cibconfig: Allow nodes and resources with the same ID (bsc#948547)
+  + high: cibconfig: Allow node/rsc id collision in _set_update (bsc#948547)
+  + medium: hb_report: Don't cat binary logs
+  + low: report: Silence tar warning on early stream close
+
+-------------------------------------------------------------------

Old:
----
  crmsh-2.2.0~rc3+git.1443544100.aa2abda.tar.bz2

New:
----
  crmsh-2.2.0~rc3+git.1444340345.59850ca.tar.bz2

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

Other differences:
------------------
++++++ crmsh.spec ++++++
--- /var/tmp/diff_new_pack.lYKxtr/_old  2015-10-12 10:02:44.000000000 +0200
+++ /var/tmp/diff_new_pack.lYKxtr/_new  2015-10-12 10:02:44.000000000 +0200
@@ -36,7 +36,7 @@
 Summary:        High Availability cluster command-line interface
 License:        GPL-2.0+
 Group:          %{pkg_group}
-Version:        2.2.0~rc3+git.1443544100.aa2abda
+Version:        2.2.0~rc3+git.1444340345.59850ca
 Release:        0
 Url:            http://crmsh.github.io
 Source0:        %{name}-%{version}.tar.bz2

++++++ _servicedata ++++++
--- /var/tmp/diff_new_pack.lYKxtr/_old  2015-10-12 10:02:44.000000000 +0200
+++ /var/tmp/diff_new_pack.lYKxtr/_new  2015-10-12 10:02:44.000000000 +0200
@@ -1,4 +1,4 @@
 <servicedata>
 <service name="tar_scm">
             <param name="url">git://github.com/ClusterLabs/crmsh.git</param>
-          <param 
name="changesrevision">aa2abdad0c401d1cebf43e1a20da26b3de2992c5</param></service></servicedata>
\ No newline at end of file
+          <param 
name="changesrevision">59850ca9ed07b3e965170b1fb50712ea1bfa502f</param></service></servicedata>
\ No newline at end of file

++++++ crmsh-2.2.0~rc3+git.1443544100.aa2abda.tar.bz2 -> 
crmsh-2.2.0~rc3+git.1444340345.59850ca.tar.bz2 ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/crmsh-2.2.0~rc3+git.1443544100.aa2abda/doc/crm.8.adoc 
new/crmsh-2.2.0~rc3+git.1444340345.59850ca/doc/crm.8.adoc
--- old/crmsh-2.2.0~rc3+git.1443544100.aa2abda/doc/crm.8.adoc   2015-09-30 
17:21:36.000000000 +0200
+++ new/crmsh-2.2.0~rc3+git.1444340345.59850ca/doc/crm.8.adoc   2015-10-08 
23:44:05.000000000 +0200
@@ -797,12 +797,12 @@
 
 id_spec :: $id=<id> | $id-ref=<id>
 score :: <number> | <attribute> | [-]inf
-expression :: <simple_exp> [bool_op <simple_exp> ...]
+expression :: <simple_exp> [<bool_op> <simple_exp> ...]
 bool_op :: or | and
 simple_exp :: <attribute> [type:]<binary_op> <value>
           | <unary_op> <attribute>
           | date <date_expr>
-type :: string | version | number
+type :: <string> | <version> | <number>
 binary_op :: lt | gt | lte | gte | eq | ne
 unary_op :: defined | not_defined
 
@@ -2574,8 +2574,8 @@
 ...............
 clone <name> <rsc>
   [description=<description>]
-  [meta attr_list]
-  [params attr_list]
+  [meta <attr_list>]
+  [params <attr_list>]
 
 attr_list :: [$id=<id>] <attr>=<val> [<attr>=<val>...] | $id-ref=<id>
 ...............
@@ -2622,13 +2622,13 @@
 colocation <id> <score>: <rsc>[:<role>] <with-rsc>[:<role>]
   [node-attribute=<node_attr>]
 
-colocation <id> <score>: resource_sets
+colocation <id> <score>: <resource_sets>
   [node-attribute=<node_attr>]
 
-resource_sets :: resource_set [resource_set ...]
+resource_sets :: <resource_set> [<resource_set> ...]
 
 resource_set :: ["("|"["] <rsc>[:<role>] [<rsc>[:<role>] ...] \
-                [attributes]  [")"|"]"]
+                [<attributes>]  [")"|"]"]
 
 attributes :: [require-all=(true|false)] [sequential=(true|false)]
 
@@ -2924,6 +2924,9 @@
 * Tag containing resource ids: +location loc1 tag1 100: node1+
 * Resource pattern: +location loc1 /web.*/ 100: node1+
 
+The +resource-discovery+ attribute allows probes to be selectively
+enabled or disabled per resource and node.
+
 The syntax for resource sets is described in detail for
 <<cmdhelp_configure_colocation,`colocation`>>.
 
@@ -2935,12 +2938,14 @@
 
 Usage:
 ...............
-location <id> rsc [role=<role>] {node_pref|rules}
+location <id> <rsc> [<attributes>] {<node_pref>|<rules>}
 
 rsc :: /<rsc-pattern>/
         | { resource_sets }
         | <rsc>
 
+attributes :: role=<role> | resource-discovery=always|never|exclusive
+
 node_pref :: <score>: <node>
 
 rules ::
@@ -2949,7 +2954,7 @@
 
 id_spec :: $id=<id> | $id-ref=<id>
 score :: <number> | <attribute> | [-]inf
-expression :: <simple_exp> [bool_op <simple_exp> ...]
+expression :: <simple_exp> [<bool_op> <simple_exp> ...]
 bool_op :: or | and
 simple_exp :: <attribute> [type:]<binary_op> <value>
           | <unary_op> <attribute>
@@ -2984,6 +2989,9 @@
 
 location conn_2 dummy_float \
   rule -inf: not_defined pingd or pingd number:lte 0
+
+# never probe for rsc1 on node1
+location no-probe rsc1 resource-discovery=never -inf: node1
 ...............
 
 [[cmdhelp_configure_modgroup,modify group]]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/crmsh-2.2.0~rc3+git.1443544100.aa2abda/hb_report/hb_report.in 
new/crmsh-2.2.0~rc3+git.1444340345.59850ca/hb_report/hb_report.in
--- old/crmsh-2.2.0~rc3+git.1443544100.aa2abda/hb_report/hb_report.in   
2015-09-30 17:21:36.000000000 +0200
+++ new/crmsh-2.2.0~rc3+git.1444340345.59850ca/hb_report/hb_report.in   
2015-10-08 23:44:05.000000000 +0200
@@ -330,8 +330,10 @@
                echo "gzip -dc"
        elif echo $1 | grep -qs 'xz$'; then
                echo "xz -dc"
-       else
+       elif file $1 | grep -qs 'text'; then
                echo "cat"
+       else
+               echo "echo"
        fi
 }
 #
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/crmsh-2.2.0~rc3+git.1443544100.aa2abda/modules/cibconfig.py 
new/crmsh-2.2.0~rc3+git.1444340345.59850ca/modules/cibconfig.py
--- old/crmsh-2.2.0~rc3+git.1443544100.aa2abda/modules/cibconfig.py     
2015-09-30 17:21:36.000000000 +0200
+++ new/crmsh-2.2.0~rc3+git.1444340345.59850ca/modules/cibconfig.py     
2015-10-08 23:44:05.000000000 +0200
@@ -494,28 +494,6 @@
             rc |= obj.check_sanity()
         return rc
 
-    def is_edit_valid(self, id_set):
-        '''
-        1. Cannot name any elements as those which exist but
-        were not picked for editing.
-        2. Cannot remove running resources.
-        '''
-        rc = True
-        not_allowed = id_set & self.locked_ids
-        rscstat = RscState()
-        if not_allowed:
-            common_err("Elements %s already exist" %
-                       ', '.join(list(not_allowed)))
-            rc = False
-        delete_set = self.obj_ids - id_set
-        cannot_delete = [x for x in delete_set
-                         if not rscstat.can_delete(x)]
-        if cannot_delete:
-            common_err("Cannot delete running resources: %s" %
-                       ', '.join(cannot_delete))
-            rc = False
-        return rc
-
 
 class CibObjectSetCli(CibObjectSet):
     '''
@@ -570,9 +548,7 @@
         coming from edit). The original CIB is preserved and no
         changes are made.
         '''
-        edit_d = {}
-        id_set = oset()
-        del_set = oset()
+        diff = CibDiff(self)
         rc = True
         err_buf.start_tmp_lineno()
         cp = CliParser()
@@ -580,32 +556,17 @@
             err_buf.incr_lineno()
             node = cp.parse(cli_text)
             if node not in (False, None):
-                obj_id = id_for_node(node)
-                if obj_id is None:
-                    common_err("element %s has no id!" %
-                               etree.tostring(node, pretty_print=True))
-                    rc = False
-                elif obj_id in id_set:
-                    common_err("duplicate element %s" % obj_id)
-                    rc = False
-                else:
-                    id_set.add(obj_id)
-                    edit_d[obj_id] = node
+                rc = diff.add(node)
             elif node is False:
                 rc = False
         err_buf.stop_tmp_lineno()
+
         # we can't proceed if there was a syntax error, but we
         # can ask the user to fix problems
-        if not no_remove:
-            rc &= self.is_edit_valid(id_set)
-            del_set = self.obj_ids - id_set
         if not rc:
             return rc
-        mk_set = id_set - self.obj_ids
-        upd_set = id_set & self.obj_ids
 
-        rc = cib_factory.set_update(edit_d, mk_set, upd_set, del_set,
-                                    upd_type="cli", method=method)
+        rc = diff.apply(cib_factory, mode='cli', no_remove=no_remove, 
method=method)
         if not rc:
             self._initialize()
         return rc
@@ -639,29 +600,12 @@
         if not show_unrecognized_elems(cib_elem):
             return False
         rc = True
-        id_set = oset()
-        del_set = oset()
-        edit_d = {}
+        diff = CibDiff(self)
         for node in get_top_cib_nodes(cib_elem, []):
-            id = self._get_id(node)
-            if id is None:
-                common_err("element %s has no id!" %
-                           etree.tostring(node, pretty_print=True))
-                rc = False
-            elif id in id_set:
-                common_err("duplicate element %s" % id)
-                rc = False
-            else:
-                id_set.add(id)
-                edit_d[id] = node
-        if not no_remove:
-            rc &= self.is_edit_valid(id_set)
-            del_set = self.obj_ids - id_set
+            rc = diff.add(node)
         if not rc:
             return rc
-        mk_set = id_set - self.obj_ids
-        upd_set = id_set & self.obj_ids
-        rc = cib_factory.set_update(edit_d, mk_set, upd_set, del_set, "xml", 
method)
+        rc = diff.apply(cib_factory, mode='xml', no_remove=no_remove, 
method=method)
         if not rc:
             self._initialize()
         return rc
@@ -1145,7 +1089,7 @@
         Check if all operation attributes are supported by the
         schema.
         '''
-        rc = True
+        rc = 0
         op_id = op_node.get("name")
         for name in op_node.keys():
             vals = schema.rng_attr_values(op_node.tag, name)
@@ -1155,14 +1099,14 @@
             if v not in vals:
                 common_warn("%s: op '%s' attribute '%s' value '%s' not 
recognized" %
                             (self.obj_id, op_id, name, v))
-                rc = False
+                rc = 1
         return rc
 
     def _check_ops_attributes(self):
         '''
         Check if operation attributes settings are valid.
         '''
-        rc = True
+        rc = 0
         if self.node is None:
             return rc
         for op_node in self.node.xpath("operations/op"):
@@ -2139,6 +2083,112 @@
 cib_upgrade = "cibadmin --upgrade --force"
 
 
+class CibDiff(object):
+    '''
+    Represents a cib edit order.
+    Is complicated by the fact that
+    nodes and resources can have
+    colliding ids.
+
+    Can carry changes either as CLI objects
+    or as XML statements.
+    '''
+    def __init__(self, objset):
+        self.objset = objset
+        self._node_set = oset()
+        self._nodes = {}
+        self._rsc_set = oset()
+        self._resources = {}
+
+    def add(self, item):
+        obj_id = id_for_node(item)
+        is_node = item.tag == 'node'
+        if obj_id is None:
+            common_err("element %s has no id!" %
+                       etree.tostring(item, pretty_print=True))
+            return False
+        elif is_node and obj_id in self._node_set:
+            common_err("Duplicate node: %s" % (obj_id))
+            return False
+        elif not is_node and obj_id in self._rsc_set:
+            common_err("Duplicate resource: %s" % (obj_id))
+            return False
+        elif is_node:
+            self._node_set.add(obj_id)
+            self._nodes[obj_id] = item
+        else:
+            self._rsc_set.add(obj_id)
+            self._resources[obj_id] = item
+        return True
+
+    def _obj_type(self, nid):
+        for obj in self.objset.all_set:
+            if obj.obj_id == nid:
+                return obj.obj_type
+        return None
+
+    def _obj_nodes(self):
+        return oset([n for n in self.objset.obj_ids
+                     if self._obj_type(n) == 'node'])
+
+    def _obj_resources(self):
+        return oset([n for n in self.objset.obj_ids
+                     if self._obj_type(n) != 'node'])
+
+    def _is_edit_valid(self, id_set, existing):
+        '''
+        1. Cannot name any elements as those which exist but
+        were not picked for editing.
+        2. Cannot remove running resources.
+        '''
+        rc = True
+        not_allowed = id_set & self.objset.locked_ids
+        rscstat = RscState()
+        if not_allowed:
+            common_err("Elements %s already exist" %
+                       ', '.join(list(not_allowed)))
+            rc = False
+        delete_set = existing - id_set
+        cannot_delete = [x for x in delete_set
+                         if not rscstat.can_delete(x)]
+        if cannot_delete:
+            common_err("Cannot delete running resources: %s" %
+                       ', '.join(cannot_delete))
+            rc = False
+        return rc
+
+
+    def apply(self, factory, mode='cli', no_remove=False, method='replace'):
+        rc = True
+
+        edited_nodes = self._nodes.copy()
+        edited_resources = self._resources.copy()
+
+        def calc_sets(input_set, existing):
+            rc = True
+            if not no_remove:
+                rc = self._is_edit_valid(input_set, existing)
+                del_set = existing - (input_set)
+            else:
+                del_set = oset()
+            mk_set = (input_set) - existing
+            upd_set = (input_set) & existing
+            return rc, mk_set, upd_set, del_set
+
+        if not rc:
+            return rc
+
+        for e, s, existing in ((edited_nodes, self._node_set, 
self._obj_nodes()),
+                               (edited_resources, self._rsc_set, 
self._obj_resources())):
+            rc, mk, upd, rm = calc_sets(s, existing)
+            if not rc:
+                return rc
+            rc = cib_factory.set_update(e, mk, upd, rm, upd_type=mode, 
method=method)
+            if not rc:
+                return rc
+        return rc
+
+
 class CibFactory(object):
     '''
     Juggle with CIB objects.
@@ -2602,7 +2652,7 @@
         # need to get addresses of all new objects created by
         # deepcopy
         for obj in self.cib_objects:
-            obj.node = self.find_node(obj.xml_obj_type, obj.obj_id)
+            obj.node = self.find_xml_node(obj.xml_obj_type, obj.obj_id)
             self._update_links(obj)
         idmgmt.pop_state()
         return self.check_structure()
@@ -2649,9 +2699,34 @@
         if objs is None:
             return None
         if len(objs) > 0:
+            for obj in objs:
+                if obj.obj_type != 'node':
+                    return obj
             return objs[0]
         return None
 
+    def find_resource(self, obj_id):
+        if not self.is_cib_sane():
+            return None
+        objs = self.find_objects(obj_id)
+        if objs is None:
+            return None
+        for obj in objs:
+            if obj.obj_type != 'node':
+                return obj
+        return None
+
+    def find_node(self, obj_id):
+        if not self.is_cib_sane():
+            return None
+        objs = self.find_objects(obj_id)
+        if objs is None:
+            return None
+        for obj in objs:
+            if obj.obj_type == 'node':
+                return obj
+        return None
+
     #
     # tab completion functions
     #
@@ -2687,8 +2762,8 @@
 
     def node_id_list(self):
         "List of node ids."
-        return [x.node.get("uname") for x in self.cib_objects
-                if x.obj_type == "node"]
+        return sorted([x.node.get("uname") for x in self.cib_objects
+                       if x.obj_type == "node"])
 
     def f_prim_free_id_list(self):
         "List of possible primitives ids (for group completion)."
@@ -2723,8 +2798,8 @@
                 return obj
         return None
 
-    def find_node(self, tag, id, strict=True):
-        "Find a node of this type with this id."
+    def find_xml_node(self, tag, id, strict=True):
+        "Find a xml node of this type with this id."
         try:
             if tag in constants.defaults_tags:
                 expr = '//%s/meta_attributes[@id="%s"]' % (tag, id)
@@ -2754,7 +2829,7 @@
             return False
         rc = True
         for obj_id in args:
-            obj = self.find_object(obj_id)
+            obj = self.find_resource(obj_id)
             if not obj:
                 no_object_err(obj_id)
                 rc = False
@@ -2834,7 +2909,7 @@
         id to reference.
         '''
         self.id_refs[id_ref] = attr_list_type
-        obj = self.find_object(id_ref)
+        obj = self.find_resource(id_ref)
         if obj:
             nodes = obj.node.xpath(".//%s" % attr_list_type)
             if len(nodes) > 1:
@@ -2904,7 +2979,7 @@
         matching_tags = [x for x in self.cib_objects if x.obj_type == 'tag' 
and x.obj_id == t]
         ret = []
         for mt in matching_tags:
-            matches = [cib_factory.find_object(o) for o in 
mt.node.xpath('./obj_ref/@id')]
+            matches = [cib_factory.find_resource(o) for o in 
mt.node.xpath('./obj_ref/@id')]
             ret += [m for m in matches if m is not None]
         return ret
 
@@ -2955,7 +3030,7 @@
         rc = True
         constraint_id = node.get("id")
         for obj_id in referenced_resources(node):
-            if not self.find_object(obj_id):
+            if not self.find_resource(obj_id):
                 constraint_norefobj_err(constraint_id, obj_id)
                 rc = False
         return rc
@@ -2993,7 +3068,7 @@
 
     def _verify_child(self, child_id, parent_tag, obj_id):
         'Check if child exists and obj_id is (or may become) its parent.'
-        child = self.find_object(child_id)
+        child = self.find_resource(child_id)
         if not child:
             no_object_err(child_id)
             return False
@@ -3062,7 +3137,7 @@
         '''Add an op to a primitive.'''
         # does the referenced primitive exist
         rsc_id = node.get('rsc')
-        rsc_obj = self.find_object(rsc_id)
+        rsc_obj = self.find_resource(rsc_id)
         if not rsc_obj:
             no_object_err(rsc_id)
             return None
@@ -3095,7 +3170,7 @@
         if obj_type == "op":
             return self.add_op(elem)
         if obj_type == "node":
-            obj = self.find_object(obj_id)
+            obj = self.find_node(obj_id)
             # make an exception and allow updating nodes
             if obj:
                 self.merge_from_cli(obj, elem)
@@ -3166,17 +3241,32 @@
         del_set is a set to be removed.
         method is either replace or update.
         '''
-        common_debug("_cli_set_update: %s, %s, %s" % (mk_set, upd_set, 
del_set))
+        common_debug("_cli_set_update: mk=%s, upd=%s, del=%s" % (mk_set, 
upd_set, del_set))
         test_l = []
 
         def obj_is_container(x):
-            obj = self.find_object(x)
+            obj = self.find_resource(x)
             return obj and is_container(obj.node)
 
-        del_containers = [x for x in del_set if obj_is_container(x)]
-        del_objs = [x for x in del_set if not obj_is_container(x)]
+        def obj_is_constraint(x):
+            obj = self.find_resource(x)
+            return obj and is_constraint(obj.node)
+
+        del_constraints = []
+        del_containers = []
+        del_objs = []
+        for x in del_set:
+            if obj_is_constraint(x):
+                del_constraints.append(x)
+            elif obj_is_container(x):
+                del_containers.append(x)
+            else:
+                del_objs.append(x)
 
-        # delete containers first in case objects are moved elsewhere
+        # delete constraints and containers first in case objects are moved 
elsewhere
+        if not self.delete(*del_constraints):
+            common_debug("delete %s failed" % (list(del_set)))
+            return False
         if not self.delete(*del_containers):
             common_debug("delete %s failed" % (list(del_set)))
             return False
@@ -3190,7 +3280,10 @@
             test_l.append(obj)
 
         for id in upd_set:
-            obj = self.find_object(id)
+            if edit_d[id].tag == 'node':
+                obj = self.find_node(id)
+            else:
+                obj = self.find_resource(id)
             if not obj:
                 common_debug("%s not found!" % (id))
                 return False
@@ -3203,7 +3296,8 @@
                              (obj, etree.tostring(node), method))
                 return False
             test_l.append(obj)
-        if not self.delete(*del_objs):
+
+        if not self.delete(*reversed(del_objs)):
             common_debug("delete %s failed" % (list(del_set)))
             return False
         rc = True
@@ -3229,7 +3323,10 @@
                 return False
             test_l.append(obj)
         for id in upd_set:
-            obj = self.find_object(id)
+            if edit_d[id].tag == 'node':
+                obj = self.find_node(id)
+            else:
+                obj = self.find_resource(id)
             if not obj:
                 return False
             if not self.update_from_node(obj, edit_d[id]):
@@ -3272,7 +3369,7 @@
         if not new_children_ids:
             return True
         old_children = [x for x in obj.children if x.parent == obj]
-        new_children = [self.find_object(x) for x in new_children_ids]
+        new_children = [self.find_resource(x) for x in new_children_ids]
         new_children = [c for c in new_children if c is not None]
         obj.children = new_children
         # relink orphans to top
@@ -3380,7 +3477,7 @@
 
         for c in node.iterchildren('primitive'):
             pid = c.get('id')
-            child_obj = self.find_object(pid)
+            child_obj = self.find_resource(pid)
             if child_obj is None:
                 child_obj = self.create_from_node(copy.deepcopy(c))
                 if not child_obj:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/crmsh-2.2.0~rc3+git.1443544100.aa2abda/modules/parse.py 
new/crmsh-2.2.0~rc3+git.1444340345.59850ca/modules/parse.py
--- old/crmsh-2.2.0~rc3+git.1443544100.aa2abda/modules/parse.py 2015-09-30 
17:21:36.000000000 +0200
+++ new/crmsh-2.2.0~rc3+git.1444340345.59850ca/modules/parse.py 2015-10-08 
23:44:05.000000000 +0200
@@ -742,8 +742,8 @@
 
     def parse_location(self):
         """
-        location <id> rsc [[$]<attribute>=<value>] <score>: <node>
-        location <id> rsc [[$]<attribute>=<value>] <rule> [<rule> ...]
+        location <id> <rsc> [[$]<attribute>=<value>] <score>: <node>
+        location <id> <rsc> [[$]<attribute>=<value>] <rule> [<rule> ...]
         rsc :: /<rsc-pattern>/
             | { <rsc-set> }
             | <rsc>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/crmsh-2.2.0~rc3+git.1443544100.aa2abda/modules/report.py 
new/crmsh-2.2.0~rc3+git.1444340345.59850ca/modules/report.py
--- old/crmsh-2.2.0~rc3+git.1443544100.aa2abda/modules/report.py        
2015-09-30 17:21:36.000000000 +0200
+++ new/crmsh-2.2.0~rc3+git.1444340345.59850ca/modules/report.py        
2015-10-08 23:44:05.000000000 +0200
@@ -751,7 +751,7 @@
                 self.error(msg)
                 return None
         try:
-            rc, tf_loc = get_stdout("tar -t%s < %s | head -1" % 
(tar_unpack_option, quote(bfname)))
+            rc, tf_loc = get_stdout("tar -t%s < %s 2> /dev/null | head -1" % 
(tar_unpack_option, quote(bfname)))
             if os.path.abspath(tf_loc) != os.path.abspath(loc):
                 common_debug("top directory in tarball: %s, doesn't match the 
tarball name: %s" %
                              (tf_loc, loc))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/crmsh-2.2.0~rc3+git.1443544100.aa2abda/modules/ui_assist.py 
new/crmsh-2.2.0~rc3+git.1444340345.59850ca/modules/ui_assist.py
--- old/crmsh-2.2.0~rc3+git.1443544100.aa2abda/modules/ui_assist.py     
2015-09-30 17:21:36.000000000 +0200
+++ new/crmsh-2.2.0~rc3+git.1444340345.59850ca/modules/ui_assist.py     
2015-10-08 23:44:05.000000000 +0200
@@ -39,7 +39,7 @@
         '''
         if len(primitives) < 1:
             context.fatal_error("Expected at least one primitive argument")
-        objs = [cib_factory.find_object(p) for p in primitives]
+        objs = [cib_factory.find_resource(p) for p in primitives]
         for prim, obj in zip(primitives, objs):
             if obj is None:
                 context.fatal_error("Primitive %s not found" % (prim))
@@ -100,7 +100,7 @@
             context.fatal_error("Need at least two arguments")
 
         for node in nodes:
-            obj = cib_factory.find_object(node)
+            obj = cib_factory.find_resource(node)
             if not obj:
                 context.fatal_error("Object not found: %s" % (node))
             if not xmlutil.is_primitive(obj.node):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/crmsh-2.2.0~rc3+git.1443544100.aa2abda/modules/ui_configure.py 
new/crmsh-2.2.0~rc3+git.1444340345.59850ca/modules/ui_configure.py
--- old/crmsh-2.2.0~rc3+git.1443544100.aa2abda/modules/ui_configure.py  
2015-09-30 17:21:36.000000000 +0200
+++ new/crmsh-2.2.0~rc3+git.1444340345.59850ca/modules/ui_configure.py  
2015-10-08 23:44:05.000000000 +0200
@@ -105,7 +105,7 @@
 
 def ra_agent_for_template(tmpl):
     '''@template -> ra.agent'''
-    obj = cib_factory.find_object(tmpl[1:])
+    obj = cib_factory.find_resource(tmpl[1:])
     if obj is None:
         return None
     return ra.get_ra(obj.node)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/crmsh-2.2.0~rc3+git.1443544100.aa2abda/modules/utils.py 
new/crmsh-2.2.0~rc3+git.1444340345.59850ca/modules/utils.py
--- old/crmsh-2.2.0~rc3+git.1443544100.aa2abda/modules/utils.py 2015-09-30 
17:21:36.000000000 +0200
+++ new/crmsh-2.2.0~rc3+git.1444340345.59850ca/modules/utils.py 2015-10-08 
23:44:05.000000000 +0200
@@ -1438,7 +1438,7 @@
     if not nodes:
         nodes = list_cluster_nodes()
         nodes.remove(this_node())
-        opts = parallax.Options()
+    opts = parallax.Options()
     opts.timeout = 60
     opts.ssh_options += ['ControlPersist=no']
     ok = True
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/crmsh-2.2.0~rc3+git.1443544100.aa2abda/modules/xmlutil.py 
new/crmsh-2.2.0~rc3+git.1444340345.59850ca/modules/xmlutil.py
--- old/crmsh-2.2.0~rc3+git.1443544100.aa2abda/modules/xmlutil.py       
2015-09-30 17:21:36.000000000 +0200
+++ new/crmsh-2.2.0~rc3+git.1444340345.59850ca/modules/xmlutil.py       
2015-10-08 23:44:05.000000000 +0200
@@ -1021,7 +1021,7 @@
 def rename_rscref(c_obj, old_id, new_id):
     if rename_rscref_simple(c_obj, old_id, new_id) or \
             rename_rscref_rset(c_obj, old_id, new_id):
-        err_buf.info("resource references in %s updated" % str(c_obj))
+        err_buf.info("modified %s from %s to %s" % (str(c_obj), old_id, 
new_id))
 
 
 def delete_rscref(c_obj, rsc_id):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/crmsh-2.2.0~rc3+git.1443544100.aa2abda/test/testcases/edit 
new/crmsh-2.2.0~rc3+git.1444340345.59850ca/test/testcases/edit
--- old/crmsh-2.2.0~rc3+git.1443544100.aa2abda/test/testcases/edit      
2015-09-30 17:21:36.000000000 +0200
+++ new/crmsh-2.2.0~rc3+git.1444340345.59850ca/test/testcases/edit      
2015-10-08 23:44:05.000000000 +0200
@@ -12,7 +12,9 @@
        op monitor interval=120m OCF_CHECK_LEVEL=10
 filter "sed '$aprimitive p2 ocf:heartbeat:Dummy'"
 filter "sed '$agroup g1 p1 p2'"
+show
 filter "sed 's/p2/p3/;$aprimitive p3 ocf:heartbeat:Dummy'" g1
+show
 filter "sed '$aclone c1 p2'"
 filter "sed 's/p2/g1/'" c1
 filter "sed '/clone/s/g1/p2/'" c1 g1
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/crmsh-2.2.0~rc3+git.1443544100.aa2abda/test/testcases/edit.exp 
new/crmsh-2.2.0~rc3+git.1444340345.59850ca/test/testcases/edit.exp
--- old/crmsh-2.2.0~rc3+git.1443544100.aa2abda/test/testcases/edit.exp  
2015-09-30 17:21:36.000000000 +0200
+++ new/crmsh-2.2.0~rc3+git.1444340345.59850ca/test/testcases/edit.exp  
2015-10-08 23:44:05.000000000 +0200
@@ -9,7 +9,38 @@
 .INP: primitive p1 ocf:heartbeat:Dummy         op monitor interval=60m         
op monitor interval=120m OCF_CHECK_LEVEL=10
 .INP: filter "sed '$aprimitive p2 ocf:heartbeat:Dummy'"
 .INP: filter "sed '$agroup g1 p1 p2'"
+.INP: show
+node node1 \
+       attributes mem=16G
+primitive p1 Dummy \
+       op monitor interval=60m \
+       op monitor interval=120m OCF_CHECK_LEVEL=10
+primitive p2 Dummy
+primitive st stonith:null \
+       params hostlist=node1 \
+       meta description="some description here" \
+       op start requires=nothing interval=0 \
+       op monitor interval=60m
+group g1 p1 p2
+property cib-bootstrap-options: \
+       default-action-timeout=2m
 .INP: filter "sed 's/p2/p3/;$aprimitive p3 ocf:heartbeat:Dummy'" g1
+.INP: show
+node node1 \
+       attributes mem=16G
+primitive p1 Dummy \
+       op monitor interval=60m \
+       op monitor interval=120m OCF_CHECK_LEVEL=10
+primitive p2 Dummy
+primitive p3 Dummy
+primitive st stonith:null \
+       params hostlist=node1 \
+       meta description="some description here" \
+       op start requires=nothing interval=0 \
+       op monitor interval=60m
+group g1 p1 p3
+property cib-bootstrap-options: \
+       default-action-timeout=2m
 .INP: filter "sed '$aclone c1 p2'"
 .INP: filter "sed 's/p2/g1/'" c1
 .INP: filter "sed '/clone/s/g1/p2/'" c1 g1
@@ -26,7 +57,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:g1: Child primitive:d1 already in group:g2
+ERROR: 29: Cannot create group:g1: Child primitive:d1 already in group:g2
 .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
@@ -41,15 +72,15 @@
 .INP: modgroup g1 add p1
 ERROR: 1: syntax in group: child p1 listed more than once in group g1 parsing 
'group g1 p1 p2 d3 p1'
 .INP: modgroup g1 remove st
-ERROR: 40: configure.modgroup: st is not member of g1
+ERROR: 42: configure.modgroup: st is not member of g1
 .INP: modgroup g1 remove c1
-ERROR: 41: configure.modgroup: c1 is not member of g1
+ERROR: 43: configure.modgroup: c1 is not member of g1
 .INP: modgroup g1 remove nosuch
-ERROR: 42: configure.modgroup: nosuch is not member of g1
+ERROR: 44: configure.modgroup: nosuch is not member of g1
 .INP: modgroup g1 add c1
-ERROR: 43: a group may contain only primitives; c1 is clone
+ERROR: 45: a group may contain only primitives; c1 is clone
 .INP: modgroup g1 add nosuch
-ERROR: 44: g1 refers to missing object nosuch
+ERROR: 46: g1 refers to missing object nosuch
 .INP: filter "sed 's/^/# this is a comment\n/'" loc-d1
 .INP: rsc_defaults $id="rsc_options" failure-timeout=10m
 .INP: filter "sed 's/2m/60s/'" cib-bootstrap-options
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/crmsh-2.2.0~rc3+git.1443544100.aa2abda/test/testcases/history.exp 
new/crmsh-2.2.0~rc3+git.1444340345.59850ca/test/testcases/history.exp
--- old/crmsh-2.2.0~rc3+git.1443544100.aa2abda/test/testcases/history.exp       
2015-09-30 17:21:36.000000000 +0200
+++ new/crmsh-2.2.0~rc3+git.1444340345.59850ca/test/testcases/history.exp       
2015-10-08 23:44:05.000000000 +0200
@@ -2,6 +2,7 @@
 .INP: history
 .INP: source history-test.tar.bz2
 .INP: info
+.EXT tar -tj < history-test.tar.bz2 2> /dev/null | head -1
 .EXT tar -xj < history-test.tar.bz2
 Source: history-test.tar.bz2
 Created on: Fri 14 Dec 19:08:38 UTC 2012
@@ -278,6 +279,7 @@
 .TRY History 2
 .INP: history
 .INP: session load _crmsh_regtest
+.EXT tar -tj < history-test.tar.bz2 2> /dev/null | head -1
 .EXT tar -xj < history-test.tar.bz2
 .INP: exclude
 corosync|crmd|pengine|stonith-ng|cib|attrd|mgmtd|sshd
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/crmsh-2.2.0~rc3+git.1443544100.aa2abda/test/testcases/newfeatures 
new/crmsh-2.2.0~rc3+git.1444340345.59850ca/test/testcases/newfeatures
--- old/crmsh-2.2.0~rc3+git.1443544100.aa2abda/test/testcases/newfeatures       
2015-09-30 17:21:36.000000000 +0200
+++ new/crmsh-2.2.0~rc3+git.1444340345.59850ca/test/testcases/newfeatures       
2015-10-08 23:44:05.000000000 +0200
@@ -19,6 +19,7 @@
 tag tag1: p0 p1 p2
 tag tag2 p0 p1 p2
 location l1 { p0 p1 p2 } inf: node1
+primitive node1 Dummy
 show
 _test
 verify
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/crmsh-2.2.0~rc3+git.1443544100.aa2abda/test/testcases/newfeatures.exp 
new/crmsh-2.2.0~rc3+git.1444340345.59850ca/test/testcases/newfeatures.exp
--- old/crmsh-2.2.0~rc3+git.1443544100.aa2abda/test/testcases/newfeatures.exp   
2015-09-30 17:21:36.000000000 +0200
+++ new/crmsh-2.2.0~rc3+git.1444340345.59850ca/test/testcases/newfeatures.exp   
2015-10-08 23:44:05.000000000 +0200
@@ -13,8 +13,10 @@
 .INP: tag tag1: p0 p1 p2
 .INP: tag tag2 p0 p1 p2
 .INP: location l1 { p0 p1 p2 } inf: node1
+.INP: primitive node1 Dummy
 .INP: show
 node node1
+primitive node1 Dummy
 primitive p0 Dummy \
        params state=1
 primitive p1 Dummy \
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/crmsh-2.2.0~rc3+git.1443544100.aa2abda/test/testcases/resource.exp 
new/crmsh-2.2.0~rc3+git.1444340345.59850ca/test/testcases/resource.exp
--- old/crmsh-2.2.0~rc3+git.1443544100.aa2abda/test/testcases/resource.exp      
2015-09-30 17:21:36.000000000 +0200
+++ new/crmsh-2.2.0~rc3+git.1444340345.59850ca/test/testcases/resource.exp      
2015-10-08 23:44:05.000000000 +0200
@@ -87,7 +87,7 @@
 
 .SETENV showobj=cli-prefer-p3
 .TRY resource migrate p3 node1
-.EXT crm_resource --move -r 'p3' --node='node1'
+.EXT crm_resource --quiet --move -r 'p3' --node='node1'
 .INP: configure
 .INP: _regtest on
 .INP: show xml cli-prefer-p3
@@ -105,10 +105,10 @@
 
 .SETENV showobj=
 .TRY resource unmigrate p3
-.EXT crm_resource --clear -r 'p3'
+.EXT crm_resource --quiet --clear -r 'p3'
 .SETENV showobj=cli-prefer-p3
 .TRY resource migrate p3 node1 force
-.EXT crm_resource --move -r 'p3' --node='node1' --force
+.EXT crm_resource --quiet --move -r 'p3' --node='node1' --force
 .INP: configure
 .INP: _regtest on
 .INP: show xml cli-prefer-p3
@@ -126,7 +126,7 @@
 
 .SETENV showobj=
 .TRY resource unmigrate p3
-.EXT crm_resource --clear -r 'p3'
+.EXT crm_resource --quiet --clear -r 'p3'
 .SETENV showobj=p0
 .TRY resource param p0 set a0 "1 2 3"
 .EXT crm_resource -r 'p0' -p 'a0' -v '1 2 3'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/crmsh-2.2.0~rc3+git.1443544100.aa2abda/test/unittests/__init__.py 
new/crmsh-2.2.0~rc3+git.1444340345.59850ca/test/unittests/__init__.py
--- old/crmsh-2.2.0~rc3+git.1443544100.aa2abda/test/unittests/__init__.py       
2015-09-30 17:21:36.000000000 +0200
+++ new/crmsh-2.2.0~rc3+git.1444340345.59850ca/test/unittests/__init__.py       
2015-10-08 23:44:05.000000000 +0200
@@ -17,6 +17,8 @@
 config.path.sharedir = os.path.join(_here, "../../doc")
 config.path.crm_dtd_dir = os.path.join(_here, "schemas")
 
+os.environ["CIB_file"] = "test"
+
 
 # install a basic CIB
 from crmsh import cibconfig
@@ -35,9 +37,9 @@
       </cluster_property_set>
     </crm_config>
     <nodes>
-      <node id="1" uname="ha-one"/>
-      <node id="2" uname="ha-two"/>
-      <node id="3" uname="ha-three"/>
+      <node id="ha-one" uname="ha-one"/>
+      <node id="ha-two" uname="ha-two"/>
+      <node id="ha-three" uname="ha-three"/>
     </nodes>
     <resources>
     </resources>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/crmsh-2.2.0~rc3+git.1443544100.aa2abda/test/unittests/test_bugs.py 
new/crmsh-2.2.0~rc3+git.1444340345.59850ca/test/unittests/test_bugs.py
--- old/crmsh-2.2.0~rc3+git.1443544100.aa2abda/test/unittests/test_bugs.py      
2015-09-30 17:21:36.000000000 +0200
+++ new/crmsh-2.2.0~rc3+git.1444340345.59850ca/test/unittests/test_bugs.py      
2015-10-08 23:44:05.000000000 +0200
@@ -531,3 +531,219 @@
     factory.create_object('colocation', 'coloc-p1-p2-p3', 'inf:', 'p1', 'p2', 
'p3')
     c = factory.find_object('coloc-p1-p2-p3')
     assert c and c.check_sanity() > 0
+
+
+@with_setup(setup_func, teardown_func)
+def test_existing_node_resource():
+    factory.create_object('primitive', 'ha-one', 'Dummy')
+
+    n = factory.find_node('ha-one')
+    assert factory.test_element(n)
+
+    r = factory.find_resource('ha-one')
+    assert factory.test_element(r)
+
+    assert n != r
+
+    assert factory.check_structure()
+    factory.cli_use_validate_all()
+
+    ok, s = factory.mkobj_set('ha-one')
+    assert ok
+
+
+@with_setup(setup_func, teardown_func)
+def test_existing_node_resource_2():
+    obj = cibconfig.mkset_obj()
+    assert obj is not None
+
+    from crmsh import clidisplay
+    with clidisplay.nopretty():
+        text = obj.repr()
+    text += "\nprimitive ha-one Dummy"
+    ok = obj.save(text)
+    assert ok
+
+    obj = cibconfig.mkset_obj()
+    assert obj is not None
+    with clidisplay.nopretty():
+        text2 = obj.repr()
+
+    assert sorted(text.split('\n')) == sorted(text2.split('\n'))
+
+
+@with_setup(setup_func, teardown_func)
+def test_id_collision_breakage_1():
+    from crmsh import clidisplay
+
+    obj = cibconfig.mkset_obj()
+    assert obj is not None
+    with clidisplay.nopretty():
+        original_cib = obj.repr()
+    print original_cib
+
+    obj = cibconfig.mkset_obj()
+    assert obj is not None
+
+    ok = obj.save("""node node1
+primitive p0 ocf:pacemaker:Dummy
+primitive p1 ocf:pacemaker:Dummy
+primitive p2 ocf:heartbeat:Delay \
+    params startdelay=2 mondelay=2 stopdelay=2
+primitive p3 ocf:pacemaker:Dummy
+primitive st stonith:null params hostlist=node1
+clone c1 p1
+ms m1 p2
+property default-action-timeout=60s
+""")
+    assert ok
+
+    obj = cibconfig.mkset_obj()
+    assert obj is not None
+    ok = obj.save("""property default-action-timeout=2m
+node node1 \
+    attributes mem=16G
+primitive st stonith:null \
+    params hostlist='node1' \
+    meta description="some description here" \
+    op start requires=nothing \
+    op monitor interval=60m
+primitive p1 ocf:heartbeat:Dummy \
+    op monitor interval=60m \
+    op monitor interval=120m OCF_CHECK_LEVEL=10
+""")
+    assert ok
+
+    obj = cibconfig.mkset_obj()
+    with clidisplay.nopretty():
+        text = obj.repr()
+    text = text + "\nprimitive p2 ocf:heartbeat:Dummy"
+    ok = obj.save(text)
+    assert ok
+
+    obj = cibconfig.mkset_obj()
+    with clidisplay.nopretty():
+        text = obj.repr()
+    text = text + "\ngroup g1 p1 p2"
+    ok = obj.save(text)
+    assert ok
+
+    obj = cibconfig.mkset_obj("g1")
+    with clidisplay.nopretty():
+        text = obj.repr()
+    text = text.replace("group g1 p1 p2", "group g1 p1 p3")
+    text = text + "\nprimitive p3 ocf:heartbeat:Dummy"
+    ok = obj.save(text)
+    assert ok
+
+    obj = cibconfig.mkset_obj("g1")
+    with clidisplay.nopretty():
+        print obj.repr().strip()
+        assert obj.repr().strip() == "group g1 p1 p3"
+
+    obj = cibconfig.mkset_obj()
+    assert obj is not None
+    ok = obj.save(original_cib)
+    assert ok
+    obj = cibconfig.mkset_obj()
+    with clidisplay.nopretty():
+        print "*** ORIGINAL"
+        print original_cib
+        print "*** NOW"
+        print obj.repr()
+        assert original_cib == obj.repr()
+
+
+@with_setup(setup_func, teardown_func)
+def test_id_collision_breakage_2():
+    from crmsh import clidisplay
+
+    obj = cibconfig.mkset_obj()
+    assert obj is not None
+    with clidisplay.nopretty():
+        original_cib = obj.repr()
+    print original_cib
+
+    obj = cibconfig.mkset_obj()
+    assert obj is not None
+
+    ok = obj.save("""node 168633610: webui
+node 168633611: node1
+rsc_template web-server apache \
+       params port=8000 \
+       op monitor interval=10s
+primitive d0 Dummy \
+       meta target-role=Started
+primitive d1 Dummy
+primitive d2 Dummy
+# Never use this STONITH agent in production!
+primitive development-stonith stonith:null \
+       params hostlist="webui node1 node2 node3"
+primitive proxy systemd:haproxy \
+       op monitor interval=10s
+primitive proxy-vip IPaddr2 \
+       params ip=10.13.37.20
+primitive srv1 @web-server
+primitive srv2 @web-server
+primitive vip1 IPaddr2 \
+       params ip=10.13.37.21 \
+       op monitor interval=20s
+primitive vip2 IPaddr2 \
+       params ip=10.13.37.22 \
+       op monitor interval=20s
+primitive virtual-ip IPaddr2 \
+       params ip=10.13.37.77 lvs_support=false \
+       op start timeout=20 interval=0 \
+       op stop timeout=20 interval=0 \
+       op monitor interval=10 timeout=20
+primitive yet-another-virtual-ip IPaddr2 \
+       params ip=10.13.37.72 cidr_netmask=24 \
+       op start interval=0 timeout=20 \
+       op stop interval=0 timeout=20 \
+       op monitor interval=10 timeout=20 \
+       meta target-role=Started
+group dovip d0 virtual-ip \
+       meta target-role=Stopped
+group g-proxy proxy-vip proxy
+group g-serv1 vip1 srv1
+group g-serv2 vip2 srv2
+clone d2-clone d2 \
+       meta target-role=Started
+tag dummytag d0 d1 d1-on-node1 d2 d2-clone
+# Never put the two web servers on the same node
+colocation co-serv -inf: g-serv1 g-serv2
+location d1-on-node1 d1 inf: node1
+# Never put any web server or haproxy on webui
+location l-avoid-webui { g-proxy g-serv1 g-serv2 } -inf: webui
+# Prever to spread groups across nodes
+location l-proxy g-proxy 200: node1
+location l-serv1 g-serv1 200: node2
+location l-serv2 g-serv2 200: node3
+property cib-bootstrap-options: \
+       have-watchdog=false \
+       
dc-version="1.1.13+git20150917.20c2178-224.2-1.1.13+git20150917.20c2178" \
+       cluster-infrastructure=corosync \
+       cluster-name=hacluster \
+       stonith-enabled=true \
+       no-quorum-policy=ignore \
+       placement-strategy=balanced
+rsc_defaults rsc-options: \
+       resource-stickiness=1 \
+       migration-threshold=3
+op_defaults op-options: \
+       timeout=600 \
+       record-pending=true
+""")
+    assert ok
+
+    obj = cibconfig.mkset_obj()
+    assert obj is not None
+    ok = obj.save(original_cib)
+    assert ok
+    obj = cibconfig.mkset_obj()
+    with clidisplay.nopretty():
+        print "*** ORIGINAL"
+        print original_cib
+        print "*** NOW"
+        print obj.repr()
+        assert original_cib == obj.repr()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/crmsh-2.2.0~rc3+git.1443544100.aa2abda/test/unittests/test_objset.py 
new/crmsh-2.2.0~rc3+git.1444340345.59850ca/test/unittests/test_objset.py
--- old/crmsh-2.2.0~rc3+git.1443544100.aa2abda/test/unittests/test_objset.py    
2015-09-30 17:21:36.000000000 +0200
+++ new/crmsh-2.2.0~rc3+git.1444340345.59850ca/test/unittests/test_objset.py    
2015-10-08 23:44:05.000000000 +0200
@@ -39,4 +39,4 @@
     setobj = cibconfig.mkset_obj()
     s = setobj.repr_nopretty()
     sp = s.splitlines()
-    assert_in("node 1: ha-one", sp[0:3])
+    assert_in("node ha-one", sp[0:3])
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/crmsh-2.2.0~rc3+git.1443544100.aa2abda/test/unittests/test_parse.py 
new/crmsh-2.2.0~rc3+git.1444340345.59850ca/test/unittests/test_parse.py
--- old/crmsh-2.2.0~rc3+git.1443544100.aa2abda/test/unittests/test_parse.py     
2015-09-30 17:21:36.000000000 +0200
+++ new/crmsh-2.2.0~rc3+git.1444340345.59850ca/test/unittests/test_parse.py     
2015-10-08 23:44:05.000000000 +0200
@@ -434,7 +434,8 @@
         # num test nodes are 3
 
         out = self.parser.parse('fencing_topology poison-pill power')
-        self.assertEqual("""<fencing-topology><fencing-level 
devices="poison-pill" index="1" target="ha-one"/><fencing-level devices="power" 
index="2" target="ha-one"/><fencing-level devices="poison-pill" index="1" 
target="ha-two"/><fencing-level devices="power" index="2" 
target="ha-two"/><fencing-level devices="poison-pill" index="1" 
target="ha-three"/><fencing-level devices="power" index="2" 
target="ha-three"/></fencing-topology>""", etree.tostring(out))
+        expect = '<fencing-topology><fencing-level devices="poison-pill" 
index="1" target="ha-one"/><fencing-level devices="power" index="2" 
target="ha-one"/><fencing-level devices="poison-pill" index="1" 
target="ha-three"/><fencing-level devices="power" index="2" 
target="ha-three"/><fencing-level devices="poison-pill" index="1" 
target="ha-two"/><fencing-level devices="power" index="2" 
target="ha-two"/></fencing-topology>'
+        self.assertEqual(expect, etree.tostring(out))
 
         out = self.parser.parse('fencing_topology node-a: poison-pill power 
node-b: ipmi serial')
         self.assertEqual(4, len(out))
@@ -661,7 +662,7 @@
             '<rsc_ticket id="ticket-A_m6" ticket="ticket-A" rsc="m6"/>',
             '<rsc_ticket id="ticket-B_m6_m5" ticket="ticket-B" 
loss-policy="fence"><resource_set><resource_ref id="m6"/><resource_ref 
id="m5"/></resource_set></rsc_ticket>',
             '<rsc_ticket id="ticket-C_master" ticket="ticket-C" 
loss-policy="fence"><resource_set><resource_ref 
id="m6"/></resource_set><resource_set role="Master"><resource_ref 
id="m5"/></resource_set></rsc_ticket>',
-            '<fencing-topology><fencing-level devices="st" index="1" 
target="ha-one"/><fencing-level devices="st2" index="2" 
target="ha-one"/><fencing-level devices="st" index="1" 
target="ha-two"/><fencing-level devices="st2" index="2" 
target="ha-two"/><fencing-level devices="st" index="1" 
target="ha-three"/><fencing-level devices="st2" index="2" 
target="ha-three"/></fencing-topology>',
+            '<fencing-topology><fencing-level devices="st" index="1" 
target="ha-one"/><fencing-level devices="st2" index="2" 
target="ha-one"/><fencing-level devices="st" index="1" 
target="ha-three"/><fencing-level devices="st2" index="2" 
target="ha-three"/><fencing-level devices="st" index="1" 
target="ha-two"/><fencing-level devices="st2" index="2" 
target="ha-two"/></fencing-topology>',
             '<cluster_property_set><nvpair name="stonith-enabled" 
value="true"/></cluster_property_set>',
             '<cluster_property_set id="cpset2"><nvpair name="maintenance-mode" 
value="true"/></cluster_property_set>',
             '<rsc_defaults><meta_attributes><nvpair name="failure-timeout" 
value="10m"/></meta_attributes></rsc_defaults>',


Reply via email to