summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAngus Salkeld <asalkeld@redhat.com>2012-08-15 10:38:29 +1000
committerAngus Salkeld <asalkeld@redhat.com>2012-08-20 20:32:23 +1000
commit053789a75b7fcde1bde82ee366ad43f3aa7e70b9 (patch)
tree5400b81b32ff80c96744e5bcc5363230142df3c9
parenta3af744743746f796cb6746d5038c7650b2dfe11 (diff)
downloadoslo-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.py41
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.