Merge lp:~brad-marshall/charms/trusty/cinder/add-nrpe-checks into lp:~openstack-charmers-archive/charms/trusty/cinder/trunk

Proposed by Brad Marshall
Status: Merged
Merged at revision: 67
Proposed branch: lp:~brad-marshall/charms/trusty/cinder/add-nrpe-checks
Merge into: lp:~openstack-charmers-archive/charms/trusty/cinder/trunk
Diff against target: 537 lines (+448/-0)
6 files modified
charm-helpers-hooks.yaml (+1/-0)
config.yaml (+11/-0)
hooks/charmhelpers/contrib/charmsupport/nrpe.py (+222/-0)
hooks/charmhelpers/contrib/charmsupport/volumes.py (+156/-0)
hooks/cinder_hooks.py (+55/-0)
metadata.yaml (+3/-0)
To merge this branch: bzr merge lp:~brad-marshall/charms/trusty/cinder/add-nrpe-checks
Reviewer Review Type Date Requested Status
Liam Young (community) Disapprove
Review via email: mp+241495@code.launchpad.net

Description of the change

Adds nrpe-external-master interface and adds basic nrpe checks.

To post a comment you must log in.
Revision history for this message
Ryan Beisner (1chb1n) wrote :

UOSCI bot says:
charm_lint_check #990 trusty-cinder for brad-marshall mp241495
    LINT FAIL: lint-test failed

LINT Results (max last 5 lines):
ERROR:root:Make target returned non-zero.
  hooks/cinder_hooks.py:416:80: E501 line too long (92 > 79 characters)
  hooks/cinder_hooks.py:443:22: E251 unexpected spaces around keyword / parameter equals
  hooks/cinder_hooks.py:443:24: E251 unexpected spaces around keyword / parameter equals
  make: *** [lint] Error 1

Full lint test output: http://paste.ubuntu.com/8955747/
Build: http://10.98.191.181:8080/job/charm_lint_check/990/

Revision history for this message
Ryan Beisner (1chb1n) wrote :

UOSCI bot says:
charm_unit_test #825 trusty-cinder for brad-marshall mp241495
    UNIT FAIL: unit-test failed

UNIT Results (max last 5 lines):
  hooks/cinder_utils 173 14 92% 191, 410-415, 452-464
  TOTAL 439 39 91%
  Ran 86 tests in 6.013s
  FAILED (errors=5)
  make: *** [unit_test] Error 1

Full unit test output: http://paste.ubuntu.com/8955751/
Build: http://10.98.191.181:8080/job/charm_unit_test/825/

Revision history for this message
Ryan Beisner (1chb1n) wrote :

UOSCI bot says:
charm_amulet_test #370 trusty-cinder for brad-marshall mp241495
    AMULET FAIL: amulet-test failed

AMULET Results (max last 5 lines):
  juju-test.conductor DEBUG : Calling "juju destroy-environment -y osci-sv03"
  WARNING cannot delete security group "juju-osci-sv03-0". Used by another environment?
  juju-test INFO : Results: 1 passed, 2 failed, 0 errored
  ERROR subprocess encountered error code 2
  make: *** [test] Error 2

Full amulet test output: http://paste.ubuntu.com/8955878/
Build: http://10.98.191.181:8080/job/charm_amulet_test/370/

62. By Brad Marshall

[brad] Fixes from pep8 run, change to using services() function for services to monitor, add sysvinit style daemon monitoring

Revision history for this message
uosci-testing-bot (uosci-testing-bot) wrote :

UOSCI bot says:
charm_lint_check #1082 trusty-cinder for brad-marshall mp241495
    LINT OK: passed

LINT Results (max last 5 lines):
  I: config.yaml: option ssl_ca has no default value
  I: config.yaml: option config-flags has no default value
  I: config.yaml: option ssl_cert has no default value
  I: config.yaml: option os-internal-network has no default value
  I: config.yaml: option os-public-network has no default value

Full lint test output: http://paste.ubuntu.com/9051424/
Build: http://10.98.191.181:8080/job/charm_lint_check/1082/

