Here is a patch that adds the 'avail' command that lists all available program sections and says whether they are in use or not:
supervisor> status foo STOPPED Not started zegroup:baz STOPPED Not started zegroup:gazonk RUNNING pid 31549, uptime 0:11:34 supervisor> avail bar removed manual 999:999 foo in use manual 999:999 zegroup:baz in use manual 999:999 zegroup:gazonk in use auto 999:999
Index: src/supervisor/rpcinterface.py =================================================================== --- src/supervisor/rpcinterface.py (revision 789) +++ src/supervisor/rpcinterface.py (working copy) @@ -433,6 +433,29 @@ killall.rpcinterface = self return killall # deferred + def getAllConfigInfo(self): + """ Get info about all availible process configurations. Each record + represents a single process (i.e. groups get flattened). + + @return array result An array of process config info records + """ + self._update('getAllConfigInfo') + + configinfo = [] + for gconfig in self.supervisord.options.process_group_configs: + inuse = gconfig.name in self.supervisord.process_groups + for pconfig in gconfig.process_configs: + configinfo.append( + { 'name': pconfig.name, + 'group': gconfig.name, + 'inuse': inuse, + 'autostart': pconfig.autostart, + 'group_prio': gconfig.priority, + 'process_prio': pconfig.priority }) + + configinfo.sort() + return configinfo + def _interpretProcessInfo(self, info): state = info['state'] Index: src/supervisor/tests/test_supervisorctl.py =================================================================== --- src/supervisor/tests/test_supervisorctl.py (revision 789) +++ src/supervisor/tests/test_supervisorctl.py (working copy) @@ -466,6 +466,38 @@ plugin._formatChanges([['added'], ['changed'], ['dropped']]) plugin._formatChanges([[], [], []]) + def test__formatConfigInfo(self): + info = { 'group': 'group1', + 'name': 'process1', + 'inuse': True, + 'autostart': True, + 'process_prio': 999, + 'group_prio': 999 } + plugin = self._makeOne() + plugin._formatConfigInfo(info) + info = { 'group': 'group1', + 'name': 'process1', + 'inuse': False, + 'autostart': False, + 'process_prio': 999, + 'group_prio': 999 } + plugin._formatConfigInfo(info) + + def test_avail(self): + calls = [] + plugin = self._makeOne() + + class FakeSupervisor(object): + def getAllConfigInfo(self): + return [{ 'group': 'group1', 'name': 'process1', + 'inuse': False, 'autostart': False, + 'process_prio': 999, 'group_prio': 999 }] + + plugin.ctl.get_supervisor = lambda : FakeSupervisor() + plugin.ctl.output = calls.append + result = plugin.do_avail('') + self.assertEqual(result, None) + def test_add(self): plugin = self._makeOne() result = plugin.do_add('foo') Index: src/supervisor/tests/test_rpcinterfaces.py =================================================================== --- src/supervisor/tests/test_rpcinterfaces.py (revision 789) +++ src/supervisor/tests/test_rpcinterfaces.py (working copy) @@ -821,6 +821,31 @@ self.assertEqual(result[1]['status'], Faults.SUCCESS) self.assertEqual(result[1]['description'], 'OK') + def test_getAllConfigInfo(self): + options = DummyOptions() + supervisord = DummySupervisor(options, 'foo') + + pconfig1 = DummyPConfig(options, 'process1', __file__) + pconfig2 = DummyPConfig(options, 'process2', __file__) + gconfig = DummyPGroupConfig(options, 'group1', pconfigs=[pconfig1, pconfig2]) + supervisord.process_groups = {'group1': DummyProcessGroup(gconfig)} + supervisord.options.process_group_configs = [gconfig] + + interface = self._makeOne(supervisord) + configs = interface.getAllConfigInfo() + self.assertEqual(configs, [{ 'group': 'group1', + 'name': 'process1', + 'inuse': True, + 'autostart': True, + 'process_prio': 999, + 'group_prio': 999 }, + { 'group': 'group1', + 'name': 'process2', + 'inuse': True, + 'autostart': True, + 'process_prio': 999, + 'group_prio': 999 }]) + def test__interpretProcessInfo(self): supervisord = DummySupervisor() interface = self._makeOne(supervisord) Index: src/supervisor/supervisorctl.py =================================================================== --- src/supervisor/supervisorctl.py (revision 789) +++ src/supervisor/supervisorctl.py (working copy) @@ -659,6 +659,40 @@ else: self.ctl.output("No config updates to proccesses") + def _formatConfigInfo(self, configinfo): + if configinfo['group'] == configinfo['name']: + name = configinfo['group'] + else: + name = "%s:%s" % (configinfo['group'], configinfo['name']) + formatted = { 'name': name } + if configinfo['inuse']: + formatted['inuse'] = 'in use' + else: + formatted['inuse'] = 'removed' + 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_avail(self, arg): + supervisor = self.ctl.get_supervisor() + try: + configinfo = supervisor.getAllConfigInfo() + except xmlrpclib.Fault, e: + if e.faultCode == xmlrpc.Faults.SHUTDOWN_STATE: + self.ctl.output('ERROR: supervisor shutting down') + else: + for pinfo in configinfo: + self.ctl.output(self._formatConfigInfo(pinfo)) + + def help_avail(self): + self.ctl.output("avail\t\t\tDisplay all configured processes") + def do_add(self, arg): names = arg.strip().split()
-- Anders Qvist, Open End AB Tel: +46 31 7490887
_______________________________________________ Supervisor-users mailing list Supervisor-users@lists.supervisord.org http://lists.supervisord.org/mailman/listinfo/supervisor-users