Merge lp:~brad-marshall/charms/trusty/glance/add-nrpe-checks into lp:~openstack-charmers-archive/charms/trusty/glance/trunk
- Trusty Tahr (14.04)
- add-nrpe-checks
- Merge into trunk
Status: | Superseded | ||||
---|---|---|---|---|---|
Proposed branch: | lp:~brad-marshall/charms/trusty/glance/add-nrpe-checks | ||||
Merge into: | lp:~openstack-charmers-archive/charms/trusty/glance/trunk | ||||
Diff against target: |
969 lines (+853/-0) 10 files modified
charm-helpers-hooks.yaml (+1/-0) config.yaml (+11/-0) files/nrpe-external-master/check_exit_status.pl (+189/-0) files/nrpe-external-master/check_status_file.py (+60/-0) files/nrpe-external-master/check_upstart_job (+72/-0) files/nrpe-external-master/nagios_plugin.py (+78/-0) hooks/charmhelpers/contrib/charmsupport/nrpe.py (+222/-0) hooks/charmhelpers/contrib/charmsupport/volumes.py (+156/-0) hooks/glance_relations.py (+61/-0) metadata.yaml (+3/-0) |
||||
To merge this branch: | bzr merge lp:~brad-marshall/charms/trusty/glance/add-nrpe-checks | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Liam Young (community) | Needs Fixing | ||
Review via email:
|
This proposal has been superseded by a proposal from 2014-11-17.
Commit message
Description of the change
Adds nrpe-external-
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Ryan Beisner (1chb1n) wrote : | # |
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Ryan Beisner (1chb1n) wrote : | # |
UOSCI bot says:
charm_unit_test #824 trusty-glance for brad-marshall mp241494
UNIT FAIL: unit-test failed
UNIT Results (max last 5 lines):
hooks/
TOTAL 369 39 89%
Ran 65 tests in 3.551s
FAILED (errors=3)
make: *** [unit_test] Error 1
Full unit test output: http://
Build: http://
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Ryan Beisner (1chb1n) wrote : | # |
UOSCI bot says:
charm_amulet_test #369 trusty-glance for brad-marshall mp241494
AMULET FAIL: amulet-test failed
AMULET Results (max last 5 lines):
juju-
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://
Build: http://
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Liam Young (gnuoy) wrote : | # |
Thanks again for adding the nagios checks.
Please could check_upstart_job go into charm helpers. Also it'd be nice (but I wouldn't block on it) if glance_
- 84. By Brad Marshall
-
[bradm] Fixes from pep8 run, added sysvinit daemon services monitoring, use services() to get services to monitor
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
uosci-testing-bot (uosci-testing-bot) wrote : | # |
UOSCI bot says:
charm_lint_check #1081 trusty-glance for brad-marshall mp241494
LINT OK: passed
LINT Results (max last 5 lines):
I: config.yaml: option ssl_ca has no default value
I: config.yaml: option ssl_cert has no default value
I: config.yaml: option os-internal-network has no default value
I: config.yaml: option os-public-network has no default value
OK
Full lint test output: http://
Build: http://
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
uosci-testing-bot (uosci-testing-bot) wrote : | # |
UOSCI bot says:
charm_unit_test #915 trusty-glance for brad-marshall mp241494
UNIT FAIL: unit-test failed
UNIT Results (max last 5 lines):
hooks/
TOTAL 382 51 87%
Ran 65 tests in 3.421s
FAILED (errors=3)
make: *** [unit_test] Error 1
Full unit test output: http://
Build: http://
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
uosci-testing-bot (uosci-testing-bot) wrote : | # |
UOSCI bot says:
charm_amulet_test #423 trusty-glance for brad-marshall mp241494
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://
- 85. By Brad Marshall
-
[bradm] Removed puppet header from nagios_plugin module
- 86. By Brad Marshall
-
[bradm] Removed nagios check files that were moved to nrpe-external-
master charm
Unmerged revisions
Preview Diff
1 | === modified file 'charm-helpers-hooks.yaml' | |||
2 | --- charm-helpers-hooks.yaml 2014-10-01 22:14:32 +0000 | |||
3 | +++ charm-helpers-hooks.yaml 2014-11-17 02:32:28 +0000 | |||
4 | @@ -8,3 +8,4 @@ | |||
5 | 8 | - contrib.storage.linux.ceph | 8 | - contrib.storage.linux.ceph |
6 | 9 | - payload.execd | 9 | - payload.execd |
7 | 10 | - contrib.network.ip | 10 | - contrib.network.ip |
8 | 11 | - contrib.charmsupport | ||
9 | 11 | 12 | ||
10 | === modified file 'config.yaml' | |||
11 | --- config.yaml 2014-10-08 10:40:04 +0000 | |||
12 | +++ config.yaml 2014-11-17 02:32:28 +0000 | |||
13 | @@ -153,3 +153,14 @@ | |||
14 | 153 | The CPU core multiplier to use when configuring worker processes for | 153 | The CPU core multiplier to use when configuring worker processes for |
15 | 154 | Glance. By default, the number of workers for each daemon is set to | 154 | Glance. By default, the number of workers for each daemon is set to |
16 | 155 | twice the number of CPU cores a service unit has. | 155 | twice the number of CPU cores a service unit has. |
17 | 156 | nagios_context: | ||
18 | 157 | default: "juju" | ||
19 | 158 | type: string | ||
20 | 159 | description: | | ||
21 | 160 | Used by the nrpe-external-master subordinate charm. | ||
22 | 161 | A string that will be prepended to instance name to set the host name | ||
23 | 162 | in nagios. So for instance the hostname would be something like: | ||
24 | 163 | juju-myservice-0 | ||
25 | 164 | If you're running multiple environments with the same services in them | ||
26 | 165 | this allows you to differentiate between them. | ||
27 | 166 | |||
28 | 156 | 167 | ||
29 | === added directory 'files' | |||
30 | === added directory 'files/nrpe-external-master' | |||
31 | === added file 'files/nrpe-external-master/check_exit_status.pl' | |||
32 | --- files/nrpe-external-master/check_exit_status.pl 1970-01-01 00:00:00 +0000 | |||
33 | +++ files/nrpe-external-master/check_exit_status.pl 2014-11-17 02:32:28 +0000 | |||
34 | @@ -0,0 +1,189 @@ | |||
35 | 1 | #!/usr/bin/perl | ||
36 | 2 | ################################################################################ | ||
37 | 3 | # # | ||
38 | 4 | # Copyright (C) 2011 Chad Columbus <ccolumbu@hotmail.com> # | ||
39 | 5 | # # | ||
40 | 6 | # This program is free software; you can redistribute it and/or modify # | ||
41 | 7 | # it under the terms of the GNU General Public License as published by # | ||
42 | 8 | # the Free Software Foundation; either version 2 of the License, or # | ||
43 | 9 | # (at your option) any later version. # | ||
44 | 10 | # # | ||
45 | 11 | # This program is distributed in the hope that it will be useful, # | ||
46 | 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of # | ||
47 | 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # | ||
48 | 14 | # GNU General Public License for more details. # | ||
49 | 15 | # # | ||
50 | 16 | # You should have received a copy of the GNU General Public License # | ||
51 | 17 | # along with this program; if not, write to the Free Software # | ||
52 | 18 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # | ||
53 | 19 | # # | ||
54 | 20 | ################################################################################ | ||
55 | 21 | |||
56 | 22 | use strict; | ||
57 | 23 | use Getopt::Std; | ||
58 | 24 | $| = 1; | ||
59 | 25 | |||
60 | 26 | my %opts; | ||
61 | 27 | getopts('heronp:s:', \%opts); | ||
62 | 28 | |||
63 | 29 | my $VERSION = "Version 1.0"; | ||
64 | 30 | my $AUTHOR = '(c) 2011 Chad Columbus <ccolumbu@hotmail.com>'; | ||
65 | 31 | |||
66 | 32 | # Default values: | ||
67 | 33 | my $script_to_check; | ||
68 | 34 | my $pattern = 'is running'; | ||
69 | 35 | my $cmd; | ||
70 | 36 | my $message; | ||
71 | 37 | my $error; | ||
72 | 38 | |||
73 | 39 | # Exit codes | ||
74 | 40 | my $STATE_OK = 0; | ||
75 | 41 | my $STATE_WARNING = 1; | ||
76 | 42 | my $STATE_CRITICAL = 2; | ||
77 | 43 | my $STATE_UNKNOWN = 3; | ||
78 | 44 | |||
79 | 45 | # Parse command line options | ||
80 | 46 | if ($opts{'h'} || scalar(%opts) == 0) { | ||
81 | 47 | &print_help(); | ||
82 | 48 | exit($STATE_OK); | ||
83 | 49 | } | ||
84 | 50 | |||
85 | 51 | # Make sure scipt is provided: | ||
86 | 52 | if ($opts{'s'} eq '') { | ||
87 | 53 | # Script to run not provided | ||
88 | 54 | print "\nYou must provide a script to run. Example: -s /etc/init.d/httpd\n"; | ||
89 | 55 | exit($STATE_UNKNOWN); | ||
90 | 56 | } else { | ||
91 | 57 | $script_to_check = $opts{'s'}; | ||
92 | 58 | } | ||
93 | 59 | |||
94 | 60 | # Make sure only a-z, 0-9, /, _, and - are used in the script. | ||
95 | 61 | if ($script_to_check =~ /[^a-z0-9\_\-\/\.]/) { | ||
96 | 62 | # Script contains illegal characters exit. | ||
97 | 63 | print "\nScript to check can only contain Letters, Numbers, Periods, Underscores, Hyphens, and/or Slashes\n"; | ||
98 | 64 | exit($STATE_UNKNOWN); | ||
99 | 65 | } | ||
100 | 66 | |||
101 | 67 | # See if script is executable | ||
102 | 68 | if (! -x "$script_to_check") { | ||
103 | 69 | print "\nIt appears you can't execute $script_to_check, $!\n"; | ||
104 | 70 | exit($STATE_UNKNOWN); | ||
105 | 71 | } | ||
106 | 72 | |||
107 | 73 | # If a pattern is provided use it: | ||
108 | 74 | if ($opts{'p'} ne '') { | ||
109 | 75 | $pattern = $opts{'p'}; | ||
110 | 76 | } | ||
111 | 77 | |||
112 | 78 | # If -r run command via sudo as root: | ||
113 | 79 | if ($opts{'r'}) { | ||
114 | 80 | $cmd = "sudo -n $script_to_check status" . ' 2>&1'; | ||
115 | 81 | } else { | ||
116 | 82 | $cmd = "$script_to_check status" . ' 2>&1'; | ||
117 | 83 | } | ||
118 | 84 | |||
119 | 85 | my $cmd_result = `$cmd`; | ||
120 | 86 | chomp($cmd_result); | ||
121 | 87 | if ($cmd_result =~ /sudo/i) { | ||
122 | 88 | # This means it could not run the sudo command | ||
123 | 89 | $message = "$script_to_check CRITICAL - Could not run: 'sudo -n $script_to_check status'. Result is $cmd_result"; | ||
124 | 90 | $error = $STATE_UNKNOWN; | ||
125 | 91 | } else { | ||
126 | 92 | # Check exitstatus instead of output: | ||
127 | 93 | if ($opts{'e'} == 1) { | ||
128 | 94 | if ($? != 0) { | ||
129 | 95 | # error | ||
130 | 96 | $message = "$script_to_check CRITICAL - Exit code: $?\."; | ||
131 | 97 | if ($opts{'o'} == 0) { | ||
132 | 98 | $message .= " $cmd_result"; | ||
133 | 99 | } | ||
134 | 100 | $error = $STATE_CRITICAL; | ||
135 | 101 | } else { | ||
136 | 102 | # success | ||
137 | 103 | $message = "$script_to_check OK - Exit code: $?\."; | ||
138 | 104 | if ($opts{'o'} == 0) { | ||
139 | 105 | $message .= " $cmd_result"; | ||
140 | 106 | } | ||
141 | 107 | $error = $STATE_OK; | ||
142 | 108 | } | ||
143 | 109 | } else { | ||
144 | 110 | my $not_check = 1; | ||
145 | 111 | if ($opts{'n'} == 1) { | ||
146 | 112 | $not_check = 0; | ||
147 | 113 | } | ||
148 | 114 | if (($cmd_result =~ /$pattern/i) == $not_check) { | ||
149 | 115 | $message = "$script_to_check OK"; | ||
150 | 116 | if ($opts{'o'} == 0) { | ||
151 | 117 | $message .= " - $cmd_result"; | ||
152 | 118 | } | ||
153 | 119 | $error = $STATE_OK; | ||
154 | 120 | } else { | ||
155 | 121 | $message = "$script_to_check CRITICAL"; | ||
156 | 122 | if ($opts{'o'} == 0) { | ||
157 | 123 | $message .= " - $cmd_result"; | ||
158 | 124 | } | ||
159 | 125 | $error = $STATE_CRITICAL; | ||
160 | 126 | } | ||
161 | 127 | } | ||
162 | 128 | } | ||
163 | 129 | |||
164 | 130 | if ($message eq '') { | ||
165 | 131 | print "Error: program failed in an unknown way\n"; | ||
166 | 132 | exit($STATE_UNKNOWN); | ||
167 | 133 | } | ||
168 | 134 | |||
169 | 135 | if ($error) { | ||
170 | 136 | print "$message\n"; | ||
171 | 137 | exit($error); | ||
172 | 138 | } else { | ||
173 | 139 | # If we get here we are OK | ||
174 | 140 | print "$message\n"; | ||
175 | 141 | exit($STATE_OK); | ||
176 | 142 | } | ||
177 | 143 | |||
178 | 144 | #################################### | ||
179 | 145 | # Start Subs: | ||
180 | 146 | #################################### | ||
181 | 147 | sub print_help() { | ||
182 | 148 | print << "EOF"; | ||
183 | 149 | Check the output or exit status of a script. | ||
184 | 150 | $VERSION | ||
185 | 151 | $AUTHOR | ||
186 | 152 | |||
187 | 153 | Options: | ||
188 | 154 | -h | ||
189 | 155 | Print detailed help screen | ||
190 | 156 | |||
191 | 157 | -s | ||
192 | 158 | 'FULL PATH TO SCRIPT' (required) | ||
193 | 159 | This is the script to run, the script is designed to run scripts in the | ||
194 | 160 | /etc/init.d dir (but can run any script) and will call the script with | ||
195 | 161 | a 'status' argument. So if you use another script make sure it will | ||
196 | 162 | work with /path/script status, example: /etc/init.d/httpd status | ||
197 | 163 | |||
198 | 164 | -e | ||
199 | 165 | This is the "exitstaus" flag, it means check the exit status | ||
200 | 166 | code instead of looking for a pattern in the output of the script. | ||
201 | 167 | |||
202 | 168 | -p 'REGEX' | ||
203 | 169 | This is a pattern to look for in the output of the script to confirm it | ||
204 | 170 | is running, default is 'is running', but not all init.d scripts output | ||
205 | 171 | (iptables), so you can specify an arbitrary pattern. | ||
206 | 172 | All patterns are case insensitive. | ||
207 | 173 | |||
208 | 174 | -n | ||
209 | 175 | This is the "NOT" flag, it means not the -p pattern, so if you want to | ||
210 | 176 | make sure the output of the script does NOT contain -p 'REGEX' | ||
211 | 177 | |||
212 | 178 | -r | ||
213 | 179 | This is the "ROOT" flag, it means run as root via sudo. You will need a | ||
214 | 180 | line in your /etc/sudoers file like: | ||
215 | 181 | nagios ALL=(root) NOPASSWD: /etc/init.d/* status | ||
216 | 182 | |||
217 | 183 | -o | ||
218 | 184 | This is the "SUPPRESS OUTPUT" flag. Some programs have a long output | ||
219 | 185 | (like iptables), this flag suppresses that output so it is not printed | ||
220 | 186 | as a part of the nagios message. | ||
221 | 187 | EOF | ||
222 | 188 | } | ||
223 | 189 | |||
224 | 0 | 190 | ||
225 | === added file 'files/nrpe-external-master/check_status_file.py' | |||
226 | --- files/nrpe-external-master/check_status_file.py 1970-01-01 00:00:00 +0000 | |||
227 | +++ files/nrpe-external-master/check_status_file.py 2014-11-17 02:32:28 +0000 | |||
228 | @@ -0,0 +1,60 @@ | |||
229 | 1 | #!/usr/bin/python | ||
230 | 2 | |||
231 | 3 | # m | ||
232 | 4 | # mmmm m m mmmm mmmm mmm mm#mm | ||
233 | 5 | # #" "# # # #" "# #" "# #" # # | ||
234 | 6 | # # # # # # # # # #"""" # | ||
235 | 7 | # ##m#" "mm"# ##m#" ##m#" "#mm" "mm | ||
236 | 8 | # # # # | ||
237 | 9 | # " " " | ||
238 | 10 | # This file is managed by puppet. Do not make local changes. | ||
239 | 11 | |||
240 | 12 | # | ||
241 | 13 | # Copyright 2014 Canonical Ltd. | ||
242 | 14 | # | ||
243 | 15 | # Author: Jacek Nykis <jacek.nykis@canonical.com> | ||
244 | 16 | # | ||
245 | 17 | |||
246 | 18 | import re | ||
247 | 19 | import nagios_plugin | ||
248 | 20 | |||
249 | 21 | |||
250 | 22 | def parse_args(): | ||
251 | 23 | import argparse | ||
252 | 24 | |||
253 | 25 | parser = argparse.ArgumentParser( | ||
254 | 26 | description='Read file and return nagios status based on its content', | ||
255 | 27 | formatter_class=argparse.ArgumentDefaultsHelpFormatter) | ||
256 | 28 | parser.add_argument('-f', '--status-file', required=True, | ||
257 | 29 | help='Status file path') | ||
258 | 30 | parser.add_argument('-c', '--critical-text', default='CRITICAL', | ||
259 | 31 | help='String indicating critical status') | ||
260 | 32 | parser.add_argument('-w', '--warning-text', default='WARNING', | ||
261 | 33 | help='String indicating warning status') | ||
262 | 34 | parser.add_argument('-o', '--ok-text', default='OK', | ||
263 | 35 | help='String indicating OK status') | ||
264 | 36 | parser.add_argument('-u', '--unknown-text', default='UNKNOWN', | ||
265 | 37 | help='String indicating unknown status') | ||
266 | 38 | return parser.parse_args() | ||
267 | 39 | |||
268 | 40 | |||
269 | 41 | def check_status(args): | ||
270 | 42 | nagios_plugin.check_file_freshness(args.status_file, 43200) | ||
271 | 43 | |||
272 | 44 | with open(args.status_file, "r") as f: | ||
273 | 45 | content = [l.strip() for l in f.readlines()] | ||
274 | 46 | |||
275 | 47 | for line in content: | ||
276 | 48 | if re.search(args.critical_text, line): | ||
277 | 49 | raise nagios_plugin.CriticalError(line) | ||
278 | 50 | elif re.search(args.warning_text, line): | ||
279 | 51 | raise nagios_plugin.WarnError(line) | ||
280 | 52 | elif re.search(args.unknown_text, line): | ||
281 | 53 | raise nagios_plugin.UnknownError(line) | ||
282 | 54 | else: | ||
283 | 55 | print line | ||
284 | 56 | |||
285 | 57 | |||
286 | 58 | if __name__ == '__main__': | ||
287 | 59 | args = parse_args() | ||
288 | 60 | nagios_plugin.try_check(check_status, args) | ||
289 | 0 | 61 | ||
290 | === added file 'files/nrpe-external-master/check_upstart_job' | |||
291 | --- files/nrpe-external-master/check_upstart_job 1970-01-01 00:00:00 +0000 | |||
292 | +++ files/nrpe-external-master/check_upstart_job 2014-11-17 02:32:28 +0000 | |||
293 | @@ -0,0 +1,72 @@ | |||
294 | 1 | #!/usr/bin/python | ||
295 | 2 | |||
296 | 3 | # | ||
297 | 4 | # Copyright 2012, 2013 Canonical Ltd. | ||
298 | 5 | # | ||
299 | 6 | # Author: Paul Collins <paul.collins@canonical.com> | ||
300 | 7 | # | ||
301 | 8 | # Based on http://www.eurion.net/python-snippets/snippet/Upstart%20service%20status.html | ||
302 | 9 | # | ||
303 | 10 | |||
304 | 11 | import sys | ||
305 | 12 | |||
306 | 13 | import dbus | ||
307 | 14 | |||
308 | 15 | |||
309 | 16 | class Upstart(object): | ||
310 | 17 | def __init__(self): | ||
311 | 18 | self._bus = dbus.SystemBus() | ||
312 | 19 | self._upstart = self._bus.get_object('com.ubuntu.Upstart', | ||
313 | 20 | '/com/ubuntu/Upstart') | ||
314 | 21 | def get_job(self, job_name): | ||
315 | 22 | path = self._upstart.GetJobByName(job_name, | ||
316 | 23 | dbus_interface='com.ubuntu.Upstart0_6') | ||
317 | 24 | return self._bus.get_object('com.ubuntu.Upstart', path) | ||
318 | 25 | |||
319 | 26 | def get_properties(self, job): | ||
320 | 27 | path = job.GetInstance([], dbus_interface='com.ubuntu.Upstart0_6.Job') | ||
321 | 28 | instance = self._bus.get_object('com.ubuntu.Upstart', path) | ||
322 | 29 | return instance.GetAll('com.ubuntu.Upstart0_6.Instance', | ||
323 | 30 | dbus_interface=dbus.PROPERTIES_IFACE) | ||
324 | 31 | |||
325 | 32 | def get_job_instances(self, job_name): | ||
326 | 33 | job = self.get_job(job_name) | ||
327 | 34 | paths = job.GetAllInstances([], dbus_interface='com.ubuntu.Upstart0_6.Job') | ||
328 | 35 | return [self._bus.get_object('com.ubuntu.Upstart', path) for path in paths] | ||
329 | 36 | |||
330 | 37 | def get_job_instance_properties(self, job): | ||
331 | 38 | return job.GetAll('com.ubuntu.Upstart0_6.Instance', | ||
332 | 39 | dbus_interface=dbus.PROPERTIES_IFACE) | ||
333 | 40 | |||
334 | 41 | try: | ||
335 | 42 | upstart = Upstart() | ||
336 | 43 | try: | ||
337 | 44 | job = upstart.get_job(sys.argv[1]) | ||
338 | 45 | props = upstart.get_properties(job) | ||
339 | 46 | |||
340 | 47 | if props['state'] == 'running': | ||
341 | 48 | print 'OK: %s is running' % sys.argv[1] | ||
342 | 49 | sys.exit(0) | ||
343 | 50 | else: | ||
344 | 51 | print 'CRITICAL: %s is not running' % sys.argv[1] | ||
345 | 52 | sys.exit(2) | ||
346 | 53 | |||
347 | 54 | except dbus.DBusException as e: | ||
348 | 55 | instances = upstart.get_job_instances(sys.argv[1]) | ||
349 | 56 | propses = [upstart.get_job_instance_properties(instance) for instance in instances] | ||
350 | 57 | states = dict([(props['name'], props['state']) for props in propses]) | ||
351 | 58 | if len(states) != states.values().count('running'): | ||
352 | 59 | not_running = [] | ||
353 | 60 | for name in states.keys(): | ||
354 | 61 | if states[name] != 'running': | ||
355 | 62 | not_running.append(name) | ||
356 | 63 | print 'CRITICAL: %d instances of %s not running: %s' % \ | ||
357 | 64 | (len(not_running), sys.argv[1], not_running.join(', ')) | ||
358 | 65 | sys.exit(2) | ||
359 | 66 | else: | ||
360 | 67 | print 'OK: %d instances of %s running' % (len(states), sys.argv[1]) | ||
361 | 68 | |||
362 | 69 | except dbus.DBusException as e: | ||
363 | 70 | print 'CRITICAL: failed to get properties of \'%s\' from upstart' % sys.argv[1] | ||
364 | 71 | sys.exit(2) | ||
365 | 72 | |||
366 | 0 | 73 | ||
367 | === added file 'files/nrpe-external-master/nagios_plugin.py' | |||
368 | --- files/nrpe-external-master/nagios_plugin.py 1970-01-01 00:00:00 +0000 | |||
369 | +++ files/nrpe-external-master/nagios_plugin.py 2014-11-17 02:32:28 +0000 | |||
370 | @@ -0,0 +1,78 @@ | |||
371 | 1 | #!/usr/bin/env python | ||
372 | 2 | # m | ||
373 | 3 | # mmmm m m mmmm mmmm mmm mm#mm | ||
374 | 4 | # #" "# # # #" "# #" "# #" # # | ||
375 | 5 | # # # # # # # # # #"""" # | ||
376 | 6 | # ##m#" "mm"# ##m#" ##m#" "#mm" "mm | ||
377 | 7 | # # # # | ||
378 | 8 | # " " " | ||
379 | 9 | # This file is managed by puppet. Do not make local changes. | ||
380 | 10 | |||
381 | 11 | # Copyright (C) 2005, 2006, 2007, 2012 James Troup <james.troup@canonical.com> | ||
382 | 12 | |||
383 | 13 | import os | ||
384 | 14 | import stat | ||
385 | 15 | import time | ||
386 | 16 | import traceback | ||
387 | 17 | import sys | ||
388 | 18 | |||
389 | 19 | |||
390 | 20 | ################################################################################ | ||
391 | 21 | |||
392 | 22 | class CriticalError(Exception): | ||
393 | 23 | """This indicates a critical error.""" | ||
394 | 24 | pass | ||
395 | 25 | |||
396 | 26 | |||
397 | 27 | class WarnError(Exception): | ||
398 | 28 | """This indicates a warning condition.""" | ||
399 | 29 | pass | ||
400 | 30 | |||
401 | 31 | |||
402 | 32 | class UnknownError(Exception): | ||
403 | 33 | """This indicates a unknown error was encountered.""" | ||
404 | 34 | pass | ||
405 | 35 | |||
406 | 36 | |||
407 | 37 | def try_check(function, *args, **kwargs): | ||
408 | 38 | """Perform a check with error/warn/unknown handling.""" | ||
409 | 39 | try: | ||
410 | 40 | function(*args, **kwargs) | ||
411 | 41 | except UnknownError, msg: | ||
412 | 42 | print msg | ||
413 | 43 | sys.exit(3) | ||
414 | 44 | except CriticalError, msg: | ||
415 | 45 | print msg | ||
416 | 46 | sys.exit(2) | ||
417 | 47 | except WarnError, msg: | ||
418 | 48 | print msg | ||
419 | 49 | sys.exit(1) | ||
420 | 50 | except: | ||
421 | 51 | print "%s raised unknown exception '%s'" % (function, sys.exc_info()[0]) | ||
422 | 52 | print '=' * 60 | ||
423 | 53 | traceback.print_exc(file=sys.stdout) | ||
424 | 54 | print '=' * 60 | ||
425 | 55 | sys.exit(3) | ||
426 | 56 | |||
427 | 57 | |||
428 | 58 | ################################################################################ | ||
429 | 59 | |||
430 | 60 | def check_file_freshness(filename, newer_than=600): | ||
431 | 61 | """Check a file exists, is readable and is newer than <n> seconds (where <n> defaults to 600).""" | ||
432 | 62 | # First check the file exists and is readable | ||
433 | 63 | if not os.path.exists(filename): | ||
434 | 64 | raise CriticalError("%s: does not exist." % (filename)) | ||
435 | 65 | if os.access(filename, os.R_OK) == 0: | ||
436 | 66 | raise CriticalError("%s: is not readable." % (filename)) | ||
437 | 67 | |||
438 | 68 | # Then ensure the file is up-to-date enough | ||
439 | 69 | mtime = os.stat(filename)[stat.ST_MTIME] | ||
440 | 70 | last_modified = time.time() - mtime | ||
441 | 71 | if last_modified > newer_than: | ||
442 | 72 | raise CriticalError("%s: was last modified on %s and is too old (> %s seconds)." | ||
443 | 73 | % (filename, time.ctime(mtime), newer_than)) | ||
444 | 74 | if last_modified < 0: | ||
445 | 75 | raise CriticalError("%s: was last modified on %s which is in the future." | ||
446 | 76 | % (filename, time.ctime(mtime))) | ||
447 | 77 | |||
448 | 78 | ################################################################################ | ||
449 | 0 | 79 | ||
450 | === added directory 'hooks/charmhelpers/contrib/charmsupport' | |||
451 | === added file 'hooks/charmhelpers/contrib/charmsupport/__init__.py' | |||
452 | === added file 'hooks/charmhelpers/contrib/charmsupport/nrpe.py' | |||
453 | --- hooks/charmhelpers/contrib/charmsupport/nrpe.py 1970-01-01 00:00:00 +0000 | |||
454 | +++ hooks/charmhelpers/contrib/charmsupport/nrpe.py 2014-11-17 02:32:28 +0000 | |||
455 | @@ -0,0 +1,222 @@ | |||
456 | 1 | """Compatibility with the nrpe-external-master charm""" | ||
457 | 2 | # Copyright 2012 Canonical Ltd. | ||
458 | 3 | # | ||
459 | 4 | # Authors: | ||
460 | 5 | # Matthew Wedgwood <matthew.wedgwood@canonical.com> | ||
461 | 6 | |||
462 | 7 | import subprocess | ||
463 | 8 | import pwd | ||
464 | 9 | import grp | ||
465 | 10 | import os | ||
466 | 11 | import re | ||
467 | 12 | import shlex | ||
468 | 13 | import yaml | ||
469 | 14 | |||
470 | 15 | from charmhelpers.core.hookenv import ( | ||
471 | 16 | config, | ||
472 | 17 | local_unit, | ||
473 | 18 | log, | ||
474 | 19 | relation_ids, | ||
475 | 20 | relation_set, | ||
476 | 21 | ) | ||
477 | 22 | |||
478 | 23 | from charmhelpers.core.host import service | ||
479 | 24 | |||
480 | 25 | # This module adds compatibility with the nrpe-external-master and plain nrpe | ||
481 | 26 | # subordinate charms. To use it in your charm: | ||
482 | 27 | # | ||
483 | 28 | # 1. Update metadata.yaml | ||
484 | 29 | # | ||
485 | 30 | # provides: | ||
486 | 31 | # (...) | ||
487 | 32 | # nrpe-external-master: | ||
488 | 33 | # interface: nrpe-external-master | ||
489 | 34 | # scope: container | ||
490 | 35 | # | ||
491 | 36 | # and/or | ||
492 | 37 | # | ||
493 | 38 | # provides: | ||
494 | 39 | # (...) | ||
495 | 40 | # local-monitors: | ||
496 | 41 | # interface: local-monitors | ||
497 | 42 | # scope: container | ||
498 | 43 | |||
499 | 44 | # | ||
500 | 45 | # 2. Add the following to config.yaml | ||
501 | 46 | # | ||
502 | 47 | # nagios_context: | ||
503 | 48 | # default: "juju" | ||
504 | 49 | # type: string | ||
505 | 50 | # description: | | ||
506 | 51 | # Used by the nrpe subordinate charms. | ||
507 | 52 | # A string that will be prepended to instance name to set the host name | ||
508 | 53 | # in nagios. So for instance the hostname would be something like: | ||
509 | 54 | # juju-myservice-0 | ||
510 | 55 | # If you're running multiple environments with the same services in them | ||
511 | 56 | # this allows you to differentiate between them. | ||
512 | 57 | # | ||
513 | 58 | # 3. Add custom checks (Nagios plugins) to files/nrpe-external-master | ||
514 | 59 | # | ||
515 | 60 | # 4. Update your hooks.py with something like this: | ||
516 | 61 | # | ||
517 | 62 | # from charmsupport.nrpe import NRPE | ||
518 | 63 | # (...) | ||
519 | 64 | # def update_nrpe_config(): | ||
520 | 65 | # nrpe_compat = NRPE() | ||
521 | 66 | # nrpe_compat.add_check( | ||
522 | 67 | # shortname = "myservice", | ||
523 | 68 | # description = "Check MyService", | ||
524 | 69 | # check_cmd = "check_http -w 2 -c 10 http://localhost" | ||
525 | 70 | # ) | ||
526 | 71 | # nrpe_compat.add_check( | ||
527 | 72 | # "myservice_other", | ||
528 | 73 | # "Check for widget failures", | ||
529 | 74 | # check_cmd = "/srv/myapp/scripts/widget_check" | ||
530 | 75 | # ) | ||
531 | 76 | # nrpe_compat.write() | ||
532 | 77 | # | ||
533 | 78 | # def config_changed(): | ||
534 | 79 | # (...) | ||
535 | 80 | # update_nrpe_config() | ||
536 | 81 | # | ||
537 | 82 | # def nrpe_external_master_relation_changed(): | ||
538 | 83 | # update_nrpe_config() | ||
539 | 84 | # | ||
540 | 85 | # def local_monitors_relation_changed(): | ||
541 | 86 | # update_nrpe_config() | ||
542 | 87 | # | ||
543 | 88 | # 5. ln -s hooks.py nrpe-external-master-relation-changed | ||
544 | 89 | # ln -s hooks.py local-monitors-relation-changed | ||
545 | 90 | |||
546 | 91 | |||
547 | 92 | class CheckException(Exception): | ||
548 | 93 | pass | ||
549 | 94 | |||
550 | 95 | |||
551 | 96 | class Check(object): | ||
552 | 97 | shortname_re = '[A-Za-z0-9-_]+$' | ||
553 | 98 | service_template = (""" | ||
554 | 99 | #--------------------------------------------------- | ||
555 | 100 | # This file is Juju managed | ||
556 | 101 | #--------------------------------------------------- | ||
557 | 102 | define service {{ | ||
558 | 103 | use active-service | ||
559 | 104 | host_name {nagios_hostname} | ||
560 | 105 | service_description {nagios_hostname}[{shortname}] """ | ||
561 | 106 | """{description} | ||
562 | 107 | check_command check_nrpe!{command} | ||
563 | 108 | servicegroups {nagios_servicegroup} | ||
564 | 109 | }} | ||
565 | 110 | """) | ||
566 | 111 | |||
567 | 112 | def __init__(self, shortname, description, check_cmd): | ||
568 | 113 | super(Check, self).__init__() | ||
569 | 114 | # XXX: could be better to calculate this from the service name | ||
570 | 115 | if not re.match(self.shortname_re, shortname): | ||
571 | 116 | raise CheckException("shortname must match {}".format( | ||
572 | 117 | Check.shortname_re)) | ||
573 | 118 | self.shortname = shortname | ||
574 | 119 | self.command = "check_{}".format(shortname) | ||
575 | 120 | # Note: a set of invalid characters is defined by the | ||
576 | 121 | # Nagios server config | ||
577 | 122 | # The default is: illegal_object_name_chars=`~!$%^&*"|'<>?,()= | ||
578 | 123 | self.description = description | ||
579 | 124 | self.check_cmd = self._locate_cmd(check_cmd) | ||
580 | 125 | |||
581 | 126 | def _locate_cmd(self, check_cmd): | ||
582 | 127 | search_path = ( | ||
583 | 128 | '/', | ||
584 | 129 | os.path.join(os.environ['CHARM_DIR'], | ||
585 | 130 | 'files/nrpe-external-master'), | ||
586 | 131 | '/usr/lib/nagios/plugins', | ||
587 | 132 | '/usr/local/lib/nagios/plugins', | ||
588 | 133 | ) | ||
589 | 134 | parts = shlex.split(check_cmd) | ||
590 | 135 | for path in search_path: | ||
591 | 136 | if os.path.exists(os.path.join(path, parts[0])): | ||
592 | 137 | command = os.path.join(path, parts[0]) | ||
593 | 138 | if len(parts) > 1: | ||
594 | 139 | command += " " + " ".join(parts[1:]) | ||
595 | 140 | return command | ||
596 | 141 | log('Check command not found: {}'.format(parts[0])) | ||
597 | 142 | return '' | ||
598 | 143 | |||
599 | 144 | def write(self, nagios_context, hostname): | ||
600 | 145 | nrpe_check_file = '/etc/nagios/nrpe.d/{}.cfg'.format( | ||
601 | 146 | self.command) | ||
602 | 147 | with open(nrpe_check_file, 'w') as nrpe_check_config: | ||
603 | 148 | nrpe_check_config.write("# check {}\n".format(self.shortname)) | ||
604 | 149 | nrpe_check_config.write("command[{}]={}\n".format( | ||
605 | 150 | self.command, self.check_cmd)) | ||
606 | 151 | |||
607 | 152 | if not os.path.exists(NRPE.nagios_exportdir): | ||
608 | 153 | log('Not writing service config as {} is not accessible'.format( | ||
609 | 154 | NRPE.nagios_exportdir)) | ||
610 | 155 | else: | ||
611 | 156 | self.write_service_config(nagios_context, hostname) | ||
612 | 157 | |||
613 | 158 | def write_service_config(self, nagios_context, hostname): | ||
614 | 159 | for f in os.listdir(NRPE.nagios_exportdir): | ||
615 | 160 | if re.search('.*{}.cfg'.format(self.command), f): | ||
616 | 161 | os.remove(os.path.join(NRPE.nagios_exportdir, f)) | ||
617 | 162 | |||
618 | 163 | templ_vars = { | ||
619 | 164 | 'nagios_hostname': hostname, | ||
620 | 165 | 'nagios_servicegroup': nagios_context, | ||
621 | 166 | 'description': self.description, | ||
622 | 167 | 'shortname': self.shortname, | ||
623 | 168 | 'command': self.command, | ||
624 | 169 | } | ||
625 | 170 | nrpe_service_text = Check.service_template.format(**templ_vars) | ||
626 | 171 | nrpe_service_file = '{}/service__{}_{}.cfg'.format( | ||
627 | 172 | NRPE.nagios_exportdir, hostname, self.command) | ||
628 | 173 | with open(nrpe_service_file, 'w') as nrpe_service_config: | ||
629 | 174 | nrpe_service_config.write(str(nrpe_service_text)) | ||
630 | 175 | |||
631 | 176 | def run(self): | ||
632 | 177 | subprocess.call(self.check_cmd) | ||
633 | 178 | |||
634 | 179 | |||
635 | 180 | class NRPE(object): | ||
636 | 181 | nagios_logdir = '/var/log/nagios' | ||
637 | 182 | nagios_exportdir = '/var/lib/nagios/export' | ||
638 | 183 | nrpe_confdir = '/etc/nagios/nrpe.d' | ||
639 | 184 | |||
640 | 185 | def __init__(self, hostname=None): | ||
641 | 186 | super(NRPE, self).__init__() | ||
642 | 187 | self.config = config() | ||
643 | 188 | self.nagios_context = self.config['nagios_context'] | ||
644 | 189 | self.unit_name = local_unit().replace('/', '-') | ||
645 | 190 | if hostname: | ||
646 | 191 | self.hostname = hostname | ||
647 | 192 | else: | ||
648 | 193 | self.hostname = "{}-{}".format(self.nagios_context, self.unit_name) | ||
649 | 194 | self.checks = [] | ||
650 | 195 | |||
651 | 196 | def add_check(self, *args, **kwargs): | ||
652 | 197 | self.checks.append(Check(*args, **kwargs)) | ||
653 | 198 | |||
654 | 199 | def write(self): | ||
655 | 200 | try: | ||
656 | 201 | nagios_uid = pwd.getpwnam('nagios').pw_uid | ||
657 | 202 | nagios_gid = grp.getgrnam('nagios').gr_gid | ||
658 | 203 | except: | ||
659 | 204 | log("Nagios user not set up, nrpe checks not updated") | ||
660 | 205 | return | ||
661 | 206 | |||
662 | 207 | if not os.path.exists(NRPE.nagios_logdir): | ||
663 | 208 | os.mkdir(NRPE.nagios_logdir) | ||
664 | 209 | os.chown(NRPE.nagios_logdir, nagios_uid, nagios_gid) | ||
665 | 210 | |||
666 | 211 | nrpe_monitors = {} | ||
667 | 212 | monitors = {"monitors": {"remote": {"nrpe": nrpe_monitors}}} | ||
668 | 213 | for nrpecheck in self.checks: | ||
669 | 214 | nrpecheck.write(self.nagios_context, self.hostname) | ||
670 | 215 | nrpe_monitors[nrpecheck.shortname] = { | ||
671 | 216 | "command": nrpecheck.command, | ||
672 | 217 | } | ||
673 | 218 | |||
674 | 219 | service('restart', 'nagios-nrpe-server') | ||
675 | 220 | |||
676 | 221 | for rid in relation_ids("local-monitors"): | ||
677 | 222 | relation_set(relation_id=rid, monitors=yaml.dump(monitors)) | ||
678 | 0 | 223 | ||
679 | === added file 'hooks/charmhelpers/contrib/charmsupport/volumes.py' | |||
680 | --- hooks/charmhelpers/contrib/charmsupport/volumes.py 1970-01-01 00:00:00 +0000 | |||
681 | +++ hooks/charmhelpers/contrib/charmsupport/volumes.py 2014-11-17 02:32:28 +0000 | |||
682 | @@ -0,0 +1,156 @@ | |||
683 | 1 | ''' | ||
684 | 2 | Functions for managing volumes in juju units. One volume is supported per unit. | ||
685 | 3 | Subordinates may have their own storage, provided it is on its own partition. | ||
686 | 4 | |||
687 | 5 | Configuration stanzas: | ||
688 | 6 | volume-ephemeral: | ||
689 | 7 | type: boolean | ||
690 | 8 | default: true | ||
691 | 9 | description: > | ||
692 | 10 | If false, a volume is mounted as sepecified in "volume-map" | ||
693 | 11 | If true, ephemeral storage will be used, meaning that log data | ||
694 | 12 | will only exist as long as the machine. YOU HAVE BEEN WARNED. | ||
695 | 13 | volume-map: | ||
696 | 14 | type: string | ||
697 | 15 | default: {} | ||
698 | 16 | description: > | ||
699 | 17 | YAML map of units to device names, e.g: | ||
700 | 18 | "{ rsyslog/0: /dev/vdb, rsyslog/1: /dev/vdb }" | ||
701 | 19 | Service units will raise a configure-error if volume-ephemeral | ||
702 | 20 | is 'true' and no volume-map value is set. Use 'juju set' to set a | ||
703 | 21 | value and 'juju resolved' to complete configuration. | ||
704 | 22 | |||
705 | 23 | Usage: | ||
706 | 24 | from charmsupport.volumes import configure_volume, VolumeConfigurationError | ||
707 | 25 | from charmsupport.hookenv import log, ERROR | ||
708 | 26 | def post_mount_hook(): | ||
709 | 27 | stop_service('myservice') | ||
710 | 28 | def post_mount_hook(): | ||
711 | 29 | start_service('myservice') | ||
712 | 30 | |||
713 | 31 | if __name__ == '__main__': | ||
714 | 32 | try: | ||
715 | 33 | configure_volume(before_change=pre_mount_hook, | ||
716 | 34 | after_change=post_mount_hook) | ||
717 | 35 | except VolumeConfigurationError: | ||
718 | 36 | log('Storage could not be configured', ERROR) | ||
719 | 37 | ''' | ||
720 | 38 | |||
721 | 39 | # XXX: Known limitations | ||
722 | 40 | # - fstab is neither consulted nor updated | ||
723 | 41 | |||
724 | 42 | import os | ||
725 | 43 | from charmhelpers.core import hookenv | ||
726 | 44 | from charmhelpers.core import host | ||
727 | 45 | import yaml | ||
728 | 46 | |||
729 | 47 | |||
730 | 48 | MOUNT_BASE = '/srv/juju/volumes' | ||
731 | 49 | |||
732 | 50 | |||
733 | 51 | class VolumeConfigurationError(Exception): | ||
734 | 52 | '''Volume configuration data is missing or invalid''' | ||
735 | 53 | pass | ||
736 | 54 | |||
737 | 55 | |||
738 | 56 | def get_config(): | ||
739 | 57 | '''Gather and sanity-check volume configuration data''' | ||
740 | 58 | volume_config = {} | ||
741 | 59 | config = hookenv.config() | ||
742 | 60 | |||
743 | 61 | errors = False | ||
744 | 62 | |||
745 | 63 | if config.get('volume-ephemeral') in (True, 'True', 'true', 'Yes', 'yes'): | ||
746 | 64 | volume_config['ephemeral'] = True | ||
747 | 65 | else: | ||
748 | 66 | volume_config['ephemeral'] = False | ||
749 | 67 | |||
750 | 68 | try: | ||
751 | 69 | volume_map = yaml.safe_load(config.get('volume-map', '{}')) | ||
752 | 70 | except yaml.YAMLError as e: | ||
753 | 71 | hookenv.log("Error parsing YAML volume-map: {}".format(e), | ||
754 | 72 | hookenv.ERROR) | ||
755 | 73 | errors = True | ||
756 | 74 | if volume_map is None: | ||
757 | 75 | # probably an empty string | ||
758 | 76 | volume_map = {} | ||
759 | 77 | elif not isinstance(volume_map, dict): | ||
760 | 78 | hookenv.log("Volume-map should be a dictionary, not {}".format( | ||
761 | 79 | type(volume_map))) | ||
762 | 80 | errors = True | ||
763 | 81 | |||
764 | 82 | volume_config['device'] = volume_map.get(os.environ['JUJU_UNIT_NAME']) | ||
765 | 83 | if volume_config['device'] and volume_config['ephemeral']: | ||
766 | 84 | # asked for ephemeral storage but also defined a volume ID | ||
767 | 85 | hookenv.log('A volume is defined for this unit, but ephemeral ' | ||
768 | 86 | 'storage was requested', hookenv.ERROR) | ||
769 | 87 | errors = True | ||
770 | 88 | elif not volume_config['device'] and not volume_config['ephemeral']: | ||
771 | 89 | # asked for permanent storage but did not define volume ID | ||
772 | 90 | hookenv.log('Ephemeral storage was requested, but there is no volume ' | ||
773 | 91 | 'defined for this unit.', hookenv.ERROR) | ||
774 | 92 | errors = True | ||
775 | 93 | |||
776 | 94 | unit_mount_name = hookenv.local_unit().replace('/', '-') | ||
777 | 95 | volume_config['mountpoint'] = os.path.join(MOUNT_BASE, unit_mount_name) | ||
778 | 96 | |||
779 | 97 | if errors: | ||
780 | 98 | return None | ||
781 | 99 | return volume_config | ||
782 | 100 | |||
783 | 101 | |||
784 | 102 | def mount_volume(config): | ||
785 | 103 | if os.path.exists(config['mountpoint']): | ||
786 | 104 | if not os.path.isdir(config['mountpoint']): | ||
787 | 105 | hookenv.log('Not a directory: {}'.format(config['mountpoint'])) | ||
788 | 106 | raise VolumeConfigurationError() | ||
789 | 107 | else: | ||
790 | 108 | host.mkdir(config['mountpoint']) | ||
791 | 109 | if os.path.ismount(config['mountpoint']): | ||
792 | 110 | unmount_volume(config) | ||
793 | 111 | if not host.mount(config['device'], config['mountpoint'], persist=True): | ||
794 | 112 | raise VolumeConfigurationError() | ||
795 | 113 | |||
796 | 114 | |||
797 | 115 | def unmount_volume(config): | ||
798 | 116 | if os.path.ismount(config['mountpoint']): | ||
799 | 117 | if not host.umount(config['mountpoint'], persist=True): | ||
800 | 118 | raise VolumeConfigurationError() | ||
801 | 119 | |||
802 | 120 | |||
803 | 121 | def managed_mounts(): | ||
804 | 122 | '''List of all mounted managed volumes''' | ||
805 | 123 | return filter(lambda mount: mount[0].startswith(MOUNT_BASE), host.mounts()) | ||
806 | 124 | |||
807 | 125 | |||
808 | 126 | def configure_volume(before_change=lambda: None, after_change=lambda: None): | ||
809 | 127 | '''Set up storage (or don't) according to the charm's volume configuration. | ||
810 | 128 | Returns the mount point or "ephemeral". before_change and after_change | ||
811 | 129 | are optional functions to be called if the volume configuration changes. | ||
812 | 130 | ''' | ||
813 | 131 | |||
814 | 132 | config = get_config() | ||
815 | 133 | if not config: | ||
816 | 134 | hookenv.log('Failed to read volume configuration', hookenv.CRITICAL) | ||
817 | 135 | raise VolumeConfigurationError() | ||
818 | 136 | |||
819 | 137 | if config['ephemeral']: | ||
820 | 138 | if os.path.ismount(config['mountpoint']): | ||
821 | 139 | before_change() | ||
822 | 140 | unmount_volume(config) | ||
823 | 141 | after_change() | ||
824 | 142 | return 'ephemeral' | ||
825 | 143 | else: | ||
826 | 144 | # persistent storage | ||
827 | 145 | if os.path.ismount(config['mountpoint']): | ||
828 | 146 | mounts = dict(managed_mounts()) | ||
829 | 147 | if mounts.get(config['mountpoint']) != config['device']: | ||
830 | 148 | before_change() | ||
831 | 149 | unmount_volume(config) | ||
832 | 150 | mount_volume(config) | ||
833 | 151 | after_change() | ||
834 | 152 | else: | ||
835 | 153 | before_change() | ||
836 | 154 | mount_volume(config) | ||
837 | 155 | after_change() | ||
838 | 156 | return config['mountpoint'] | ||
839 | 0 | 157 | ||
840 | === modified file 'hooks/glance_relations.py' | |||
841 | --- hooks/glance_relations.py 2014-10-01 22:14:32 +0000 | |||
842 | +++ hooks/glance_relations.py 2014-11-17 02:32:28 +0000 | |||
843 | @@ -1,5 +1,6 @@ | |||
844 | 1 | #!/usr/bin/python | 1 | #!/usr/bin/python |
845 | 2 | import sys | 2 | import sys |
846 | 3 | import os | ||
847 | 3 | 4 | ||
848 | 4 | from glance_utils import ( | 5 | from glance_utils import ( |
849 | 5 | do_openstack_upgrade, | 6 | do_openstack_upgrade, |
850 | @@ -7,6 +8,7 @@ | |||
851 | 7 | migrate_database, | 8 | migrate_database, |
852 | 8 | register_configs, | 9 | register_configs, |
853 | 9 | restart_map, | 10 | restart_map, |
854 | 11 | services, | ||
855 | 10 | CLUSTER_RES, | 12 | CLUSTER_RES, |
856 | 11 | PACKAGES, | 13 | PACKAGES, |
857 | 12 | SERVICES, | 14 | SERVICES, |
858 | @@ -30,6 +32,7 @@ | |||
859 | 30 | relation_get, | 32 | relation_get, |
860 | 31 | relation_set, | 33 | relation_set, |
861 | 32 | relation_ids, | 34 | relation_ids, |
862 | 35 | relations_of_type, | ||
863 | 33 | service_name, | 36 | service_name, |
864 | 34 | unit_get, | 37 | unit_get, |
865 | 35 | UnregisteredHookError, ) | 38 | UnregisteredHookError, ) |
866 | @@ -73,6 +76,8 @@ | |||
867 | 73 | 76 | ||
868 | 74 | from charmhelpers.contrib.openstack.context import ADDRESS_TYPES | 77 | from charmhelpers.contrib.openstack.context import ADDRESS_TYPES |
869 | 75 | 78 | ||
870 | 79 | from charmhelpers.contrib.charmsupport.nrpe import NRPE | ||
871 | 80 | |||
872 | 76 | from subprocess import ( | 81 | from subprocess import ( |
873 | 77 | check_call, | 82 | check_call, |
874 | 78 | call, ) | 83 | call, ) |
875 | @@ -297,6 +302,8 @@ | |||
876 | 297 | open_port(9292) | 302 | open_port(9292) |
877 | 298 | configure_https() | 303 | configure_https() |
878 | 299 | 304 | ||
879 | 305 | update_nrpe_config() | ||
880 | 306 | |||
881 | 300 | # Pickup and changes due to network reference architecture | 307 | # Pickup and changes due to network reference architecture |
882 | 301 | # configuration | 308 | # configuration |
883 | 302 | [keystone_joined(rid) for rid in relation_ids('identity-service')] | 309 | [keystone_joined(rid) for rid in relation_ids('identity-service')] |
884 | @@ -334,6 +341,7 @@ | |||
885 | 334 | def upgrade_charm(): | 341 | def upgrade_charm(): |
886 | 335 | apt_install(filter_installed_packages(PACKAGES), fatal=True) | 342 | apt_install(filter_installed_packages(PACKAGES), fatal=True) |
887 | 336 | configure_https() | 343 | configure_https() |
888 | 344 | update_nrpe_config() | ||
889 | 337 | CONFIGS.write_all() | 345 | CONFIGS.write_all() |
890 | 338 | 346 | ||
891 | 339 | 347 | ||
892 | @@ -446,6 +454,59 @@ | |||
893 | 446 | return | 454 | return |
894 | 447 | CONFIGS.write(GLANCE_API_CONF) | 455 | CONFIGS.write(GLANCE_API_CONF) |
895 | 448 | 456 | ||
896 | 457 | |||
897 | 458 | @hooks.hook('nrpe-external-master-relation-joined', | ||
898 | 459 | 'nrpe-external-master-relation-changed') | ||
899 | 460 | def update_nrpe_config(): | ||
900 | 461 | # Find out if nrpe set nagios_hostname | ||
901 | 462 | hostname = None | ||
902 | 463 | host_context = None | ||
903 | 464 | for rel in relations_of_type('nrpe-external-master'): | ||
904 | 465 | if 'nagios_hostname' in rel: | ||
905 | 466 | hostname = rel['nagios_hostname'] | ||
906 | 467 | host_context = rel['nagios_host_context'] | ||
907 | 468 | break | ||
908 | 469 | nrpe = NRPE(hostname=hostname) | ||
909 | 470 | apt_install('python-dbus') | ||
910 | 471 | |||
911 | 472 | if host_context: | ||
912 | 473 | current_unit = "%s:%s" % (host_context, local_unit()) | ||
913 | 474 | else: | ||
914 | 475 | current_unit = local_unit() | ||
915 | 476 | |||
916 | 477 | services_to_monitor = services() | ||
917 | 478 | |||
918 | 479 | for service in services_to_monitor: | ||
919 | 480 | upstart_init = '/etc/init/%s.conf' % service | ||
920 | 481 | sysv_init = '/etc/init.d/%s' % service | ||
921 | 482 | |||
922 | 483 | if os.path.exists(upstart_init): | ||
923 | 484 | nrpe.add_check( | ||
924 | 485 | shortname=service, | ||
925 | 486 | description='process check {%s}' % current_unit, | ||
926 | 487 | check_cmd='check_upstart_job %s' % service, | ||
927 | 488 | ) | ||
928 | 489 | elif os.path.exists(sysv_init): | ||
929 | 490 | cronpath = '/etc/cron.d/nagios-service-check-%s' % service | ||
930 | 491 | checkpath = os.path.join(os.environ['CHARM_DIR'], | ||
931 | 492 | 'files/nrpe-external-master', | ||
932 | 493 | 'check_exit_status.pl'), | ||
933 | 494 | cron_template = '*/5 * * * * root \ | ||
934 | 495 | %s -s /etc/init.d/%s status > /var/lib/nagios/service-check-%s.txt\n' \ | ||
935 | 496 | % (checkpath[0], service, service) | ||
936 | 497 | f = open(cronpath, 'w') | ||
937 | 498 | f.write(cron_template) | ||
938 | 499 | f.close() | ||
939 | 500 | nrpe.add_check( | ||
940 | 501 | shortname=service, | ||
941 | 502 | description='process check {%s}' % current_unit, | ||
942 | 503 | check_cmd='check_status_file.py -f \ | ||
943 | 504 | /var/lib/nagios/service-check-%s.txt' % service, | ||
944 | 505 | ) | ||
945 | 506 | |||
946 | 507 | nrpe.write() | ||
947 | 508 | |||
948 | 509 | |||
949 | 449 | if __name__ == '__main__': | 510 | if __name__ == '__main__': |
950 | 450 | try: | 511 | try: |
951 | 451 | hooks.execute(sys.argv) | 512 | hooks.execute(sys.argv) |
952 | 452 | 513 | ||
953 | === added symlink 'hooks/nrpe-external-master-relation-changed' | |||
954 | === target is u'glance_relations.py' | |||
955 | === added symlink 'hooks/nrpe-external-master-relation-joined' | |||
956 | === target is u'glance_relations.py' | |||
957 | === modified file 'metadata.yaml' | |||
958 | --- metadata.yaml 2014-09-11 07:05:30 +0000 | |||
959 | +++ metadata.yaml 2014-11-17 02:32:28 +0000 | |||
960 | @@ -9,6 +9,9 @@ | |||
961 | 9 | categories: | 9 | categories: |
962 | 10 | - miscellaneous | 10 | - miscellaneous |
963 | 11 | provides: | 11 | provides: |
964 | 12 | nrpe-external-master: | ||
965 | 13 | interface: nrpe-external-master | ||
966 | 14 | scope: container | ||
967 | 12 | image-service: | 15 | image-service: |
968 | 13 | interface: glance | 16 | interface: glance |
969 | 14 | requires: | 17 | requires: |
UOSCI bot says:
charm_lint_check #989 trusty-glance for brad-marshall mp241494
LINT FAIL: lint-test failed
LINT Results (max last 5 lines): glance_ relations. py:476: 18: E251 unexpected spaces around keyword / parameter equals glance_ relations. py:476: 20: E251 unexpected spaces around keyword / parameter equals glance_ relations. py:481: 18: E251 unexpected spaces around keyword / parameter equals glance_ relations. py:481: 20: E251 unexpected spaces around keyword / parameter equals
hooks/
hooks/
hooks/
hooks/
make: *** [lint] Error 1
Full lint test output: http:// paste.ubuntu. com/8955744/ 10.98.191. 181:8080/ job/charm_ lint_check/ 989/
Build: http://