Revision history for this message
uosci-testing-bot (uosci-testing-bot) wrote :

UOSCI bot says:
charm_unit_test #916 trusty-cinder for brad-marshall mp241495
    UNIT FAIL: unit-test failed

UNIT Results (max last 5 lines):
  hooks/cinder_utils 173 14 92% 191, 410-415, 452-464
  TOTAL 450 51 89%
  Ran 86 tests in 6.211s
  FAILED (errors=5)
  make: *** [unit_test] Error 1

Full unit test output: http://paste.ubuntu.com/9051430/
Build: http://10.98.191.181:8080/job/charm_unit_test/916/

Revision history for this message
uosci-testing-bot (uosci-testing-bot) wrote :

UOSCI bot says:
charm_amulet_test #424 trusty-cinder for brad-marshall mp241495
    AMULET FAIL: amulet-test failed

AMULET Results (max last 5 lines):
  juju-test.conductor DEBUG : Tearing down osci-sv05 juju environment
  juju-test.conductor DEBUG : Calling "juju destroy-environment -y osci-sv05"
  juju-test INFO : Results: 1 passed, 2 failed, 0 errored
  ERROR subprocess encountered error code 2
  make: *** [test] Error 2

Full amulet test output: http://paste.ubuntu.com/9051446/
Build: http://10.98.191.181:8080/job/charm_amulet_test/424/

63. By Brad Marshall

[bradm] Add missing nrpe files

Revision history for this message
uosci-testing-bot (uosci-testing-bot) wrote :

UOSCI bot says:
charm_lint_check #1102 trusty-cinder for brad-marshall mp241495
    LINT OK: passed

LINT Results (max last 5 lines):
  I: config.yaml: option ssl_ca has no default value
  I: config.yaml: option config-flags has no default value
  I: config.yaml: option ssl_cert has no default value
  I: config.yaml: option os-internal-network has no default value
  I: config.yaml: option os-public-network has no default value

Full lint test output: http://paste.ubuntu.com/9053007/
Build: http://10.98.191.181:8080/job/charm_lint_check/1102/

Revision history for this message
uosci-testing-bot (uosci-testing-bot) wrote :

UOSCI bot says:
charm_unit_test #936 trusty-cinder for brad-marshall mp241495
    UNIT FAIL: unit-test failed

UNIT Results (max last 5 lines):
  hooks/cinder_utils 173 14 92% 191, 410-415, 452-464
  TOTAL 450 51 89%
  Ran 86 tests in 6.226s
  FAILED (errors=5)
  make: *** [unit_test] Error 1

Full unit test output: http://paste.ubuntu.com/9053008/
Build: http://10.98.191.181:8080/job/charm_unit_test/936/

Revision history for this message
uosci-testing-bot (uosci-testing-bot) wrote :

UOSCI bot says:
charm_amulet_test #444 trusty-cinder for brad-marshall mp241495
    AMULET FAIL: amulet-test failed

AMULET Results (max last 5 lines):
  juju-test.conductor DEBUG : Calling "juju destroy-environment -y osci-sv05"
  WARNING cannot delete security group "juju-osci-sv05-0". Used by another environment?
  juju-test INFO : Results: 1 passed, 2 failed, 0 errored
  ERROR subprocess encountered error code 2
  make: *** [test] Error 2

Full amulet test output: http://paste.ubuntu.com/9053064/
Build: http://10.98.191.181:8080/job/charm_amulet_test/444/

64. By Brad Marshall

[bradm] Removed nagios check files that were moved to nrpe-external-master charm

Revision history for this message
uosci-testing-bot (uosci-testing-bot) wrote :

UOSCI bot says:
charm_lint_check #1118 trusty-cinder for brad-marshall mp241495
    LINT OK: passed

LINT Results (max last 5 lines):
  I: config.yaml: option ssl_ca has no default value
  I: config.yaml: option config-flags has no default value
  I: config.yaml: option ssl_cert has no default value
  I: config.yaml: option os-internal-network has no default value
  I: config.yaml: option os-public-network has no default value

