diff options
-rw-r--r-- | openstack/common/service.py | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/openstack/common/service.py b/openstack/common/service.py index 9c712c6..5141ae4 100644 --- a/openstack/common/service.py +++ b/openstack/common/service.py @@ -19,10 +19,18 @@ """Generic Node base class for all workers that run on hosts.""" +import signal import sys + import eventlet import greenlet +from openstack.common import log as logging +from openstack.common.gettextutils import _ + + +LOG = logging.getLogger(__name__) + class Launcher(object): """Launch one or more services and wait for them to complete.""" @@ -78,6 +86,39 @@ class Launcher(object): pass +class SignalExit(SystemExit): + def __init__(self, signo, exccode=1): + super(SignalExit, self).__init__(exccode) + self.signo = signo + + +class ServiceLauncher(Launcher): + def _handle_signal(self, signo, frame): + # Allow the process to be killed again and die from natural causes + signal.signal(signal.SIGTERM, signal.SIG_DFL) + signal.signal(signal.SIGINT, signal.SIG_DFL) + + raise SignalExit(signo) + + def wait(self): + signal.signal(signal.SIGTERM, self._handle_signal) + signal.signal(signal.SIGINT, self._handle_signal) + + status = None + try: + super(ServiceLauncher, self).wait() + except SignalExit as exc: + signame = {signal.SIGTERM: 'SIGTERM', + signal.SIGINT: 'SIGINT'}[exc.signo] + LOG.info(_('Caught %s, exiting'), signame) + status = exc.code + except SystemExit as exc: + status = exc.code + finally: + self.stop() + return status + + class Service(object): """Service object for binaries running on hosts. |