]> git.llucax.com Git - software/pymin.git/commitdiff
Merge branch 'procman'
authorLeandro Lucarella <llucax@gmail.com>
Thu, 27 Dec 2007 15:53:10 +0000 (12:53 -0300)
committerLeandro Lucarella <llucax@gmail.com>
Thu, 27 Dec 2007 15:53:10 +0000 (12:53 -0300)
* procman:
  Bugfix: set the catched signal to None *after* calling the signal handler.
  Improve vrrp restorable defaults readability.
  Use procman.restart() to restart vrrp service.
  Add ProcessManager.restart() method to block until the restart is done.
  Use procman to manage vrrp service.
  Bugfix: raise a KeyError, don't return it.
  Bugfix: call ProcessInfo.stop() in the right way (without parameters).
  Bugfix: use self instead of an unbinded pi object when killing a process.
  Remove unused ProcessInfo.last_return attribute.
  Bugfix: use correct module for simbol ECHILD.
  Handle SIGCHLD in PyminDaemon.
  Add a global ProcessManager instance and functions to procman module.
  Implement timer in PyminDaemon using EventLoop signal handling.
  Support general signals handling in EventLoop.
  Replace time.sleep() for signal.pause() in the ProcessManager test.
  Improve ProcessManager to manage registerable named services.
  Add a ProcessManager class to manage processes.
  Improve ProcessManager to manage registerable named services.
  Add a ProcessManager class to manage processes.

Conflicts:

pymin/eventloop.py
pymin/pymindaemon.py
pymin/services/vrrp/__init__.py

1  2 
pymin/eventloop.py
pymin/pymindaemon.py
pymin/services/vrrp/__init__.py

index c9f6adeccecb653c284236af5550b7cf1acabf97,fe3c4eca57936743468be1d83a1c8a3fa3ded02d..0f720120730c1326c5ed852e35883ca96c18b344
@@@ -94,8 -95,6 +96,7 @@@ class EventLoop
  
          See EventLoop class documentation for more info.
          """
-         log.debug(u'EventLoop(%r, %r, %r, %r)', file, handler,
-                     timer, timer_handler)
++        log.debug(u'EventLoop(%r, %r, %r)', file, handler, signals)
          self.poll = select.poll()
          self._stop = False
          self.__register(file)
          Wait for events and handle then when they arrive. If once is True,
          then only 1 event is processed and then this method returns.
          """
-         # Flag modified by the signal handler
-         global timeout
-         # If we use a timer, we set up the signal
-         if self.timer is not None:
-             signal.signal(signal.SIGALRM, alarm_handler)
-             self.handle_timer()
-             signal.alarm(self.timer)
 +        log.debug(u'EventLoop.loop(%s)', once)
+         # List of pending signals
+         global signals
          while True:
              try:
 +                log.debug(u'EventLoop.loop: polling')
                  res = self.poll.poll()
              except select.error, e:
-                 # The error is not an interrupt caused by the alarm, then raise
-                 if e.args[0] != errno.EINTR or not timeout:
+                 # The error is not an interrupt caused by a signal, then raise
+                 if e.args[0] != errno.EINTR or not signals:
                      raise LoopInterruptedError(e)
-             # There was a timeout, so execute the timer handler
-             if timeout:
-                 log.debug(u'EventLoop.loop: timer catched, handling...')
-                 timeout = False
-                 self.handle_timer()
-                 signal.alarm(self.timer)
-             # Not a timeout, execute the regular handler
-             else:
-                 log.debug(u'EventLoop.loop: no timeout, handle event')
+             # If we have signals to process, we just do it
+             have_signals = bool(signals)
+             while signals:
 -                self.handle_signal(signals.pop(0))
++                signum = signals.pop(0)
++                log.debug(u'EventLoop.loop: processing signal %d...', signum)
++                self.handle_signal(signum)
+             # No signals to process, execute the regular handler
+             if not have_signals:
++                log.debug(u'EventLoop.loop: processing event...')
                  self.handle()
 -            import os
              # Look if we have to stop
              if self._stop or once:
 +                log.debug(u'EventLoop.loop: stopped')
                  self._stop = False
                  break
  
@@@ -203,7 -205,7 +219,7 @@@ if __name__ == '__main__'
  
      p = EventLoop(0, handle)
  
--    os.write(1, 'Say something once: ')
++    os.write(1, 'Say something once:\n')
      p.loop(once=True)
      os.write(1, 'Great!\n')
  
