def act(self, subject, msg): messages = [msg] def write(msg): self.stderr.write('%s\n' % msg) self.stderr.flush() messages.append(msg) try: specs = self.rpc.supervisor.getAllProcessInfo() except Exception as e: write('Exception retrieving process info %s, not acting' % e) return waiting = list(self.programs) if self.any: write('Restarting all running processes') for spec in specs: name = spec['name'] group = spec['group'] self.restart(spec, write) namespec = make_namespec(group, name) if name in waiting: waiting.remove(name) if namespec in waiting: waiting.remove(namespec) else: write('Restarting selected processes %s' % self.programs) for spec in specs: name = spec['name'] group = spec['group'] namespec = make_namespec(group, name) if (name in self.programs) or (namespec in self.programs): self.restart(spec, write) if name in waiting: waiting.remove(name) if namespec in waiting: waiting.remove(namespec) if waiting: write( 'Programs not restarted because they did not exist: %s' % waiting) if self.email: message = '\n'.join(messages) self.mail(self.email, subject, message) if self.dingding: ding = DingDing(self.token) message = '\n'.join(messages) ding.send_text(message, at_all=True)
def act(self, subject, msg): messages = [msg] def write(msg): self.stderr.write('%s\n' % msg) self.stderr.flush() messages.append(msg) try: specs = self.rpc.supervisor.getAllProcessInfo() except Exception as e: write('Exception retrieving process info %s, not acting' % e) return waiting = list(self.programs) write(msg) if self.any: write('Restarting all running processes') for spec in specs: name = spec['name'] group = spec['group'] self.restart(spec, write) namespec = make_namespec(group, name) if name in waiting: waiting.remove(name) if namespec in waiting: waiting.remove(namespec) else: write('Restarting selected processes %s' % self.programs) for spec in specs: name = spec['name'] group = spec['group'] namespec = make_namespec(group, name) if (name in self.programs) or (namespec in self.programs): self.restart(spec, write) if name in waiting: waiting.remove(name) if namespec in waiting: waiting.remove(namespec) if waiting: write( 'Programs not restarted because they did not exist: %s' % waiting) if self.email: message = '\n'.join(messages) self.mail(self.email, subject, message)
def _show_statuses(self, process_infos): namespecs, maxlen = [], 30 for i, info in enumerate(process_infos): namespecs.append(make_namespec(info['group'], info['name'])) if len(namespecs[i]) > maxlen: maxlen = len(namespecs[i]) global_ports = self._get_tcp_ports() template = '%(namespec)-' + str(maxlen + 3) + 's%(state)-10s%(desc)s' for i, info in enumerate(process_infos): process_pid = info['pid'] description = info['description'] try: ports = self._get_listen_ports(process_pid, global_ports) if ports: description = description + ', ports: ' + '|'.join( str(x) for x in ports) else: description = description + ', ports: ' + str(None) except Exception as e: description = description line = template % { 'namespec': namespecs[i], 'state': info['statename'], 'desc': description } self.ctl.output(line)
def do_clear(self, arg): if not self.ctl.upcheck(): return names = arg.split() if not names: self.ctl.output('Error: clear requires a process name') self.help_clear() return supervisor = self.ctl.get_supervisor() if 'all' in names: results = supervisor.clearAllProcessLogs() for result in results: result = self._clearresult(result) self.ctl.output(result) else: for name in names: group_name, process_name = split_namespec(name) try: supervisor.clearProcessLogs(name) except xmlrpclib.Fault as e: error = self._clearresult({'status': e.faultCode, 'name': process_name, 'group': group_name, 'description': e.faultString}) self.ctl.output(error) else: name = make_namespec(group_name, process_name) self.ctl.output('%s: cleared' % name)
def clearall(): if not callbacks: return results group, process, callback = callbacks.pop(0) name = make_namespec(group.config.name, process.config.name) try: callback(name) except RPCError as e: results.append( {"name": process.config.name, "group": group.config.name, "status": e.code, "description": e.text} ) else: results.append( { "name": process.config.name, "group": group.config.name, "status": Faults.SUCCESS, "description": "OK", } ) if callbacks: return NOT_DONE_YET return results
def do_clear(self, arg): if not self.ctl.upcheck(): return names = arg.split() if not names: self.ctl.output("Error: clear requires a process name") self.help_clear() return supervisor = self.ctl.get_supervisor() if "all" in names: results = supervisor.clearAllProcessLogs() for result in results: result = self._clearresult(result) self.ctl.output(result) else: for name in names: group_name, process_name = split_namespec(name) try: result = supervisor.clearProcessLogs(name) except xmlrpclib.Fault, e: error = self._clearresult( {"status": e.faultCode, "name": process_name, "group": group_name, "description": e.faultString} ) self.ctl.output(error) else: name = make_namespec(group_name, process_name) self.ctl.output("%s: cleared" % name)
def _restart_processes(self): try: specs = self.rpc.supervisor.getAllProcessInfo() except Exception as e: print("Unable to get process info: {}. No action taken.".format(e), file=self.stderr) else: waiting = set(self.restart_programs) for spec in specs: name = spec["name"] namespec = make_namespec(spec["group"], name) if self.restart_any_program or name in waiting or namespec in waiting: if spec["state"] is ProcessStates.RUNNING: print("Restarting process: {}.".format(namespec), file=self.stderr) try: self.rpc.supervisor.stopProcess(namespec) except xmlrpclib.Fault as e: print("Unable to stop process {}: {}.".format(namespec, e), file=self.stderr) try: self.rpc.supervisor.startProcess(namespec) except xmlrpclib.Fault as e: print("Unable to start process {}: {}.".format(namespec, e), file=self.stderr) else: print("Restarted process {}.".format(namespec), file=self.stderr) else: print("Process {} is not in RUNNING state. No action taken.".format(namespec)) waiting.discard(name) waiting.discard(namespec) if len(waiting) > 0: print("Programs specified could not be found: {}.".format(", ".join(waiting)), file=self.stderr)
def stopProcessGroup(self, name, wait=True): """ Stop all processes in the process group named 'name' @param string name The group name @param boolean wait Wait for each process to be fully stopped @return array result An array of process status info structs """ self._update('stopProcessGroup') group = self.supervisord.process_groups.get(name) if group is None: raise RPCError(Faults.BAD_NAME, name) processes = group.processes.values() processes.sort() processes = [ (group, process) for process in processes ] results=[] for group, process in processes: name = make_namespec(group.config.name, process.config.name) grp, proc = self._getGroupAndProcess(name) msg=proc.stop() results.append( {'name':process.config.name, 'group':group.config.name, 'status':Faults.SUCCESS, 'description':'OK'} ) return results # deferred
def stopAllProcesses(self, wait=True): """ Stop all processes in the process list @param boolean wait Wait for each process to be fully stopped @return array result An array of process status info structs """ self._update('stopAllProcesses') processes = self._getAllProcesses() results=[] for group, process in processes: name = make_namespec(group.config.name, process.config.name) grp, proc = self._getGroupAndProcess(name) msg=proc.stop() results.append( {'name':process.config.name, 'group':group.config.name, 'status':Faults.SUCCESS, 'description':'OK'} ) #killall.rpcinterface = self return results # deferred
def restart(self, spec, write): namespec = make_namespec(spec['group'], spec['name']) if spec['state'] is ProcessStates.RUNNING: if self.coredir and self.gcore: corename = os.path.join(self.coredir, namespec) cmd = self.gcore + ' "%s" %s' % (corename, spec['pid']) with os.popen(cmd) as m: write('gcore output for %s:\n\n %s' % ( namespec, m.read())) write('%s is in RUNNING state, restarting' % namespec) try: self.rpc.supervisor.stopProcess(namespec) except xmlrpclib.Fault as e: write('Failed to stop process %s: %s' % ( namespec, e)) try: self.rpc.supervisor.startProcess(namespec) except xmlrpclib.Fault as e: write('Failed to start process %s: %s' % ( namespec, e)) else: write('%s restarted' % namespec) else: write('%s not in RUNNING state, NOT restarting' % namespec)
def allfunc( processes=processes, predicate=predicate, func=func, extra_kwargs=extra_kwargs, callbacks=callbacks, # used only to fool scoping, never passed by caller results=results, # used only to fool scoping, never passed by caller ): if not callbacks: for group, process in processes: name = make_namespec(group.config.name, process.config.name) if predicate(process): try: callback = func(name, **extra_kwargs) except RPCError, e: results.append({'name':process.config.name, 'group':group.config.name, 'status':e.code, 'description':e.text}) continue if isinstance(callback, types.FunctionType): callbacks.append((group, process, callback)) else: results.append( {'name':process.config.name, 'group':group.config.name, 'status':Faults.SUCCESS, 'description':'OK'} )
def clearall(): if not callbacks: return results group, process, callback = callbacks.pop(0) name = make_namespec(group.config.name, process.config.name) try: callback(name) except RPCError as e: results.append( {'name': process.config.name, 'group': group.config.name, 'status': e.code, 'description': e.text}) else: results.append( {'name': process.config.name, 'group': group.config.name, 'status': Faults.SUCCESS, 'description': 'OK'} ) if callbacks: return NOT_DONE_YET return results
def do_clear(self, arg): if not self.ctl.upcheck(): return names = arg.split() if not names: self.ctl.output('Error: clear requires a process name') self.help_clear() return supervisor = self.ctl.get_supervisor() if 'all' in names: results = supervisor.clearAllProcessLogs() for result in results: result = self._clearresult(result) self.ctl.output(result) else: for name in names: group_name, process_name = split_namespec(name) try: supervisor.clearProcessLogs(name) except xmlrpclib.Fault as e: error = self._clearresult({'status': e.faultCode, 'name': process_name, 'group': group_name, 'description': e.faultString}) self.ctl.output(error) else: name = make_namespec(group_name, process_name) self.ctl.output('%s: cleared' % name)
def clearall(): if not callbacks: return results group, process, callback = callbacks.pop(0) name = make_namespec(group.config.name, process.config.name) try: callback(name) except RPCError as e: results.append( {'name':process.config.name, 'group':group.config.name, 'status':e.code, 'description':e.text}) else: results.append( {'name':process.config.name, 'group':group.config.name, 'status':Faults.SUCCESS, 'description':'OK'} ) if callbacks: return NOT_DONE_YET return results
def allfunc(processes=processes, predicate=predicate, func=func, extra_kwargs=extra_kwargs, callbacks=callbacks, # used only to fool scoping, never passed by caller results=results): # used only to fool scoping, never passed by caller if not callbacks: for group, process in processes: name = make_namespec(group.config.name, process.config.name) if predicate(process): try: callback = func(name, **extra_kwargs) except RPCError as e: results.append({ 'name': process.config.name, 'group': group.config.name, 'status': e.code, 'description': e.text }) continue if isinstance(callback, types.FunctionType): callbacks.append((group, process, callback)) else: results.append({ 'name': process.config.name, 'group': group.config.name, 'status': Faults.SUCCESS, 'description': 'OK' }) if not callbacks: return results for struct in callbacks[:]: group, process, cb = struct try: value = cb() except RPCError as e: results.append({ 'name': process.config.name, 'group': group.config.name, 'status': e.code, 'description': e.text }) callbacks.remove(struct) else: if value is not NOT_DONE_YET: results.append({ 'name': process.config.name, 'group': group.config.name, 'status': Faults.SUCCESS, 'description': 'OK' }) callbacks.remove(struct) if callbacks: return NOT_DONE_YET return results
def restart(self, spec, write): namespec = make_namespec(spec['group'], spec['name']) if spec['state'] is ProcessStates.RUNNING: if self.coredir and self.gcore: corename = os.path.join(self.coredir, namespec) cmd = self.gcore + ' "%s" %s' % (corename, spec['pid']) with os.popen(cmd) as m: write('gcore output for %s:\n\n %s' % ( namespec, m.read())) write('%s is in RUNNING state, restarting' % namespec) try: self.rpc.supervisor.stopProcess(namespec) except xmlrpclib.Fault as e: write('Failed to stop process %s: %s' % ( namespec, e)) try: self.rpc.supervisor.startProcess(namespec) except xmlrpclib.Fault as e: write('Failed to start process %s: %s' % ( namespec, e)) else: write('%s restarted' % namespec) else: write('%s not in RUNNING state, NOT restarting' % namespec)
def _restart_process(self, process_spec): """Restart a process. """ name_spec = make_namespec( process_spec[GROUP_KEY], process_spec[NAME_KEY]) rpc_client = childutils.getRPCInterface(self._environment) process_spec = rpc_client.supervisor.getProcessInfo(name_spec) if process_spec[STATE_KEY] is ProcessStates.RUNNING: self._log('Trying to stop process %s', name_spec) try: rpc_client.supervisor.stopProcess(name_spec) self._log('Stopped process %s', name_spec) except xmlrpclib.Fault as exc: self._log('Failed to stop process %s: %s', name_spec, exc) try: self._log('Starting process %s', name_spec) rpc_client.supervisor.startProcess(name_spec, False) except xmlrpclib.Fault as exc: self._log('Failed to start process %s: %s', name_spec, exc) else: self._log('%s not in RUNNING state, cannot restart', name_spec)
def allfunc( processes=processes, predicate=predicate, func=func, extra_kwargs=extra_kwargs, callbacks=callbacks, # used only to fool scoping, never passed by caller results=results, # used only to fool scoping, never passed by caller ): if not callbacks: for group, process in processes: name = make_namespec(group.config.name, process.config.name) if predicate(process): try: callback = func(name, **extra_kwargs) except RPCError, e: results.append({'name':process.config.name, 'group':group.config.name, 'status':e.code, 'description':e.text}) continue if isinstance(callback, types.FunctionType): callbacks.append((group, process, callback)) else: results.append( {'name':process.config.name, 'group':group.config.name, 'status':Faults.SUCCESS, 'description':'OK'} )
def logname(self): """ The name of this subprocess as used in logging. """ if self.group is None: return self.config.name else: return make_namespec(self.group.config.name, self.config.name)
def match(spec): name = spec['name'] group = spec['group'] namespec = make_namespec(name, group) for pattern in self.programs: if fnmatch.fnmatch(name, pattern) or fnmatch.fnmatch(namespec, pattern): return True return False
def logname(self): """ The name of this subprocess as used in logging. """ if self.group is None: return self.config.name else: return make_namespec(self.group.config.name, self.config.name)
def allfunc(processes=processes, predicate=predicate, func=func, extra_kwargs=extra_kwargs, callbacks=callbacks, results=results): if not callbacks: for group, process in processes: name = make_namespec(group.config.name, process.config.name) if predicate(process): try: callback = func(name, **extra_kwargs) callbacks.append((group, process, callback)) except RPCError: e = sys.exc_info()[1] results.append({ 'name': process.config.name, 'group': group.config.name, 'status': e.code, 'description': e.text }) continue if not callbacks: return results group, process, callback = callbacks.pop(0) try: value = callback() except RPCError: e = sys.exc_info()[1] results.append({ 'name': process.config.name, 'group': group.config.name, 'status': e.code, 'description': e.text }) return NOT_DONE_YET if value is NOT_DONE_YET: # push it back into the queue; it will finish eventually callbacks.append((group, process, callback)) else: results.append({ 'name': process.config.name, 'group': group.config.name, 'status': Faults.SUCCESS, 'description': 'OK' }) if callbacks: return NOT_DONE_YET return results
def stop(self, spec, write): namespec = make_namespec(spec['group'], spec['name']) if spec['state'] is ProcessStates.STOPPED: return write('%s is in RUNNING state, stopping' % namespec) try: self.rpc.supervisor.stopProcess(namespec) except xmlrpclib.Fault, what: write('Failed to stop process %s: %s' % ( namespec, what))
def _getGroupProcessInfo(self, group): """ Get info about the processes of a certian group @return array result An array of process status results """ output = [] for process in group.processes.values(): name = make_namespec(group.config.name, process.config.name) output.append(self.getProcessInfo(name)) return output
def _getGroupProcessInfo(self, group): """ Get info about the processes of a certain group @return array result An array of process status results """ output = [] for process in group.processes.values(): name = make_namespec(group.config.name, process.config.name) output.append(self.getProcessInfo(name)) return output
def start(self, spec, write): namespec = make_namespec(spec['group'], spec['name']) if spec['state'] is ProcessStates.RUNNING: return try: self.rpc.supervisor.startProcess(namespec) except xmlrpclib.Fault, what: write('Failed to start process %s: %s' % ( namespec, what))
def _spawn_as_parent(self, pid): # Parent self.pid = pid options = self.config.options options.close_child_pipes(self.pipes) options.logger.info('spawned: %r with pid %s' % (make_namespec(self.group.config.name, self.config.name), pid)) self.spawnerr = None self.delay = time.time() + self.config.startsecs options.pidhistory[pid] = self return pid
def _clearresult(self, result): name = make_namespec(result['group'], result['name']) code = result['status'] template = '%s: ERROR (%s)' if code == xmlrpc.Faults.BAD_NAME: return template % (name, 'no such process') elif code == xmlrpc.Faults.FAILED: return template % (name, 'failed') elif code == xmlrpc.Faults.SUCCESS: return '%s: cleared' % name raise ValueError('Unknown result code %s for %s' % (code, name))
def start_stop(self, spec, start=True): namespec = make_namespec(spec['group'], spec['name']) if spec['state'] is ProcessStates.RUNNING and not start: self.write_stderr('%s is in RUNNING state, stopping' % namespec) try: self.rpc.supervisor.stopProcess(namespec) except xmlrpclib.Fault, what: self.write_stderr('Failed to stop process %s: %s' % (namespec, what)) else: self.write_stderr('%s stopped' % namespec)
def _clearresult(self, result): name = make_namespec(result["group"], result["name"]) code = result["status"] template = "%s: ERROR (%s)" if code == xmlrpc.Faults.BAD_NAME: return template % (name, "no such process") elif code == xmlrpc.Faults.FAILED: return template % (name, "failed") elif code == xmlrpc.Faults.SUCCESS: return "%s: cleared" % name raise ValueError("Unknown result code %s for %s" % (code, name))
def stop(self, spec): namespec = make_namespec(spec['group'], spec['name']) if spec['state'] in [ProcessStates.RUNNING, ProcessStates.STARTING]: self.write('%s is in RUNNING/STARTING state, stopping' % namespec) try: self.rpc.supervisor.stopProcess(namespec) self.write('stopping %s' % namespec) except Exception as e: self.write('Failed to stop process %s: %s' % (namespec, e)) else: self.write('%s not in RUNNING state, NOT stopping' % namespec)
def _show_statuses(self, process_infos): namespecs, maxlen = [], 30 for i, info in enumerate(process_infos): namespecs.append(make_namespec(info["group"], info["name"])) if len(namespecs[i]) > maxlen: maxlen = len(namespecs[i]) template = "%(namespec)-" + str(maxlen + 3) + "s%(state)-10s%(desc)s" for i, info in enumerate(process_infos): line = template % {"namespec": namespecs[i], "state": info["statename"], "desc": info["description"]} self.ctl.output(line)
def _clearresult(self, result): name = make_namespec(result['group'], result['name']) code = result['status'] template = '%s: ERROR (%s)' if code == xmlrpc.Faults.BAD_NAME: return template % (name, 'no such process') elif code == xmlrpc.Faults.FAILED: return template % (name, 'failed') elif code == xmlrpc.Faults.SUCCESS: return '%s: cleared' % name raise ValueError('Unknown result code %s for %s' % (code, name))
def write_process_table(self, root): """ Rendering of the processes managed through Supervisor """ # collect data on processes data = [] try: for info in self.info_source.supervisor_rpc_interface.getAllProcessInfo(): data.append({'application_name': info['group'], 'process_name': info['name'], 'namespec': make_namespec(info['group'], info['name']), 'statename': info['statename'], 'statecode': info['state'], 'desc': info['description']}) except RPCError, e: self.logger.warn('failed to get all process info from {}: {}'.format(self.address, e.text))
def allfunc( processes=processes, predicate=predicate, func=func, extra_kwargs=extra_kwargs, callbacks=callbacks, # used only to fool scoping, never passed by caller results=results, # used only to fool scoping, never passed by caller ): if not callbacks: for group, process in processes: name = make_namespec(group.config.name, process.config.name) if predicate(process): try: callback = func(name, **extra_kwargs) callbacks.append((group, process, callback)) except RPCError as e: results.append({'name':process.config.name, 'group':group.config.name, 'status':e.code, 'description':e.text}) continue if not callbacks: return results group, process, callback = callbacks.pop(0) try: value = callback() except RPCError as e: results.append( {'name':process.config.name, 'group':group.config.name, 'status':e.code, 'description':e.text}) return NOT_DONE_YET if value is NOT_DONE_YET: # push it back into the queue; it will finish eventually callbacks.append((group, process, callback)) else: results.append( {'name':process.config.name, 'group':group.config.name, 'status':Faults.SUCCESS, 'description':'OK'} ) if callbacks: return NOT_DONE_YET return results
def _show_statuses(self, process_infos): namespecs, maxlen = [], 30 for i, info in enumerate(process_infos): namespecs.append(make_namespec(info['group'], info['name'])) if len(namespecs[i]) > maxlen: maxlen = len(namespecs[i]) template = '%(namespec)-' + str(maxlen+3) + 's%(state)-10s%(desc)s' for i, info in enumerate(process_infos): line = template % {'namespec': namespecs[i], 'state': info['statename'], 'desc': info['description']} self.ctl.output(line)
def _show_statuses(self, process_infos): namespecs, maxlen = [], 30 for i, info in enumerate(process_infos): namespecs.append(make_namespec(info['group'], info['name'])) if len(namespecs[i]) > maxlen: maxlen = len(namespecs[i]) template = '%(namespec)-' + str(maxlen+3) + 's%(state)-10s%(desc)s' for i, info in enumerate(process_infos): line = template % {'namespec': namespecs[i], 'state': info['statename'], 'desc': info['description']} self.ctl.output(line)
def do_signal(self, arg): if not self.ctl.upcheck(): return args = arg.split() if len(args) < 2: self.ctl.error_output( 'Error: signal requires a signal name and a process name') self.help_signal() return sig = args[0] names = args[1:] supervisor = self.ctl.get_supervisor() if 'all' in names: results = supervisor.signalAllProcesses(sig) for result in results: result = self._signalresult(result) self.ctl.output(result) else: for name in names: group_name, process_name = split_namespec(name) if process_name is None: try: results = supervisor.signalProcessGroup( group_name, sig) for result in results: result = self._signalresult(result) self.ctl.output(result) except xmlrpclib.Fault as e: if e.faultCode == xmlrpc.Faults.BAD_NAME: error = "%s: ERROR (no such group)" % group_name self.ctl.error_output(error) else: raise else: try: supervisor.signalProcess(name, sig) except xmlrpclib.Fault as e: error = self._signalresult({ 'status': e.faultCode, 'name': process_name, 'group': group_name, 'description': e.faultString }) self.ctl.error_output(error) else: name = make_namespec(group_name, process_name) self.ctl.output('%s: signalled' % name)
def getAllProcessInfo(self): """ Get info about all processes @return array result An array of process status results """ self._update('getAllProcessInfo') all_processes = self._getAllProcesses(lexical=True) output = [] for group, process in all_processes: name = make_namespec(group.config.name, process.config.name) output.append(self.getProcessInfo(name)) return output
def getAllProcessInfo(self): """ Get info about all processes @return array result An array of process status results """ self._update('getAllProcessInfo') all_processes = self._getAllProcesses(lexical=True) output = [] for group, process in all_processes: name = make_namespec(group.config.name, process.config.name) output.append(self.getProcessInfo(name)) return output
def clearall(): if not callbacks: return results group, process, callback = callbacks.pop(0) name = make_namespec(group.config.name, process.config.name) try: callback(name) except RPCError, e: results.append( {'name':process.config.name, 'group':group.config.name, 'status':e.code, 'description':e.text})
def do_signal(self, arg): if not self.ctl.upcheck(): return args = arg.split() if len(args) < 2: self.ctl.output( 'Error: signal requires a signal name and a process name') self.help_signal() return sig = args[0] names = args[1:] supervisor = self.ctl.get_supervisor() if 'all' in names: results = supervisor.signalAllProcesses(sig) for result in results: result = self._signalresult(result) self.ctl.output(result) else: for name in names: group_name, process_name = split_namespec(name) if process_name is None: try: results = supervisor.signalProcessGroup( group_name, sig ) for result in results: result = self._signalresult(result) self.ctl.output(result) except xmlrpclib.Fault as e: if e.faultCode == xmlrpc.Faults.BAD_NAME: error = "%s: ERROR (no such group)" % group_name self.ctl.output(error) else: raise else: try: supervisor.signalProcess(name, sig) except xmlrpclib.Fault as e: error = self._signalresult({'status': e.faultCode, 'name': process_name, 'group': group_name, 'description':e.faultString}) self.ctl.output(error) else: name = make_namespec(group_name, process_name) self.ctl.output('%s: signalled' % name)
def clearall(): if not callbacks: return results group, process, callback = callbacks.pop(0) name = make_namespec(group.config.name, process.config.name) try: callback(name) except RPCError, e: results.append( {'name':process.config.name, 'group':group.config.name, 'status':e.code, 'description':e.text})
def _stopresult(self, result): name = make_namespec(result['group'], result['name']) code = result['status'] fault_string = result['description'] template = '%s: ERROR (%s)' if code == xmlrpc.Faults.BAD_NAME: return template % (name, 'no such process') elif code == xmlrpc.Faults.NOT_RUNNING: return template % (name, 'not running') elif code == xmlrpc.Faults.SUCCESS: return '%s: stopped' % name elif code == xmlrpc.Faults.FAILED: return fault_string # assertion raise ValueError('Unknown result code %s for %s' % (code, name))
def _stopresult(self, result): name = make_namespec(result["group"], result["name"]) code = result["status"] fault_string = result["description"] template = "%s: ERROR (%s)" if code == xmlrpc.Faults.BAD_NAME: return template % (name, "no such process") elif code == xmlrpc.Faults.NOT_RUNNING: return template % (name, "not running") elif code == xmlrpc.Faults.SUCCESS: return "%s: stopped" % name elif code == xmlrpc.Faults.FAILED: return fault_string # assertion raise ValueError("Unknown result code %s for %s" % (code, name))
def _formatConfigInfo(self, configinfo): name = make_namespec(configinfo["group"], configinfo["name"]) formatted = {"name": name} if configinfo["inuse"]: formatted["inuse"] = "in use" else: formatted["inuse"] = "avail" if configinfo["autostart"]: formatted["autostart"] = "auto" else: formatted["autostart"] = "manual" formatted["priority"] = "%s:%s" % (configinfo["group_prio"], configinfo["process_prio"]) template = "%(name)-32s %(inuse)-9s %(autostart)-9s %(priority)s" return template % formatted
def start(self, spec): namespec = make_namespec(spec['group'], spec['name']) if spec['state'] in [ ProcessStates.STOPPED, ProcessStates.EXITED, ProcessStates.FATAL ]: self.write('%s is in STOPPED/EXITED/FATAL state, starting' % namespec) try: self.rpc.supervisor.startProcess(namespec) self.write('starting %s' % namespec) except Exception as e: self.write('Failed to start process %s: %s' % (namespec, e)) else: self.write('%s in RUNNING state, NOT starting' % namespec)
def do_stop(self, arg, exitOnError=True): if not self.ctl.upcheck(): return names = arg.split() supervisor = self.ctl.get_supervisor() if not names: self.handle_error('Error: stop requires a process name') self.help_stop() return if 'all' in names: results = supervisor.stopAllProcesses() for result in results: result = self._stopresult(result) self.ctl.output(result) else: for name in names: group_name, process_name = split_namespec(name) if process_name is None: try: results = supervisor.stopProcessGroup(group_name) for result in results: result = self._stopresult(result) self.ctl.output(result) except xmlrpclib.Fault as e: if e.faultCode == xmlrpc.Faults.BAD_NAME: error = "%s: ERROR (no such group)" % group_name logOnly = not exitOnError self.handle_error(message=error, logOnly=logOnly) else: self.handle_error(unhandled=True) else: try: supervisor.stopProcess(name) except xmlrpclib.Fault as e: error = self._stopresult({ 'status': e.faultCode, 'name': process_name, 'group': group_name, 'description': e.faultString }) self.ctl.error_output(error) else: name = make_namespec(group_name, process_name) self.ctl.output('%s: stopped' % name)
def _formatConfigInfo(self, configinfo): name = make_namespec(configinfo['group'], configinfo['name']) formatted = { 'name': name } if configinfo['inuse']: formatted['inuse'] = 'in use' else: formatted['inuse'] = 'avail' if configinfo['autostart']: formatted['autostart'] = 'auto' else: formatted['autostart'] = 'manual' formatted['priority'] = "%s:%s" % (configinfo['group_prio'], configinfo['process_prio']) template = '%(name)-32s %(inuse)-9s %(autostart)-9s %(priority)s' return template % formatted
def do_start(self, arg): if not self.ctl.upcheck(): return names = arg.split() supervisor = self.ctl.get_supervisor() if not names: self.ctl.output("Error: start requires a process name") self.help_start() return if 'all' in names: results = supervisor.startAllProcesses() for result in results: result = self._startresult(result) self.ctl.output(result) else: for name in names: group_name, process_name = split_namespec(name) if process_name is None: try: results = supervisor.startProcessGroup(group_name) for result in results: result = self._startresult(result) self.ctl.output(result) except xmlrpclib.Fault as e: if e.faultCode == xmlrpc.Faults.BAD_NAME: error = "%s: ERROR (no such group)" % group_name self.ctl.output(error) else: raise else: try: result = supervisor.startProcess(name) except xmlrpclib.Fault as e: error = self._startresult({ 'status': e.faultCode, 'name': process_name, 'group': group_name, 'description': e.faultString }) self.ctl.output(error) else: name = make_namespec(group_name, process_name) self.ctl.output('%s: started' % name)
def allfunc(processes=processes, predicate=predicate, func=func, extra_kwargs=extra_kwargs, callbacks=callbacks, results=results): if not callbacks: for group, process in processes: name = make_namespec(group.config.name, process.config.name) if predicate(process): try: callback = func(name, **extra_kwargs) callbacks.append((group, process, callback)) except RPCError, e: results.append({'name':process.config.name, 'group':group.config.name, 'status':e.code, 'description':e.text}) continue
def actions_for_process(self, process): state = process.get_state() processname = urllib.quote( make_namespec(process.group.config.name, process.config.name)) start = { 'name': 'Start', 'href': 'index.html?processname=%s&action=start' % processname, 'target': None, } restart = { 'name': 'Restart', 'href': 'index.html?processname=%s&action=restart' % processname, 'target': None, } stop = { 'name': 'Stop', 'href': 'index.html?processname=%s&action=stop' % processname, 'target': None, } clearlog = { 'name': 'Clear Log', 'href': 'index.html?processname=%s&action=clearlog' % processname, 'target': None, } tailf = { 'name': 'Tail -f', 'href': 'logtail/%s/stderr' % processname, 'target': '_blank' } signalhup = { 'name': 'HUP', 'href': 'index.html?processname=%s&action=signalhup' % processname, 'target': None } if state == ProcessStates.RUNNING: actions = [restart, stop, clearlog, tailf, signalhup] elif state in (ProcessStates.STOPPED, ProcessStates.EXITED, ProcessStates.FATAL): actions = [start, None, clearlog, tailf] else: actions = [None, None, clearlog, tailf] return actions
def _startresult(self, result): name = make_namespec(result['group'], result['name']) code = result['status'] template = '%s: ERROR (%s)' if code == xmlrpc.Faults.BAD_NAME: return template % (name, 'no such process') elif code == xmlrpc.Faults.NO_FILE: return template % (name, 'no such file') elif code == xmlrpc.Faults.NOT_EXECUTABLE: return template % (name, 'file is not executable') elif code == xmlrpc.Faults.ALREADY_STARTED: return template % (name, 'already started') elif code == xmlrpc.Faults.SPAWN_ERROR: return template % (name, 'spawn error') elif code == xmlrpc.Faults.ABNORMAL_TERMINATION: return template % (name, 'abnormal termination') elif code == xmlrpc.Faults.SUCCESS: return '%s: started' % name # assertion raise ValueError('Unknown result code %s for %s' % (code, name))
def do_extstop(self, arg): if not self.ctl.upcheck(): self.ctl.exitstatus = LSBStatusExitStatuses.UNKNOWN return supervisor = self.ctl.get_supervisor() all_infos = supervisor.getAllProcessInfo() names = arg.split() if not names or "all" in names: matching_names = 'all' else: matching_names = '' for name in names: bad_name = True group_name, process_name = split_namespec(name) for info in all_infos: matched = info['group'] == group_name if process_name is not None: matched = matched and info['name'] == process_name if group_name == process_name: matched = fnmatch(info['name'], process_name) if matched: bad_name = False program_name = make_namespec(info['group'], info['name']) matching_names = matching_names + ' ' + program_name if bad_name: if process_name is None: msg = "%s: ERROR (no such group)" % group_name else: msg = "%s: ERROR (no such process)" % name self.ctl.output(msg) self.ctl.exitstatus = LSBStatusExitStatuses.UNKNOWN if matching_names: self._extstop(matching_names)
def render(self): form = self.context.form response = self.context.response processname = form.get('processname') action = form.get('action') message = form.get('message') if action: if not self.callback: self.callback = self.make_callback(processname, action) return NOT_DONE_YET else: message = self.callback() if message is NOT_DONE_YET: return NOT_DONE_YET if message is not None: server_url = form['SERVER_URL'] location = server_url + '?message=%s' % urllib.quote( message) response['headers']['Location'] = location supervisord = self.context.supervisord rpcinterface = RootRPCInterface([ ('supervisor', SupervisorNamespaceRPCInterface(supervisord)) ]) processnames = [] groups = supervisord.process_groups.values() for group in groups: gprocnames = group.processes.keys() for gprocname in gprocnames: processnames.append((group.config.name, gprocname)) processnames.sort() data = [] for groupname, processname in processnames: actions = self.actions_for_process( supervisord.process_groups[groupname].processes[processname]) sent_name = make_namespec(groupname, processname) info = rpcinterface.supervisor.getProcessInfo(sent_name) data.append({ 'status': info['statename'], 'name': processname, 'group': groupname, 'actions': actions, 'state': info['state'], 'description': info['description'], }) root = self.clone() if message is not None: statusarea = root.findmeld('statusmessage') statusarea.attrib['class'] = 'status_msg' statusarea.content(message) if data: iterator = root.findmeld('tr').repeat(data) shaded_tr = False for tr_element, item in iterator: status_text = tr_element.findmeld('status_text') status_text.content(item['status'].lower()) status_text.attrib['class'] = self.css_class_for_state( item['state']) info_text = tr_element.findmeld('info_text') info_text.content(item['description']) anchor = tr_element.findmeld('name_anchor') processname = make_namespec(item['group'], item['name']) anchor.attributes(href='tail.html?processname=%s' % urllib.quote(processname)) anchor.content(processname) actions = item['actions'] actionitem_td = tr_element.findmeld('actionitem_td') for li_element, actionitem in actionitem_td.repeat(actions): anchor = li_element.findmeld('actionitem_anchor') if actionitem is None: anchor.attrib['class'] = 'hidden' else: anchor.attributes(href=actionitem['href'], name=actionitem['name']) anchor.content(actionitem['name']) if actionitem['target']: anchor.attributes(target=actionitem['target']) if shaded_tr: tr_element.attrib['class'] = 'shade' shaded_tr = not shaded_tr else: table = root.findmeld('statustable') table.replace('No programs to manage') copyright_year = str(datetime.date.today().year) root.findmeld('copyright_date').content(copyright_year) return root.write_xhtmlstring()