Blame SOURCES/bz1303136-01-fix-check-if-id-exists-in-cib.patch

15f218
From cb2347ad79fe30076fad1579d1f5ee27a1835963 Mon Sep 17 00:00:00 2001
15f218
From: Tomas Jelinek <tojeline@redhat.com>
15f218
Date: Fri, 22 Jul 2016 16:29:04 +0200
15f218
Subject: [PATCH] fix check if id exists in cib
15f218
15f218
---
15f218
 pcs/lib/cib/tools.py           | 11 ++++++++++-
15f218
 pcs/test/test_lib_cib_tools.py | 24 ++++++++++++++++++++++++
15f218
 pcs/utils.py                   | 30 +++++++++++++++++++++++++-----
15f218
 3 files changed, 59 insertions(+), 6 deletions(-)
15f218
15f218
diff --git a/pcs/lib/cib/tools.py b/pcs/lib/cib/tools.py
15f218
index b59d50d..f86b63b 100644
15f218
--- a/pcs/lib/cib/tools.py
15f218
+++ b/pcs/lib/cib/tools.py
15f218
@@ -21,7 +21,16 @@ def does_id_exist(tree, check_id):
15f218
     tree cib etree node
15f218
     check_id id to check
15f218
     """
15f218
-    return tree.find('.//*[@id="{0}"]'.format(check_id)) is not None
15f218
+    # ElementTree has getroot, Elemet has getroottree
15f218
+    root = tree.getroot() if hasattr(tree, "getroot") else tree.getroottree()
15f218
+    # do not search in /cib/status, it may contain references to previously
15f218
+    # existing and deleted resources and thus preventing creating them again
15f218
+    existing = root.xpath(
15f218
+        '(/cib/*[name()!="status"]|/*[name()!="cib"])//*[@id="{0}"]'.format(
15f218
+            check_id
15f218
+        )
15f218
+    )
15f218
+    return len(existing) > 0
15f218
 
15f218
 def validate_id_does_not_exist(tree, id):
15f218
     """
15f218
diff --git a/pcs/test/test_lib_cib_tools.py b/pcs/test/test_lib_cib_tools.py
15f218
index 1149a3f..e1f2313 100644
15f218
--- a/pcs/test/test_lib_cib_tools.py
15f218
+++ b/pcs/test/test_lib_cib_tools.py
15f218
@@ -48,6 +48,30 @@ class DoesIdExistTest(CibToolsTest):
15f218
         self.assertFalse(lib.does_id_exist(self.cib.tree, "myId "))
15f218
         self.assertFalse(lib.does_id_exist(self.cib.tree, "my Id"))
15f218
 
15f218
+    def test_ignore_status_section(self):
15f218
+        self.cib.append_to_first_tag_name(
15f218
+            "status",
15f218
+            """\
15f218
+<elem1 id="status-1">
15f218
+    <elem1a id="status-1a">
15f218
+        <elem1aa id="status-1aa"/>
15f218
+        <elem1ab id="status-1ab"/>
15f218
+    </elem1a>
15f218
+    <elem1b id="status-1b">
15f218
+        <elem1ba id="status-1ba"/>
15f218
+        <elem1bb id="status-1bb"/>
15f218
+    </elem1b>
15f218
+</elem1>
15f218
+"""
15f218
+        )
15f218
+        self.assertFalse(lib.does_id_exist(self.cib.tree, "status-1"))
15f218
+        self.assertFalse(lib.does_id_exist(self.cib.tree, "status-1a"))
15f218
+        self.assertFalse(lib.does_id_exist(self.cib.tree, "status-1aa"))
15f218
+        self.assertFalse(lib.does_id_exist(self.cib.tree, "status-1ab"))
15f218
+        self.assertFalse(lib.does_id_exist(self.cib.tree, "status-1b"))
15f218
+        self.assertFalse(lib.does_id_exist(self.cib.tree, "status-1ba"))
15f218
+        self.assertFalse(lib.does_id_exist(self.cib.tree, "status-1bb"))
15f218
+
15f218
 class FindUniqueIdTest(CibToolsTest):
15f218
     def test_already_unique(self):
15f218
         self.fixture_add_primitive_with_id("myId")
15f218
diff --git a/pcs/utils.py b/pcs/utils.py
15f218
index 079d916..a7ed975 100644
15f218
--- a/pcs/utils.py
15f218
+++ b/pcs/utils.py
15f218
@@ -1589,15 +1589,35 @@ def is_valid_cib_scope(scope):
15f218
 # Checks to see if id exists in the xml dom passed
15f218
 # DEPRECATED use lxml version available in pcs.lib.cib.tools
15f218
 def does_id_exist(dom, check_id):
15f218
+    # do not search in /cib/status, it may contain references to previously
15f218
+    # existing and deleted resources and thus preventing creating them again
15f218
     if is_etree(dom):
15f218
-        for elem in dom.findall(str(".//*")):
15f218
+        for elem in dom.findall(str(
15f218
+            '(/cib/*[name()!="status"]|/*[name()!="cib"])/*'
15f218
+        )):
15f218
             if elem.get("id") == check_id:
15f218
                 return True
15f218
     else:
15f218
-        all_elem = dom.getElementsByTagName("*")
15f218
-        for elem in all_elem:
15f218
-            if elem.getAttribute("id") == check_id:
15f218
-                return True
15f218
+        document = (
15f218
+            dom
15f218
+            if isinstance(dom, xml.dom.minidom.Document)
15f218
+            else dom.ownerDocument
15f218
+        )
15f218
+        cib_found = False
15f218
+        for cib in dom_get_children_by_tag_name(document, "cib"):
15f218
+            cib_found = True
15f218
+            for section in cib.childNodes:
15f218
+                if section.nodeType != xml.dom.minidom.Node.ELEMENT_NODE:
15f218
+                    continue
15f218
+                if section.tagName == "status":
15f218
+                    continue
15f218
+                for elem in section.getElementsByTagName("*"):
15f218
+                    if elem.getAttribute("id") == check_id:
15f218
+                        return True
15f218
+        if not cib_found:
15f218
+            for elem in document.getElementsByTagName("*"):
15f218
+                if elem.getAttribute("id") == check_id:
15f218
+                    return True
15f218
     return False
15f218
 
15f218
 # Returns check_id if it doesn't exist in the dom, otherwise it adds an integer
15f218
-- 
15f218
1.8.3.1
15f218