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

Proposed by Brad Marshall
Status: Merged
Merged at revision: 76
Proposed branch: lp:~brad-marshall/charms/trusty/swift-proxy/add-nrpe-checks
Merge into: lp:~openstack-charmers-archive/charms/trusty/swift-proxy/trunk
Diff against target: 559 lines (+462/-0) (has conflicts)
7 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/swift_hooks.py (+61/-0)
hooks/swift_utils.py (+8/-0)
metadata.yaml (+3/-0)
Text conflict in hooks/swift_hooks.py
To merge this branch: bzr merge lp:~brad-marshall/charms/trusty/swift-proxy/add-nrpe-checks
Reviewer Review Type Date Requested Status
Liam Young (community) Disapprove
Review via email: mp+241484@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_unit_test #822 trusty-swift-proxy for brad-marshall mp241484
    UNIT OK: passed

UNIT Results (max last 5 lines):
  hooks/swift_hooks 190 190 0% 3-388
  hooks/swift_utils 189 189 0% 1-393
  TOTAL 464 464 0%
  Ran 5 tests in 0.179s
  OK

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

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

UOSCI bot says:
charm_lint_check #987 trusty-swift-proxy for brad-marshall mp241484
    LINT FAIL: lint-test failed

LINT Results (max last 5 lines):
  hooks/swift_hooks.py:357:80: E501 line too long (92 > 79 characters)
  hooks/swift_hooks.py:378:18: E251 unexpected spaces around keyword / parameter equals
  hooks/swift_hooks.py:378:20: E251 unexpected spaces around keyword / parameter equals
  hooks/swift_hooks.py:379:9: E123 closing bracket does not match indentation of opening bracket's line
  make: *** [lint] Error 1

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

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

UOSCI bot says:
charm_amulet_test #367 trusty-swift-proxy for brad-marshall mp241484
    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/8955846/
Build: http://10.98.191.181:8080/job/charm_amulet_test/367/

72. By Brad Marshall

[bradm] Added sysvinit daemon monitoring, use services() instead of hard coded daemon list, pep8 fixes

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

UOSCI bot says:
charm_lint_check #1084 trusty-swift-proxy for brad-marshall mp241484
    LINT FAIL: lint-test failed

LINT Results (max last 5 lines):
INFO:root:command: make -f Makefile lint
ERROR:root:Make target returned non-zero.
  hooks/swift_hooks.py:387:17: E123 closing bracket does not match indentation of opening bracket's line
  hooks/swift_hooks.py:404:17: E123 closing bracket does not match indentation of opening bracket's line
  make: *** [lint] Error 1

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

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

UOSCI bot says:
charm_unit_test #918 trusty-swift-proxy for brad-marshall mp241484
    UNIT OK: passed

UNIT Results (max last 5 lines):
  hooks/swift_hooks 203 203 0% 3-413
  hooks/swift_utils 194 194 0% 1-401
  TOTAL 482 482 0%
  Ran 5 tests in 0.190s
  OK

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

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

UOSCI bot says:
charm_amulet_test #426 trusty-swift-proxy for brad-marshall mp241484
    AMULET FAIL: amulet-test failed

AMULET Results (max last 5 lines):
  juju-test.conductor DEBUG : Tearing down osci-sv07 juju environment
  juju-test.conductor DEBUG : Calling "juju destroy-environment -y osci-sv07"
  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/9052216/
Build: http://10.98.191.181:8080/job/charm_amulet_test/426/

73. By Brad Marshall

[bradm] Removed puppet header from nagios_plugin module

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

UOSCI bot says:
charm_lint_check #1096 trusty-swift-proxy for brad-marshall mp241484
    LINT FAIL: lint-test failed

LINT Results (max last 5 lines):
INFO:root:command: make -f Makefile lint
ERROR:root:Make target returned non-zero.
  hooks/swift_hooks.py:387:17: E123 closing bracket does not match indentation of opening bracket's line
  hooks/swift_hooks.py:404:17: E123 closing bracket does not match indentation of opening bracket's line
  make: *** [lint] Error 1

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

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

UOSCI bot says:
charm_unit_test #930 trusty-swift-proxy for brad-marshall mp241484
    UNIT OK: passed

UNIT Results (max last 5 lines):
  hooks/swift_hooks 203 203 0% 3-413
  hooks/swift_utils 194 194 0% 1-401
  TOTAL 482 482 0%
  Ran 5 tests in 0.224s
  OK

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

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

