Skip to content

Commit

Permalink
Add group name syntax to the status command. Closes #135, #383
Browse files Browse the repository at this point in the history
  • Loading branch information
mnaberez committed Feb 25, 2014
1 parent 4d774b3 commit 9354776
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 23 deletions.
3 changes: 3 additions & 0 deletions CHANGES.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@
Supervisor's runtime configuration when using the ``add`` and ``remove``
commands in ``supervisorctl``. Patch by Brent Tubbs.

- The ``status`` command in ``supervisorctl`` now supports group name
syntax: ``status groupname:*``.

3.0 (2013-07-30)
----------------

Expand Down
48 changes: 31 additions & 17 deletions supervisor/supervisorctl.py
Original file line number Diff line number Diff line change
Expand Up @@ -565,30 +565,44 @@ def do_status(self, arg):
return

supervisor = self.ctl.get_supervisor()
all_infos = supervisor.getAllProcessInfo()

names = arg.strip().split()
if not names or "all" in names:
matching_infos = all_infos
else:
matching_infos = []

if names:
for name in names:
try:
info = supervisor.getProcessInfo(name)
except xmlrpclib.Fault, e:
if e.faultCode == xmlrpc.Faults.BAD_NAME:
self.ctl.output('No such process %s' % name)
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 matched:
bad_name = False
matching_infos.append(info)

if bad_name:
if process_name is None:
msg = "%s: ERROR (no such group)" % group_name
else:
raise
continue
self.ctl.output(self._procrepr(info))
else:
for info in supervisor.getAllProcessInfo():
self.ctl.output(self._procrepr(info))
msg = "%s: ERROR (no such process)" % name
self.ctl.output(msg)

for info in matching_infos:
self.ctl.output(self._procrepr(info))

def help_status(self):
self.ctl.output("status\t\t\tGet all process status info.")
self.ctl.output(
"status <name>\t\tGet status on a single process by name.")
self.ctl.output("status <name> <name>\tGet status on multiple named "
"processes.")
self.ctl.output("status <name>\t\tGet status for a single process")
self.ctl.output("status <gname>:*\tGet status for all "
"processes in a group")
self.ctl.output("status <name> <name>\tGet status for multiple named "
"processes")
self.ctl.output("status\t\t\tGet all process status info")

def do_pid(self, arg):
supervisor = self.ctl.get_supervisor()
Expand Down
61 changes: 55 additions & 6 deletions supervisor/tests/test_supervisorctl.py
Original file line number Diff line number Diff line change
Expand Up @@ -294,27 +294,76 @@ def test_tail_explicit_channel_unrecognized(self):
value = plugin.ctl.stdout.getvalue().strip()
self.assertEqual(value, "Error: bad channel 'fudge'")

def test_status_oneprocess(self):
def test_status_all_processes_no_arg(self):
plugin = self._makeOne()
result = plugin.do_status('')
self.assertEqual(result, None)
value = plugin.ctl.stdout.getvalue().split('\n')
self.assertEqual(value[0].split(None, 2),
['foo', 'RUNNING', 'foo description'])
self.assertEqual(value[1].split(None, 2),
['bar', 'FATAL', 'bar description'])
self.assertEqual(value[2].split(None, 2),
['baz:baz_01', 'STOPPED', 'baz description'])

def test_status_all_processes_all_arg(self):
plugin = self._makeOne()
result = plugin.do_status('all')
self.assertEqual(result, None)
value = plugin.ctl.stdout.getvalue().split('\n')
self.assertEqual(value[0].split(None, 2),
['foo', 'RUNNING', 'foo description'])
self.assertEqual(value[1].split(None, 2),
['bar', 'FATAL', 'bar description'])
self.assertEqual(value[2].split(None, 2),
['baz:baz_01', 'STOPPED', 'baz description'])

def test_status_process_name(self):
plugin = self._makeOne()
result = plugin.do_status('foo')
self.assertEqual(result, None)
value = plugin.ctl.stdout.getvalue().strip()
self.assertEqual(value.split(None, 2),
['foo', 'RUNNING', 'foo description'])

def test_status_group_name(self):
plugin = self._makeOne()
result = plugin.do_status('baz:*')
value = plugin.ctl.stdout.getvalue().split('\n')
self.assertEqual(value[0].split(None, 2),
['baz:baz_01', 'STOPPED', 'baz description'])

def test_status_allprocesses(self):
def test_status_mixed_names(self):
plugin = self._makeOne()
result = plugin.do_status('')
self.assertEqual(result, None)
result = plugin.do_status('foo baz:*')
value = plugin.ctl.stdout.getvalue().split('\n')
self.assertEqual(value[0].split(None, 2),
['foo', 'RUNNING', 'foo description'])
self.assertEqual(value[1].split(None, 2),
['bar', 'FATAL', 'bar description'])
self.assertEqual(value[2].split(None, 2),
['baz:baz_01', 'STOPPED', 'baz description'])

def test_status_bad_group_name(self):
plugin = self._makeOne()
result = plugin.do_status('badgroup:*')
self.assertEqual(result, None)
value = plugin.ctl.stdout.getvalue().split('\n')
self.assertEqual(value[0], "badgroup: ERROR (no such group)")

def test_status_bad_process_name(self):
plugin = self._makeOne()
result = plugin.do_status('badprocess')
self.assertEqual(result, None)
value = plugin.ctl.stdout.getvalue().split('\n')
self.assertEqual(value[0], "badprocess: ERROR (no such process)")

def test_status_bad_process_name_with_group(self):
plugin = self._makeOne()
result = plugin.do_status('badgroup:badprocess')
self.assertEqual(result, None)
value = plugin.ctl.stdout.getvalue().split('\n')
self.assertEqual(value[0], "badgroup:badprocess: "
"ERROR (no such process)")

def test_start_fail(self):
plugin = self._makeOne()
result = plugin.do_start('')
Expand Down

0 comments on commit 9354776

Please sign in to comment.