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)
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()
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)
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)
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)
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, ))
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, ) )
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()
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')
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)
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)
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')
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()
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
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))
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)
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
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
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)
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)
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()
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()
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)
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')
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
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)
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
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
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 ) )