Esempio n. 1
0
    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)
Esempio n. 2
0
    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)