Blame SOURCES/bz1329472-01-when-removing-a-remote-node-remove-it-from-pacemakers-caches-as-well.patch

15f218
From 6805a235de50925ed7f30ac79b3d96be3f5d71df Mon Sep 17 00:00:00 2001
15f218
From: Tomas Jelinek <tojeline@redhat.com>
15f218
Date: Mon, 25 Jul 2016 14:23:23 +0200
15f218
Subject: [PATCH 1/2] remove dead code
15f218
15f218
Function resource_master_remove could not ever be called because conditions
15f218
with xpath queries were never True. In the case when the resource_id was
15f218
an id of a master resource, it got changed to the id of the master's child
15f218
right at the beginning of resource_remove function.
15f218
---
15f218
 pcs/resource.py | 49 ++++++-------------------------------------------
15f218
 1 file changed, 6 insertions(+), 43 deletions(-)
15f218
15f218
diff --git a/pcs/resource.py b/pcs/resource.py
15f218
index 9384a21..24128ba 100644
15f218
--- a/pcs/resource.py
15f218
+++ b/pcs/resource.py
15f218
@@ -1618,45 +1618,9 @@ def resource_master_create(dom, argv, update=False, master_id=None):
15f218
 
15f218
     return dom, master_element.getAttribute("id")
15f218
 
15f218
-def resource_master_remove(argv):
15f218
-    if len(argv) < 1:
15f218
-        usage.resource()
15f218
-        sys.exit(1)
15f218
-
15f218
-    dom = utils.get_cib_dom()
15f218
-    master_id = argv.pop(0)
15f218
-
15f218
-    master_found = False
15f218
-# Check to see if there's a resource/group with the master_id if so, we remove the parent
15f218
-    for rg in (dom.getElementsByTagName("primitive") + dom.getElementsByTagName("group")):
15f218
-        if rg.getAttribute("id") == master_id and rg.parentNode.tagName == "master":
15f218
-            master_id = rg.parentNode.getAttribute("id")
15f218
-
15f218
-    resources_to_cleanup = []
15f218
-    for master in dom.getElementsByTagName("master"):
15f218
-        if master.getAttribute("id") == master_id:
15f218
-            childNodes = master.getElementsByTagName("primitive")
15f218
-            for child in childNodes:
15f218
-                resources_to_cleanup.append(child.getAttribute("id"))
15f218
-            master_found = True
15f218
-            break
15f218
-
15f218
-    if not master_found:
15f218
-        utils.err("Unable to find multi-state resource with id %s" % master_id)
15f218
-
15f218
-    constraints_element = dom.getElementsByTagName("constraints")
15f218
-    if len(constraints_element) > 0:
15f218
-        constraints_element = constraints_element[0]
15f218
-        for resource_id in resources_to_cleanup:
15f218
-            remove_resource_references(
15f218
-                dom, resource_id, constraints_element=constraints_element
15f218
-            )
15f218
-    master.parentNode.removeChild(master)
15f218
-    print("Removing Master - " + master_id)
15f218
-    utils.replace_cib_configuration(dom)
15f218
-
15f218
 def resource_remove(resource_id, output = True):
15f218
     dom = utils.get_cib_dom()
15f218
+    # if resource is a clone or a master, work with its child instead
15f218
     cloned_resource = utils.dom_get_clone_ms_resource(dom, resource_id)
15f218
     if cloned_resource:
15f218
         resource_id = cloned_resource.getAttribute("id")
15f218
@@ -1704,16 +1668,15 @@ def resource_remove(resource_id, output = True):
15f218
             resource_remove(res.getAttribute("id"))
15f218
         sys.exit(0)
15f218
 
15f218
+    # now we know resource is not a group, a clone nor a master
15f218
+    # because of the conditions above
15f218
+    if not utils.does_exist('//resources/descendant::primitive[@id="'+resource_id+'"]'):
15f218
+        utils.err("Resource '{0}' does not exist.".format(resource_id))
15f218
+
15f218
     group_xpath = '//group/primitive[@id="'+resource_id+'"]/..'
15f218
     group = utils.get_cib_xpath(group_xpath)
15f218
     num_resources_in_group = 0
15f218
 
15f218
-    if not utils.does_exist('//resources/descendant::primitive[@id="'+resource_id+'"]'):
15f218
-        if utils.does_exist('//resources/master[@id="'+resource_id+'"]'):
15f218
-            return resource_master_remove([resource_id])
15f218
-
15f218
-        utils.err("Resource '{0}' does not exist.".format(resource_id))
15f218
-
15f218
     if (group != ""):
15f218
         num_resources_in_group = len(parseString(group).documentElement.getElementsByTagName("primitive"))
15f218
 