Full lint test output: http://paste.ubuntu.com/9063913/
Build: http://10.98.191.181:8080/job/charm_lint_check/1118/

Revision history for this message
uosci-testing-bot (uosci-testing-bot) wrote :

UOSCI bot says:
charm_unit_test #952 trusty-cinder for brad-marshall mp241495
    UNIT FAIL: unit-test failed

UNIT Results (max last 5 lines):
  hooks/cinder_utils 173 14 92% 191, 410-415, 452-464
  TOTAL 449 50 89%
  Ran 86 tests in 5.809s
  FAILED (errors=5)
  make: *** [unit_test] Error 1

Full unit test output: http://paste.ubuntu.com/9063919/
Build: http://10.98.191.181:8080/job/charm_unit_test/952/

Revision history for this message
uosci-testing-bot (uosci-testing-bot) wrote :

UOSCI bot says:
charm_amulet_test #460 trusty-cinder for brad-marshall mp241495
    AMULET FAIL: amulet-test failed

AMULET Results (max last 5 lines):
  juju-test.conductor DEBUG : Calling "juju destroy-environment -y osci-sv11"
  WARNING cannot delete security group "juju-osci-sv11-0". Used by another environment?
  juju-test INFO : Results: 1 passed, 2 failed, 0 errored
  ERROR subprocess encountered error code 2
  make: *** [test] Error 2

Full amulet test output: http://paste.ubuntu.com/9064054/
Build: http://10.98.191.181:8080/job/charm_amulet_test/460/

Revision history for this message
uosci-testing-bot (uosci-testing-bot) wrote :

UOSCI bot says:
charm_lint_check #1252 trusty-cinder for brad-marshall mp241495
    LINT OK: passed

LINT Results (max last 5 lines):
  I: config.yaml: option ssl_ca has no default value
  I: config.yaml: option config-flags has no default value
  I: config.yaml: option ssl_cert has no default value
  I: config.yaml: option os-internal-network has no default value
  I: config.yaml: option os-public-network has no default value

Full lint test output: http://paste.ubuntu.com/9281314/
Build: http://10.98.191.181:8080/job/charm_lint_check/1252/

Revision history for this message
uosci-testing-bot (uosci-testing-bot) wrote :

UOSCI bot says:
charm_unit_test #1086 trusty-cinder for brad-marshall mp241495
    UNIT FAIL: unit-test failed

UNIT Results (max last 5 lines):
  hooks/cinder_utils 173 14 92% 191, 410-415, 452-464
  TOTAL 449 50 89%
  Ran 86 tests in 7.340s
  FAILED (errors=5)
  make: *** [unit_test] Error 1

Full unit test output: http://paste.ubuntu.com/9281316/
Build: http://10.98.191.181:8080/job/charm_unit_test/1086/

Revision history for this message
uosci-testing-bot (uosci-testing-bot) wrote :

UOSCI bot says:
charm_amulet_test #555 trusty-cinder for brad-marshall mp241495
    AMULET FAIL: amulet-test failed

AMULET Results (max last 5 lines):
  juju-test.conductor DEBUG : Calling "juju destroy-environment -y osci-sv11"
  WARNING cannot delete security group "juju-osci-sv11-0". Used by another environment?
  juju-test INFO : Results: 1 passed, 2 failed, 0 errored
  ERROR subprocess encountered error code 2
  make: *** [test] Error 2

Full amulet test output: http://paste.ubuntu.com/9281433/
Build: http://10.98.191.181:8080/job/charm_amulet_test/555/

Revision history for this message
Liam Young (gnuoy) wrote :

Thank for the mp. The new nrpe support is very gratefully received !

I've taken this branch and centralised the common code between this and the other nrpe branches and moved it to charm-helpers. To land it I created a new branch from this one which has now been merged into the 'next' charm. The 'next' charms will overwrite the stable ones in a couple of weeks.

