Exemplo n.º 1
0
    def found_terminator (self):
        self.buffer, data = [], ''.join(self.buffer)

        if self.pstate is self.STATE_LENGTH:
            packet_length = int (data, 16)
            self.set_terminator (packet_length)
            self.pstate = self.STATE_PACKET
        else:
            self.set_terminator (8)
            self.pstate = self.STATE_LENGTH
            (path, params) = marshal.loads (data)
            o = self.root

            e = None

            try:
                for p in path:
                    o = getattr (o, p)
                result = o(*params)
            except:
                e = repr (asyncore.compact_traceback())
                result = None

            rb = marshal.dumps ((e,result))
            self.push (('%08x' % len(rb)) + rb)
Exemplo n.º 2
0
    def handle_error(self):
        nil, t, v, tbinfo = compact_traceback()

        self.process.config.options.logger.critical(
            'uncaptured python exception, closing channel %s (%s:%s %s)' %
            (repr(self), t, v, tbinfo))
        self.close()
Exemplo n.º 3
0
    def found_terminator(self):
        self.buffer, data = [], ''.join(self.buffer)

        if self.pstate is self.STATE_LENGTH:
            packet_length = int(data, 16)
            self.set_terminator(packet_length)
            self.pstate = self.STATE_PACKET
        else:
            self.set_terminator(8)
            self.pstate = self.STATE_LENGTH
            (path, params) = marshal.loads(data)
            o = self.root

            e = None

            try:
                for p in path:
                    o = getattr(o, p)
                result = o(*params)
            except:
                e = repr(asyncore.compact_traceback())
                result = None

            rb = marshal.dumps((e, result))
            self.push(('%08x' % len(rb)) + rb)
Exemplo n.º 4
0
 def _spawn_as_child(self, filename, argv):
     options = self.config.options
     try:
         # prevent child from receiving signals sent to the
         # parent by calling os.setpgrp to create a new process
         # group for the child; this prevents, for instance,
         # the case of child processes being sent a SIGINT when
         # running supervisor in foreground mode and Ctrl-C in
         # the terminal window running supervisord is pressed.
         # Presumably it also prevents HUP, etc received by
         # supervisord from being sent to children.
         options.setpgrp()
         self._prepare_child_fds()
         # sending to fd 2 will put this output in the stderr log
         msg = self.set_uid()
         if msg:
             uid = self.config.uid
             s = 'supervisor: error trying to setuid to %s ' % uid
             options.write(2, s)
             options.write(2, "(%s)\n" % msg)
         env = os.environ.copy()
         env['SUPERVISOR_ENABLED'] = '1'
         serverurl = self.config.serverurl
         if serverurl is None:  # unset
             serverurl = self.config.options.serverurl  # might still be None
         if serverurl:
             env['SUPERVISOR_SERVER_URL'] = serverurl
         env['SUPERVISOR_PROCESS_NAME'] = self.config.name
         if self.group:
             env['SUPERVISOR_GROUP_NAME'] = self.group.config.name
         if self.config.environment is not None:
             env.update(self.config.environment)
         cwd = self.config.directory
         try:
             if cwd is not None:
                 options.chdir(cwd)
         except OSError:
             why = sys.exc_info()[1]
             code = errno.errorcode.get(why.args[0], why.args[0])
             msg = "couldn't chdir to %s: %s\n" % (cwd, code)
             options.write(2, msg)
         else:
             try:
                 if self.config.umask is not None:
                     options.setumask(self.config.umask)
                 options.execve(filename, argv, env)
             except OSError:
                 why = sys.exc_info()[1]
                 code = errno.errorcode.get(why.args[0], why.args[0])
                 msg = "couldn't exec %s: %s\n" % (argv[0], code)
                 options.write(2, msg)
             except:
                 (file, fun,
                  line), t, v, tbinfo = asyncore.compact_traceback()
                 error = '%s, %s: file: %s line: %s' % (t, v, file, line)
                 options.write(2,
                               "couldn't exec %s: %s\n" % (filename, error))
     finally:
         options._exit(127)
Exemplo n.º 5
0
 def _spawn_as_child(self, filename, argv):
     options = self.config.options
     try:
         # prevent child from receiving signals sent to the
         # parent by calling os.setpgrp to create a new process
         # group for the child; this prevents, for instance,
         # the case of child processes being sent a SIGINT when
         # running supervisor in foreground mode and Ctrl-C in
         # the terminal window running supervisord is pressed.
         # Presumably it also prevents HUP, etc received by
         # supervisord from being sent to children.
         options.setpgrp()
         self._prepare_child_fds()
         # sending to fd 2 will put this output in the stderr log
         msg = self.set_uid()
         if msg:
             uid = self.config.uid
             s = 'supervisor: error trying to setuid to %s ' % uid
             options.write(2, s)
             options.write(2, "(%s)\n" % msg)
         env = os.environ.copy()
         env['SUPERVISOR_ENABLED'] = '1'
         serverurl = self.config.serverurl
         if serverurl is None: # unset
             serverurl = self.config.options.serverurl # might still be None
         if serverurl:
             env['SUPERVISOR_SERVER_URL'] = serverurl
         env['SUPERVISOR_PROCESS_NAME'] = self.config.name
         if self.group:
             env['SUPERVISOR_GROUP_NAME'] = self.group.config.name
         if self.config.environment is not None:
             env.update(self.config.environment)
         cwd = self.config.directory
         try:
             if cwd is not None:
                 options.chdir(cwd)
         except OSError:
             why = sys.exc_info()[1]
             code = errno.errorcode.get(why.args[0], why.args[0])
             msg = "couldn't chdir to %s: %s\n" % (cwd, code)
             options.write(2, msg)
         else:
             try:
                 if self.config.umask is not None:
                     options.setumask(self.config.umask)
                 options.execve(filename, argv, env)
             except OSError:
                 why = sys.exc_info()[1]
                 code = errno.errorcode.get(why.args[0], why.args[0])
                 msg = "couldn't exec %s: %s\n" % (argv[0], code)
                 options.write(2, msg)
             except:
                 (file, fun, line), t,v,tbinfo = asyncore.compact_traceback()
                 error = '%s, %s: file: %s line: %s' % (t, v, file, line)
                 options.write(2, "couldn't exec %s: %s\n" % (filename,
                                                              error))
     finally:
         options._exit(127)
