Commit ff1c051b authored by Thomas Thrainer's avatar Thomas Thrainer
Browse files

Use node UUIDs for executing LU hooks

LUNodeAdd, the only LU using a node name still, is changed to overwrite
PreparePostHookNodes() and use node UUIDs only as well.
This allows to remove the support for 3-tuples as results of
BuildHooksNodes() and removes the translation to node names.

Fixes issue 742.
Signed-off-by: default avatarThomas Thrainer <>
Reviewed-by: default avatarMichele Tartara <>
parent 237a833c
......@@ -269,13 +269,10 @@ class LogicalUnit(object):
def BuildHooksNodes(self):
"""Build list of nodes to run LU's hooks.
@rtype: tuple; (list, list) or (list, list, list)
@rtype: tuple; (list, list)
@return: Tuple containing a list of node UUIDs on which the hook
should run before the execution and a list of node UUIDs on which the
hook should run after the execution. As it might be possible that the
node UUID is not known at the time this method is invoked, an optional
third list can be added which contains node names on which the hook
should run after the execution (in case of node add, for instance).
hook should run after the execution.
No nodes should be returned as an empty list (and not None).
@note: If the C{HPATH} attribute of the LU class is C{None}, this function
will not be called.
......@@ -138,7 +138,10 @@ class LUNodeAdd(LogicalUnit):
hook_nodes = list(set(hook_nodes) - set([new_node_info.uuid]))
# add the new node as post hook node by name; it does not have an UUID yet
return (hook_nodes, hook_nodes, [self.op.node_name, ])
return (hook_nodes, hook_nodes)
def PreparePostHookNodes(self, post_hook_node_uuids):
return post_hook_node_uuids + [self.new_node.uuid]
def CheckPrereq(self):
"""Check prerequisites.
......@@ -268,15 +268,10 @@ class HooksMaster(object):
nodes = (None, None)
hooks_nodes = lu.BuildHooksNodes()
to_name = lambda node_uuids: frozenset(lu.cfg.GetNodeNames(node_uuids))
if len(hooks_nodes) == 2:
nodes = (to_name(hooks_nodes[0]), to_name(hooks_nodes[1]))
elif len(hooks_nodes) == 3:
nodes = (to_name(hooks_nodes[0]),
to_name(hooks_nodes[1]) | frozenset(hooks_nodes[2]))
if len(hooks_nodes) != 2:
raise errors.ProgrammerError(
"LogicalUnit.BuildHooksNodes must return a 2- or 3-tuple")
"LogicalUnit.BuildHooksNodes must return a 2-tuple")
nodes = (frozenset(hooks_nodes[0]), frozenset(hooks_nodes[1]))
master_name = cluster_name = None
if lu.cfg:
......@@ -234,7 +234,7 @@ class TestLUClusterPostInit(CmdlibTestCase):
......@@ -495,7 +495,7 @@ class TestHooksRunnerEnv(unittest.TestCase):
assert isinstance(, FakeNoHooksLU), "LU was replaced"
class FakeEnvWithNodeNameLU(cmdlib.LogicalUnit):
class FakeEnvWithCustomPostHookNodesLU(cmdlib.LogicalUnit):
HPATH = "env_test_lu"
......@@ -506,7 +506,10 @@ class FakeEnvWithNodeNameLU(cmdlib.LogicalUnit):
return {}
def BuildHooksNodes(self):
return (["a"], ["a"], ["", ""])
return (["a"], ["a"])
def PreparePostHookNodes(self, post_hook_node_uuids):
return post_hook_node_uuids + ["b"]
class TestHooksRunnerEnv(unittest.TestCase):
......@@ -514,7 +517,8 @@ class TestHooksRunnerEnv(unittest.TestCase):
self._rpcs = []
self.op = opcodes.OpTestDummy(result=False, messages=[], fail=False) = FakeEnvWithNodeNameLU(FakeProc(), self.op, FakeContext(), None) = FakeEnvWithCustomPostHookNodesLU(FakeProc(), self.op,
FakeContext(), None)
def _HooksRpc(self, *args):
......@@ -526,15 +530,13 @@ class TestHooksRunnerEnv(unittest.TestCase):
(node_list, hpath, phase, env) = self._rpcs.pop(0)
self.assertEqual(node_list, set([""]))
self.assertEqual(node_list, set(["a"]))
# Check post-phase hook
(node_list, hpath, phase, env) = self._rpcs.pop(0)
self.assertEqual(node_list, set(["",
self.assertEqual(node_list, set(["a", "b"]))
self.assertRaises(IndexError, self._rpcs.pop)
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment