فهرست منبع

Add group name syntax to the status command. Closes #135, #383

Mike Naberezny 11 سال پیش
والد
کامیت
93547760dc
3فایلهای تغییر یافته به همراه89 افزوده شده و 23 حذف شده
  1. 3 0
      CHANGES.txt
  2. 31 17
      supervisor/supervisorctl.py
  3. 55 6
      supervisor/tests/test_supervisorctl.py

+ 3 - 0
CHANGES.txt

@@ -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)
 ----------------
 

+ 31 - 17
supervisor/supervisorctl.py

@@ -565,30 +565,44 @@ class DefaultControllerPlugin(ControllerPluginBase):
             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()

+ 55 - 6
supervisor/tests/test_supervisorctl.py

@@ -294,7 +294,31 @@ class TestDefaultControllerPlugin(unittest.TestCase):
         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)
@@ -302,19 +326,44 @@ class TestDefaultControllerPlugin(unittest.TestCase):
         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('')