|
|
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 |
|