Exemplo n.º 6
0
    def found_terminator(self):

        line = self.in_buffer

        if not len(line):
            return

        sp = line.find(' ')
        if sp != -1:
            line = [line[:sp], line[sp + 1:]]
        else:
            line = [line]

        command = line[0].lower()
        # watch especially for 'urgent' abort commands.
        if command.find('abor') != -1:
            # strip off telnet sync chars and the like...
            while command and command[0] not in letters:
                command = command[1:]
        fun_name = 'cmd_%s' % command
        if command != 'pass':
            self.log('<== %s' % repr(self.in_buffer)[1:-1])
        else:
            self.log('<== %s' % line[0] + ' <password>')
        self.in_buffer = ''
        if not hasattr(self, fun_name):
            self.command_not_understood(line[0])
            return
        if hasattr(self, '_rnfr_src') and fun_name != 'cmd_rnto':
            del self._rnfr_src
            self.respond('503 RNTO Command expected!')
            return

        fun = getattr(self, fun_name)
        if (not self.authorized) and (command
                                      not in ('user', 'pass', 'help', 'quit')):
            self.respond('530 Please log in with USER and PASS')
        elif not self.check_command_authorization(command):
            self.command_not_authorized(command)
        else:
            try:
                fun(*(line, ))
            except:
                self.server.total_exceptions.increment()
                (file, fun, line), t, v, tbinfo = asyncore.compact_traceback()
                if self.client_dc:
                    try:
                        self.client_dc.close()
                    except:
                        pass
                self.respond('451 Server Error: %s, %s: file: %s line: %s' % (
                    t,
                    v,
                    file,
                    line,
                ))
Exemplo n.º 7
0
    def found_terminator (self):

        line = self.in_buffer

        if not len(line):
            return

        sp = line.find(' ')
        if sp != -1:
            line = [line[:sp], line[sp+1:]]
        else:
            line = [line]

        command = line[0].lower()
        # watch especially for 'urgent' abort commands.
        if command.find('abor') != -1:
            # strip off telnet sync chars and the like...
            while command and command[0] not in letters:
                command = command[1:]

        fun_name = 'cmd_%s' % command
        if command != 'pass':
            self.log ('<== %s' % repr(self.in_buffer)[1:-1])
        else:
            self.log ('<== %s' % line[0]+' <password>')
        self.in_buffer = ''
        if not hasattr (self, fun_name):
            self.command_not_understood (line[0])
            return
        if hasattr(self,'_rnfr_src') and fun_name!='cmd_rnto':
            del self._rnfr_src
            self.respond ('503 RNTO Command expected!')
            return

        fun = getattr (self, fun_name)
        if (not self.authorized) and (command not in ('user', 'pass', 'help', 'quit')):
            self.respond ('530 Please log in with USER and PASS')
        elif not self.check_command_authorization (command):
            self.command_not_authorized (command)
        else:
            try:
                fun(*(line,))
            except:
                self.server.total_exceptions.increment()
                (file, fun, line), t,v, tbinfo = asyncore.compact_traceback()
                if self.client_dc:
                    try:
                        self.client_dc.close()
                    except:
                        pass
                self.respond (
                        '451 Server Error: %s, %s: file: %s line: %s' % (
                                t,v,file,line,
                                )
                        )
Exemplo n.º 8
0
    def handle_error(self):
        nil, t, v, tbinfo = compact_traceback()

        self.process.config.options.logger.critical(
            'uncaptured python exception, closing channel %s (%s:%s %s)' % (
                repr(self),
                t,
                v,
                tbinfo
                )
            )
        self.close()
Exemplo n.º 9
0
 def reap (self):          # find DNS requests that have timed out
     now = int(time.time())
     if now - self.last_reap_time > 180:        # reap every 3 minutes
         self.last_reap_time = now              # update before we forget
         for k,(host,unpack,callback,when) in list(self.request_map.items()):
             if now - when > 180:               # over 3 minutes old
                 del self.request_map[k]
                 try:                           # same code as in handle_read
                     callback (host, 0, None)   # timeout val is (0,None)
                 except:
                     file_fun_line, t, v, tbinfo = asyncore.compact_traceback()
                     self.log_info('%s %s %s' % (t,v,tbinfo), 'error')
Exemplo n.º 10
0
 def onecmd(self, line):
     """ Override the onecmd method to:
       - catch and print all exceptions
       - allow for composite commands in interactive mode (foo; bar)
       - call 'do_foo' on plugins rather than ourself
     """
     origline = line
     lines = line.split(';')  # don't filter(None, line.split), as we pop
     line = lines.pop(0)
     # stuffing the remainder into cmdqueue will cause cmdloop to
     # call us again for each command.
     self.cmdqueue.extend(lines)
     cmd, arg, line = self.parseline(line)
     if not line:
         return self.emptyline()
     if cmd is None:
         return self.default(line)
     self._complete_info = None
     self.lastcmd = line
     if cmd == '':
         return self.default(line)
     else:
         do_func = self._get_do_func(cmd)
         if do_func is None:
             return self.default(line)
         try:
             try:
                 return do_func(arg)
             except xmlrpclib.ProtocolError as e:
                 if e.errcode == 401:
                     if self.options.interactive:
                         self.output('Server requires authentication')
                         username = raw_input('Username:'******'Password:'******'')
                         self.options.username = username
                         self.options.password = password
                         return self.onecmd(origline)
                     else:
                         self.options.usage(
                             'Server requires authentication')
                 else:
                     raise
             do_func(arg)
         except SystemExit:
             raise
         except Exception:
             (file, fun, line), t, v, tbinfo = asyncore.compact_traceback()
             error = 'error: %s, %s: file: %s line: %s' % (t, v, file, line)
             self.output(error)
             if not self.options.interactive:
                 sys.exit(2)