UOSCI bot says:
charm_amulet_test #438 trusty-swift-proxy for brad-marshall mp241484
    AMULET FAIL: amulet-test failed

AMULET Results (max last 5 lines):
  juju-test.conductor DEBUG : Calling "juju destroy-environment -y osci-sv07"
  WARNING cannot delete security group "juju-osci-sv07-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/9053031/
Build: http://10.98.191.181:8080/job/charm_amulet_test/438/

74. 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 #1112 trusty-swift-proxy for brad-marshall mp241484
    LINT FAIL: lint-test failed

LINT Results (max last 5 lines):
ERROR:root:Make target returned non-zero.
  hooks/swift_hooks.py:387:17: E123 closing bracket does not match indentation of opening bracket's line
  hooks/swift_hooks.py:390:13: F841 local variable 'checkpath' is assigned to but never used
  hooks/swift_hooks.py:404:17: E123 closing bracket does not match indentation of opening bracket's line
  make: *** [lint] Error 1

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

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

UOSCI bot says:
charm_unit_test #946 trusty-swift-proxy for brad-marshall mp241484
    UNIT OK: passed

UNIT Results (max last 5 lines):
  hooks/swift_hooks 203 203 0% 3-413
  hooks/swift_utils 194 194 0% 1-401
  TOTAL 482 482 0%
  Ran 5 tests in 0.200s
  OK

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

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

UOSCI bot says:
charm_amulet_test #454 trusty-swift-proxy for brad-marshall mp241484
    AMULET FAIL: amulet-test failed

AMULET Results (max last 5 lines):
  juju-test.conductor DEBUG : Calling "juju destroy-environment -y osci-sv07"
  WARNING cannot delete security group "juju-osci-sv07-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/9063932/
Build: http://10.98.191.181:8080/job/charm_amulet_test/454/

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

UOSCI bot says:
charm_lint_check #1242 trusty-swift-proxy for brad-marshall mp241484
    LINT FAIL: lint-test failed

LINT Results (max last 5 lines):
ERROR:root:Make target returned non-zero.
  hooks/swift_hooks.py:387:17: E123 closing bracket does not match indentation of opening bracket's line
  hooks/swift_hooks.py:390:13: F841 local variable 'checkpath' is assigned to but never used
  hooks/swift_hooks.py:404:17: E123 closing bracket does not match indentation of opening bracket's line
  make: *** [lint] Error 1

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

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

UOSCI bot says:
charm_unit_test #1076 trusty-swift-proxy for brad-marshall mp241484
    UNIT OK: passed

UNIT Results (max last 5 lines):
  hooks/swift_hooks 203 203 0% 3-413
  hooks/swift_utils 194 194 0% 1-401
  TOTAL 482 482 0%
  Ran 5 tests in 0.160s
  OK

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

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

UOSCI bot says:
charm_amulet_test #545 trusty-swift-proxy for brad-marshall mp241484
    AMULET FAIL: amulet-test failed

AMULET Results (max last 5 lines):
  WARNING cannot delete security group "juju-osci-sv11". Used by another environment?
  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/9281343/
Build: http://10.98.191.181:8080/job/charm_amulet_test/545/

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

