All the errors during an opcode execution are reported via exceptions. Except all the exceptions and execute POST global hooks with FAILED status.
Signed-off-by: Oleg Ponomarev <[email protected]> --- lib/mcpu.py | 72 +++++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 41 insertions(+), 31 deletions(-) diff --git a/lib/mcpu.py b/lib/mcpu.py index 9be8d46..e0f3a6d 100644 --- a/lib/mcpu.py +++ b/lib/mcpu.py @@ -688,39 +688,49 @@ class Processor(object): self._cbs = cbs try: - if self._enable_locks: - # Acquire the Big Ganeti Lock exclusively if this LU requires it, - # and in a shared fashion otherwise (to prevent concurrent run with - # an exclusive LU. - self._AcquireLocks(locking.LEVEL_CLUSTER, locking.BGL, - not lu_class.REQ_BGL, False, calc_timeout()) - elif lu_class.REQ_BGL: - raise errors.ProgrammerError("Opcode '%s' requires BGL, but locks are" - " disabled" % op.OP_ID) - - lu = lu_class(self, op, self.cfg, self.rpc, - self._wconfdcontext, self.wconfd) - lu.wconfdlocks = self.wconfd.Client().ListLocks(self._wconfdcontext) - _CheckSecretParameters(op) - lu.ExpandNames() - assert lu.needed_locks is not None, "needed_locks not set by LU" - try: - result = self._LockAndExecLU(lu, locking.LEVEL_CLUSTER + 1, - calc_timeout) - finally: - if self._ec_id: - self.cfg.DropECReservations(self._ec_id) - finally: - self.wconfd.Client().FreeLocksLevel( - self._wconfdcontext, locking.LEVEL_NAMES[locking.LEVEL_CLUSTER]) - self._cbs = None - - self._CheckLUResult(op, result) + if self._enable_locks: + # Acquire the Big Ganeti Lock exclusively if this LU requires it, + # and in a shared fashion otherwise (to prevent concurrent run with + # an exclusive LU. + self._AcquireLocks(locking.LEVEL_CLUSTER, locking.BGL, + not lu_class.REQ_BGL, False, calc_timeout()) + elif lu_class.REQ_BGL: + raise errors.ProgrammerError("Opcode '%s' requires BGL, but locks are" + " disabled" % op.OP_ID) + + lu = lu_class(self, op, self.cfg, self.rpc, + self._wconfdcontext, self.wconfd) + lu.wconfdlocks = self.wconfd.Client().ListLocks(self._wconfdcontext) + _CheckSecretParameters(op) + lu.ExpandNames() + assert lu.needed_locks is not None, "needed_locks not set by LU" - if self._hm is not None: - self._hm.RunPhase(constants.HOOKS_PHASE_POST, None, True, - constants.POST_HOOKS_STATUS_SUCCEEDED) + try: + result = self._LockAndExecLU(lu, locking.LEVEL_CLUSTER + 1, + calc_timeout) + finally: + if self._ec_id: + self.cfg.DropECReservations(self._ec_id) + finally: + self.wconfd.Client().FreeLocksLevel( + self._wconfdcontext, locking.LEVEL_NAMES[locking.LEVEL_CLUSTER]) + self._cbs = None + + self._CheckLUResult(op, result) + + if self._hm is not None: + self._hm.RunPhase(constants.HOOKS_PHASE_POST, None, True, + constants.POST_HOOKS_STATUS_SUCCEEDED) + except: + # execute global post hooks with the failed status on any exception + hm = self.hmclass(op.OP_ID, None, ([], [self.cfg.GetMasterNodeName()]), + self.rpc.call_hooks_runner, None, None, None, + logging.warning, self.cfg.GetClusterName(), + self.cfg.GetMasterNodeName(), self.GetECId()) + hm.RunPhase(phase = constants.HOOKS_PHASE_POST, glob = True, + post_status = constants.POST_HOOKS_STATUS_FAILED) + raise return result -- 2.6.0.rc2.230.g3dd15c0