index a65f19cf57fa7d73f2f7f7bcaf6dbbf0f3227e12,3881857ea29c93d8276e5af33667900a08c1f510..067a727e265b42cd629f53deaa71fad585bb1020
@@@ -43,28 -43,35 +44,38 @@@ class PyminDaemon(eventloop.EventLoop)
  
          See PyminDaemon class documentation for more info.
          """
 +        log.debug(u'PyminDaemon(%r, %r, %r)', root, bind_addr, timer)
+         # Timer timeout time
+         self.timer = timer
          # Create and bind socket
          sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
          sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
          sock.bind(bind_addr)
-         # Create EventLoop
-         eventloop.EventLoop.__init__(self, sock, timer=timer)
-         # Create Dispatcher
-         #TODO root.pymin = PyminHandler()
-         self.dispatcher = dispatcher.Dispatcher(root)
          # Signal handling
-         def quit(signum, frame):
+         def quit(loop, signum):
 -            print "Shuting down ..."
 +            log.debug(u'PyminDaemon quit() handler: signal %r', signum)
 +            log.info(u'Shutting down...')
-             self.stop() # tell main event loop to stop
-         def reload_config(signum, frame):
+             loop.stop() # tell main event loop to stop
+         def reload_config(loop, signum):
 -            print "Reloading configuration..."
 +            log.debug(u'PyminDaemon reload_config() handler: signal %r', signum)
 +            log.info(u'Reloading configuration...')
              # TODO iterate handlers list propagating reload action
-         signal.signal(signal.SIGINT, quit)
-         signal.signal(signal.SIGTERM, quit)
-         signal.signal(signal.SIGUSR1, reload_config)
+         def timer(loop, signum):
+             loop.handle_timer()
+             signal.alarm(loop.timer)
+         def child(loop, signum):
+             procman.sigchild_handler(signum)
+         # Create EventLoop
+         eventloop.EventLoop.__init__(self, sock, signals={
+                 signal.SIGINT: quit,
+                 signal.SIGTERM: quit,
+                 signal.SIGUSR1: reload_config,
+                 signal.SIGALRM: timer,
+                 signal.SIGCHLD: child,
+             })
+         # Create Dispatcher
+         #TODO root.pymin = PyminHandler()
+         self.dispatcher = dispatcher.Dispatcher(root)
  
      def handle(self):
          r"handle() -> None :: Handle incoming events using the dispatcher."
  
      def run(self):
          r"run() -> None :: Run the event loop (shortcut to loop())"
 +        log.debug(u'PyminDaemon.loop()')
+         # Start the timer
+         self.handle_timer()
+         signal.alarm(self.timer)
+         # Loop
          try:
              return self.loop()
          except eventloop.LoopInterruptedError, e:
index 4739c528fc3e874f1299e1301f647826b4e34f9e,9fdfd1a526ce1755429fd9aca87ef8af0984b04e..f13db3ebf7b29f1b654c9230abc09397b11294ea
@@@ -4,8 -4,8 +4,9 @@@ import o
  from os import path
  from signal import SIGTERM
  from subprocess import Popen, PIPE
 +import logging ; log = logging.getLogger('pymin.services.vrrp')
  
+ from pymin import procman
  from pymin.seqtools import Sequence
  from pymin.dispatcher import Handler, handler, HandlerError
  from pymin.services.util import Restorable, TransactionalHandler, \
@@@ -22,39 -24,42 +25,45 @@@ class VrrpHandler(Restorable, Parameter
      _persistent_attrs = ['params']
  
      _restorable_defaults = dict(
-                             params = dict( ipaddress='192.168.0.1',
-                                             id = '1',
-                                             prio = '',
-                                             dev = 'eth0',
-                                     ),
-                             )
+         params = dict(
+                 ipaddress = '192.168.0.1',
+                 id        = '1',
+                 prio      = '',
+                 dev       = 'eth0',
+                 persist   = True,
+             ),
+         )
+     @property
+     def _command(self):
+         command = ['vrrpd', '-i', self.params['dev'], '-v', self.params['id']]
+         if self.params['prio']:
+             command.extend(('-p', self.params['prio']))
+         command.append(self.params['ipaddress'])
+         return command
  
      def _service_start(self):
-         if self.params['prio'] != '':
-             call(('vrrp', '-i', self.params['dev'], '-v', self.params['id'],
-                     '-p', self.params['prio'], self.params['ipaddress']))
-         else:
-             call(('vrrp', '-i', self.params['dev'], '-v', self.params['id'], \
-                     self.params['ipaddress']))
 +        log.debug(u'VrrpHandler._service_start()')
+         procinfo = procman.get('vrrp')
+         procinfo.command = self._command
+         procinfo.persist = self.params['persist']
+         procman.start('vrrp')
  
      def _service_stop(self):
-         try:
-             pid_filename = 'vrrpd_%(dev)s_%(id)s.pid' % self.params
-             log.debug(u'VrrpHandler._service_stop: getting pid from %r',
-                         pid_filename)
-             pid = file(path.join(self._pid_dir, pid_filename )).read()
-             pid = int(pid.strip())
-             log.debug(u'VrrpHandler._service_stop: killing pid %r', pid)
-             os.kill(pid, SIGTERM)
-         except (IOError, OSError), e:
-             log.debug(u'VrrpHandler._service_stop: error %r', e)
 +        log.debug(u'VrrpHandler._service_stop()')
+         procman.stop('vrrp')
+     def _service_restart(self):
+         procinfo = procman.get('vrrp')
+         procinfo.command = self._command
+         procinfo.persist = self.params['persist']
+         procman.restart('vrrp')
  
      def __init__(self, pickle_dir='.', config_dir='.', pid_dir='.'):
 +        log.debug(u'VrrpHandler(%r, %r, $r)', pickle_dir, config_dir, pid_dir)
          self._persistent_dir = pickle_dir
          self._pid_dir = pid_dir
+         procman.register('vrrp', None)
          ServiceHandler.__init__(self)