Exemplo n.º 11
0
 def onecmd(self, line):
     """ Override the onecmd method to:
       - catch and print all exceptions
       - allow for composite commands in interactive mode (foo; bar)
       - call 'do_foo' on plugins rather than ourself
     """
     origline = line
     lines = line.split(';') # don't filter(None, line.split), as we pop
     line = lines.pop(0)
     # stuffing the remainder into cmdqueue will cause cmdloop to
     # call us again for each command.
     self.cmdqueue.extend(lines)
     cmd, arg, line = self.parseline(line)
     if not line:
         return self.emptyline()
     if cmd is None:
         return self.default(line)
     self._complete_info = None
     self.lastcmd = line
     if cmd == '':
         return self.default(line)
     else:
         do_func = self._get_do_func(cmd)
         if do_func is None:
             return self.default(line)
         try:
             try:
                 return do_func(arg)
             except xmlrpclib.ProtocolError as e:
                 if e.errcode == 401:
                     if self.options.interactive:
                         self.output('Server requires authentication')
                         username = raw_input('Username:'******'Password:'******'')
                         self.options.username = username
                         self.options.password = password
                         return self.onecmd(origline)
                     else:
                         self.options.usage('Server requires authentication')
                 else:
                     raise
             do_func(arg)
         except SystemExit:
             raise
         except Exception:
             (file, fun, line), t, v, tbinfo = asyncore.compact_traceback()
             error = 'error: %s, %s: file: %s line: %s' % (t, v, file, line)
             self.output(error)
             if not self.options.interactive:
                 sys.exit(2)
Exemplo n.º 12
0
 def handle_read (self):
     reply, whence = self.socket.recvfrom (512)
     # for security reasons we may want to double-check
     # that <whence> is the server we sent the request to.
     id = (ord(reply[0])<<8) + ord(reply[1])
     if id in self.request_map:
         host, unpack, callback, when = self.request_map[id]
         del self.request_map[id]
         ttl, answer = unpack (reply)
         try:
             callback (host, ttl, answer)
         except:
             file_fun_line, t, v, tbinfo = asyncore.compact_traceback()
             self.log_info('%s %s %s' % ( t,v,tbinfo), 'error')
Exemplo n.º 13
0
 def handle_read (self):
     try:
         self.recv(8192)
     except socket.error:
         return
     self.lock.acquire()
     try:
         for thunk in self.thunks:
             try:
                 thunk()
             except:
                 nil, t, v, tbinfo = asyncore.compact_traceback()
                 print('exception in trigger thunk: (%s:%s %s)' % (t, v, tbinfo))
         self.thunks = []
     finally:
         self.lock.release()
Exemplo n.º 14
0
            except OSError, why:
                code = errno.errorcode.get(why[0], why[0])
                msg = "couldn't chdir to %s: %s\n" % (cwd, code)
                options.write(2, msg)
            else:
                try:
                    if self.config.umask is not None:
                        options.setumask(self.config.umask)
                    options.execve(filename, argv, env)
                except OSError, why:
                    code = errno.errorcode.get(why[0], why[0])
                    msg = "couldn't exec %s: %s\n" % (argv[0], code)
                    options.write(2, msg)
                except:
                    (file, fun,
                     line), t, v, tbinfo = asyncore.compact_traceback()
                    error = '%s, %s: file: %s line: %s' % (t, v, file, line)
                    options.write(2,
                                  "couldn't exec %s: %s\n" % (filename, error))
        finally:
            options._exit(127)

    def stop(self):
        """ Administrative stop """
        self.administrative_stop = 1
        return self.kill(self.config.stopsignal)

    def give_up(self):
        self.delay = 0
        self.backoff = 0
        self.system_stop = 1
Exemplo n.º 15
0
    def found_terminator(self):
        self.buffer, data = [], ''.join(self.buffer)

        if self.pstate is self.STATE_LENGTH:
            packet_length = int(data, 16)
            self.set_terminator(packet_length)
            self.pstate = self.STATE_PACKET
        else:

            self.set_terminator(8)
            self.pstate = self.STATE_LENGTH

            oid, kind, arg = marshal.loads(data)

            obj, refcnt = self.proxies[oid]
            reply_kind = 2

            try:
                if kind == 0:
                    # __call__
                    result = obj(*arg)
                elif kind == 1:
                    # __getattr__
                    result = getattr(obj, arg)
                elif kind == 2:
                    # __setattr__
                    key, value = arg
                    setattr(obj, key, value)
                    result = None
                elif kind == 3:
                    # __repr__
                    result = repr(obj)
                elif kind == 4:
                    # __del__
                    self.forget_reference(oid)
                    result = None
                elif kind == 5:
                    # __getitem__
                    result = obj[arg]
                elif kind == 6:
                    # __setitem__
                    (key, value) = arg
                    obj[key] = value
                    result = None
                elif kind == 7:
                    # __len__
                    result = len(obj)
                else:
                    result = None

            except:
                reply_kind = 1
                (file, fun, line), t, v, tbinfo = asyncore.compact_traceback()
                result = '%s:%s:%s:%s (%s:%s)' % (MY_NAME, file, fun, line, t,
                                                  str(v))
                self.log_info(result, 'error')
                self.exception_counter.increment()

            self.request_counter.increment()

            try:
                rb = marshal.dumps((reply_kind, result))
            except ValueError:
                # unmarshallable object, return a reference
                rid = id(result)
                self.new_reference(result)
                rb = marshal.dumps((0, rid))

            self.push_with_producer(
                scanning_producer(('%08x' % len(rb)) + rb, buffer_size=65536))