Thanks for this branch. I've taken it and fixed up a few minor bits and proposed it against the 'next' branch. It has now landed into 'next' and will promulgate to staging at the end of the month as part of the 15.01 openstack charm release.

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-02 09:28:13 +0000
3+++ charm-helpers-hooks.yaml 2014-11-18 01:29:44 +0000
4@@ -11,3 +11,4 @@
5 - payload.execd
6 - contrib.network.ip
7 - contrib.peerstorage
8+ - contrib.charmsupport
9
10=== modified file 'config.yaml'
11--- config.yaml 2014-10-02 20:31:24 +0000
12+++ config.yaml 2014-11-18 01:29:44 +0000
13@@ -177,3 +177,14 @@
14 order for this charm to function correctly, the privacy extension must be
15 disabled and a non-temporary address must be configured/available on
16 your network interface.
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:29:44 +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:29:44 +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=== added symlink 'hooks/nrpe-external-master-relation-changed'
421=== target is u'swift_hooks.py'
422=== added symlink 'hooks/nrpe-external-master-relation-joined'
423=== target is u'swift_hooks.py'
424=== modified file 'hooks/swift_hooks.py'
425--- hooks/swift_hooks.py 2014-10-23 16:17:57 +0000
426+++ hooks/swift_hooks.py 2014-11-18 01:29:44 +0000
427@@ -11,6 +11,7 @@
428 from swift_utils import (
429 register_configs,
430 restart_map,
431+ services,
432 determine_packages,
433 ensure_swift_dir,
434 SWIFT_RINGS, get_www_dir,
435@@ -35,10 +36,16 @@
436 relation_set,
437 relation_ids,
438 relation_get,
439+<<<<<<< TREE
440 log,
441 INFO,
442 WARNING,
443 ERROR,
444+=======
445+ relations_of_type,
446+ local_unit,
447+ log, ERROR,
448+>>>>>>> MERGE-SOURCE
449 Hooks, UnregisteredHookError,
450 open_port
451 )
452@@ -69,6 +76,8 @@
453
454 from charmhelpers.contrib.openstack.context import ADDRESS_TYPES
455
456+from charmhelpers.contrib.charmsupport.nrpe import NRPE
457+
458 extra_pkgs = [
459 "haproxy",
460 "python-jinja2"
461@@ -275,6 +284,7 @@
462
463 configure_https()
464 open_port(config('bind-port'))
465+ update_nrpe_config()
466 # Determine whether or not we should do an upgrade, based on the
467 # the version offered in keyston-release.
468 if (openstack.openstack_upgrade_available('python-swift')):
469@@ -454,6 +464,57 @@
470 write_rc_script()
471
472
473+@hooks.hook('nrpe-external-master-relation-joined',
474+ 'nrpe-external-master-relation-changed')
475+def update_nrpe_config():
476+ apt_install('python-dbus')
477+ # Find out if nrpe set nagios_hostname
478+ hostname = None
479+ host_context = None
480+ for rel in relations_of_type('nrpe-external-master'):
481+ if 'nagios_hostname' in rel:
482+ hostname = rel['nagios_hostname']
483+ host_context = rel['nagios_host_context']
484+ break
485+ nrpe = NRPE(hostname=hostname)
486+
487+ if host_context:
488+ current_unit = "%s:%s" % (host_context, local_unit())
489+ else:
490+ current_unit = local_unit()
491+
492+ services_to_monitor = services()
493+ for service in services_to_monitor:
494+ upstart_init = '/etc/init/%s.conf' % service
495+ sysv_init = '/etc/init.d/%s' % service
496+
497+ if os.path.exists(upstart_init):
498+ nrpe.add_check(
499+ shortname=service,
500+ description='process check {%s}' % current_unit,
501+ check_cmd='check_upstart_job %s' % service,
502+ )
503+ elif os.path.exists(sysv_init):
504+ cronpath = '/etc/cron.d/nagios-service-check-%s' % service
505+ checkpath = os.path.join(os.environ['CHARM_DIR'],
506+ 'files/nrpe-external-master',
507+ 'check_exit_status.pl'),
508+ cron_template = '*/5 * * * * root \
509+/usr/local/lib/nagios/plugins/check_exit_status.pl -s /etc/init.d/%s \
510+status > /var/lib/nagios/service-check-%s.txt\n' % (service, service)
511+ f = open(cronpath, 'w')
512+ f.write(cron_template)
513+ f.close()
514+ nrpe.add_check(
515+ shortname=service,
516+ description='process check {%s}' % current_unit,
517+ check_cmd='check_status_file.py -f \
518+/var/lib/nagios/service-check-%s.txt' % service,
519+ )
520+
521+ nrpe.write()
522+
523+
524 def main():
525 try:
526 hooks.execute(sys.argv)
527
528=== modified file 'hooks/swift_utils.py'
529--- hooks/swift_utils.py 2014-10-21 08:32:52 +0000
530+++ hooks/swift_utils.py 2014-11-18 01:29:44 +0000
531@@ -166,6 +166,14 @@
532 return OrderedDict(_map)
533
534
535+def services():
536+ ''' Returns a list of services associate with this charm '''
537+ _services = []
538+ for v in restart_map().values():
539+ _services = _services + v
540+ return list(set(_services))
541+
542+
543 def swift_user(username='swift'):
544 user = pwd.getpwnam(username)
545 return (user.pw_uid, user.pw_gid)
546
547=== modified file 'metadata.yaml'
548--- metadata.yaml 2013-07-11 19:18:37 +0000
549+++ metadata.yaml 2014-11-18 01:29:44 +0000
550@@ -7,6 +7,9 @@
551 categories:
552 - cache-proxy
553 provides:
554+ nrpe-external-master:
555+ interface: nrpe-external-master
556+ scope: container
557 object-store:
558 interface: swift-proxy
559 requires:

Subscribers

People subscribed via source and target branches