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