Exemplo n.º 16
0
class Controller(cmd.Cmd):

    def __init__(self, options, completekey='tab', stdin=None,
                 stdout=None):
        self.options = options
        self.prompt = self.options.prompt + '> '
        self.options.plugins = []
        self.vocab = ['add','exit','maintail','pid','reload',
                      'restart','start','stop','version','clear',
                      'fg','open','quit','remove','shutdown','status',
                      'tail','help']
        cmd.Cmd.__init__(self, completekey, stdin, stdout)
        for name, factory, kwargs in self.options.plugin_factories:
            plugin = factory(self, **kwargs)
            self.options.plugins.append(plugin)
            plugin.name = name

    def emptyline(self):
        # We don't want a blank line to repeat the last command.
        return

    def onecmd(self, line):
        """ Override the onecmd method to:
          - catch and print all exceptions
          - allow for composite commands in interactive mode (foo; bar)
          - call 'do_foo' on plugins rather than ourself
        """
        origline = line
        lines = line.split(';') # don't filter(None, line.split), as we pop
        line = lines.pop(0)
        # stuffing the remainder into cmdqueue will cause cmdloop to
        # call us again for each command.
        self.cmdqueue.extend(lines)
        cmd, arg, line = self.parseline(line)
        if not line:
            return self.emptyline()
        if cmd is None:
            return self.default(line)
        self.lastcmd = line
        if cmd == '':
            return self.default(line)
        else:
            do_func = self._get_do_func(cmd)
            if do_func is None:
                return self.default(line)
            try:
                try:
                    return do_func(arg)
                except xmlrpclib.ProtocolError, e:
                    if e.errcode == 401:
                        if self.options.interactive:
                            self.output('Server requires authentication')
                            username = raw_input('Username:'******'Password:'******'')
                            self.options.username = username
                            self.options.password = password
                            return self.onecmd(origline)
                        else:
                            self.options.usage('Server requires authentication')
                    else:
                        raise
                do_func(arg)
            except SystemExit:
                raise
            except Exception, e:
                (file, fun, line), t, v, tbinfo = asyncore.compact_traceback()
                error = 'error: %s, %s: file: %s line: %s' % (t, v, file, line)
                self.output(error)
                if not self.options.interactive:
                    sys.exit(2)
Exemplo n.º 17
0
                    options.chdir(cwd)
            except OSError, why:
                code = errno.errorcode.get(why[0], why[0])
                msg = "couldn't chdir to %s: %s\n" % (cwd, code)
                options.write(2, msg)
            else:
                try:
                    if self.config.umask is not None:
                        options.setumask(self.config.umask)
                    options.execve(filename, argv, env)
                except OSError, why:
                    code = errno.errorcode.get(why[0], why[0])
                    msg = "couldn't exec %s: %s\n" % (argv[0], code)
                    options.write(2, msg)
                except:
                    (file, fun, line), t,v,tbinfo = asyncore.compact_traceback()
                    error = '%s, %s: file: %s line: %s' % (t, v, file, line)
                    options.write(2, "couldn't exec %s: %s\n" % (filename,
                                                                 error))
        finally:
            options._exit(127)

    def stop(self):
        """ Administrative stop """
        self.drain()
        self.administrative_stop = 1
        return self.kill(self.config.stopsignal)

    def give_up(self):
        self.delay = 0
        self.backoff = 0
Exemplo n.º 18
0
    def _spawn_as_child(self, filename, argv):
        options = self.config.options
        # try:
        # prevent child from receiving signals sent to the
        # parent by calling os.setpgrp to create a new process
        # group for the child; this prevents, for instance,
        # the case of child processes being sent a SIGINT when
        # running supervisor in foreground mode and Ctrl-C in
        # the terminal window running supervisord is pressed.
        # Presumably it also prevents HUP, etc received by
        # supervisord from being sent to children.
        options.setpgrp()

        # set user
        try:
            setuid_msg = self.set_uid()
        except NotImplementedError:
            setuid_msg = None
        if setuid_msg:
            uid = self.config.uid
            msg = "couldn't setuid to %s: %s\n" % (uid, setuid_msg)
            options.logger.error("supervisor/process: " + msg)
            return  # finally clause will exit the child process

        # set environment
        env = os.environ.copy()
        env['SUPERVISOR_ENABLED'] = '1'
        serverurl = self.config.serverurl
        if serverurl is None:  # unset
            serverurl = self.config.options.serverurl  # might still be None
        if serverurl:
            env['SUPERVISOR_SERVER_URL'] = serverurl
        env['SUPERVISOR_PROCESS_NAME'] = self.config.name
        if self.group:
            env['SUPERVISOR_GROUP_NAME'] = self.group.config.name
        if self.config.environment is not None:
            env.update(self.config.environment)

        # Fixes bug in unicode strings env
        for key in env:
            if isinstance(key, unicode) or isinstance(env[key], unicode):
                value = env.pop(key)  # only way to update key unicode!
                key = key.encode('utf-8')
                env[key] = value.encode('utf-8')

        try:
            if self.config.umask is not None:
                options.setumask(self.config.umask)
            kwargs = dict(env=env,
                          cwd=self.config.directory,
                          redirect_stderr=self.config.redirect_stderr)
            try:
                self.process = options.execve(filename, argv, env)
                if self.process is None:
                    options.write(2, "child process was not spawned\n")
            except NotImplementedError:
                self.process = self.execute(filename, argv, **kwargs)
        except OSError as why:
            code = errno.errorcode.get(why.args[0], why.args[0])
            msg = "couldn't exec %s: %s\n" % (argv[0], code)
            options.write(2, "supervisor: " + msg)
            self.record_spawnerr(msg)
            self._assertInState(ProcessStates.STARTING)
            self.change_state(ProcessStates.BACKOFF)
        except:
            (file, fun, line), t, v, tbinfo = asyncore.compact_traceback()
            error = '%s, %s: file: %s line: %s' % (t, v, file, line)
            msg = "couldn't exec %s: %s\n" % (filename, error)
            options.write(2, "supervisor: " + msg)
            self.record_spawnerr(msg)
            self._assertInState(ProcessStates.STARTING)
            self.change_state(ProcessStates.BACKOFF)

        if self.process:
            self.pid = self.process.pid
            self._setup_system_resource()
            options.register_pid(self.process.pid, self)
            options.logger.info('Spawned: %r with pid %s' %
                                (self.config.name, self.pid))
            self.delay = time.time() + self.config.startsecs
            self.spawnerr = None  # no error