15f218
-- 
15f218
1.8.3.1
15f218
15f218
15f218
From cd96c34c7ad1f4f767c0d14475b683a70c3b0862 Mon Sep 17 00:00:00 2001
15f218
From: Tomas Jelinek <tojeline@redhat.com>
15f218
Date: Mon, 25 Jul 2016 17:34:35 +0200
15f218
Subject: [PATCH 2/2] when removing a remote node remove it from pacemaker's
15f218
 caches as well
15f218
15f218
---
15f218
 pcs/cluster.py         |  6 +++++
15f218
 pcs/resource.py        | 64 ++++++++++++++++++++++++++++----------------------
15f218
 pcs/test/test_utils.py |  9 +++++++
15f218
 pcs/utils.py           |  8 +++++++
15f218
 4 files changed, 59 insertions(+), 28 deletions(-)
15f218
15f218
diff --git a/pcs/cluster.py b/pcs/cluster.py
15f218
index 7a8615d..1c3b425 100644
15f218
--- a/pcs/cluster.py
15f218
+++ b/pcs/cluster.py
15f218
@@ -1922,6 +1922,12 @@ def cluster_remote_node(argv):
15f218
             nvpair.parentNode.removeChild(nvpair)
15f218
         dom = constraint.remove_constraints_containing_node(dom, hostname)
15f218
         utils.replace_cib_configuration(dom)
15f218
+        if not utils.usefile:
15f218
+            output, retval = utils.run([
15f218
+                "crm_node", "--force", "--remove", hostname
15f218
+            ])
15f218
+            if retval != 0:
15f218
+                utils.err("unable to remove: {0}".fomat(output))
15f218
     else:
15f218
         usage.cluster(["remote-node"])
15f218
         sys.exit(1)
15f218
diff --git a/pcs/resource.py b/pcs/resource.py
15f218
index 24128ba..a85f46f 100644
15f218
--- a/pcs/resource.py
15f218
+++ b/pcs/resource.py
15f218
@@ -929,31 +929,11 @@ def resource_update(res_id,args):
15f218
             ia.setAttribute("value", val)
15f218
             instance_attributes.appendChild(ia)
15f218
 
15f218
-    meta_attributes = resource.getElementsByTagName("meta_attributes")
15f218
-    if len(meta_attributes) == 0:
15f218
-        meta_attributes = dom.createElement("meta_attributes")
15f218
-        meta_attributes.setAttribute("id", res_id + "-meta_attributes")
15f218
-        resource.appendChild(meta_attributes)
15f218
-    else:
15f218
-        meta_attributes = meta_attributes[0]
15f218
-
15f218
-    meta_attrs = utils.convert_args_to_tuples(meta_values)
15f218
-    for (key,val) in meta_attrs:
15f218
-        meta_found = False
15f218
-        for ma in meta_attributes.getElementsByTagName("nvpair"):
15f218
-            if ma.getAttribute("name") == key:
15f218
-                meta_found = True
15f218
-                if val == "":
15f218
-                    meta_attributes.removeChild(ma)
15f218
-                else:
15f218
-                    ma.setAttribute("value", val)
15f218
-                break
15f218
-        if not meta_found:
15f218
-            ma = dom.createElement("nvpair")
15f218
-            ma.setAttribute("id", res_id + "-meta_attributes-" + key)
15f218
-            ma.setAttribute("name", key)
15f218
-            ma.setAttribute("value", val)
15f218
-            meta_attributes.appendChild(ma)
15f218
+    remote_node_name = utils.dom_get_resource_remote_node_name(resource)
15f218
+    utils.dom_update_meta_attr(
15f218
+        resource,
15f218
+        utils.convert_args_to_tuples(meta_values)
15f218
+    )
15f218
 
15f218
     operations = resource.getElementsByTagName("operations")
15f218
     if len(operations) == 0:
15f218
@@ -1005,6 +985,17 @@ def resource_update(res_id,args):
15f218
 
15f218
     utils.replace_cib_configuration(dom)
15f218
 
15f218
+    if (
15f218
+        remote_node_name
15f218
+        and
15f218
+        remote_node_name != utils.dom_get_resource_remote_node_name(resource)
15f218
+    ):
15f218
+        # if the resource was a remote node and it is not anymore, (or its name
15f218
+        # changed) we need to tell pacemaker about it
15f218
+        output, retval = utils.run([
15f218
+            "crm_node", "--force", "--remove", remote_node_name
15f218
+        ])
15f218
+
15f218
     if "--wait" in utils.pcs_options:
15f218
         args = ["crm_resource", "--wait"]
15f218
         if wait_timeout:
15f218
@@ -1231,10 +1222,22 @@ def resource_meta(res_id, argv):
15f218
     if "--wait" in utils.pcs_options:
