diff options
author | Angus Salkeld <asalkeld@redhat.com> | 2012-08-15 10:38:29 +1000 |
---|---|---|
committer | Angus Salkeld <asalkeld@redhat.com> | 2012-08-20 20:32:23 +1000 |
commit | 053789a75b7fcde1bde82ee366ad43f3aa7e70b9 (patch) | |
tree | 5400b81b32ff80c96744e5bcc5363230142df3c9 | |
parent | a3af744743746f796cb6746d5038c7650b2dfe11 (diff) | |
download | oslo-053789a75b7fcde1bde82ee366ad43f3aa7e70b9.tar.gz oslo-053789a75b7fcde1bde82ee366ad43f3aa7e70b9.tar.xz oslo-053789a75b7fcde1bde82ee366ad43f3aa7e70b9.zip |
Add signal handling to service launcher
Part of blueprint service-infrastructure
Change-Id: Iff072199ebd3c1abcb4218c9b647f8bef75f934a
Signed-off-by: Angus Salkeld <asalkeld@redhat.com>
-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. |