Exemplo n.º 19
0
    def found_terminator(self):
        """ We only override this to use 'deferring_http_request' class
        instead of the normal http_request class; it sucks to need to override
        this """
        if self.current_request:
            self.current_request.found_terminator()
        else:
            # we convert the header to text to facilitate processing.
            # some of the underlying APIs (such as splitquery)
            # expect text rather than bytes.
            header = as_string(self.in_buffer)
            self.in_buffer = b''
            lines = header.split('\r\n')

            # --------------------------------------------------
            # crack the request header
            # --------------------------------------------------

            while lines and not lines[0]:
                # as per the suggestion of http-1.1 section 4.1, (and
                # Eric Parker <*****@*****.**>), ignore a leading
                # blank lines (buggy browsers tack it onto the end of
                # POST requests)
                lines = lines[1:]

            if not lines:
                self.close_when_done()
                return

            request = lines[0]

            command, uri, version = http_server.crack_request(request)
            header = http_server.join_headers(lines[1:])

            # unquote path if necessary (thanks to Skip Montanaro for pointing
            # out that we must unquote in piecemeal fashion).
            rpath, rquery = http_server.splitquery(uri)
            if '%' in rpath:
                if rquery:
                    uri = http_server.unquote(rpath) + '?' + rquery
                else:
                    uri = http_server.unquote(rpath)

            r = deferring_http_request(self, request, command, uri, version,
                                       header)
            self.request_counter.increment()
            self.server.total_requests.increment()

            if command is None:
                self.log_info('Bad HTTP request: %s' % repr(request), 'error')
                r.error(400)
                return

            # --------------------------------------------------
            # handler selection and dispatch
            # --------------------------------------------------
            for h in self.server.handlers:
                if h.match(r):
                    try:
                        self.current_request = r
                        # This isn't used anywhere.
                        # r.handler = h # CYCLE
                        h.handle_request(r)
                    except:
                        self.server.exceptions.increment()
                        (file, fun, line), t, v, tbinfo = \
                               asyncore.compact_traceback()
                        self.server.log_info(
                            'Server Error: %s, %s: file: %s line: %s' %
                            (t, v, file, line), 'error')
                        try:
                            r.error(500)
                        except:
                            pass
                    return

            # no handlers, so complain
            r.error(404)
Exemplo n.º 20
0
    def found_terminator(self):  # @important 重载,在async_chat.handle_read中被调用
        if self.current_request:
            self.current_request.found_terminator()
        else:
            # 拆分 http 协议体,获取相关内容,基于uri路由转发
            header = self.in_buffer
            self.in_buffer = b''
            lines = header.split(b'\r\n')

            # --------------------------------------------------
            # crack the request header
            # --------------------------------------------------

            while lines and not lines[0]:
                # as per the suggestion of http-1.1 section 4.1, (and
                # Eric Parker <*****@*****.**>), ignore a leading
                # blank lines (buggy browsers tack it onto the end of
                # POST requests)
                lines = lines[1:]

            if not lines:
                self.close_when_done()
                return

            request = lines[0]

            command, uri, version = crack_request(request)
            header = join_headers(lines[1:])

            # unquote path if necessary (thanks to Skip Montanaro for pointing
            # out that we must unquote in piecemeal fashion).
            rpath, rquery = splitquery(uri)
            if '%' in rpath:
                if rquery:
                    uri = unquote(rpath) + '?' + rquery
                else:
                    uri = unquote(rpath)

            r = http_request(self, request, command, uri, version, header)
            self.request_counter.increment()
            self.server.total_requests.increment()

            if command is None:
                self.log_info('Bad HTTP request: %s' % repr(request), 'error')
                r.error(400)
                return

            # --------------------------------------------------
            # handler selection and dispatch
            # --------------------------------------------------
            for h in self.server.handlers:
                if h.match(r):
                    try:
                        self.current_request = r
                        # This isn't used anywhere.
                        # r.handler = h # CYCLE
                        h.handle_request(r)
                    except:
                        self.server.exceptions.increment()
                        (file, fun,
                         line), t, v, tbinfo = asyncore.compact_traceback()
                        self.log_info(
                            'Server Error: %s, %s: file: %s line: %s' %
                            (t, v, file, line), 'error')
                        try:
                            r.error(500)
                        except:
                            pass
                    return

            # no handlers, so complain
            r.error(404)
Exemplo n.º 21
0
 def found_terminator(self):
     line = self.clean_line(self.data)
     self.data = ''
     self.line_counter.increment()
     # check for special case inputs...
     if not line and not self.multi_line:
         self.prompt()
         return
     if line in ['\004', 'exit']:
         self.push('BCNU\r\n')
         self.close_when_done()
         return
     oldout = sys.stdout
     olderr = sys.stderr
     try:
         p = output_producer(self, olderr)
         sys.stdout = p
         sys.stderr = p
         try:
             # this is, of course, a blocking operation.
             # if you wanted to thread this, you would have
             # to synchronize, etc... and treat the output
             # like a pipe.  Not Fun.
             #
             # try eval first.  If that fails, try exec.  If that fails,
             # hurl.
             try:
                 if self.multi_line:
                     # oh, this is horrible...
                     raise SyntaxError
                 co = compile(line, repr(self), 'eval')
                 result = eval(co, self.local_env)
                 method = 'eval'
                 if result is not None:
                     print(repr(result))
                 self.local_env['_'] = result
             except SyntaxError:
                 try:
                     if self.multi_line:
                         if line and line[0] in [' ', '\t']:
                             self.multi_line.append(line)
                             self.push('... ')
                             return
                         else:
                             self.multi_line.append(line)
                             line = '\n'.join(self.multi_line)
                             co = compile(line, repr(self), 'exec')
                             self.multi_line = []
                     else:
                         co = compile(line, repr(self), 'exec')
                 except SyntaxError:
                     why = sys.exc_info()[1]
                     if why.args[0] == 'unexpected EOF while parsing':
                         self.push('... ')
                         self.multi_line.append(line)
                         return
                     else:
                         t, v, tb = sys.exc_info()
                         del tb
                         raise t(v)
                 exec(co in self.local_env)
                 method = 'exec'
         except:
             method = 'exception'
             self.multi_line = []
             (file, fun, line), t, v, tbinfo = asyncore.compact_traceback()
             self.log_info('%s %s %s' % (t, v, tbinfo), 'warning')
     finally:
         sys.stdout = oldout
         sys.stderr = olderr
     self.log_info('%s:%s (%s)> %s' %
                   (self.number, self.line_counter, method, repr(line)))
     self.push_with_producer(p)
     self.prompt()
