예제 #1
0
    def listen_messenger(self, timeout=60):
        """
        Wait for msg from slave side and take care about them.
        """
        succ, r_cmd = self.read_msg(timeout)
        if succ is None:
            return r_cmd
        if not succ:
            raise remote_interface.CommanderError("Remote process died.")

        self.listen_errors(r_cmd)
        self.listen_streams(r_cmd)
        self.listen_cmds(r_cmd)
        self.listen_queries(r_cmd)
        return r_cmd
예제 #2
0
    def __init__(self, stdin, stdout, debug=False):
        """
        :type stdin: IOWrapper with implemented write function.
        :type stout: IOWrapper with implemented read function.
        """
        super(CommanderMaster, self).__init__(stdin, stdout)
        self.cmds = {}
        self.debug = debug
        self.responder = None

        self.flush_stdin()
        self.write_msg("start")
        succ, msg = self.read_msg()
        if not succ or msg != "Started":
            raise remote_interface.CommanderError("Remote commander"
                                                  " not started.")
예제 #3
0
    def cmd_loop(self):
        """
        Wait for commands from master and receive results and outputs from
        commands.
        """
        try:
            while (not self._exit):
                stdios = [self.stdin, self.o_stdout, self.o_stderr]
                r_pipes = [
                    cmd.r_pipe for cmd in list(self.cmds.values())
                    if cmd.r_pipe is not None
                ]
                stdouts = [
                    cmd.stdout_pipe for cmd in list(self.cmds.values())
                    if cmd.stdout_pipe is not None
                ]
                stderrs = [
                    cmd.stderr_pipe for cmd in list(self.cmds.values())
                    if cmd.stderr_pipe is not None
                ]

                r, _, _ = select.select(stdios + r_pipes + stdouts + stderrs,
                                        [], [])

                if self.stdin in r:  # command from controller
                    m = self.read_msg()
                    if m[0] is False:
                        logger.info("Other side is closed.")
                        break
                    if m[0] is None:
                        logger.info("Reading is timeouted.")
                        break
                    cmd = CmdSlave(m[1])
                    self.cmds[cmd.cmd_id] = cmd
                    try:
                        # There is hidden bug. We can bump into condition when
                        # we running some function-command. That function dump
                        # some data to stdio. But, stdio is out of
                        # consideration at this point. It can stuck.
                        cmd(self)
                        self.write_msg(cmd.basecmd)
                    except Exception:
                        err_msg = traceback.format_exc()
                        self.write_msg(
                            remote_interface.CommanderError(err_msg))

                if self.o_stdout in r:  # Send message from stdout
                    msg = os.read(self.o_stdout, 16384)
                    self.write_msg(remote_interface.StdOut(msg))
                if self.o_stderr in r:  # Send message from stdout
                    msg = os.read(self.o_stderr, 16384)
                    self.write_msg(remote_interface.StdErr(msg))

                # test all commands for io
                for cmd in list(self.cmds.values()):
                    if cmd.stdout_pipe in r:  # command stdout
                        data = os.read(cmd.stdout_pipe, 16384)
                        if data != "":  # pipe is not closed on another side.
                            self.write_msg(
                                remote_interface.StdOut(data, cmd.cmd_id))
                        else:
                            os.close(cmd.stdout_pipe)
                            cmd.stdout_pipe = None
                    if cmd.stderr_pipe in r:  # command stderr
                        data = os.read(cmd.stderr_pipe, 16384)
                        if data != "":  # pipe is not closed on another side.
                            self.write_msg(
                                remote_interface.StdErr(data, cmd.cmd_id))
                        else:
                            os.close(cmd.stderr_pipe)
                            cmd.stderr_pipe = None
                    if cmd.r_pipe in r:  # command results
                        if cmd.work():
                            cmd.finish(self)
                        self.write_msg(cmd.basecmd)
        except Exception:
            err_msg = traceback.format_exc()
            self.write_msg(remote_interface.CommanderError(err_msg))