def make_callback(self, namespec, action): message = None supervisord = self.context.supervisord # the rpc interface code is already written to deal properly in a # deferred world, so just use it main = ('supervisor', SupervisorNamespaceRPCInterface(supervisord)) system = ('system', SystemNamespaceRPCInterface([main])) rpcinterface = RootRPCInterface([main, system]) if action: if action == 'refresh': def donothing(): message = 'Page refreshed at %s' % time.ctime() return message donothing.delay = 0.05 return donothing elif action == 'stopall': callback = rpcinterface.supervisor.stopAllProcesses() def stopall(): if callback() is NOT_DONE_YET: return NOT_DONE_YET else: return 'All stopped at %s' % time.ctime() stopall.delay = 0.05 return stopall elif action == 'restartall': callback = rpcinterface.system.multicall([{ 'methodName': 'supervisor.stopAllProcesses' }, { 'methodName': 'supervisor.startAllProcesses' }]) def restartall(): result = callback() if result is NOT_DONE_YET: return NOT_DONE_YET return 'All restarted at %s' % time.ctime() restartall.delay = 0.05 return restartall elif namespec: def wrong(): return 'No such process named %s' % namespec wrong.delay = 0.05 group_name, process_name = split_namespec(namespec) group = supervisord.process_groups.get(group_name) if group is None: return wrong process = group.processes.get(process_name) if process is None: return wrong elif action == 'stop': callback = rpcinterface.supervisor.stopProcess(namespec) def stopprocess(): result = callback() if result is NOT_DONE_YET: return NOT_DONE_YET return 'Process %s stopped' % namespec stopprocess.delay = 0.05 return stopprocess elif action == 'restart': callback = rpcinterface.system.multicall([ { 'methodName': 'supervisor.stopProcess', 'params': [namespec] }, { 'methodName': 'supervisor.startProcess', 'params': [namespec] }, ]) def restartprocess(): result = callback() if result is NOT_DONE_YET: return NOT_DONE_YET return 'Process %s restarted' % namespec restartprocess.delay = 0.05 return restartprocess elif action == 'start': try: callback = rpcinterface.supervisor.startProcess( namespec) except RPCError, e: if e.code == Faults.SPAWN_ERROR: def spawnerr(): return 'Process %s spawn error' % namespec spawnerr.delay = 0.05 return spawnerr def startprocess(): if callback() is NOT_DONE_YET: return NOT_DONE_YET return 'Process %s started' % namespec startprocess.delay = 0.05 return startprocess elif action == 'clearlog': callback = rpcinterface.supervisor.clearProcessLog( namespec) def clearlog(): return 'Log for %s cleared' % namespec clearlog.delay = 0.05 return clearlog
def _makeOne(self, namespaces=()): from supervisor.xmlrpc import SystemNamespaceRPCInterface return SystemNamespaceRPCInterface(namespaces)
def make_http_servers(options, supervisord): servers = [] wrapper = LogWrapper(options.logger) for config in options.server_configs: family = config['family'] if family == socket.AF_INET: host, port = config['host'], config['port'] hs = supervisor_af_inet_http_server(host, port, logger_object=wrapper) elif family == socket.AF_UNIX: socketname = config['file'] sockchmod = config['chmod'] sockchown = config['chown'] hs = supervisor_af_unix_http_server(socketname, sockchmod, sockchown, logger_object=wrapper) else: raise ValueError('Cannot determine socket type %r' % family) from supervisor.xmlrpc import supervisor_xmlrpc_handler from supervisor.xmlrpc import SystemNamespaceRPCInterface from supervisor.web import supervisor_ui_handler subinterfaces = [] for name, factory, d in options.rpcinterface_factories: try: inst = factory(supervisord, **d) except: tb = traceback.format_exc() options.logger.warn(tb) raise ValueError('Could not make %s rpc interface' % name) subinterfaces.append((name, inst)) options.logger.info('RPC interface %r initialized' % name) subinterfaces.append( ('system', SystemNamespaceRPCInterface(subinterfaces))) xmlrpchandler = supervisor_xmlrpc_handler(supervisord, subinterfaces) tailhandler = logtail_handler(supervisord) maintailhandler = mainlogtail_handler(supervisord) uihandler = supervisor_ui_handler(supervisord) here = os.path.abspath(os.path.dirname(__file__)) templatedir = os.path.join(here, 'ui') filesystem = filesys.os_filesystem(templatedir) defaulthandler = default_handler.default_handler(filesystem) username = config['username'] password = config['password'] if username: # wrap the xmlrpc handler and tailhandler in an authentication # handler users = {username: password} xmlrpchandler = supervisor_auth_handler(users, xmlrpchandler) tailhandler = supervisor_auth_handler(users, tailhandler) maintailhandler = supervisor_auth_handler(users, maintailhandler) uihandler = supervisor_auth_handler(users, uihandler) defaulthandler = supervisor_auth_handler(users, defaulthandler) else: options.logger.critical('Server %r running without any HTTP ' 'authentication checking' % config['section']) # defaulthandler must be consulted last as its match method matches # everything, so it's first here (indicating last checked) hs.install_handler(defaulthandler) hs.install_handler(uihandler) hs.install_handler(maintailhandler) hs.install_handler(tailhandler) hs.install_handler(xmlrpchandler) # last for speed (first checked) servers.append((config, hs)) return servers
def make_callback(self, namespec, action): supervisord = self.context.supervisord # the rpc interface code is already written to deal properly in a # deferred world, so just use it main = ('supervisor', SupervisorNamespaceRPCInterface(supervisord)) system = ('system', SystemNamespaceRPCInterface([main])) rpcinterface = RootRPCInterface([main, system]) if action: if action == 'refresh': def donothing(): message = 'Page refreshed at %s' % time.ctime() return message donothing.delay = 0.05 return donothing elif action == 'stopall': callback = rpcinterface.supervisor.stopAllProcesses() def stopall(): if callback() is NOT_DONE_YET: return NOT_DONE_YET else: return 'All stopped at %s' % time.ctime() stopall.delay = 0.05 return stopall elif action == 'restartall': callback = rpcinterface.system.multicall([{ 'methodName': 'supervisor.stopAllProcesses' }, { 'methodName': 'supervisor.startAllProcesses' }]) def restartall(): result = callback() if result is NOT_DONE_YET: return NOT_DONE_YET return 'All restarted at %s' % time.ctime() restartall.delay = 0.05 return restartall elif namespec: def wrong(): return 'No such process named %s' % namespec wrong.delay = 0.05 group_name, process_name = split_namespec(namespec) group = supervisord.process_groups.get(group_name) if group is None: return wrong process = group.processes.get(process_name) if process is None: return wrong if action == 'start': try: bool_or_callback = ( rpcinterface.supervisor.startProcess(namespec)) except RPCError as e: if e.code == Faults.NO_FILE: msg = 'no such file' elif e.code == Faults.NOT_EXECUTABLE: msg = 'file not executable' elif e.code == Faults.ALREADY_STARTED: msg = 'already started' elif e.code == Faults.SPAWN_ERROR: msg = 'spawn error' elif e.code == Faults.ABNORMAL_TERMINATION: msg = 'abnormal termination' else: msg = 'unexpected rpc fault [%d] %s' % (e.code, e.text) def starterr(): return 'ERROR: Process %s: %s' % (namespec, msg) starterr.delay = 0.05 return starterr if callable(bool_or_callback): def startprocess(): try: result = bool_or_callback() except RPCError as e: if e.code == Faults.SPAWN_ERROR: msg = 'spawn error' elif e.code == Faults.ABNORMAL_TERMINATION: msg = 'abnormal termination' else: msg = 'unexpected rpc fault [%d] %s' % ( e.code, e.text) return 'ERROR: Process %s: %s' % (namespec, msg) if result is NOT_DONE_YET: return NOT_DONE_YET return 'Process %s started' % namespec startprocess.delay = 0.05 return startprocess else: def startdone(): return 'Process %s started' % namespec startdone.delay = 0.05 return startdone elif action == 'stop': try: bool_or_callback = ( rpcinterface.supervisor.stopProcess(namespec)) except RPCError as e: msg = 'unexpected rpc fault [%d] %s' % (e.code, e.text) def stoperr(): return msg stoperr.delay = 0.05 return stoperr if callable(bool_or_callback): def stopprocess(): try: result = bool_or_callback() except RPCError as e: return 'unexpected rpc fault [%d] %s' % ( e.code, e.text) if result is NOT_DONE_YET: return NOT_DONE_YET return 'Process %s stopped' % namespec stopprocess.delay = 0.05 return stopprocess else: def stopdone(): return 'Process %s stopped' % namespec stopdone.delay = 0.05 return stopdone elif action == 'restart': results_or_callback = rpcinterface.system.multicall([ { 'methodName': 'supervisor.stopProcess', 'params': [namespec] }, { 'methodName': 'supervisor.startProcess', 'params': [namespec] }, ]) if callable(results_or_callback): callback = results_or_callback def restartprocess(): results = callback() if results is NOT_DONE_YET: return NOT_DONE_YET return 'Process %s restarted' % namespec restartprocess.delay = 0.05 return restartprocess else: def restartdone(): return 'Process %s restarted' % namespec restartdone.delay = 0.05 return restartdone elif action == 'clearlog': try: callback = rpcinterface.supervisor.clearProcessLogs( namespec) except RPCError as e: msg = 'unexpected rpc fault [%d] %s' % (e.code, e.text) def clearerr(): return msg clearerr.delay = 0.05 return clearerr def clearlog(): return 'Log for %s cleared' % namespec clearlog.delay = 0.05 return clearlog raise ValueError(action)
def make_http_servers(options, supervisord): servers = [] # options.logger:Logger # 这种想扩展但是不创建子列而是把原类当做参数传进新类的设计方法很好 wrapper = LogWrapper(options.logger) for config in options.server_configs: family = config['family'] if family == socket.AF_INET: host, port = config['host'], config['port'] hs = supervisor_af_inet_http_server(host, port, logger_object=wrapper) elif family == socket.AF_UNIX: #典型的本地IPC,类似于管道,依赖路径名标识发送方和接收方。即发送数据时,指定接收方绑定的路径名,操作系统根据 # 该路径名可以直接找到对应的接收方,并将原始数据直接拷贝到接收方的内核缓冲区中,并上报给接收方进程进行处理。 # 同样的接收方可以从收到的数据包中获取到发送方的路径名,并通过此路径名向其发送数据。 # 我们适应的是unix 'family': 1, 'section': 'unix_http_server', 'chmod': 448, 'chown': (-1, -1), 'file': '/tmp/supervisor.sock', socketname = config['file'] sockchmod = config['chmod'] sockchown = config['chown'] # hs是实例对象,在该对象中建立了sock文件和连接 hs = supervisor_af_unix_http_server(socketname, sockchmod, sockchown, logger_object=wrapper) # 在supervisor_af_unix_http_server 设置了socket_map else: raise ValueError('Cannot determine socket type %r' % family) from supervisor.xmlrpc import supervisor_xmlrpc_handler from supervisor.xmlrpc import SystemNamespaceRPCInterface from supervisor.web import supervisor_ui_handler subinterfaces = [] # self.rpcinterface_factories = section.rpcinterface_factories # [('supervisor', <function make_main_rpcinterface at 0x7fcaea23a140>, {})] for name, factory, d in options.rpcinterface_factories: # print(name,factory,d) try: # inst就是supervisord的实例对象 # rpcinterface 的1026行 #def make_main_rpcinterface(supervisord): #return SupervisorNamespaceRPCInterface(supervisord) inst = factory(supervisord, **d) # factory 是函数,factory(supervisord, **d)调用函数 # inst是SupervisorNamespaceRPCInterface(supervisord)实例 # 这一步是创建rpc,但是我不知怎么做到的 except: tb = traceback.format_exc() options.logger.warn(tb) raise ValueError('Could not make %s rpc interface' % name) subinterfaces.append((name, inst)) options.logger.info('RPC interface %r initialized' % name) # 注册xml接口 # ('supervisor', <supervisor.rpcinterface.SupervisorNamespaceRPCInterface instance at 0x7f6e2f40d758>) supervisor实例 subinterfaces.append( ('system', SystemNamespaceRPCInterface(subinterfaces))) # print(subinterfaces) # [('supervisor', < supervisor.rpcinterface.SupervisorNamespaceRPCInterface instance at 0x7f350f874b48 >), # ('system', < supervisor.xmlrpc.SystemNamespaceRPCInterface instance at 0x7f350f874b90 >)] # Supervisor XML-RPC Handler 和 path # 创建 xmlrpchandler xmlrpchandler = supervisor_xmlrpc_handler(supervisord, subinterfaces) tailhandler = logtail_handler(supervisord) maintailhandler = mainlogtail_handler(supervisord) uihandler = supervisor_ui_handler(supervisord) here = os.path.abspath(os.path.dirname(__file__)) templatedir = os.path.join(here, 'ui') filesystem = filesys.os_filesystem(templatedir) defaulthandler = default_handler.default_handler(filesystem) username = config['username'] password = config['password'] if username: # wrap the xmlrpc handler and tailhandler in an authentication # handler users = {username: password} xmlrpchandler = supervisor_auth_handler(users, xmlrpchandler) tailhandler = supervisor_auth_handler(users, tailhandler) maintailhandler = supervisor_auth_handler(users, maintailhandler) uihandler = supervisor_auth_handler(users, uihandler) defaulthandler = supervisor_auth_handler(users, defaulthandler) else: options.logger.critical('Server %r running without any HTTP ' 'authentication checking' % config['section']) # defaulthandler must be consulted last as its match method matches # everything, so it's first here (indicating last checked) hs.install_handler(defaulthandler) hs.install_handler(uihandler) hs.install_handler(maintailhandler) hs.install_handler(tailhandler) hs.install_handler( xmlrpchandler) # last for speed (first checked) 最前面 servers.append((config, hs)) return servers