review: Disapprove

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'charm-helpers-hooks.yaml'
2--- charm-helpers-hooks.yaml 2014-10-06 21:50:53 +0000
3+++ charm-helpers-hooks.yaml 2014-11-18 01:05:07 +0000
4@@ -11,3 +11,4 @@
5 - fetch
6 - payload.execd
7 - contrib.network.ip
8+ - contrib.charmsupport
9
10=== modified file 'config.yaml'
11--- config.yaml 2014-10-14 15:59:34 +0000
12+++ config.yaml 2014-11-18 01:05:07 +0000
13@@ -198,3 +198,14 @@
14 The CPU core multiplier to use when configuring worker processes for
15 Cinder. By default, the number of workers for each daemon is set to
16 twice the number of CPU cores a service unit has.
17+ nagios_context:
18+ default: "juju"
19+ type: string
20+ description: |
21+ Used by the nrpe-external-master subordinate charm.
22+ A string that will be prepended to instance name to set the host name
23+ in nagios. So for instance the hostname would be something like:
24+ juju-myservice-0
25+ If you're running multiple environments with the same services in them
26+ this allows you to differentiate between them.
27+
28
29=== added directory 'files'
30=== added directory 'hooks/charmhelpers/contrib/charmsupport'
31=== added file 'hooks/charmhelpers/contrib/charmsupport/__init__.py'
32=== added file 'hooks/charmhelpers/contrib/charmsupport/nrpe.py'
33--- hooks/charmhelpers/contrib/charmsupport/nrpe.py 1970-01-01 00:00:00 +0000
34+++ hooks/charmhelpers/contrib/charmsupport/nrpe.py 2014-11-18 01:05:07 +0000
35@@ -0,0 +1,222 @@
36+"""Compatibility with the nrpe-external-master charm"""
37+# Copyright 2012 Canonical Ltd.
38+#
39+# Authors:
40+# Matthew Wedgwood <matthew.wedgwood@canonical.com>
41+
42+import subprocess
43+import pwd
44+import grp
45+import os
46+import re
47+import shlex
48+import yaml
49+
50+from charmhelpers.core.hookenv import (
51+ config,
52+ local_unit,
53+ log,
54+ relation_ids,
55+ relation_set,
56+)
57+
58+from charmhelpers.core.host import service
59+
60+# This module adds compatibility with the nrpe-external-master and plain nrpe
61+# subordinate charms. To use it in your charm:
62+#
63+# 1. Update metadata.yaml
64+#
65+# provides:
66+# (...)
67+# nrpe-external-master:
68+# interface: nrpe-external-master
69+# scope: container
70+#
71+# and/or
72+#
73+# provides:
74+# (...)
75+# local-monitors:
76+# interface: local-monitors
77+# scope: container
78+
79+#
80+# 2. Add the following to config.yaml
81+#
82+# nagios_context:
83+# default: "juju"
84+# type: string
85+# description: |
86+# Used by the nrpe subordinate charms.
87+# A string that will be prepended to instance name to set the host name
88+# in nagios. So for instance the hostname would be something like:
89+# juju-myservice-0
90+# If you're running multiple environments with the same services in them
91+# this allows you to differentiate between them.
92+#
93+# 3. Add custom checks (Nagios plugins) to files/nrpe-external-master
94+#
95+# 4. Update your hooks.py with something like this:
96+#
97+# from charmsupport.nrpe import NRPE
98+# (...)
99+# def update_nrpe_config():
100+# nrpe_compat = NRPE()
101+# nrpe_compat.add_check(
102+# shortname = "myservice",
103+# description = "Check MyService",
104+# check_cmd = "check_http -w 2 -c 10 http://localhost"
105+# )
106+# nrpe_compat.add_check(
107+# "myservice_other",
108+# "Check for widget failures",
109+# check_cmd = "/srv/myapp/scripts/widget_check"
110+# )
111+# nrpe_compat.write()
112+#
113+# def config_changed():
114+# (...)
115+# update_nrpe_config()
116+#
117+# def nrpe_external_master_relation_changed():
118+# update_nrpe_config()
119+#
120+# def local_monitors_relation_changed():
121+# update_nrpe_config()
122+#
123+# 5. ln -s hooks.py nrpe-external-master-relation-changed
124+# ln -s hooks.py local-monitors-relation-changed
125+
126+
127+class CheckException(Exception):
128+ pass
129+
130+
131+class Check(object):
132+ shortname_re = '[A-Za-z0-9-_]+$'
133+ service_template = ("""
134+#---------------------------------------------------
135+# This file is Juju managed
136+#---------------------------------------------------
137+define service {{
138+ use active-service
139+ host_name {nagios_hostname}
140+ service_description {nagios_hostname}[{shortname}] """
141+ """{description}
142+ check_command check_nrpe!{command}
143+ servicegroups {nagios_servicegroup}
144+}}
145+""")
146+
147+ def __init__(self, shortname, description, check_cmd):
148+ super(Check, self).__init__()
149+ # XXX: could be better to calculate this from the service name
150+ if not re.match(self.shortname_re, shortname):
151+ raise CheckException("shortname must match {}".format(
152+ Check.shortname_re))
153+ self.shortname = shortname
154+ self.command = "check_{}".format(shortname)
155+ # Note: a set of invalid characters is defined by the
156+ # Nagios server config
157+ # The default is: illegal_object_name_chars=`~!$%^&*"|'<>?,()=
158+ self.description = description
159+ self.check_cmd = self._locate_cmd(check_cmd)
160+
161+ def _locate_cmd(self, check_cmd):
162+ search_path = (
163+ '/',
164+ os.path.join(os.environ['CHARM_DIR'],
165+ 'files/nrpe-external-master'),
166+ '/usr/lib/nagios/plugins',
167+ '/usr/local/lib/nagios/plugins',
168+ )
169+ parts = shlex.split(check_cmd)
170+ for path in search_path:
171+ if os.path.exists(os.path.join(path, parts[0])):
172+ command = os.path.join(path, parts[0])
173+ if len(parts) > 1:
174+ command += " " + " ".join(parts[1:])
175+ return command
176+ log('Check command not found: {}'.format(parts[0]))
177+ return ''
178+
179+ def write(self, nagios_context, hostname):
180+ nrpe_check_file = '/etc/nagios/nrpe.d/{}.cfg'.format(
181+ self.command)
182+ with open(nrpe_check_file, 'w') as nrpe_check_config:
183+ nrpe_check_config.write("# check {}\n".format(self.shortname))
184+ nrpe_check_config.write("command[{}]={}\n".format(
185+ self.command, self.check_cmd))
186+
187+ if not os.path.exists(NRPE.nagios_exportdir):
188+ log('Not writing service config as {} is not accessible'.format(
189+ NRPE.nagios_exportdir))
190+ else:
191+ self.write_service_config(nagios_context, hostname)
192+
193+ def write_service_config(self, nagios_context, hostname):
194+ for f in os.listdir(NRPE.nagios_exportdir):
195+ if re.search('.*{}.cfg'.format(self.command), f):
196+ os.remove(os.path.join(NRPE.nagios_exportdir, f))
197+
198+ templ_vars = {
199+ 'nagios_hostname': hostname,
200+ 'nagios_servicegroup': nagios_context,
201+ 'description': self.description,
202+ 'shortname': self.shortname,
203+ 'command': self.command,
204+ }
205+ nrpe_service_text = Check.service_template.format(**templ_vars)
206+ nrpe_service_file = '{}/service__{}_{}.cfg'.format(
207+ NRPE.nagios_exportdir, hostname, self.command)
208+ with open(nrpe_service_file, 'w') as nrpe_service_config:
209+ nrpe_service_config.write(str(nrpe_service_text))
210+
211+ def run(self):
212+ subprocess.call(self.check_cmd)
213+
214+
215+class NRPE(object):
216+ nagios_logdir = '/var/log/nagios'
217+ nagios_exportdir = '/var/lib/nagios/export'
218+ nrpe_confdir = '/etc/nagios/nrpe.d'
219+
220+ def __init__(self, hostname=None):
221+ super(NRPE, self).__init__()
222+ self.config = config()
223+ self.nagios_context = self.config['nagios_context']
224+ self.unit_name = local_unit().replace('/', '-')
225+ if hostname:
226+ self.hostname = hostname
227+ else:
228+ self.hostname = "{}-{}".format(self.nagios_context, self.unit_name)
229+ self.checks = []
230+
231+ def add_check(self, *args, **kwargs):
232+ self.checks.append(Check(*args, **kwargs))
233+
234+ def write(self):
235+ try:
236+ nagios_uid = pwd.getpwnam('nagios').pw_uid
237+ nagios_gid = grp.getgrnam('nagios').gr_gid
238+ except:
239+ log("Nagios user not set up, nrpe checks not updated")
240+ return
241+
242+ if not os.path.exists(NRPE.nagios_logdir):
243+ os.mkdir(NRPE.nagios_logdir)
244+ os.chown(NRPE.nagios_logdir, nagios_uid, nagios_gid)
245+
246+ nrpe_monitors = {}
247+ monitors = {"monitors": {"remote": {"nrpe": nrpe_monitors}}}
248+ for nrpecheck in self.checks:
249+ nrpecheck.write(self.nagios_context, self.hostname)
250+ nrpe_monitors[nrpecheck.shortname] = {
251+ "command": nrpecheck.command,
252+ }
253+
254+ service('restart', 'nagios-nrpe-server')
255+
256+ for rid in relation_ids("local-monitors"):
257+ relation_set(relation_id=rid, monitors=yaml.dump(monitors))
258
259=== added file 'hooks/charmhelpers/contrib/charmsupport/volumes.py'
260--- hooks/charmhelpers/contrib/charmsupport/volumes.py 1970-01-01 00:00:00 +0000
261+++ hooks/charmhelpers/contrib/charmsupport/volumes.py 2014-11-18 01:05:07 +0000
262@@ -0,0 +1,156 @@
263+'''
264+Functions for managing volumes in juju units. One volume is supported per unit.
265+Subordinates may have their own storage, provided it is on its own partition.
266+
267+Configuration stanzas:
268+ volume-ephemeral:
269+ type: boolean
270+ default: true
271+ description: >
272+ If false, a volume is mounted as sepecified in "volume-map"
273+ If true, ephemeral storage will be used, meaning that log data
274+ will only exist as long as the machine. YOU HAVE BEEN WARNED.
275+ volume-map:
276+ type: string
277+ default: {}
278+ description: >
279+ YAML map of units to device names, e.g:
280+ "{ rsyslog/0: /dev/vdb, rsyslog/1: /dev/vdb }"
281+ Service units will raise a configure-error if volume-ephemeral
282+ is 'true' and no volume-map value is set. Use 'juju set' to set a
283+ value and 'juju resolved' to complete configuration.
284+
285+Usage:
286+ from charmsupport.volumes import configure_volume, VolumeConfigurationError
287+ from charmsupport.hookenv import log, ERROR
288+ def post_mount_hook():
289+ stop_service('myservice')
290+ def post_mount_hook():
291+ start_service('myservice')
292+
293+ if __name__ == '__main__':
294+ try:
295+ configure_volume(before_change=pre_mount_hook,
296+ after_change=post_mount_hook)
297+ except VolumeConfigurationError:
298+ log('Storage could not be configured', ERROR)
299+'''
300+
301+# XXX: Known limitations
302+# - fstab is neither consulted nor updated
303+
304+import os
305+from charmhelpers.core import hookenv
306+from charmhelpers.core import host
307+import yaml
308+
309+
310+MOUNT_BASE = '/srv/juju/volumes'
311+
312+
313+class VolumeConfigurationError(Exception):
314+ '''Volume configuration data is missing or invalid'''
315+ pass
316+
317+
318+def get_config():
319+ '''Gather and sanity-check volume configuration data'''
320+ volume_config = {}
321+ config = hookenv.config()
322+
323+ errors = False
324+
325+ if config.get('volume-ephemeral') in (True, 'True', 'true', 'Yes', 'yes'):
326+ volume_config['ephemeral'] = True
327+ else:
328+ volume_config['ephemeral'] = False
329+
330+ try:
331+ volume_map = yaml.safe_load(config.get('volume-map', '{}'))
332+ except yaml.YAMLError as e:
333+ hookenv.log("Error parsing YAML volume-map: {}".format(e),
334+ hookenv.ERROR)
335+ errors = True
336+ if volume_map is None:
337+ # probably an empty string
338+ volume_map = {}
339+ elif not isinstance(volume_map, dict):
340+ hookenv.log("Volume-map should be a dictionary, not {}".format(
341+ type(volume_map)))
342+ errors = True
343+
344+ volume_config['device'] = volume_map.get(os.environ['JUJU_UNIT_NAME'])
345+ if volume_config['device'] and volume_config['ephemeral']:
346+ # asked for ephemeral storage but also defined a volume ID
347+ hookenv.log('A volume is defined for this unit, but ephemeral '
348+ 'storage was requested', hookenv.ERROR)
349+ errors = True
350+ elif not volume_config['device'] and not volume_config['ephemeral']:
351+ # asked for permanent storage but did not define volume ID
352+ hookenv.log('Ephemeral storage was requested, but there is no volume '
353+ 'defined for this unit.', hookenv.ERROR)
354+ errors = True
355+
356+ unit_mount_name = hookenv.local_unit().replace('/', '-')
357+ volume_config['mountpoint'] = os.path.join(MOUNT_BASE, unit_mount_name)
358+
359+ if errors:
360+ return None
361+ return volume_config
362+
363+
364+def mount_volume(config):
365+ if os.path.exists(config['mountpoint']):
366+ if not os.path.isdir(config['mountpoint']):
367+ hookenv.log('Not a directory: {}'.format(config['mountpoint']))
368+ raise VolumeConfigurationError()
369+ else:
370+ host.mkdir(config['mountpoint'])
371+ if os.path.ismount(config['mountpoint']):
372+ unmount_volume(config)
373+ if not host.mount(config['device'], config['mountpoint'], persist=True):
374+ raise VolumeConfigurationError()
375+
376+
377+def unmount_volume(config):
378+ if os.path.ismount(config['mountpoint']):
379+ if not host.umount(config['mountpoint'], persist=True):
380+ raise VolumeConfigurationError()
381+
382+
383+def managed_mounts():
384+ '''List of all mounted managed volumes'''
385+ return filter(lambda mount: mount[0].startswith(MOUNT_BASE), host.mounts())
386+
387+
388+def configure_volume(before_change=lambda: None, after_change=lambda: None):
389+ '''Set up storage (or don't) according to the charm's volume configuration.
390+ Returns the mount point or "ephemeral". before_change and after_change
391+ are optional functions to be called if the volume configuration changes.
392+ '''
393+
394+ config = get_config()
395+ if not config:
396+ hookenv.log('Failed to read volume configuration', hookenv.CRITICAL)
397+ raise VolumeConfigurationError()
398+
399+ if config['ephemeral']:
400+ if os.path.ismount(config['mountpoint']):
401+ before_change()
402+ unmount_volume(config)
403+ after_change()
404+ return 'ephemeral'
405+ else:
406+ # persistent storage
407+ if os.path.ismount(config['mountpoint']):
408+ mounts = dict(managed_mounts())
409+ if mounts.get(config['mountpoint']) != config['device']:
410+ before_change()
411+ unmount_volume(config)
412+ mount_volume(config)
413+ after_change()
414+ else:
415+ before_change()
416+ mount_volume(config)
417+ after_change()
418+ return config['mountpoint']
419
420=== modified file 'hooks/cinder_hooks.py'
421--- hooks/cinder_hooks.py 2014-10-09 19:51:49 +0000
422+++ hooks/cinder_hooks.py 2014-11-18 01:05:07 +0000
423@@ -15,6 +15,7 @@
424 configure_lvm_storage,
425 register_configs,
426 restart_map,
427+ services,
428 service_enabled,
429 set_ceph_env_variables,
430 CLUSTER_RES,
431@@ -33,6 +34,7 @@
432 relation_get,
433 relation_ids,
434 relation_set,
435+ relations_of_type,
436 service_name,
437 unit_get,
438 log,
439@@ -72,6 +74,8 @@
440 )
441 from charmhelpers.contrib.openstack.context import ADDRESS_TYPES
442
443+from charmhelpers.contrib.charmsupport.nrpe import NRPE
444+
445 hooks = Hooks()
446
447 CONFIGS = register_configs()
448@@ -117,6 +121,7 @@
449
450 CONFIGS.write_all()
451 configure_https()
452+ update_nrpe_config()
453
454 for rid in relation_ids('cluster'):
455 cluster_joined(relation_id=rid)
456@@ -399,6 +404,7 @@
457 def upgrade_charm():
458 for rel_id in relation_ids('amqp'):
459 amqp_joined(relation_id=rel_id)
460+ update_nrpe_config()
461
462
463 @hooks.hook('storage-backend-relation-changed')
464@@ -408,6 +414,55 @@
465 CONFIGS.write(CINDER_CONF)
466
467
468+@hooks.hook('nrpe-external-master-relation-joined',
469+ 'nrpe-external-master-relation-changed')
470+def update_nrpe_config():
471+ # Find out if nrpe set nagios_hostname
472+ hostname = None
473+ host_context = None
474+ for rel in relations_of_type('nrpe-external-master'):
475+ if 'nagios_hostname' in rel:
476+ hostname = rel['nagios_hostname']
477+ host_context = rel['nagios_host_context']
478+ break
479+ nrpe = NRPE(hostname=hostname)
480+ apt_install('python-dbus')
481+
482+ if host_context:
483+ current_unit = "%s:%s" % (host_context, local_unit())
484+ else:
485+ current_unit = local_unit()
486+
487+ services_to_monitor = services()
488+
489+ for service in services_to_monitor:
490+ upstart_init = '/etc/init/%s.conf' % service
491+ sysv_init = '/etc/init.d/%s' % service
492+
493+ if os.path.exists(upstart_init):
494+ nrpe.add_check(
495+ shortname=service,
496+ description='process check {%s}' % current_unit,
497+ check_cmd='check_upstart_job %s' % service,
498+ )
499+ elif os.path.exists(sysv_init):
500+ cronpath = '/etc/cron.d/nagios-service-check-%s' % service
501+ cron_template = '*/5 * * * * root \
502+/usr/local/lib/nagios/plugins/check_exit_status.pl -s /etc/init.d/%s \
503+status > /var/lib/nagios/service-check-%s.txt\n' % (service, service)
504+ f = open(cronpath, 'w')
505+ f.write(cron_template)
506+ f.close()
507+ nrpe.add_check(
508+ shortname=service,
509+ description='process check {%s}' % current_unit,
510+ check_cmd='check_status_file.py \
511+ -f /var/lib/nagios/service-check-%s.txt' % service,
512+ )
513+
514+ nrpe.write()
515+
516+
517 if __name__ == '__main__':
518 try:
519 hooks.execute(sys.argv)
520
521=== added symlink 'hooks/nrpe-external-master-relation-changed'
522=== target is u'cinder_hooks.py'
523=== added symlink 'hooks/nrpe-external-master-relation-joined'
524=== target is u'cinder_hooks.py'
525=== modified file 'metadata.yaml'
526--- metadata.yaml 2014-04-02 07:58:11 +0000
527+++ metadata.yaml 2014-11-18 01:05:07 +0000
528@@ -6,6 +6,9 @@
529 categories:
530 - miscellaneous
531 provides:
532+ nrpe-external-master:
533+ interface: nrpe-external-master
534+ scope: container
535 cinder-volume-service:
536 interface: cinder
537 requires:

Subscribers

People subscribed via source and target branches