Exemplo n.º 22
0
 def found_terminator (self):
     line = self.clean_line (self.data)
     self.data = ''
     self.line_counter.increment()
     # check for special case inputs...
     if not line and not self.multi_line:
         self.prompt()
         return
     if line in ['\004', 'exit']:
         self.push ('BCNU\r\n')
         self.close_when_done()
         return
     oldout = sys.stdout
     olderr = sys.stderr
     try:
         p = output_producer(self, olderr)
         sys.stdout = p
         sys.stderr = p
         try:
             # this is, of course, a blocking operation.
             # if you wanted to thread this, you would have
             # to synchronize, etc... and treat the output
             # like a pipe.  Not Fun.
             #
             # try eval first.  If that fails, try exec.  If that fails,
             # hurl.
             try:
                 if self.multi_line:
                     # oh, this is horrible...
                     raise SyntaxError
                 co = compile (line, repr(self), 'eval')
                 result = eval (co, self.local_env)
                 method = 'eval'
                 if result is not None:
                     print(repr(result))
                 self.local_env['_'] = result
             except SyntaxError:
                 try:
                     if self.multi_line:
                         if line and line[0] in [' ','\t']:
                             self.multi_line.append (line)
                             self.push ('... ')
                             return
                         else:
                             self.multi_line.append (line)
                             line =  '\n'.join (self.multi_line)
                             co = compile (line, repr(self), 'exec')
                             self.multi_line = []
                     else:
                         co = compile (line, repr(self), 'exec')
                 except SyntaxError:
                     why = sys.exc_info()[1]
                     if why.args[0] == 'unexpected EOF while parsing':
                         self.push ('... ')
                         self.multi_line.append (line)
                         return
                     else:
                         t,v,tb = sys.exc_info()
                         del tb
                         raise t(v)
                 exec(co in self.local_env)
                 method = 'exec'
         except:
             method = 'exception'
             self.multi_line = []
             (file, fun, line), t, v, tbinfo = asyncore.compact_traceback()
             self.log_info('%s %s %s' %(t, v, tbinfo), 'warning')
     finally:
         sys.stdout = oldout
         sys.stderr = olderr
     self.log_info('%s:%s (%s)> %s' % (
             self.number,
             self.line_counter,
             method,
             repr(line))
             )
     self.push_with_producer (p)
     self.prompt()
Exemplo n.º 23
0
class Controller(cmd.Cmd):
    def __init__(self, options, completekey='tab', stdin=None, stdout=None):
        self.options = options
        self.prompt = self.options.prompt + '> '
        self.options.plugins = []
        self.vocab = ['help']
        self._complete_info = None
        cmd.Cmd.__init__(self, completekey, stdin, stdout)
        for name, factory, kwargs in self.options.plugin_factories:
            plugin = factory(self, **kwargs)
            for a in dir(plugin):
                if a.startswith('do_') and callable(getattr(plugin, a)):
                    self.vocab.append(a[3:])
            self.options.plugins.append(plugin)
            plugin.name = name

    def emptyline(self):
        # We don't want a blank line to repeat the last command.
        return

    def exec_cmdloop(self, args, options):
        try:
            import readline
            delims = readline.get_completer_delims()
            delims = delims.replace(':', '')  # "group:process" as one word
            delims = delims.replace('*', '')  # "group:*" as one word
            delims = delims.replace('-', '')  # names with "-" as one word
            readline.set_completer_delims(delims)

            if options.history_file:
                try:
                    readline.read_history_file(options.history_file)
                except IOError:
                    pass

                def save():
                    try:
                        readline.write_history_file(options.history_file)
                    except IOError:
                        pass

                import atexit
                atexit.register(save)
        except ImportError:
            pass
        try:
            self.cmdqueue.append('status')
            self.cmdloop()
        except KeyboardInterrupt:
            self.output('')
            pass

    def onecmd(self, line):
        """ Override the onecmd method to:
          - catch and print all exceptions
          - allow for composite commands in interactive mode (foo; bar)
          - call 'do_foo' on plugins rather than ourself
        """
        origline = line
        lines = line.split(';')  # don't filter(None, line.split), as we pop
        line = lines.pop(0)
        # stuffing the remainder into cmdqueue will cause cmdloop to
        # call us again for each command.
        self.cmdqueue.extend(lines)
        cmd, arg, line = self.parseline(line)
        if not line:
            return self.emptyline()
        if cmd is None:
            return self.default(line)
        self._complete_info = None
        self.lastcmd = line

        if cmd == '':
            return self.default(line)
        else:
            do_func = self._get_do_func(cmd)
            if do_func is None:
                return self.default(line)
            try:
                try:
                    return do_func(arg)
                except xmlrpclib.ProtocolError, e:
                    if e.errcode == 401:
                        if self.options.interactive:
                            self.output('Server requires authentication')
                            username = raw_input('Username:'******'Password:'******'')
                            self.options.username = username
                            self.options.password = password
                            return self.onecmd(origline)
                        else:
                            self.options.usage(
                                'Server requires authentication')
                    else:
                        raise
                do_func(arg)
            except SystemExit:
                raise
            except Exception:
                (file, fun, line), t, v, tbinfo = asyncore.compact_traceback()
                error = 'error: %s, %s: file: %s line: %s' % (t, v, file, line)
                self.output(error)
                if not self.options.interactive:
                    sys.exit(2)
Exemplo n.º 24
0
 def handle_error (self):      # don't close the connection on error
     file_fun_line, t, v, tbinfo = asyncore.compact_traceback()
     self.log_info(
                     'Problem with DNS lookup (%s:%s %s)' % (t, v, tbinfo),
                     'error')
