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

Proposed by Brad Marshall
Status: Merged
Merged at revision: 97
Proposed branch: lp:~brad-marshall/charms/trusty/nova-compute/add-nrpe-checks
Merge into: lp:~openstack-charmers-archive/charms/trusty/nova-compute/trunk
Diff against target: 547 lines (+447/-3) (has conflicts)
5 files modified
charm-helpers-hooks.yaml (+1/-0)
hooks/charmhelpers/contrib/charmsupport/nrpe.py (+222/-0)
hooks/charmhelpers/contrib/charmsupport/volumes.py (+156/-0)
hooks/nova_compute_hooks.py (+58/-0)
metadata.yaml (+10/-3)
Text conflict in metadata.yaml
To merge this branch: bzr merge lp:~brad-marshall/charms/trusty/nova-compute/add-nrpe-checks
Reviewer Review Type Date Requested Status
Liam Young (community) Disapprove
Review via email: mp+241488@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 #996 trusty-nova-compute for brad-marshall mp241488
    LINT FAIL: lint-test failed

LINT Results (max last 5 lines):
  hooks/nova_compute_hooks.py:291:18: E251 unexpected spaces around keyword / parameter equals
  hooks/nova_compute_hooks.py:291:20: E251 unexpected spaces around keyword / parameter equals
  hooks/nova_compute_hooks.py:296:18: E251 unexpected spaces around keyword / parameter equals
  hooks/nova_compute_hooks.py:296:20: E251 unexpected spaces around keyword / parameter equals
  make: *** [lint] Error 1

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

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

UOSCI bot says:
charm_unit_test #831 trusty-nova-compute for brad-marshall mp241488
    UNIT FAIL: unit-test failed

UNIT Results (max last 5 lines):
  nova_compute_utils 228 110 52% 161-217, 225, 230-233, 268-270, 277, 281-284, 292-300, 304, 313-322, 335-354, 380-381, 385-386, 405-426, 443-453, 467-468, 473-474
  TOTAL 583 206 65%
  Ran 56 tests in 2.909s
  FAILED (SKIP=5, errors=5)
  make: *** [unit_test] Error 1

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

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

UOSCI bot says:
charm_amulet_test #376 trusty-nova-compute for brad-marshall mp241488
    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/8955983/
Build: http://10.98.191.181:8080/job/charm_amulet_test/376/

91. 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 #1087 trusty-nova-compute for brad-marshall mp241488
    LINT OK: passed

LINT Results (max last 5 lines):
  I: config.yaml: option os-data-network has no default value
  I: config.yaml: option config-flags has no default value
  I: config.yaml: option instances-path has no default value
  W: config.yaml: option disable-neutron-security-groups has no default value
  I: config.yaml: option migration-auth-type has no default value

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

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

UOSCI bot says:
charm_unit_test #921 trusty-nova-compute for brad-marshall mp241488
    UNIT FAIL: unit-test failed

UNIT Results (max last 5 lines):
  nova_compute_utils 228 110 52% 161-217, 225, 230-233, 268-270, 277, 281-284, 292-300, 304, 313-322, 335-354, 380-381, 385-386, 405-426, 443-453, 467-468, 473-474
  TOTAL 596 218 63%
  Ran 56 tests in 3.173s
  FAILED (SKIP=5, errors=5)
  make: *** [unit_test] Error 1

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

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

UOSCI bot says:
charm_amulet_test #429 trusty-nova-compute for brad-marshall mp241488
    AMULET FAIL: amulet-test failed

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

92. 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 #1099 trusty-nova-compute for brad-marshall mp241488
    LINT OK: passed

LINT Results (max last 5 lines):
  I: config.yaml: option os-data-network has no default value
  I: config.yaml: option config-flags has no default value
  I: config.yaml: option instances-path has no default value
  W: config.yaml: option disable-neutron-security-groups has no default value
  I: config.yaml: option migration-auth-type has no default value

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

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

UOSCI bot says:
charm_unit_test #933 trusty-nova-compute for brad-marshall mp241488
    UNIT FAIL: unit-test failed

UNIT Results (max last 5 lines):
  nova_compute_utils 228 110 52% 161-217, 225, 230-233, 268-270, 277, 281-284, 292-300, 304, 313-322, 335-354, 380-381, 385-386, 405-426, 443-453, 467-468, 473-474
  TOTAL 596 218 63%
  Ran 56 tests in 3.357s
  FAILED (SKIP=5, errors=5)
  make: *** [unit_test] Error 1

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

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

UOSCI bot says:
charm_amulet_test #441 trusty-nova-compute for brad-marshall mp241488
    AMULET FAIL: amulet-test failed

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

93. 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 #1115 trusty-nova-compute for brad-marshall mp241488
    LINT OK: passed

LINT Results (max last 5 lines):
  I: config.yaml: option os-data-network has no default value
  I: config.yaml: option config-flags has no default value
  I: config.yaml: option instances-path has no default value
  W: config.yaml: option disable-neutron-security-groups has no default value
  I: config.yaml: option migration-auth-type has no default value

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

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

UOSCI bot says:
charm_unit_test #949 trusty-nova-compute for brad-marshall mp241488
    UNIT FAIL: unit-test failed

UNIT Results (max last 5 lines):
  nova_compute_utils 228 110 52% 161-217, 225, 230-233, 268-270, 277, 281-284, 292-300, 304, 313-322, 335-354, 380-381, 385-386, 405-426, 443-453, 467-468, 473-474
  TOTAL 595 217 64%
  Ran 56 tests in 3.232s
  FAILED (SKIP=5, errors=5)
  make: *** [unit_test] Error 1

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

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

UOSCI bot says:
charm_amulet_test #457 trusty-nova-compute for brad-marshall mp241488
    AMULET FAIL: amulet-test failed

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

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

UOSCI bot says:
charm_lint_check #1249 trusty-nova-compute for brad-marshall mp241488
    LINT OK: passed

LINT Results (max last 5 lines):
  I: config.yaml: option os-data-network has no default value
  I: config.yaml: option config-flags has no default value
  I: config.yaml: option instances-path has no default value
  W: config.yaml: option disable-neutron-security-groups has no default value
  I: config.yaml: option migration-auth-type has no default value

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

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

UOSCI bot says:
charm_unit_test #1083 trusty-nova-compute for brad-marshall mp241488
    UNIT FAIL: unit-test failed

UNIT Results (max last 5 lines):
  nova_compute_utils 228 110 52% 161-217, 225, 230-233, 268-270, 277, 281-284, 292-300, 304, 313-322, 335-354, 380-381, 385-386, 405-426, 443-453, 467-468, 473-474
  TOTAL 595 217 64%
  Ran 56 tests in 3.575s
  FAILED (SKIP=5, errors=5)
  make: *** [unit_test] Error 1

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

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

UOSCI bot says:
charm_amulet_test #552 trusty-nova-compute for brad-marshall mp241488
    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/9281402/
Build: http://10.98.191.181:8080/job/charm_amulet_test/552/

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

Subscribers

People subscribed via source and target branches