15f218
         wait_timeout = utils.validate_wait_get_timeout()
15f218
 
15f218
+    remote_node_name = utils.dom_get_resource_remote_node_name(resource_el)
15f218
     utils.dom_update_meta_attr(resource_el, utils.convert_args_to_tuples(argv))
15f218
 
15f218
     utils.replace_cib_configuration(dom)
15f218
 
15f218
+    if (
15f218
+        remote_node_name
15f218
+        and
15f218
+        remote_node_name != utils.dom_get_resource_remote_node_name(resource_el)
15f218
+    ):
15f218
+        # if the resource was a remote node and it is not anymore, (or its name
15f218
+        # changed) we need to tell pacemaker about it
15f218
+        output, retval = utils.run([
15f218
+            "crm_node", "--force", "--remove", remote_node_name
15f218
+        ])
15f218
+
15f218
     if "--wait" in utils.pcs_options:
15f218
         args = ["crm_resource", "--wait"]
15f218
         if wait_timeout:
15f218
@@ -1714,11 +1717,12 @@ def resource_remove(resource_id, output = True):
15f218
     )
15f218
     dom = utils.get_cib_dom()
15f218
     resource_el = utils.dom_get_resource(dom, resource_id)
15f218
+    remote_node_name = None
15f218
     if resource_el:
15f218
-        remote_node = utils.dom_get_resource_remote_node_name(resource_el)
15f218
-        if remote_node:
15f218
+        remote_node_name = utils.dom_get_resource_remote_node_name(resource_el)
15f218
+        if remote_node_name:
15f218
             dom = constraint.remove_constraints_containing_node(
15f218
-                dom, remote_node, output
15f218
+                dom, remote_node_name, output
15f218
             )
15f218
             utils.replace_cib_configuration(dom)
15f218
             dom = utils.get_cib_dom()
15f218
@@ -1784,6 +1788,10 @@ def resource_remove(resource_id, output = True):
15f218
             if output == True:
15f218
                 utils.err("Unable to remove resource '%s' (do constraints exist?)" % (resource_id))
15f218
             return False
15f218
+    if remote_node_name and not utils.usefile:
15f218
+        output, retval = utils.run([
15f218
+            "crm_node", "--force", "--remove", remote_node_name
15f218
+        ])
15f218
     return True
15f218
 
15f218
 def stonith_level_rm_device(cib_dom, stn_id):
15f218
diff --git a/pcs/test/test_utils.py b/pcs/test/test_utils.py
15f218
index 819f8ee..192048e 100644
15f218
--- a/pcs/test/test_utils.py
15f218
+++ b/pcs/test/test_utils.py
15f218
@@ -273,6 +273,9 @@ class UtilsTest(unittest.TestCase):
15f218
                             name="remote-node" value="guest2"/>
15f218
                     </instance_attributes>
15f218
                 </primitive>
15f218
+                
15f218
+                        class="ocf" provider="pacemaker" type="remote">
15f218
+                </primitive>
15f218
             </resources>
15f218
         """).documentElement
15f218
         resources = dom.getElementsByTagName("resources")[0]
15f218
@@ -296,6 +299,12 @@ class UtilsTest(unittest.TestCase):
15f218
                 utils.dom_get_resource(dom, "vm-guest1")
15f218
             )
15f218
         )
15f218
+        self.assertEqual(
15f218
+            "dummy3",
15f218
+            utils.dom_get_resource_remote_node_name(
15f218
+                utils.dom_get_resource(dom, "dummy3")
15f218
+            )
15f218
+        )
15f218
 
15f218
     def test_dom_get_meta_attr_value(self):
15f218
         dom = self.get_cib_empty()
15f218
diff --git a/pcs/utils.py b/pcs/utils.py
15f218
index a7ed975..25274dc 100644
15f218
--- a/pcs/utils.py
15f218
+++ b/pcs/utils.py
15f218
@@ -1252,6 +1252,14 @@ def validate_constraint_resource(dom, resource_id):
15f218
 def dom_get_resource_remote_node_name(dom_resource):
15f218
     if dom_resource.tagName != "primitive":
15f218
         return None
15f218
+    if (
15f218
+        dom_resource.getAttribute("class").lower() == "ocf"
15f218
+        and
15f218
+        dom_resource.getAttribute("provider").lower() == "pacemaker"
15f218
+        and
15f218
+        dom_resource.getAttribute("type").lower() == "remote"
15f218
+    ):
15f218
+        return dom_resource.getAttribute("id")
15f218
     return dom_get_meta_attr_value(dom_resource, "remote-node")
15f218
 
15f218
 def dom_get_meta_attr_value(dom_resource, meta_name):
15f218
-- 
15f218
1.8.3.1
15f218