def CheckPrereq(self): """Check prerequisites. This checks: - the node exists in the configuration - OOB is supported Any errors are signaled by raising errors.OpPrereqError. """ self.nodes = [] self.master_node_uuid = self.cfg.GetMasterNode() master_node_obj = self.cfg.GetNodeInfo(self.master_node_uuid) assert self.op.power_delay >= 0.0 if self.op.node_uuids: if (self.op.command in self._SKIP_MASTER and master_node_obj.uuid in self.op.node_uuids): master_oob_handler = SupportsOob(self.cfg, master_node_obj) if master_oob_handler: additional_text = ( "run '%s %s %s' if you want to operate on the" " master regardless") % (master_oob_handler, self.op.command, master_node_obj.name) else: additional_text = "it does not support out-of-band operations" raise errors.OpPrereqError( ("Operating on the master node %s is not" " allowed for %s; %s") % (master_node_obj.name, self.op.command, additional_text), errors.ECODE_INVAL) else: self.op.node_uuids = self.cfg.GetNodeList() if self.op.command in self._SKIP_MASTER: self.op.node_uuids.remove(master_node_obj.uuid) if self.op.command in self._SKIP_MASTER: assert master_node_obj.uuid not in self.op.node_uuids for node_uuid in self.op.node_uuids: node = self.cfg.GetNodeInfo(node_uuid) if node is None: raise errors.OpPrereqError("Node %s not found" % node_uuid, errors.ECODE_NOENT) self.nodes.append(node) if (not self.op.ignore_status and (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") % node.name, errors.ECODE_STATE)
def Exec(self, feedback_fn): """Execute OOB and return result if we expect any. """ ret = [] for idx, node in enumerate( utils.NiceSort(self.nodes, key=lambda node: node.name)): node_entry = [(constants.RS_NORMAL, node.name)] ret.append(node_entry) oob_program = SupportsOob(self.cfg, node) if not oob_program: node_entry.append((constants.RS_UNAVAIL, None)) continue logging.info("Executing out-of-band command '%s' using '%s' on %s", self.op.command, oob_program, node.name) result = self.rpc.call_run_oob(self.master_node_uuid, oob_program, self.op.command, node.name, self.op.timeout) if result.fail_msg: self.LogWarning("Out-of-band RPC failed on node '%s': %s", node.name, result.fail_msg) node_entry.append((constants.RS_NODATA, None)) continue try: self._CheckPayload(result) except errors.OpExecError, err: self.LogWarning( "Payload returned by node '%s' is not valid: %s", node.name, err) node_entry.append((constants.RS_NODATA, None)) else: if self.op.command == constants.OOB_HEALTH: # For health we should log important events for item, status in result.payload: if status in [ constants.OOB_STATUS_WARNING, constants.OOB_STATUS_CRITICAL ]: self.LogWarning( "Item '%s' on node '%s' has status '%s'", item, node.name, status) if self.op.command == constants.OOB_POWER_ON: node.powered = True elif self.op.command == constants.OOB_POWER_OFF: node.powered = False elif self.op.command == constants.OOB_POWER_STATUS: powered = result.payload[ constants.OOB_POWER_STATUS_POWERED] if powered != node.powered: logging.warning( ("Recorded power state (%s) of node '%s' does not" " match actual power state (%s)"), node.powered, node.name, powered) # For configuration changing commands we should update the node if self.op.command in (constants.OOB_POWER_ON, constants.OOB_POWER_OFF): self.cfg.Update(node, feedback_fn) node_entry.append((constants.RS_NORMAL, result.payload)) if (self.op.command == constants.OOB_POWER_ON and idx < len(self.nodes) - 1): time.sleep(self.op.power_delay)