summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLon Hohberger <lhh@redhat.com>2014-02-18 13:44:56 -0500
committerLon Hohberger <lhh@redhat.com>2014-02-19 09:43:44 -0500
commitcceda95a35f18f5f7b52daaf0662a4cd3768b3ac (patch)
treef2e209caa6406394a61868e5005d480bac97c9ea
parent7c2c54f04d378acc79e143f906c2545ae9ec2514 (diff)
downloadheat-cceda95a35f18f5f7b52daaf0662a4cd3768b3ac.tar.gz
Add systemd notification support to heat
This mirrors work done in other OpenStack projects to add systemd notification support to signal that a given process is ready to accept requests. The heat-api, heat-api-cfn, heat-engine, and heat-api-cloudwatch processes are all covered by a new, single, 'onready' configuration file option. Additionally, the sample configuration file has been updated to match. Implements: blueprint systemd-integration Change-Id: I90d2b915e2568a65ed9ed78923c9982e19f9c948 Signed-off-by: Lon Hohberger <lhh@redhat.com>
-rwxr-xr-xbin/heat-api2
-rwxr-xr-xbin/heat-api-cfn2
-rwxr-xr-xbin/heat-api-cloudwatch2
-rwxr-xr-xbin/heat-engine3
-rw-r--r--etc/heat/heat.conf.sample8
-rw-r--r--heat/common/config.py9
-rw-r--r--heat/common/notify.py38
-rw-r--r--heat/common/systemd.py44
8 files changed, 107 insertions, 1 deletions
diff --git a/bin/heat-api b/bin/heat-api
index d9f7495e2..44e0cf486 100755
--- a/bin/heat-api
+++ b/bin/heat-api
@@ -40,6 +40,7 @@ from oslo.config import cfg
from heat.common import config
from heat.common import wsgi
+from heat.common import notify
from heat.openstack.common import log as logging
@@ -62,6 +63,7 @@ if __name__ == '__main__':
LOG.info('Starting Heat ReST API on %s:%s' % (host, port))
server = wsgi.Server()
server.start(app, cfg.CONF.heat_api, default_port=port)
+ notify.startup_notify(cfg.CONF.onready)
server.wait()
except RuntimeError as e:
sys.exit("ERROR: %s" % e)
diff --git a/bin/heat-api-cfn b/bin/heat-api-cfn
index 54bdf637f..07315f903 100755
--- a/bin/heat-api-cfn
+++ b/bin/heat-api-cfn
@@ -42,6 +42,7 @@ from oslo.config import cfg
from heat.common import config
from heat.common import wsgi
+from heat.common import notify
from heat.openstack.common import log as logging
@@ -64,6 +65,7 @@ if __name__ == '__main__':
LOG.info('Starting Heat API on %s:%s' % (host, port))
server = wsgi.Server()
server.start(app, cfg.CONF.heat_api_cfn, default_port=port)
+ notify.startup_notify(cfg.CONF.onready)
server.wait()
except RuntimeError as e:
sys.exit("ERROR: %s" % e)
diff --git a/bin/heat-api-cloudwatch b/bin/heat-api-cloudwatch
index 79feb70a9..2f3230b79 100755
--- a/bin/heat-api-cloudwatch
+++ b/bin/heat-api-cloudwatch
@@ -42,6 +42,7 @@ from oslo.config import cfg
from heat.common import config
from heat.common import wsgi
+from heat.common import notify
from heat.openstack.common import log as logging
@@ -64,6 +65,7 @@ if __name__ == '__main__':
LOG.info('Starting Heat CloudWatch API on %s:%s' % (host, port))
server = wsgi.Server()
server.start(app, cfg.CONF.heat_api_cloudwatch, default_port=port)
+ notify.startup_notify(cfg.CONF.onready)
server.wait()
except RuntimeError as e:
sys.exit("ERROR: %s" % e)
diff --git a/bin/heat-engine b/bin/heat-engine
index 185d48ee1..426d79ada 100755
--- a/bin/heat-engine
+++ b/bin/heat-engine
@@ -41,6 +41,8 @@ gettextutils.install('heat', lazy=True)
from oslo.config import cfg
+from heat.common import notify
+
from heat.openstack.common import log as logging
from heat.openstack.common import service
@@ -64,4 +66,5 @@ if __name__ == '__main__':
srv = engine.EngineService(cfg.CONF.host, rpc_api.ENGINE_TOPIC)
launcher = service.launch(srv)
+ notify.startup_notify(cfg.CONF.onready)
launcher.wait()
diff --git a/etc/heat/heat.conf.sample b/etc/heat/heat.conf.sample
index 896925ba8..7f1663c24 100644
--- a/etc/heat/heat.conf.sample
+++ b/etc/heat/heat.conf.sample
@@ -58,6 +58,14 @@
# stack locking. (integer value)
#engine_life_check_timeout=2
+# onready allows you to send a notification when the heat
+# processes are ready to serve. This is either a module with
+# the notify() method or a shell command. To enable
+# notifications with systemd, one may use the 'systemd-notify
+# --ready' shell command or the 'heat.common.systemd'
+# notification module. (string value)
+#onready=<None>
+
# Name of the engine node. This can be an opaque identifier.
# It is not necessarily a hostname, FQDN, or IP address.
# (string value)
diff --git a/heat/common/config.py b/heat/common/config.py
index 1cfb50fdd..31d348e50 100644
--- a/heat/common/config.py
+++ b/heat/common/config.py
@@ -118,7 +118,14 @@ engine_opts = [
cfg.IntOpt('engine_life_check_timeout',
default=2,
help=_('RPC timeout for the engine liveness check that is used'
- ' for stack locking.'))]
+ ' for stack locking.')),
+ cfg.StrOpt('onready',
+ help=_('onready allows you to send a notification when the'
+ ' heat processes are ready to serve. This is either a'
+ ' module with the notify() method or a shell command. '
+ ' To enable notifications with systemd, one may use'
+ ' the \'systemd-notify --ready\' shell command or'
+ ' the \'heat.common.systemd\' notification module.'))]
rpc_opts = [
cfg.StrOpt('host',
diff --git a/heat/common/notify.py b/heat/common/notify.py
new file mode 100644
index 000000000..d168482c4
--- /dev/null
+++ b/heat/common/notify.py
@@ -0,0 +1,38 @@
+# Copyright 2014 Red Hat, Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+"""
+Startup notification using a shell script or systemd NOTIFY_SOCKET
+style notification
+"""
+
+from heat.openstack.common import log as logging
+from heat.openstack.common import importutils
+from heat.openstack.common import processutils
+
+logger = logging.getLogger(__name__)
+
+
+def startup_notify(notify_param):
+ if not notify_param or notify_param == "":
+ return
+ try:
+ notifier = importutils.import_module(notify_param)
+ except ImportError:
+ try:
+ processutils.execute(notify_param, shell=True)
+ except Exception as e:
+ logger.error(_('Failed to execute onready command: %s') % str(e))
+ else:
+ notifier.notify()
diff --git a/heat/common/systemd.py b/heat/common/systemd.py
new file mode 100644
index 000000000..f094dd777
--- /dev/null
+++ b/heat/common/systemd.py
@@ -0,0 +1,44 @@
+# Copyright 2012 Red Hat, Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+"""
+Helper module for systemd start-up completion notification.
+Used for "onready" configuration parameter in heat.conf
+"""
+
+import os
+import socket
+
+from heat.openstack.common import log as logging
+
+logger = logging.getLogger(__name__)
+
+
+def _sd_notify(msg):
+ sysd = os.getenv('NOTIFY_SOCKET')
+ if sysd:
+ sock = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
+ if sysd.startswith('@'):
+ # abstract namespace socket
+ sysd = '\0%s' % sysd[1:]
+ sock.connect(sysd)
+ sock.sendall(msg)
+ sock.close()
+ else:
+ logger.warning(_('Unable to notify systemd of startup completion:'
+ ' NOTIFY_SOCKET not set'))
+
+
+def notify():
+ _sd_notify('READY=1')