Merge ~barryprice/charm-canonical-livepatch/+git/canonical-livepatch-charm:master into ~livepatch-charmers/charm-canonical-livepatch:master
- Git
- lp:~barryprice/charm-canonical-livepatch/+git/canonical-livepatch-charm
- master
- Merge into master
Proposed by
Barry Price
Status: | Merged |
---|---|
Merged at revision: | ad6b19b1a62736d33de7e124eb6f4f42859fc03c |
Proposed branch: | ~barryprice/charm-canonical-livepatch/+git/canonical-livepatch-charm:master |
Merge into: | ~livepatch-charmers/charm-canonical-livepatch:master |
Diff against target: |
224 lines (+51/-67) 4 files modified
README.md (+0/-6) config.yaml (+14/-2) reactive/canonical_livepatch.py (+11/-57) tests/99-autogen (+26/-2) |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Barry Price | Abstain | ||
Stuart Bishop (community) | Approve | ||
Review via email: mp+315749@code.launchpad.net |
Commit message
Description of the change
To post a comment you must log in.
Revision history for this message
Barry Price (barryprice) wrote : | # |
Revision history for this message
Stuart Bishop (stub) wrote : | # |
Mostly looks good.
I think the interface:
review:
Approve
Revision history for this message
Barry Price (barryprice) wrote : | # |
Local tests are now passing once again, but I want to reinstate the amulet test for nagios_
review:
Needs Fixing
Revision history for this message
Barry Price (barryprice) wrote : | # |
All tests are now passing.
Revision history for this message
Barry Price (barryprice) : | # |
review:
Abstain
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | diff --git a/README.md b/README.md | |||
2 | index 4cf16a5..8ac1e4a 100644 | |||
3 | --- a/README.md | |||
4 | +++ b/README.md | |||
5 | @@ -24,10 +24,6 @@ Or via juju config (Juju 2.x) | |||
6 | 24 | 24 | ||
7 | 25 | juju config canonical-livepatch livepatch_key=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx | 25 | juju config canonical-livepatch livepatch_key=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx |
8 | 26 | 26 | ||
9 | 27 | ## Known Limitations and Issues | ||
10 | 28 | |||
11 | 29 | The Nagios nrpe check integration code is a work in progress (but is fully functional) | ||
12 | 30 | |||
13 | 31 | # Configuration | 27 | # Configuration |
14 | 32 | 28 | ||
15 | 33 | The livepatch_key setting must be configured in order for the software to function correctly - see above. | 29 | The livepatch_key setting must be configured in order for the software to function correctly - see above. |
16 | @@ -36,8 +32,6 @@ By default, the livepatch software will attempt to retrieve its patch data direc | |||
17 | 36 | 32 | ||
18 | 37 | Likewise, if you need to use a proxy server to access the Snap Store, snap_proxy can also be set to the address of your proxy server. | 33 | Likewise, if you need to use a proxy server to access the Snap Store, snap_proxy can also be set to the address of your proxy server. |
19 | 38 | 34 | ||
20 | 39 | We set the Nagios servicegroups to 'livepatch' by default, this can also be reconfigured to suit your needs. | ||
21 | 40 | |||
22 | 41 | # Contact Information | 35 | # Contact Information |
23 | 42 | 36 | ||
24 | 43 | This charm is maintained here, by the livepatch-charmers team: | 37 | This charm is maintained here, by the livepatch-charmers team: |
25 | diff --git a/config.yaml b/config.yaml | |||
26 | index 40694b6..298611b 100644 | |||
27 | --- a/config.yaml | |||
28 | +++ b/config.yaml | |||
29 | @@ -13,7 +13,19 @@ options: | |||
30 | 13 | description: | | 13 | description: | |
31 | 14 | The address of a proxy server to use for livepatch traffic | 14 | The address of a proxy server to use for livepatch traffic |
32 | 15 | e.g. http://proxy.example.com:3128 | 15 | e.g. http://proxy.example.com:3128 |
33 | 16 | nagios_context: | ||
34 | 17 | default: "juju" | ||
35 | 18 | type: string | ||
36 | 19 | description: | | ||
37 | 20 | Used by the nrpe-external-master subordinate charm. | ||
38 | 21 | A string that will be prepended to instance name to set the host name | ||
39 | 22 | in nagios. So for instance the hostname would be something like: | ||
40 | 23 | juju-myservice-0 | ||
41 | 24 | If you're running multiple environments with the same services in them | ||
42 | 25 | this allows you to differentiate between them. | ||
43 | 16 | nagios_servicegroups: | 26 | nagios_servicegroups: |
45 | 17 | default: "livepatch" | 27 | default: "" |
46 | 18 | type: string | 28 | type: string |
48 | 19 | description: "Nagios servicegroup(s) for alerts." | 29 | description: > |
49 | 30 | A comma-separated list of nagios servicegroups. | ||
50 | 31 | If left empty, the nagios_context will be used as the servicegroup. | ||
51 | diff --git a/reactive/canonical_livepatch.py b/reactive/canonical_livepatch.py | |||
52 | index 102df07..4c12fb0 100644 | |||
53 | --- a/reactive/canonical_livepatch.py | |||
54 | +++ b/reactive/canonical_livepatch.py | |||
55 | @@ -1,11 +1,11 @@ | |||
56 | 1 | from charms.reactive import when, when_not, set_state | 1 | from charms.reactive import when, when_not, set_state |
57 | 2 | from charmhelpers.core.host import write_file | 2 | from charmhelpers.core.host import write_file |
58 | 3 | from charmhelpers.core import hookenv | 3 | from charmhelpers.core import hookenv |
59 | 4 | from charmhelpers.contrib.charmsupport import nrpe | ||
60 | 4 | from subprocess import check_call, check_output, CalledProcessError | 5 | from subprocess import check_call, check_output, CalledProcessError |
61 | 5 | from time import sleep | 6 | from time import sleep |
62 | 6 | from os import path | 7 | from os import path |
63 | 7 | from yaml import load, dump | 8 | from yaml import load, dump |
64 | 8 | from glob import glob | ||
65 | 9 | 9 | ||
66 | 10 | 10 | ||
67 | 11 | def file_to_units(local_path, unit_path): | 11 | def file_to_units(local_path, unit_path): |
68 | @@ -102,30 +102,6 @@ def restart_livepatch(): | |||
69 | 102 | check_call(cmd, universal_newlines=True) | 102 | check_call(cmd, universal_newlines=True) |
70 | 103 | 103 | ||
71 | 104 | 104 | ||
72 | 105 | def update_nagios_servicedef(service_name, service_value): | ||
73 | 106 | for service_file in glob("/var/lib/nagios/export/service__*_check_canonical-livepatch.cfg"): | ||
74 | 107 | with open(service_file, "r+") as fh: | ||
75 | 108 | output = '' | ||
76 | 109 | for line in fh: | ||
77 | 110 | if line.startswith(' {} '.format(service_name)): | ||
78 | 111 | els = line.split(' ') | ||
79 | 112 | new_els = [] | ||
80 | 113 | for e in els: | ||
81 | 114 | if e == '': | ||
82 | 115 | new_els.append(e) | ||
83 | 116 | elif e == service_name: | ||
84 | 117 | new_els.append(e) | ||
85 | 118 | else: | ||
86 | 119 | new_els.append(service_value) | ||
87 | 120 | new_line = ' '.join(new_els) + "\n" | ||
88 | 121 | output += new_line | ||
89 | 122 | else: | ||
90 | 123 | output += line | ||
91 | 124 | fh.seek(0) | ||
92 | 125 | fh.write(output) | ||
93 | 126 | fh.truncate() | ||
94 | 127 | |||
95 | 128 | |||
96 | 129 | @when('snap.installed.canonical-livepatch') | 105 | @when('snap.installed.canonical-livepatch') |
97 | 130 | @when_not('canonical-livepatch.connected') | 106 | @when_not('canonical-livepatch.connected') |
98 | 131 | def canonical_livepatch_connect(): | 107 | def canonical_livepatch_connect(): |
99 | @@ -184,24 +160,14 @@ def update_livepatch_proxy(): | |||
100 | 184 | hookenv.status_set('active', 'Ready') | 160 | hookenv.status_set('active', 'Ready') |
101 | 185 | 161 | ||
102 | 186 | 162 | ||
103 | 163 | @when('snap.installed.canonical-livepatch') | ||
104 | 187 | @when('nrpe-external-master.available') | 164 | @when('nrpe-external-master.available') |
105 | 188 | def init_nagios_checks(nagios): | 165 | def init_nagios_checks(nagios): |
106 | 189 | hookenv.status_set('maintenance', 'Configuring Nagios checks') | 166 | hookenv.status_set('maintenance', 'Configuring Nagios checks') |
107 | 190 | 167 | ||
122 | 191 | # We are a subordinate, try to find the primary hostname | 168 | # Ask charmhelpers.contrib.charmsupport's nrpe to work out our hostname |
123 | 192 | nagios_hostname = None | 169 | hostname = nrpe.get_nagios_hostname() |
124 | 193 | for hostfile in glob("/var/lib/nagios/export/host__*"): | 170 | nrpe_setup = nrpe.NRPE(hostname=hostname) |
111 | 194 | with open(hostfile) as fh: | ||
112 | 195 | for line in fh: | ||
113 | 196 | if 'host_name' in line: | ||
114 | 197 | nagios_hostname = line.split()[1] | ||
115 | 198 | |||
116 | 199 | # Otherwise, fall back to our generated hostname, probably wrong! | ||
117 | 200 | if nagios_hostname is None: | ||
118 | 201 | nagios_hostname = hookenv.local_unit() | ||
119 | 202 | |||
120 | 203 | config = hookenv.config() | ||
121 | 204 | nagios_servicegroups = config.get('nagios_servicegroups') | ||
125 | 205 | 171 | ||
126 | 206 | # install nagios support files | 172 | # install nagios support files |
127 | 207 | file_to_units( | 173 | file_to_units( |
128 | @@ -219,23 +185,11 @@ def init_nagios_checks(nagios): | |||
129 | 219 | '/var/lib/nagios/canonical-livepatch-status.txt', | 185 | '/var/lib/nagios/canonical-livepatch-status.txt', |
130 | 220 | ) | 186 | ) |
131 | 221 | 187 | ||
141 | 222 | # use the interface to create the check | 188 | # use charmhelpers to create the check |
142 | 223 | nagios.add_check(["/usr/lib/nagios/plugins/check_canonical-livepatch.py", ], | 189 | nrpe_setup.add_check('check_canonical-livepatch', |
143 | 224 | name="check_canonical-livepatch", | 190 | 'Verify canonical-livepatch is working', |
144 | 225 | description="Verify canonical-livepatch is working", | 191 | '/usr/lib/nagios/plugins/check_canonical-livepatch.py' |
145 | 226 | servicegroups=nagios_servicegroups, | 192 | ) |
137 | 227 | unit=nagios_hostname) | ||
138 | 228 | |||
139 | 229 | # clean up after https://github.com/cmars/nrpe-external-master-interface/issues/5 | ||
140 | 230 | update_nagios_servicedef('host_name', nagios_hostname) | ||
146 | 231 | 193 | ||
147 | 194 | nrpe_setup.write() | ||
148 | 232 | hookenv.status_set('active', 'Ready') | 195 | hookenv.status_set('active', 'Ready') |
149 | 233 | |||
150 | 234 | |||
151 | 235 | @when('config.changed.nagios_servicegroups') | ||
152 | 236 | def update_nagios_servicegroups(): | ||
153 | 237 | hookenv.status_set('maintenance', 'Configuring Nagios checks') | ||
154 | 238 | |||
155 | 239 | config = hookenv.config() | ||
156 | 240 | nagios_servicegroups = config.get('nagios_servicegroups') | ||
157 | 241 | update_nagios_servicedef('servicegroups', nagios_servicegroups) | ||
158 | diff --git a/tests/99-autogen b/tests/99-autogen | |||
159 | index 1527d4f..c57bbf4 100755 | |||
160 | --- a/tests/99-autogen | |||
161 | +++ b/tests/99-autogen | |||
162 | @@ -2,6 +2,7 @@ | |||
163 | 2 | 2 | ||
164 | 3 | import amulet | 3 | import amulet |
165 | 4 | import unittest | 4 | import unittest |
166 | 5 | from time import sleep | ||
167 | 5 | 6 | ||
168 | 6 | 7 | ||
169 | 7 | class TestDeployment(unittest.TestCase): | 8 | class TestDeployment(unittest.TestCase): |
170 | @@ -26,7 +27,7 @@ class TestDeployment(unittest.TestCase): | |||
171 | 26 | cls.deployment.relate('canonical-livepatch:nrpe-external-master', 'nrpe:nrpe-external-master') | 27 | cls.deployment.relate('canonical-livepatch:nrpe-external-master', 'nrpe:nrpe-external-master') |
172 | 27 | 28 | ||
173 | 28 | try: | 29 | try: |
175 | 29 | cls.deployment.setup(timeout=900) | 30 | cls.deployment.setup(timeout=3600) |
176 | 30 | cls.deployment.sentry.wait() | 31 | cls.deployment.sentry.wait() |
177 | 31 | except amulet.helpers.TimeoutError: | 32 | except amulet.helpers.TimeoutError: |
178 | 32 | amulet.raise_status(amulet.SKIP, msg="Environment wasn't stood up in time") | 33 | amulet.raise_status(amulet.SKIP, msg="Environment wasn't stood up in time") |
179 | @@ -59,21 +60,44 @@ class TestDeployment(unittest.TestCase): | |||
180 | 59 | output, exit_code = livepatch.run('stat {}'.format(path)) | 60 | output, exit_code = livepatch.run('stat {}'.format(path)) |
181 | 60 | self.assertEqual(exit_code, 0) | 61 | self.assertEqual(exit_code, 0) |
182 | 61 | 62 | ||
183 | 63 | def test_nagios_context_change(self): | ||
184 | 64 | livepatch = self.deployment.sentry['canonical-livepatch'][0] | ||
185 | 65 | |||
186 | 66 | test_context_name = 'amulet1' | ||
187 | 67 | |||
188 | 68 | # set context name | ||
189 | 69 | self.deployment.configure('canonical-livepatch', { | ||
190 | 70 | 'nagios_context': test_context_name, | ||
191 | 71 | }) | ||
192 | 72 | |||
193 | 73 | # nrpe updates can take a while | ||
194 | 74 | sleep(30) | ||
195 | 75 | |||
196 | 76 | # confirm it showed up in the right place | ||
197 | 77 | output, exit_code = livepatch.run( | ||
198 | 78 | 'grep {} /var/lib/nagios/export/service__*_check_canonical-livepatch.cfg'.format(test_context_name) | ||
199 | 79 | ) | ||
200 | 80 | self.assertEqual(exit_code, 0) | ||
201 | 81 | |||
202 | 62 | def test_nagios_servicegroup_change(self): | 82 | def test_nagios_servicegroup_change(self): |
203 | 63 | livepatch = self.deployment.sentry['canonical-livepatch'][0] | 83 | livepatch = self.deployment.sentry['canonical-livepatch'][0] |
204 | 64 | 84 | ||
206 | 65 | test_servicegroup_name = 'amulet' | 85 | test_servicegroup_name = 'amulet2' |
207 | 66 | 86 | ||
208 | 67 | # set servicegroup name | 87 | # set servicegroup name |
209 | 68 | self.deployment.configure('canonical-livepatch', { | 88 | self.deployment.configure('canonical-livepatch', { |
210 | 69 | 'nagios_servicegroups': test_servicegroup_name, | 89 | 'nagios_servicegroups': test_servicegroup_name, |
211 | 70 | }) | 90 | }) |
212 | 71 | 91 | ||
213 | 92 | # nrpe updates can take a while | ||
214 | 93 | sleep(30) | ||
215 | 94 | |||
216 | 72 | # confirm it showed up in the right place | 95 | # confirm it showed up in the right place |
217 | 73 | output, exit_code = livepatch.run( | 96 | output, exit_code = livepatch.run( |
218 | 74 | 'grep {} /var/lib/nagios/export/service__*_check_canonical-livepatch.cfg'.format(test_servicegroup_name) | 97 | 'grep {} /var/lib/nagios/export/service__*_check_canonical-livepatch.cfg'.format(test_servicegroup_name) |
219 | 75 | ) | 98 | ) |
220 | 76 | self.assertEqual(exit_code, 0) | 99 | self.assertEqual(exit_code, 0) |
221 | 77 | 100 | ||
222 | 101 | |||
223 | 78 | if __name__ == '__main__': | 102 | if __name__ == '__main__': |
224 | 79 | unittest.main() | 103 | unittest.main() |
Also upped the timeout for checks to an hour to cover sub-optimal internet connections and/or cloud environments.