summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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.