Exemplo n.º 25
0
    def _spawn_as_child(self, filename, argv):
        options = self.config.options
        # try:
        # prevent child from receiving signals sent to the
        # parent by calling os.setpgrp to create a new process
        # group for the child; this prevents, for instance,
        # the case of child processes being sent a SIGINT when
        # running supervisor in foreground mode and Ctrl-C in
        # the terminal window running supervisord is pressed.
        # Presumably it also prevents HUP, etc received by
        # supervisord from being sent to children.
        options.setpgrp()

        # set user
        try:
            setuid_msg = self.set_uid()
        except NotImplementedError:
            setuid_msg = None
        if setuid_msg:
            uid = self.config.uid
            msg = "couldn't setuid to %s: %s\n" % (uid, setuid_msg)
            options.logger.error("supervisor/process: " + msg)
            return  # finally clause will exit the child process

        # set environment
        env = os.environ.copy()
        env['SUPERVISOR_ENABLED'] = '1'
        serverurl = self.config.serverurl
        if serverurl is None:  # unset
            serverurl = self.config.options.serverurl  # might still be None
        if serverurl:
            env['SUPERVISOR_SERVER_URL'] = serverurl
        env['SUPERVISOR_PROCESS_NAME'] = self.config.name
        if self.group:
            env['SUPERVISOR_GROUP_NAME'] = self.group.config.name
        if self.config.environment is not None:
            env.update(self.config.environment)

        # Fixes bug in unicode strings env
        for key in env:
            if isinstance(key, unicode) or isinstance(env[key], unicode):
                value = env.pop(key)  # only way to update key unicode!
                key = key.encode('utf-8')
                env[key] = value.encode('utf-8')

        try:
            if self.config.umask is not None:
                options.setumask(self.config.umask)
            kwargs = dict(
                env=env,
                cwd=self.config.directory,
                redirect_stderr=self.config.redirect_stderr
            )
            try:
                self.process = options.execve(filename, argv, env)
                if self.process is None:
                    options.write(2, "child process was not spawned\n")
            except NotImplementedError:
                self.process = self.execute(filename, argv, **kwargs)
        except OSError as why:
            code = errno.errorcode.get(why.args[0], why.args[0])
            msg = "couldn't exec %s: %s\n" % (argv[0], code)
            options.write(2, "supervisor: " + msg)
            self.record_spawnerr(msg)
            self._assertInState(ProcessStates.STARTING)
            self.change_state(ProcessStates.BACKOFF)
        except:
            (file, fun, line), t, v, tbinfo = asyncore.compact_traceback()
            error = '%s, %s: file: %s line: %s' % (t, v, file, line)
            msg = "couldn't exec %s: %s\n" % (filename, error)
            options.write(2, "supervisor: " + msg)
            self.record_spawnerr(msg)
            self._assertInState(ProcessStates.STARTING)
            self.change_state(ProcessStates.BACKOFF)

        if self.process:
            self.pid = self.process.pid
            self._setup_system_resource()
            options.register_pid(self.process.pid, self)
            options.logger.info('Spawned: %r with pid %s' % (self.config.name, self.pid))
            self.delay = time.time() + self.config.startsecs
            self.spawnerr = None  # no error
Exemplo n.º 26
0
    def found_terminator (self):
        """ We only override this to use 'deferring_http_request' class
        instead of the normal http_request class; it sucks to need to override
        this """
        if self.current_request:
            self.current_request.found_terminator()
        else:
            header = self.in_buffer
            self.in_buffer = ''
            lines = header.split('\r\n')

            # --------------------------------------------------
            # crack the request header
            # --------------------------------------------------

            while lines and not lines[0]:
                # as per the suggestion of http-1.1 section 4.1, (and
                # Eric Parker <*****@*****.**>), ignore a leading
                # blank lines (buggy browsers tack it onto the end of
                # POST requests)
                lines = lines[1:]

            if not lines:
                self.close_when_done()
                return

            request = lines[0]

            command, uri, version = http_server.crack_request (request)
            header = http_server.join_headers (lines[1:])

            # unquote path if necessary (thanks to Skip Montanaro for pointing
            # out that we must unquote in piecemeal fashion).
            rpath, rquery = http_server.splitquery(uri)
            if '%' in rpath:
                if rquery:
                    uri = http_server.unquote (rpath) + '?' + rquery
                else:
                    uri = http_server.unquote (rpath)

            r = deferring_http_request (self, request, command, uri, version,
                                         header)
            self.request_counter.increment()
            self.server.total_requests.increment()

            if command is None:
                self.log_info ('Bad HTTP request: %s' % repr(request), 'error')
                r.error (400)
                return

            # --------------------------------------------------
            # handler selection and dispatch
            # --------------------------------------------------
            for h in self.server.handlers:
                if h.match (r):
                    try:
                        self.current_request = r
                        # This isn't used anywhere.
                        # r.handler = h # CYCLE
                        h.handle_request (r)
                    except:
                        self.server.exceptions.increment()
                        (file, fun, line), t, v, tbinfo = \
                               asyncore.compact_traceback()
                        self.server.log_info(
                            'Server Error: %s, %s: file: %s line: %s' %
                            (t,v,file,line),
                            'error')
                        try:
                            r.error (500)
                        except:
                            pass
                    return

            # no handlers, so complain
            r.error (404)
