Parcourir la source

signalGroup -> signalProcessGroup (for parity with startProcessGroup, etc), add signalAllProcesses, used by supervisorctl

Chris McDonough il y a 11 ans
Parent
commit
014b355fe0
5 fichiers modifiés avec 78 ajouts et 11 suppressions
  1. 3 3
      CHANGES.txt
  2. 3 1
      docs/api.rst
  3. 16 4
      supervisor/rpcinterface.py
  4. 3 1
      supervisor/supervisorctl.py
  5. 53 2
      supervisor/tests/test_rpcinterfaces.py

+ 3 - 3
CHANGES.txt

@@ -66,9 +66,9 @@
 
 - Removed medusa files not used by Supervisor.
 
-- Added ``signalProcess`` and ``signalGroup`` XML-RPC methods to supervisor
-  RPC interface.  Thanks to Casey Callendrello, Marc Abramowitz, and
-  Moriyoshi Koizumi for the patches.
+- Added ``signalProcess``, ``signalProcessGroup``, and ``signalAllProcesses``
+  XML-RPC methods to supervisor RPC interface.  Thanks to Casey Callendrello,
+  Marc Abramowitz, and Moriyoshi Koizumi for the patches.
 
 - Added ``signal`` command to supervisorctl.  Thanks to Moriyoshi Koizumi and
   Marc Abramowitz for the patches.

+ 3 - 1
docs/api.rst

@@ -307,7 +307,9 @@ Process Control
 
     .. automethod:: signalProcess
 
-    .. automethod:: signalGroup
+    .. automethod:: signalProcessGroup
+
+    .. automethod:: signalAllProcesses
 
     .. automethod:: sendProcessStdin
 

+ 16 - 4
supervisor/rpcinterface.py

@@ -475,7 +475,7 @@ class SupervisorNamespaceRPCInterface:
 
         if process is None:
             group_name, process_name = split_namespec(name)
-            return self.signalGroup(group_name, signal=signal)
+            return self.signalProcessGroup(group_name, signal=signal)
 
         try:
             sig = signal_number(signal)
@@ -493,14 +493,14 @@ class SupervisorNamespaceRPCInterface:
         return True
 
 
-    def signalGroup(self, name, signal='HUP'):
+    def signalProcessGroup(self, name, signal='HUP'):
         """ Send a signal to all processes in the group named 'name'
 
         @param string name  The group name
         @param int signal   The signal to be sent. SIGHUP by default
         @return array result
         """
-        self._update('signalGroup')
+        self._update('signalProcessGroup')
 
         group = self.supervisord.process_groups.get(name)
         if group is None:
@@ -513,10 +513,22 @@ class SupervisorNamespaceRPCInterface:
         sendall = make_allfunc(processes, isRunning, self.signalProcess,
                                signal=signal)
         result = sendall()
-        self._update('signalGroup')
+        self._update('signalProcessGroup')
 
         return result
 
+    def signalAllProcesses(self, signal='SIGHUP'):
+        """ Send a signal to all processes in the process list
+
+        @param int signal   The signal to be sent. SIGHUP by default
+        @return array result   An array of process status info structs
+        """
+        processes = self._getAllProcesses()
+        signalall = make_allfunc(processes, isRunning, self.signalProcess,
+            signal=signal)
+        result = signalall()
+        self._update('signalAllProcesses')
+        return result
 
     def getAllConfigInfo(self):
         """ Get info about all available process configurations. Each struct

+ 3 - 1
supervisor/supervisorctl.py

@@ -845,7 +845,9 @@ class DefaultControllerPlugin(ControllerPluginBase):
                 group_name, process_name = split_namespec(name)
                 if process_name is None:
                     try:
-                        results = supervisor.signalGroup(group_name, sig)
+                        results = supervisor.signalProcessGroup(
+                            group_name, sig
+                            )
                         for result in results:
                             result = self._signalresult(result)
                             self.ctl.output(result)

+ 53 - 2
supervisor/tests/test_rpcinterfaces.py

@@ -853,7 +853,7 @@ class SupervisorNamespaceXMLRPCInterfaceTests(TestBase):
         p = supervisord.process_groups[supervisord.group_name].processes['foo']
         self.assertEqual(p.sent_signal, 10 )
 
-    def test_signalGroup(self):
+    def test_signalProcess_withgroup(self):
         """ Test that sending foo:* works """
         options = DummyOptions()
         pconfig1 = DummyPConfig(options, 'process1', '/bin/foo')
@@ -865,7 +865,58 @@ class SupervisorNamespaceXMLRPCInterfaceTests(TestBase):
         supervisord.set_procattr('process2', 'state', ProcessStates.RUNNING)
         interface = self._makeOne(supervisord)
         result = interface.signalProcess('foo:*', 10)
-        self.assertEqual(interface.update_text, 'signalGroup')
+        self.assertEqual(interface.update_text, 'signalProcessGroup')
+        
+        # Sort so we get deterministic results despite hash randomization
+        result = sorted(result, key=operator.itemgetter('name'))
+
+        self.assertEqual(result, [
+            {'status':80,'group':'foo','name': 'process1','description': 'OK'},
+            {'status':80,'group':'foo','name': 'process2','description': 'OK'},
+            ] )
+        process1 = supervisord.process_groups['foo'].processes['process1']
+        self.assertEqual(process1.sent_signal, 10)
+        process2 = supervisord.process_groups['foo'].processes['process2']
+        self.assertEqual(process2.sent_signal, 10)
+
+
+    def test_signalProcessGroup(self):
+        options = DummyOptions()
+        pconfig1 = DummyPConfig(options, 'process1', '/bin/foo')
+        pconfig2 = DummyPConfig(options, 'process2', '/bin/foo2')
+        from supervisor.process import ProcessStates
+        supervisord = PopulatedDummySupervisor(options, 'foo', pconfig1,
+                                               pconfig2)
+        supervisord.set_procattr('process1', 'state', ProcessStates.RUNNING)
+        supervisord.set_procattr('process2', 'state', ProcessStates.RUNNING)
+        interface = self._makeOne(supervisord)
+        result = interface.signalProcessGroup('foo', 10)
+        self.assertEqual(interface.update_text, 'signalProcessGroup')
+
+        # Sort so we get deterministic results despite hash randomization
+        result = sorted(result, key=operator.itemgetter('name'))
+
+        self.assertEqual(result, [
+            {'status':80,'group':'foo','name': 'process1','description': 'OK'},
+            {'status':80,'group':'foo','name': 'process2','description': 'OK'},
+            ] )
+        process1 = supervisord.process_groups['foo'].processes['process1']
+        self.assertEqual(process1.sent_signal, 10)
+        process2 = supervisord.process_groups['foo'].processes['process2']
+        self.assertEqual(process2.sent_signal, 10)
+
+    def test_signalAllProcesses(self):
+        options = DummyOptions()
+        pconfig1 = DummyPConfig(options, 'process1', '/bin/foo')
+        pconfig2 = DummyPConfig(options, 'process2', '/bin/foo2')
+        from supervisor.process import ProcessStates
+        supervisord = PopulatedDummySupervisor(options, 'foo', pconfig1,
+                                               pconfig2)
+        supervisord.set_procattr('process1', 'state', ProcessStates.RUNNING)
+        supervisord.set_procattr('process2', 'state', ProcessStates.RUNNING)
+        interface = self._makeOne(supervisord)
+        result = interface.signalAllProcesses(10)
+        self.assertEqual(interface.update_text, 'signalAllProcesses')
 
         # Sort so we get deterministic results despite hash randomization
         result = sorted(result, key=operator.itemgetter('name'))