Run PRE and POST global hooks in case of succesfull job execution. POST hooks always always executed with status SUCCEEDED. On errors POST hooks will not be executed because all the errors cause related exeptions.
Also fix test which expects that hooks run only once. Now rpc called twice: for usual hooks and for global hooks. Other test fix is that currently the hooks path for the last hook is always 'global'. Signed-off-by: Oleg Ponomarev <[email protected]> --- lib/cmdlib/common.py | 2 ++ lib/mcpu.py | 17 ++++++++++++----- src/Ganeti/Constants.hs | 9 +++++++++ test/py/cmdlib/cluster_unittest.py | 6 ++++-- test/py/cmdlib/testsupport/cmdlib_testcase.py | 3 ++- 5 files changed, 29 insertions(+), 8 deletions(-) diff --git a/lib/cmdlib/common.py b/lib/cmdlib/common.py index 696a331..5b70e16 100644 --- a/lib/cmdlib/common.py +++ b/lib/cmdlib/common.py @@ -186,6 +186,8 @@ def RunPostHook(lu, node_name): hm = lu.proc.BuildHooksManager(lu) try: hm.RunPhase(constants.HOOKS_PHASE_POST, node_names=[node_name]) + hm.RunPhase(constants.HOOKS_PHASE_POST, [node_name], True, + constants.POST_HOOKS_STATUS_SUCCEEDED) except Exception, err: # pylint: disable=W0703 lu.LogWarning("Errors occurred running hooks on %s: %s", node_name, err) diff --git a/lib/mcpu.py b/lib/mcpu.py index 209e859..9be8d46 100644 --- a/lib/mcpu.py +++ b/lib/mcpu.py @@ -305,6 +305,7 @@ class Processor(object): self.cfg = context.GetConfig(ec_id) self.rpc = context.GetRpc(self.cfg) self.hmclass = hooksmaster.HooksMaster + self._hm = None self._enable_locks = enable_locks self.wconfd = wconfd # Indirection to allow testing self._wconfdcontext = context.GetWConfdContext(ec_id) @@ -483,8 +484,9 @@ class Processor(object): lu.cfg.OutDate() lu.CheckPrereq() - hm = self.BuildHooksManager(lu) - h_results = hm.RunPhase(constants.HOOKS_PHASE_PRE) + self._hm = self.BuildHooksManager(lu) + self._hm.RunPhase(constants.HOOKS_PHASE_PRE, None, True) + h_results = self._hm.RunPhase(constants.HOOKS_PHASE_PRE) lu.HooksCallBack(constants.HOOKS_PHASE_PRE, h_results, self.Log, None) @@ -504,19 +506,20 @@ class Processor(object): lusExecuting[0] += 1 try: result = _ProcessResult(submit_mj_fn, lu.op, lu.Exec(self.Log)) - h_results = hm.RunPhase(constants.HOOKS_PHASE_POST) + h_results = self._hm.RunPhase(constants.HOOKS_PHASE_POST) result = lu.HooksCallBack(constants.HOOKS_PHASE_POST, h_results, self.Log, result) finally: # FIXME: This needs locks if not lu_class.REQ_BGL lusExecuting[0] -= 1 if write_count != self.cfg.write_count: - hm.RunConfigUpdate() + self._hm.RunConfigUpdate() return result def BuildHooksManager(self, lu): - return self.hmclass.BuildFromLu(lu.rpc.call_hooks_runner, lu) + return self.hmclass.BuildFromLu(lu.rpc.call_hooks_runner, lu, + self.GetECId()) def _LockAndExecLU(self, lu, level, calc_timeout, pending=None): """Execute a Logical Unit, with the needed locks. @@ -715,6 +718,10 @@ class Processor(object): self._CheckLUResult(op, result) + if self._hm is not None: + self._hm.RunPhase(constants.HOOKS_PHASE_POST, None, True, + constants.POST_HOOKS_STATUS_SUCCEEDED) + return result def Log(self, *args): diff --git a/src/Ganeti/Constants.hs b/src/Ganeti/Constants.hs index 180ff4d..93b817a 100644 --- a/src/Ganeti/Constants.hs +++ b/src/Ganeti/Constants.hs @@ -729,6 +729,15 @@ hooksVersion = 2 globalHooksDir :: String globalHooksDir = "global" +postHooksStatusSucceeded :: String +postHooksStatusSucceeded = "succeeded" + +postHooksStatusFailed :: String +postHooksStatusFailed = "failed" + +postHooksStatusDisappeared :: String +postHooksStatusDisappeared = "disappeared" + -- * Hooks subject type (what object type does the LU deal with) htypeCluster :: String diff --git a/test/py/cmdlib/cluster_unittest.py b/test/py/cmdlib/cluster_unittest.py index 24c1ca9..31772e0 100644 --- a/test/py/cmdlib/cluster_unittest.py +++ b/test/py/cmdlib/cluster_unittest.py @@ -232,8 +232,9 @@ class TestLUClusterDestroy(CmdlibTestCase): self.ExecOpCode(op) + # The hooksdir name should be "global" because of global hooks self.assertSingleHooksCall([self.master.name], - "cluster-destroy", + constants.GLOBAL_HOOKS_DIR, constants.HOOKS_PHASE_POST) @@ -244,8 +245,9 @@ class TestLUClusterPostInit(CmdlibTestCase): self.ExecOpCode(op) + # The hooksdir name should be "global" because of global hooks self.assertSingleHooksCall([self.master.uuid], - "cluster-init", + constants.GLOBAL_HOOKS_DIR, constants.HOOKS_PHASE_POST) diff --git a/test/py/cmdlib/testsupport/cmdlib_testcase.py b/test/py/cmdlib/testsupport/cmdlib_testcase.py index 4e459f3..bd96418 100644 --- a/test/py/cmdlib/testsupport/cmdlib_testcase.py +++ b/test/py/cmdlib/testsupport/cmdlib_testcase.py @@ -362,8 +362,9 @@ class CmdlibTestCase(testutils.GanetiTestCase): @see L{assertHooksCall} for parameter description. """ + # Count below is set to 2 because both hooks ang global hooks will run. self.assertHooksCall(nodes, hook_path, phase, - environment=environment, count=1) + environment=environment, count=2) def CopyOpCode(self, opcode, **kwargs): """Creates a copy of the given opcode and applies modifications to it -- 2.6.0.rc2.230.g3dd15c0
