Merge lp:~brad-marshall/charms/trusty/swift-proxy/add-nrpe-checks into lp:~openstack-charmers-archive/charms/trusty/swift-proxy/trunk
- Trusty Tahr (14.04)
- add-nrpe-checks
- Merge into trunk
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 | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Liam Young (community) | Disapprove | ||
Review via email: mp+241484@code.launchpad.net |
Commit message
Description of the change
Adds nrpe-external-
Ryan Beisner (1chb1n) wrote : | # |
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/
hooks/
hooks/
hooks/
make: *** [lint] Error 1
Full lint test output: http://
Build: http://
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-
juju-
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://
Build: http://
- 72. By Brad Marshall
-
[bradm] Added sysvinit daemon monitoring, use services() instead of hard coded daemon list, pep8 fixes
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/
hooks/
make: *** [lint] Error 1
Full lint test output: http://
Build: http://
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://
Build: http://
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-
juju-
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://
Build: http://
- 73. By Brad Marshall
-
[bradm] Removed puppet header from nagios_plugin module
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/
hooks/
make: *** [lint] Error 1
Full lint test output: http://
Build: http://
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://
Build: http://
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-
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://
Build: http://
- 74. By Brad Marshall
-
[bradm] Removed nagios check files that were moved to nrpe-external-
master charm
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/
hooks/
hooks/
make: *** [lint] Error 1
Full lint test output: http://
Build: http://
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://
Build: http://
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-
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://
Build: http://
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/
hooks/
hooks/
make: *** [lint] Error 1
Full lint test output: http://
Build: http://
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://
Build: http://
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://
Build: http://
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.
Preview Diff
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: |
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/ 10.98.191. 181:8080/ job/charm_ unit_test/ 822/
Build: http://