diff --git a/lib/cmdlib.py b/lib/cmdlib.py index 37bdda47c8b26fa2b0d2336725ee4fe12d9c6321..774c236bcd202eb948548d609bcbfb9ed463744c 100644 --- a/lib/cmdlib.py +++ b/lib/cmdlib.py @@ -94,6 +94,19 @@ _PMigrationMode = ("mode", None, _PMigrationLive = ("live", None, ht.TMaybeBool) +def _SupportsOob(cfg, node): + """Tells if node supports OOB. + + @type cfg: L{config.ConfigWriter} + @param cfg: The cluster configuration + @type node: L{objects.Node} + @param node: The node + @return: The OOB script if supported or an empty string otherwise + + """ + return cfg.GetNdParams(node)[constants.ND_OOB_PROGRAM] + + # End types class LogicalUnit(object): """Logical Unit base class. @@ -3271,12 +3284,16 @@ class LUOobCommand(NoHooksLU): if node is None: raise errors.OpPrereqError("Node %s not found" % self.op.node_name) - self.oob_program = self.cfg.GetNdParams(node)[constants.ND_OOB_PROGRAM] + self.oob_program = _SupportsOob(self.cfg, node) if not self.oob_program: raise errors.OpPrereqError("OOB is not supported for node %s" % self.op.node_name) + if self.op.command == constants.OOB_POWER_OFF and not node.offline: + raise errors.OpPrereqError(("Cannot power off node %s because it is" + " not marked offline") % self.op.node_name) + self.node = node def ExpandNames(self): @@ -4485,6 +4502,13 @@ class LUSetNodeParams(LogicalUnit): # Past this point, any flag change to False means a transition # away from the respective state, as only real changes are kept + # TODO: We might query the real power state if it supports OOB + if _SupportsOob(self.cfg, node) and (self.op.offline is False and + not node.powered): + raise errors.OpPrereqError(("Please power on node %s first before you" + " can reset offline state") % + self.op.node_name) + # If we're being deofflined/drained, we'll MC ourself if needed if (self.op.drained == False or self.op.offline == False or (self.op.master_capable and not node.master_capable)):