Exemplo n.º 27
0
    def _spawn_as_child(self, filename, argv):
        options = self.config.options
        try:
            # prevent child from receiving signals sent to the
            # parent by calling os.setpgrp to create a new process
            # group for the child; this prevents, for instance,
            # the case of child processes being sent a SIGINT when
            # running supervisor in foreground mode and Ctrl-C in
            # the terminal window running supervisord is pressed.
            # Presumably it also prevents HUP, etc received by
            # supervisord from being sent to children.
            options.setpgrp()

            self._prepare_child_fds()
            # sending to fd 2 will put this output in the stderr log

            # set user
            setuid_msg = self.set_uid()
            if setuid_msg:
                uid = self.config.uid
                msg = "couldn't setuid to %s: %s\n" % (uid, setuid_msg)
                options.write(2, "supervisor: " + msg)
                return # finally clause will exit the child process

            # set environment
            env = os.environ.copy()
            env['SUPERVISOR_ENABLED'] = '1'
            serverurl = self.config.serverurl
            if serverurl is None: # unset
                serverurl = self.config.options.serverurl # might still be None
            if serverurl:
                env['SUPERVISOR_SERVER_URL'] = serverurl
            env['SUPERVISOR_PROCESS_NAME'] = self.config.name
            if self.group:
                env['SUPERVISOR_GROUP_NAME'] = self.group.config.name
            if self.config.environment is not None:
                env.update(self.config.environment)
            # change directory
            cwd = self.config.directory
            try:
                if cwd is not None:
                    options.chdir(cwd)
            except OSError as why:
                code = errno.errorcode.get(why.args[0], why.args[0])
                msg = "couldn't chdir to %s: %s\n" % (cwd, code)
                options.write(2, "supervisor: " + msg)
                return # finally clause will exit the child process

            # set umask, then execve
            try:
                if self.config.umask is not None:
                    options.setumask(self.config.umask)
                options.execve(filename, argv, env)
            except OSError as why:
                code = errno.errorcode.get(why.args[0], why.args[0])
                msg = "couldn't exec %s: %s\n" % (argv[0], code)
                options.write(2, "supervisor: " + msg)
            except:
                (file, fun, line), t,v,tbinfo = asyncore.compact_traceback()
                error = '%s, %s: file: %s line: %s' % (t, v, file, line)
                msg = "couldn't exec %s: %s\n" % (filename, error)
                options.write(2, "supervisor: " + msg)

            # this point should only be reached if execve failed.
            # the finally clause will exit the child process.

        finally:
            options.write(2, "supervisor: child process was not spawned\n")
            options._exit(127) # exit process with code for spawn failure
Exemplo n.º 28
0
    def _spawn_as_child(self, filename, argv):
        options = self.config.options
        try:
            # prevent child from receiving signals sent to the
            # parent by calling os.setpgrp to create a new process
            # group for the child; this prevents, for instance,
            # the case of child processes being sent a SIGINT when
            # running supervisor in foreground mode and Ctrl-C in
            # the terminal window running supervisord is pressed.
            # Presumably it also prevents HUP, etc received by
            # supervisord from being sent to children.
            options.setpgrp()

            self._prepare_child_fds()
            # sending to fd 2 will put this output in the stderr log

            # set user
            setuid_msg = self.set_uid()
            if setuid_msg:
                uid = self.config.uid
                msg = "couldn't setuid to %s: %s\n" % (uid, setuid_msg)
                options.write(2, "supervisor: " + msg)
                return  # finally clause will exit the child process

            # set environment
            env = os.environ.copy()
            env['SUPERVISOR_ENABLED'] = '1'
            serverurl = self.config.serverurl
            if serverurl is None:  # unset
                serverurl = self.config.options.serverurl  # might still be None
            if serverurl:
                env['SUPERVISOR_SERVER_URL'] = serverurl
            env['SUPERVISOR_PROCESS_NAME'] = self.config.name
            if self.group:
                env['SUPERVISOR_GROUP_NAME'] = self.group.config.name
            if self.config.environment is not None:
                env.update(self.config.environment)

            # change directory
            cwd = self.config.directory
            try:
                if cwd is not None:
                    options.chdir(cwd)
            except OSError as why:
                code = errno.errorcode.get(why.args[0], why.args[0])
                msg = "couldn't chdir to %s: %s\n" % (cwd, code)
                options.write(2, "supervisor: " + msg)
                return  # finally clause will exit the child process

            # set umask, then execve
            try:
                if self.config.umask is not None:
                    options.setumask(self.config.umask)
                options.execve(filename, argv, env)
            except OSError as why:
                code = errno.errorcode.get(why.args[0], why.args[0])
                msg = "couldn't exec %s: %s\n" % (argv[0], code)
                options.write(2, "supervisor: " + msg)
            except:
                (file, fun, line), t, v, tbinfo = asyncore.compact_traceback()
                error = '%s, %s: file: %s line: %s' % (t, v, file, line)
                msg = "couldn't exec %s: %s\n" % (filename, error)
                options.write(2, "supervisor: " + msg)

            # this point should only be reached if execve failed.
            # the finally clause will exit the child process.

        finally:
            options.write(2, "supervisor: child process was not spawned\n")
            options._exit(127)  # exit process with code for spawn failure
Exemplo n.º 29
0
    def found_terminator (self):
        self.buffer, data = [], ''.join(self.buffer)

        if self.pstate is self.STATE_LENGTH:
            packet_length = int (data, 16)
            self.set_terminator (packet_length)
            self.pstate = self.STATE_PACKET
        else:

            self.set_terminator (8)
            self.pstate = self.STATE_LENGTH

            oid, kind, arg = marshal.loads (data)

            obj, refcnt = self.proxies[oid]
            reply_kind = 2

            try:
                if kind == 0:
                    # __call__
                    result = obj(*arg)
                elif kind == 1:
                    # __getattr__
                    result = getattr (obj, arg)
                elif kind == 2:
                    # __setattr__
                    key, value = arg
                    setattr (obj, key, value)
                    result = None
                elif kind == 3:
                    # __repr__
                    result = repr(obj)
                elif kind == 4:
                    # __del__
                    self.forget_reference (oid)
                    result = None
                elif kind == 5:
                    # __getitem__
                    result = obj[arg]
                elif kind == 6:
                    # __setitem__
                    (key, value) = arg
                    obj[key] = value
                    result = None
                elif kind == 7:
                    # __len__
                    result = len(obj)
                else:
                    result = None

            except:
                reply_kind = 1
                (file,fun,line), t, v, tbinfo = asyncore.compact_traceback()
                result = '%s:%s:%s:%s (%s:%s)' % (MY_NAME, file, fun, line, t, str(v))
                self.log_info (result, 'error')
                self.exception_counter.increment()

            self.request_counter.increment()

            try:
                rb = marshal.dumps ((reply_kind, result))
            except ValueError:
                # unmarshallable object, return a reference
                rid = id(result)
                self.new_reference (result)
                rb = marshal.dumps ((0, rid))

            self.push_with_producer (
                    scanning_producer (
                            ('%08x' % len(rb)) + rb,
                            buffer_size = 65536
                            )
                    )