Merge lp:~gnuoy/charms/trusty/glance/add-nrpe-checks into lp:~openstack-charmers-archive/charms/trusty/glance/next
- Trusty Tahr (14.04)
- add-nrpe-checks
- Merge into next
Proposed by
Liam Young
Status: | Merged |
---|---|
Merged at revision: | 92 |
Proposed branch: | lp:~gnuoy/charms/trusty/glance/add-nrpe-checks |
Merge into: | lp:~openstack-charmers-archive/charms/trusty/glance/next |
Diff against target: |
655 lines (+516/-1) 9 files modified
charm-helpers-hooks.yaml (+1/-0) config.yaml (+11/-0) hooks/charmhelpers/contrib/charmsupport/nrpe.py (+308/-0) hooks/charmhelpers/contrib/charmsupport/volumes.py (+159/-0) hooks/charmhelpers/contrib/openstack/utils.py (+6/-0) hooks/charmhelpers/fetch/__init__.py (+8/-1) hooks/glance_relations.py (+19/-0) metadata.yaml (+3/-0) unit_tests/test_glance_relations.py (+1/-0) |
To merge this branch: | bzr merge lp:~gnuoy/charms/trusty/glance/add-nrpe-checks |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Liam Young (community) | Approve | ||
Review via email: mp+246151@code.launchpad.net |
Commit message
Description of the change
Add nrpe support. Based on branch from bradm with a few tweaks
To post a comment you must log in.
Revision history for this message
uosci-testing-bot (uosci-testing-bot) wrote : | # |
Revision history for this message
uosci-testing-bot (uosci-testing-bot) wrote : | # |
charm_unit_test #701 glance-next for gnuoy mp246151
UNIT OK: passed
Revision history for this message
uosci-testing-bot (uosci-testing-bot) wrote : | # |
charm_amulet_test #857 glance-next for gnuoy mp246151
AMULET OK: passed
Revision history for this message
Liam Young (gnuoy) wrote : | # |
<jamespage> gnuoy, as they are re-syncs + tweaks to the nrpe stuff in the charms, I'm happy to give a conditional +1 across the board based on osci checking things out OK
<gnuoy> jamespage, I'll take that! thanks
...
<gnuoy> jamespage, osci is still working through. But on the subject of those mps, does your +1 stand for branches with no amulet tests?
<jamespage> gnuoy, yes
review:
Approve
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-12-19 09:30:16 +0000 | |||
3 | +++ charm-helpers-hooks.yaml 2015-01-12 14:00:01 +0000 | |||
4 | @@ -9,3 +9,4 @@ | |||
5 | 9 | - payload.execd | 9 | - payload.execd |
6 | 10 | - contrib.network.ip | 10 | - contrib.network.ip |
7 | 11 | - contrib.python.packages | 11 | - contrib.python.packages |
8 | 12 | - contrib.charmsupport | ||
9 | 12 | 13 | ||
10 | === modified file 'config.yaml' | |||
11 | --- config.yaml 2014-12-15 09:17:53 +0000 | |||
12 | +++ config.yaml 2015-01-12 14:00:01 +0000 | |||
13 | @@ -167,3 +167,14 @@ | |||
14 | 167 | The CPU core multiplier to use when configuring worker processes for | 167 | The CPU core multiplier to use when configuring worker processes for |
15 | 168 | Glance. By default, the number of workers for each daemon is set to | 168 | Glance. By default, the number of workers for each daemon is set to |
16 | 169 | twice the number of CPU cores a service unit has. | 169 | twice the number of CPU cores a service unit has. |
17 | 170 | nagios_context: | ||
18 | 171 | default: "juju" | ||
19 | 172 | type: string | ||
20 | 173 | description: | | ||
21 | 174 | Used by the nrpe-external-master subordinate charm. | ||
22 | 175 | A string that will be prepended to instance name to set the host name | ||
23 | 176 | in nagios. So for instance the hostname would be something like: | ||
24 | 177 | juju-myservice-0 | ||
25 | 178 | If you're running multiple environments with the same services in them | ||
26 | 179 | this allows you to differentiate between them. | ||
27 | 180 | |||
28 | 170 | 181 | ||
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 2015-01-12 14:00:01 +0000 | |||
35 | @@ -0,0 +1,308 @@ | |||
36 | 1 | """Compatibility with the nrpe-external-master charm""" | ||
37 | 2 | # Copyright 2012 Canonical Ltd. | ||
38 | 3 | # | ||
39 | 4 | # Authors: | ||
40 | 5 | # Matthew Wedgwood <matthew.wedgwood@canonical.com> | ||
41 | 6 | |||
42 | 7 | import subprocess | ||
43 | 8 | import pwd | ||
44 | 9 | import grp | ||
45 | 10 | import os | ||
46 | 11 | import re | ||
47 | 12 | import shlex | ||
48 | 13 | import yaml | ||
49 | 14 | |||
50 | 15 | from charmhelpers.core.hookenv import ( | ||
51 | 16 | config, | ||
52 | 17 | local_unit, | ||
53 | 18 | log, | ||
54 | 19 | relation_ids, | ||
55 | 20 | relation_set, | ||
56 | 21 | relations_of_type, | ||
57 | 22 | ) | ||
58 | 23 | |||
59 | 24 | from charmhelpers.core.host import service | ||
60 | 25 | |||
61 | 26 | # This module adds compatibility with the nrpe-external-master and plain nrpe | ||
62 | 27 | # subordinate charms. To use it in your charm: | ||
63 | 28 | # | ||
64 | 29 | # 1. Update metadata.yaml | ||
65 | 30 | # | ||
66 | 31 | # provides: | ||
67 | 32 | # (...) | ||
68 | 33 | # nrpe-external-master: | ||
69 | 34 | # interface: nrpe-external-master | ||
70 | 35 | # scope: container | ||
71 | 36 | # | ||
72 | 37 | # and/or | ||
73 | 38 | # | ||
74 | 39 | # provides: | ||
75 | 40 | # (...) | ||
76 | 41 | # local-monitors: | ||
77 | 42 | # interface: local-monitors | ||
78 | 43 | # scope: container | ||
79 | 44 | |||
80 | 45 | # | ||
81 | 46 | # 2. Add the following to config.yaml | ||
82 | 47 | # | ||
83 | 48 | # nagios_context: | ||
84 | 49 | # default: "juju" | ||
85 | 50 | # type: string | ||
86 | 51 | # description: | | ||
87 | 52 | # Used by the nrpe subordinate charms. | ||
88 | 53 | # A string that will be prepended to instance name to set the host name | ||
89 | 54 | # in nagios. So for instance the hostname would be something like: | ||
90 | 55 | # juju-myservice-0 | ||
91 | 56 | # If you're running multiple environments with the same services in them | ||
92 | 57 | # this allows you to differentiate between them. | ||
93 | 58 | # nagios_servicegroups: | ||
94 | 59 | # default: "" | ||
95 | 60 | # type: string | ||
96 | 61 | # description: | | ||
97 | 62 | # A comma-separated list of nagios servicegroups. | ||
98 | 63 | # If left empty, the nagios_context will be used as the servicegroup | ||
99 | 64 | # | ||
100 | 65 | # 3. Add custom checks (Nagios plugins) to files/nrpe-external-master | ||
101 | 66 | # | ||
102 | 67 | # 4. Update your hooks.py with something like this: | ||
103 | 68 | # | ||
104 | 69 | # from charmsupport.nrpe import NRPE | ||
105 | 70 | # (...) | ||
106 | 71 | # def update_nrpe_config(): | ||
107 | 72 | # nrpe_compat = NRPE() | ||
108 | 73 | # nrpe_compat.add_check( | ||
109 | 74 | # shortname = "myservice", | ||
110 | 75 | # description = "Check MyService", | ||
111 | 76 | # check_cmd = "check_http -w 2 -c 10 http://localhost" | ||
112 | 77 | # ) | ||
113 | 78 | # nrpe_compat.add_check( | ||
114 | 79 | # "myservice_other", | ||
115 | 80 | # "Check for widget failures", | ||
116 | 81 | # check_cmd = "/srv/myapp/scripts/widget_check" | ||
117 | 82 | # ) | ||
118 | 83 | # nrpe_compat.write() | ||
119 | 84 | # | ||
120 | 85 | # def config_changed(): | ||
121 | 86 | # (...) | ||
122 | 87 | # update_nrpe_config() | ||
123 | 88 | # | ||
124 | 89 | # def nrpe_external_master_relation_changed(): | ||
125 | 90 | # update_nrpe_config() | ||
126 | 91 | # | ||
127 | 92 | # def local_monitors_relation_changed(): | ||
128 | 93 | # update_nrpe_config() | ||
129 | 94 | # | ||
130 | 95 | # 5. ln -s hooks.py nrpe-external-master-relation-changed | ||
131 | 96 | # ln -s hooks.py local-monitors-relation-changed | ||
132 | 97 | |||
133 | 98 | |||
134 | 99 | class CheckException(Exception): | ||
135 | 100 | pass | ||
136 | 101 | |||
137 | 102 | |||
138 | 103 | class Check(object): | ||
139 | 104 | shortname_re = '[A-Za-z0-9-_]+$' | ||
140 | 105 | service_template = (""" | ||
141 | 106 | #--------------------------------------------------- | ||
142 | 107 | # This file is Juju managed | ||
143 | 108 | #--------------------------------------------------- | ||
144 | 109 | define service {{ | ||
145 | 110 | use active-service | ||
146 | 111 | host_name {nagios_hostname} | ||
147 | 112 | service_description {nagios_hostname}[{shortname}] """ | ||
148 | 113 | """{description} | ||
149 | 114 | check_command check_nrpe!{command} | ||
150 | 115 | servicegroups {nagios_servicegroup} | ||
151 | 116 | }} | ||
152 | 117 | """) | ||
153 | 118 | |||
154 | 119 | def __init__(self, shortname, description, check_cmd): | ||
155 | 120 | super(Check, self).__init__() | ||
156 | 121 | # XXX: could be better to calculate this from the service name | ||
157 | 122 | if not re.match(self.shortname_re, shortname): | ||
158 | 123 | raise CheckException("shortname must match {}".format( | ||
159 | 124 | Check.shortname_re)) | ||
160 | 125 | self.shortname = shortname | ||
161 | 126 | self.command = "check_{}".format(shortname) | ||
162 | 127 | # Note: a set of invalid characters is defined by the | ||
163 | 128 | # Nagios server config | ||
164 | 129 | # The default is: illegal_object_name_chars=`~!$%^&*"|'<>?,()= | ||
165 | 130 | self.description = description | ||
166 | 131 | self.check_cmd = self._locate_cmd(check_cmd) | ||
167 | 132 | |||
168 | 133 | def _locate_cmd(self, check_cmd): | ||
169 | 134 | search_path = ( | ||
170 | 135 | '/usr/lib/nagios/plugins', | ||
171 | 136 | '/usr/local/lib/nagios/plugins', | ||
172 | 137 | ) | ||
173 | 138 | parts = shlex.split(check_cmd) | ||
174 | 139 | for path in search_path: | ||
175 | 140 | if os.path.exists(os.path.join(path, parts[0])): | ||
176 | 141 | command = os.path.join(path, parts[0]) | ||
177 | 142 | if len(parts) > 1: | ||
178 | 143 | command += " " + " ".join(parts[1:]) | ||
179 | 144 | return command | ||
180 | 145 | log('Check command not found: {}'.format(parts[0])) | ||
181 | 146 | return '' | ||
182 | 147 | |||
183 | 148 | def write(self, nagios_context, hostname, nagios_servicegroups=None): | ||
184 | 149 | nrpe_check_file = '/etc/nagios/nrpe.d/{}.cfg'.format( | ||
185 | 150 | self.command) | ||
186 | 151 | with open(nrpe_check_file, 'w') as nrpe_check_config: | ||
187 | 152 | nrpe_check_config.write("# check {}\n".format(self.shortname)) | ||
188 | 153 | nrpe_check_config.write("command[{}]={}\n".format( | ||
189 | 154 | self.command, self.check_cmd)) | ||
190 | 155 | |||
191 | 156 | if not os.path.exists(NRPE.nagios_exportdir): | ||
192 | 157 | log('Not writing service config as {} is not accessible'.format( | ||
193 | 158 | NRPE.nagios_exportdir)) | ||
194 | 159 | else: | ||
195 | 160 | self.write_service_config(nagios_context, hostname, | ||
196 | 161 | nagios_servicegroups) | ||
197 | 162 | |||
198 | 163 | def write_service_config(self, nagios_context, hostname, | ||
199 | 164 | nagios_servicegroups=None): | ||
200 | 165 | for f in os.listdir(NRPE.nagios_exportdir): | ||
201 | 166 | if re.search('.*{}.cfg'.format(self.command), f): | ||
202 | 167 | os.remove(os.path.join(NRPE.nagios_exportdir, f)) | ||
203 | 168 | |||
204 | 169 | if not nagios_servicegroups: | ||
205 | 170 | nagios_servicegroups = nagios_context | ||
206 | 171 | |||
207 | 172 | templ_vars = { | ||
208 | 173 | 'nagios_hostname': hostname, | ||
209 | 174 | 'nagios_servicegroup': nagios_servicegroups, | ||
210 | 175 | 'description': self.description, | ||
211 | 176 | 'shortname': self.shortname, | ||
212 | 177 | 'command': self.command, | ||
213 | 178 | } | ||
214 | 179 | nrpe_service_text = Check.service_template.format(**templ_vars) | ||
215 | 180 | nrpe_service_file = '{}/service__{}_{}.cfg'.format( | ||
216 | 181 | NRPE.nagios_exportdir, hostname, self.command) | ||
217 | 182 | with open(nrpe_service_file, 'w') as nrpe_service_config: | ||
218 | 183 | nrpe_service_config.write(str(nrpe_service_text)) | ||
219 | 184 | |||
220 | 185 | def run(self): | ||
221 | 186 | subprocess.call(self.check_cmd) | ||
222 | 187 | |||
223 | 188 | |||
224 | 189 | class NRPE(object): | ||
225 | 190 | nagios_logdir = '/var/log/nagios' | ||
226 | 191 | nagios_exportdir = '/var/lib/nagios/export' | ||
227 | 192 | nrpe_confdir = '/etc/nagios/nrpe.d' | ||
228 | 193 | |||
229 | 194 | def __init__(self, hostname=None): | ||
230 | 195 | super(NRPE, self).__init__() | ||
231 | 196 | self.config = config() | ||
232 | 197 | self.nagios_context = self.config['nagios_context'] | ||
233 | 198 | if 'nagios_servicegroups' in self.config: | ||
234 | 199 | self.nagios_servicegroups = self.config['nagios_servicegroups'] | ||
235 | 200 | else: | ||
236 | 201 | self.nagios_servicegroups = 'juju' | ||
237 | 202 | self.unit_name = local_unit().replace('/', '-') | ||
238 | 203 | if hostname: | ||
239 | 204 | self.hostname = hostname | ||
240 | 205 | else: | ||
241 | 206 | self.hostname = "{}-{}".format(self.nagios_context, self.unit_name) | ||
242 | 207 | self.checks = [] | ||
243 | 208 | |||
244 | 209 | def add_check(self, *args, **kwargs): | ||
245 | 210 | self.checks.append(Check(*args, **kwargs)) | ||
246 | 211 | |||
247 | 212 | def write(self): | ||
248 | 213 | try: | ||
249 | 214 | nagios_uid = pwd.getpwnam('nagios').pw_uid | ||
250 | 215 | nagios_gid = grp.getgrnam('nagios').gr_gid | ||
251 | 216 | except: | ||
252 | 217 | log("Nagios user not set up, nrpe checks not updated") | ||
253 | 218 | return | ||
254 | 219 | |||
255 | 220 | if not os.path.exists(NRPE.nagios_logdir): | ||
256 | 221 | os.mkdir(NRPE.nagios_logdir) | ||
257 | 222 | os.chown(NRPE.nagios_logdir, nagios_uid, nagios_gid) | ||
258 | 223 | |||
259 | 224 | nrpe_monitors = {} | ||
260 | 225 | monitors = {"monitors": {"remote": {"nrpe": nrpe_monitors}}} | ||
261 | 226 | for nrpecheck in self.checks: | ||
262 | 227 | nrpecheck.write(self.nagios_context, self.hostname, | ||
263 | 228 | self.nagios_servicegroups) | ||
264 | 229 | nrpe_monitors[nrpecheck.shortname] = { | ||
265 | 230 | "command": nrpecheck.command, | ||
266 | 231 | } | ||
267 | 232 | |||
268 | 233 | service('restart', 'nagios-nrpe-server') | ||
269 | 234 | |||
270 | 235 | for rid in relation_ids("local-monitors"): | ||
271 | 236 | relation_set(relation_id=rid, monitors=yaml.dump(monitors)) | ||
272 | 237 | |||
273 | 238 | |||
274 | 239 | def get_nagios_hostcontext(relation_name='nrpe-external-master'): | ||
275 | 240 | """ | ||
276 | 241 | Query relation with nrpe subordinate, return the nagios_host_context | ||
277 | 242 | |||
278 | 243 | :param str relation_name: Name of relation nrpe sub joined to | ||
279 | 244 | """ | ||
280 | 245 | for rel in relations_of_type(relation_name): | ||
281 | 246 | if 'nagios_hostname' in rel: | ||
282 | 247 | return rel['nagios_host_context'] | ||
283 | 248 | |||
284 | 249 | |||
285 | 250 | def get_nagios_hostname(relation_name='nrpe-external-master'): | ||
286 | 251 | """ | ||
287 | 252 | Query relation with nrpe subordinate, return the nagios_hostname | ||
288 | 253 | |||
289 | 254 | :param str relation_name: Name of relation nrpe sub joined to | ||
290 | 255 | """ | ||
291 | 256 | for rel in relations_of_type(relation_name): | ||
292 | 257 | if 'nagios_hostname' in rel: | ||
293 | 258 | return rel['nagios_hostname'] | ||
294 | 259 | |||
295 | 260 | |||
296 | 261 | def get_nagios_unit_name(relation_name='nrpe-external-master'): | ||
297 | 262 | """ | ||
298 | 263 | Return the nagios unit name prepended with host_context if needed | ||
299 | 264 | |||
300 | 265 | :param str relation_name: Name of relation nrpe sub joined to | ||
301 | 266 | """ | ||
302 | 267 | host_context = get_nagios_hostcontext(relation_name) | ||
303 | 268 | if host_context: | ||
304 | 269 | unit = "%s:%s" % (host_context, local_unit()) | ||
305 | 270 | else: | ||
306 | 271 | unit = local_unit() | ||
307 | 272 | return unit | ||
308 | 273 | |||
309 | 274 | |||
310 | 275 | def add_init_service_checks(nrpe, services, unit_name): | ||
311 | 276 | """ | ||
312 | 277 | Add checks for each service in list | ||
313 | 278 | |||
314 | 279 | :param NRPE nrpe: NRPE object to add check to | ||
315 | 280 | :param list services: List of services to check | ||
316 | 281 | :param str unit_name: Unit name to use in check description | ||
317 | 282 | """ | ||
318 | 283 | for svc in services: | ||
319 | 284 | upstart_init = '/etc/init/%s.conf' % svc | ||
320 | 285 | sysv_init = '/etc/init.d/%s' % svc | ||
321 | 286 | if os.path.exists(upstart_init): | ||
322 | 287 | nrpe.add_check( | ||
323 | 288 | shortname=svc, | ||
324 | 289 | description='process check {%s}' % unit_name, | ||
325 | 290 | check_cmd='check_upstart_job %s' % svc | ||
326 | 291 | ) | ||
327 | 292 | elif os.path.exists(sysv_init): | ||
328 | 293 | cronpath = '/etc/cron.d/nagios-service-check-%s' % svc | ||
329 | 294 | cron_file = ('*/5 * * * * root ' | ||
330 | 295 | '/usr/local/lib/nagios/plugins/check_exit_status.pl ' | ||
331 | 296 | '-s /etc/init.d/%s status > ' | ||
332 | 297 | '/var/lib/nagios/service-check-%s.txt\n' % (svc, | ||
333 | 298 | svc) | ||
334 | 299 | ) | ||
335 | 300 | f = open(cronpath, 'w') | ||
336 | 301 | f.write(cron_file) | ||
337 | 302 | f.close() | ||
338 | 303 | nrpe.add_check( | ||
339 | 304 | shortname=svc, | ||
340 | 305 | description='process check {%s}' % unit_name, | ||
341 | 306 | check_cmd='check_status_file.py -f ' | ||
342 | 307 | '/var/lib/nagios/service-check-%s.txt' % svc, | ||
343 | 308 | ) | ||
344 | 0 | 309 | ||
345 | === added file 'hooks/charmhelpers/contrib/charmsupport/volumes.py' | |||
346 | --- hooks/charmhelpers/contrib/charmsupport/volumes.py 1970-01-01 00:00:00 +0000 | |||
347 | +++ hooks/charmhelpers/contrib/charmsupport/volumes.py 2015-01-12 14:00:01 +0000 | |||
348 | @@ -0,0 +1,159 @@ | |||
349 | 1 | ''' | ||
350 | 2 | Functions for managing volumes in juju units. One volume is supported per unit. | ||
351 | 3 | Subordinates may have their own storage, provided it is on its own partition. | ||
352 | 4 | |||
353 | 5 | Configuration stanzas:: | ||
354 | 6 | |||
355 | 7 | volume-ephemeral: | ||
356 | 8 | type: boolean | ||
357 | 9 | default: true | ||
358 | 10 | description: > | ||
359 | 11 | If false, a volume is mounted as sepecified in "volume-map" | ||
360 | 12 | If true, ephemeral storage will be used, meaning that log data | ||
361 | 13 | will only exist as long as the machine. YOU HAVE BEEN WARNED. | ||
362 | 14 | volume-map: | ||
363 | 15 | type: string | ||
364 | 16 | default: {} | ||
365 | 17 | description: > | ||
366 | 18 | YAML map of units to device names, e.g: | ||
367 | 19 | "{ rsyslog/0: /dev/vdb, rsyslog/1: /dev/vdb }" | ||
368 | 20 | Service units will raise a configure-error if volume-ephemeral | ||
369 | 21 | is 'true' and no volume-map value is set. Use 'juju set' to set a | ||
370 | 22 | value and 'juju resolved' to complete configuration. | ||
371 | 23 | |||
372 | 24 | Usage:: | ||
373 | 25 | |||
374 | 26 | from charmsupport.volumes import configure_volume, VolumeConfigurationError | ||
375 | 27 | from charmsupport.hookenv import log, ERROR | ||
376 | 28 | def post_mount_hook(): | ||
377 | 29 | stop_service('myservice') | ||
378 | 30 | def post_mount_hook(): | ||
379 | 31 | start_service('myservice') | ||
380 | 32 | |||
381 | 33 | if __name__ == '__main__': | ||
382 | 34 | try: | ||
383 | 35 | configure_volume(before_change=pre_mount_hook, | ||
384 | 36 | after_change=post_mount_hook) | ||
385 | 37 | except VolumeConfigurationError: | ||
386 | 38 | log('Storage could not be configured', ERROR) | ||
387 | 39 | |||
388 | 40 | ''' | ||
389 | 41 | |||
390 | 42 | # XXX: Known limitations | ||
391 | 43 | # - fstab is neither consulted nor updated | ||
392 | 44 | |||
393 | 45 | import os | ||
394 | 46 | from charmhelpers.core import hookenv | ||
395 | 47 | from charmhelpers.core import host | ||
396 | 48 | import yaml | ||
397 | 49 | |||
398 | 50 | |||
399 | 51 | MOUNT_BASE = '/srv/juju/volumes' | ||
400 | 52 | |||
401 | 53 | |||
402 | 54 | class VolumeConfigurationError(Exception): | ||
403 | 55 | '''Volume configuration data is missing or invalid''' | ||
404 | 56 | pass | ||
405 | 57 | |||
406 | 58 | |||
407 | 59 | def get_config(): | ||
408 | 60 | '''Gather and sanity-check volume configuration data''' | ||
409 | 61 | volume_config = {} | ||
410 | 62 | config = hookenv.config() | ||
411 | 63 | |||
412 | 64 | errors = False | ||
413 | 65 | |||
414 | 66 | if config.get('volume-ephemeral') in (True, 'True', 'true', 'Yes', 'yes'): | ||
415 | 67 | volume_config['ephemeral'] = True | ||
416 | 68 | else: | ||
417 | 69 | volume_config['ephemeral'] = False | ||
418 | 70 | |||
419 | 71 | try: | ||
420 | 72 | volume_map = yaml.safe_load(config.get('volume-map', '{}')) | ||
421 | 73 | except yaml.YAMLError as e: | ||
422 | 74 | hookenv.log("Error parsing YAML volume-map: {}".format(e), | ||
423 | 75 | hookenv.ERROR) | ||
424 | 76 | errors = True | ||
425 | 77 | if volume_map is None: | ||
426 | 78 | # probably an empty string | ||
427 | 79 | volume_map = {} | ||
428 | 80 | elif not isinstance(volume_map, dict): | ||
429 | 81 | hookenv.log("Volume-map should be a dictionary, not {}".format( | ||
430 | 82 | type(volume_map))) | ||
431 | 83 | errors = True | ||
432 | 84 | |||
433 | 85 | volume_config['device'] = volume_map.get(os.environ['JUJU_UNIT_NAME']) | ||
434 | 86 | if volume_config['device'] and volume_config['ephemeral']: | ||
435 | 87 | # asked for ephemeral storage but also defined a volume ID | ||
436 | 88 | hookenv.log('A volume is defined for this unit, but ephemeral ' | ||
437 | 89 | 'storage was requested', hookenv.ERROR) | ||
438 | 90 | errors = True | ||
439 | 91 | elif not volume_config['device'] and not volume_config['ephemeral']: | ||
440 | 92 | # asked for permanent storage but did not define volume ID | ||
441 | 93 | hookenv.log('Ephemeral storage was requested, but there is no volume ' | ||
442 | 94 | 'defined for this unit.', hookenv.ERROR) | ||
443 | 95 | errors = True | ||
444 | 96 | |||
445 | 97 | unit_mount_name = hookenv.local_unit().replace('/', '-') | ||
446 | 98 | volume_config['mountpoint'] = os.path.join(MOUNT_BASE, unit_mount_name) | ||
447 | 99 | |||
448 | 100 | if errors: | ||
449 | 101 | return None | ||
450 | 102 | return volume_config | ||
451 | 103 | |||
452 | 104 | |||
453 | 105 | def mount_volume(config): | ||
454 | 106 | if os.path.exists(config['mountpoint']): | ||
455 | 107 | if not os.path.isdir(config['mountpoint']): | ||
456 | 108 | hookenv.log('Not a directory: {}'.format(config['mountpoint'])) | ||
457 | 109 | raise VolumeConfigurationError() | ||
458 | 110 | else: | ||
459 | 111 | host.mkdir(config['mountpoint']) | ||
460 | 112 | if os.path.ismount(config['mountpoint']): | ||
461 | 113 | unmount_volume(config) | ||
462 | 114 | if not host.mount(config['device'], config['mountpoint'], persist=True): | ||
463 | 115 | raise VolumeConfigurationError() | ||
464 | 116 | |||
465 | 117 | |||
466 | 118 | def unmount_volume(config): | ||
467 | 119 | if os.path.ismount(config['mountpoint']): | ||
468 | 120 | if not host.umount(config['mountpoint'], persist=True): | ||
469 | 121 | raise VolumeConfigurationError() | ||
470 | 122 | |||
471 | 123 | |||
472 | 124 | def managed_mounts(): | ||
473 | 125 | '''List of all mounted managed volumes''' | ||
474 | 126 | return filter(lambda mount: mount[0].startswith(MOUNT_BASE), host.mounts()) | ||
475 | 127 | |||
476 | 128 | |||
477 | 129 | def configure_volume(before_change=lambda: None, after_change=lambda: None): | ||
478 | 130 | '''Set up storage (or don't) according to the charm's volume configuration. | ||
479 | 131 | Returns the mount point or "ephemeral". before_change and after_change | ||
480 | 132 | are optional functions to be called if the volume configuration changes. | ||
481 | 133 | ''' | ||
482 | 134 | |||
483 | 135 | config = get_config() | ||
484 | 136 | if not config: | ||
485 | 137 | hookenv.log('Failed to read volume configuration', hookenv.CRITICAL) | ||
486 | 138 | raise VolumeConfigurationError() | ||
487 | 139 | |||
488 | 140 | if config['ephemeral']: | ||
489 | 141 | if os.path.ismount(config['mountpoint']): | ||
490 | 142 | before_change() | ||
491 | 143 | unmount_volume(config) | ||
492 | 144 | after_change() | ||
493 | 145 | return 'ephemeral' | ||
494 | 146 | else: | ||
495 | 147 | # persistent storage | ||
496 | 148 | if os.path.ismount(config['mountpoint']): | ||
497 | 149 | mounts = dict(managed_mounts()) | ||
498 | 150 | if mounts.get(config['mountpoint']) != config['device']: | ||
499 | 151 | before_change() | ||
500 | 152 | unmount_volume(config) | ||
501 | 153 | mount_volume(config) | ||
502 | 154 | after_change() | ||
503 | 155 | else: | ||
504 | 156 | before_change() | ||
505 | 157 | mount_volume(config) | ||
506 | 158 | after_change() | ||
507 | 159 | return config['mountpoint'] | ||
508 | 0 | 160 | ||
509 | === modified file 'hooks/charmhelpers/contrib/openstack/utils.py' | |||
510 | --- hooks/charmhelpers/contrib/openstack/utils.py 2014-12-19 09:30:16 +0000 | |||
511 | +++ hooks/charmhelpers/contrib/openstack/utils.py 2015-01-12 14:00:01 +0000 | |||
512 | @@ -53,6 +53,7 @@ | |||
513 | 53 | ('saucy', 'havana'), | 53 | ('saucy', 'havana'), |
514 | 54 | ('trusty', 'icehouse'), | 54 | ('trusty', 'icehouse'), |
515 | 55 | ('utopic', 'juno'), | 55 | ('utopic', 'juno'), |
516 | 56 | ('vivid', 'kilo'), | ||
517 | 56 | ]) | 57 | ]) |
518 | 57 | 58 | ||
519 | 58 | 59 | ||
520 | @@ -64,6 +65,7 @@ | |||
521 | 64 | ('2013.2', 'havana'), | 65 | ('2013.2', 'havana'), |
522 | 65 | ('2014.1', 'icehouse'), | 66 | ('2014.1', 'icehouse'), |
523 | 66 | ('2014.2', 'juno'), | 67 | ('2014.2', 'juno'), |
524 | 68 | ('2015.1', 'kilo'), | ||
525 | 67 | ]) | 69 | ]) |
526 | 68 | 70 | ||
527 | 69 | # The ugly duckling | 71 | # The ugly duckling |
528 | @@ -84,6 +86,7 @@ | |||
529 | 84 | ('2.0.0', 'juno'), | 86 | ('2.0.0', 'juno'), |
530 | 85 | ('2.1.0', 'juno'), | 87 | ('2.1.0', 'juno'), |
531 | 86 | ('2.2.0', 'juno'), | 88 | ('2.2.0', 'juno'), |
532 | 89 | ('2.2.1', 'kilo'), | ||
533 | 87 | ]) | 90 | ]) |
534 | 88 | 91 | ||
535 | 89 | DEFAULT_LOOPBACK_SIZE = '5G' | 92 | DEFAULT_LOOPBACK_SIZE = '5G' |
536 | @@ -289,6 +292,9 @@ | |||
537 | 289 | 'juno': 'trusty-updates/juno', | 292 | 'juno': 'trusty-updates/juno', |
538 | 290 | 'juno/updates': 'trusty-updates/juno', | 293 | 'juno/updates': 'trusty-updates/juno', |
539 | 291 | 'juno/proposed': 'trusty-proposed/juno', | 294 | 'juno/proposed': 'trusty-proposed/juno', |
540 | 295 | 'kilo': 'trusty-updates/kilo', | ||
541 | 296 | 'kilo/updates': 'trusty-updates/kilo', | ||
542 | 297 | 'kilo/proposed': 'trusty-proposed/kilo', | ||
543 | 292 | } | 298 | } |
544 | 293 | 299 | ||
545 | 294 | try: | 300 | try: |
546 | 295 | 301 | ||
547 | === modified file 'hooks/charmhelpers/fetch/__init__.py' | |||
548 | --- hooks/charmhelpers/fetch/__init__.py 2014-12-19 09:30:16 +0000 | |||
549 | +++ hooks/charmhelpers/fetch/__init__.py 2015-01-12 14:00:01 +0000 | |||
550 | @@ -64,9 +64,16 @@ | |||
551 | 64 | 'trusty-juno/updates': 'trusty-updates/juno', | 64 | 'trusty-juno/updates': 'trusty-updates/juno', |
552 | 65 | 'trusty-updates/juno': 'trusty-updates/juno', | 65 | 'trusty-updates/juno': 'trusty-updates/juno', |
553 | 66 | 'juno/proposed': 'trusty-proposed/juno', | 66 | 'juno/proposed': 'trusty-proposed/juno', |
554 | 67 | 'juno/proposed': 'trusty-proposed/juno', | ||
555 | 68 | 'trusty-juno/proposed': 'trusty-proposed/juno', | 67 | 'trusty-juno/proposed': 'trusty-proposed/juno', |
556 | 69 | 'trusty-proposed/juno': 'trusty-proposed/juno', | 68 | 'trusty-proposed/juno': 'trusty-proposed/juno', |
557 | 69 | # Kilo | ||
558 | 70 | 'kilo': 'trusty-updates/kilo', | ||
559 | 71 | 'trusty-kilo': 'trusty-updates/kilo', | ||
560 | 72 | 'trusty-kilo/updates': 'trusty-updates/kilo', | ||
561 | 73 | 'trusty-updates/kilo': 'trusty-updates/kilo', | ||
562 | 74 | 'kilo/proposed': 'trusty-proposed/kilo', | ||
563 | 75 | 'trusty-kilo/proposed': 'trusty-proposed/kilo', | ||
564 | 76 | 'trusty-proposed/kilo': 'trusty-proposed/kilo', | ||
565 | 70 | } | 77 | } |
566 | 71 | 78 | ||
567 | 72 | # The order of this list is very important. Handlers should be listed in from | 79 | # The order of this list is very important. Handlers should be listed in from |
568 | 73 | 80 | ||
569 | === modified file 'hooks/glance_relations.py' | |||
570 | --- hooks/glance_relations.py 2014-12-15 10:48:33 +0000 | |||
571 | +++ hooks/glance_relations.py 2015-01-12 14:00:01 +0000 | |||
572 | @@ -10,6 +10,7 @@ | |||
573 | 10 | migrate_database, | 10 | migrate_database, |
574 | 11 | register_configs, | 11 | register_configs, |
575 | 12 | restart_map, | 12 | restart_map, |
576 | 13 | services, | ||
577 | 13 | CLUSTER_RES, | 14 | CLUSTER_RES, |
578 | 14 | PACKAGES, | 15 | PACKAGES, |
579 | 15 | SERVICES, | 16 | SERVICES, |
580 | @@ -80,6 +81,8 @@ | |||
581 | 80 | from charmhelpers.contrib.openstack.context import ( | 81 | from charmhelpers.contrib.openstack.context import ( |
582 | 81 | ADDRESS_TYPES | 82 | ADDRESS_TYPES |
583 | 82 | ) | 83 | ) |
584 | 84 | from charmhelpers.contrib.charmsupport import nrpe | ||
585 | 85 | |||
586 | 83 | 86 | ||
587 | 84 | hooks = Hooks() | 87 | hooks = Hooks() |
588 | 85 | CONFIGS = register_configs() | 88 | CONFIGS = register_configs() |
589 | @@ -312,6 +315,8 @@ | |||
590 | 312 | open_port(9292) | 315 | open_port(9292) |
591 | 313 | configure_https() | 316 | configure_https() |
592 | 314 | 317 | ||
593 | 318 | update_nrpe_config() | ||
594 | 319 | |||
595 | 315 | # Pickup and changes due to network reference architecture | 320 | # Pickup and changes due to network reference architecture |
596 | 316 | # configuration | 321 | # configuration |
597 | 317 | [keystone_joined(rid) for rid in relation_ids('identity-service')] | 322 | [keystone_joined(rid) for rid in relation_ids('identity-service')] |
598 | @@ -349,6 +354,7 @@ | |||
599 | 349 | def upgrade_charm(): | 354 | def upgrade_charm(): |
600 | 350 | apt_install(filter_installed_packages(PACKAGES), fatal=True) | 355 | apt_install(filter_installed_packages(PACKAGES), fatal=True) |
601 | 351 | configure_https() | 356 | configure_https() |
602 | 357 | update_nrpe_config() | ||
603 | 352 | CONFIGS.write_all() | 358 | CONFIGS.write_all() |
604 | 353 | 359 | ||
605 | 354 | 360 | ||
606 | @@ -461,6 +467,19 @@ | |||
607 | 461 | return | 467 | return |
608 | 462 | CONFIGS.write(GLANCE_API_CONF) | 468 | CONFIGS.write(GLANCE_API_CONF) |
609 | 463 | 469 | ||
610 | 470 | |||
611 | 471 | @hooks.hook('nrpe-external-master-relation-joined', | ||
612 | 472 | 'nrpe-external-master-relation-changed') | ||
613 | 473 | def update_nrpe_config(): | ||
614 | 474 | # python-dbus is used by check_upstart_job | ||
615 | 475 | apt_install('python-dbus') | ||
616 | 476 | hostname = nrpe.get_nagios_hostname() | ||
617 | 477 | current_unit = nrpe.get_nagios_unit_name() | ||
618 | 478 | nrpe_setup = nrpe.NRPE(hostname=hostname) | ||
619 | 479 | nrpe.add_init_service_checks(nrpe_setup, services(), current_unit) | ||
620 | 480 | nrpe_setup.write() | ||
621 | 481 | |||
622 | 482 | |||
623 | 464 | if __name__ == '__main__': | 483 | if __name__ == '__main__': |
624 | 465 | try: | 484 | try: |
625 | 466 | hooks.execute(sys.argv) | 485 | hooks.execute(sys.argv) |
626 | 467 | 486 | ||
627 | === added symlink 'hooks/nrpe-external-master-relation-changed' | |||
628 | === target is u'glance_relations.py' | |||
629 | === added symlink 'hooks/nrpe-external-master-relation-joined' | |||
630 | === target is u'glance_relations.py' | |||
631 | === modified file 'metadata.yaml' | |||
632 | --- metadata.yaml 2014-09-11 07:05:30 +0000 | |||
633 | +++ metadata.yaml 2015-01-12 14:00:01 +0000 | |||
634 | @@ -9,6 +9,9 @@ | |||
635 | 9 | categories: | 9 | categories: |
636 | 10 | - miscellaneous | 10 | - miscellaneous |
637 | 11 | provides: | 11 | provides: |
638 | 12 | nrpe-external-master: | ||
639 | 13 | interface: nrpe-external-master | ||
640 | 14 | scope: container | ||
641 | 12 | image-service: | 15 | image-service: |
642 | 13 | interface: glance | 16 | interface: glance |
643 | 14 | requires: | 17 | requires: |
644 | 15 | 18 | ||
645 | === modified file 'unit_tests/test_glance_relations.py' | |||
646 | --- unit_tests/test_glance_relations.py 2014-12-17 18:06:08 +0000 | |||
647 | +++ unit_tests/test_glance_relations.py 2015-01-12 14:00:01 +0000 | |||
648 | @@ -52,6 +52,7 @@ | |||
649 | 52 | 'migrate_database', | 52 | 'migrate_database', |
650 | 53 | 'ensure_ceph_keyring', | 53 | 'ensure_ceph_keyring', |
651 | 54 | 'ceph_config_file', | 54 | 'ceph_config_file', |
652 | 55 | 'update_nrpe_config', | ||
653 | 55 | # other | 56 | # other |
654 | 56 | 'call', | 57 | 'call', |
655 | 57 | 'check_call', | 58 | 'check_call', |
charm_lint_check #672 glance-next for gnuoy mp246151
LINT OK: passed
Build: http:// 10.245. 162.77: 8080/job/ charm_lint_ check/672/