Merge lp:~hopem/charms/trusty/ceph-radosgw/lp1520339 into lp:~openstack-charmers-archive/charms/trusty/ceph-radosgw/next
- Trusty Tahr (14.04)
- lp1520339
- Merge into next
Status: | Merged | ||||
---|---|---|---|---|---|
Merged at revision: | 54 | ||||
Proposed branch: | lp:~hopem/charms/trusty/ceph-radosgw/lp1520339 | ||||
Merge into: | lp:~openstack-charmers-archive/charms/trusty/ceph-radosgw/next | ||||
Diff against target: |
298 lines (+141/-11) 4 files modified
hooks/ceph_radosgw_context.py (+7/-0) hooks/hooks.py (+118/-5) templates/ceph.conf (+3/-1) unit_tests/test_hooks.py (+13/-5) |
||||
To merge this branch: | bzr merge lp:~hopem/charms/trusty/ceph-radosgw/lp1520339 | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Liam Young (community) | Approve | ||
Ryan Beisner | Pending | ||
Review via email: mp+281372@code.launchpad.net |
This proposal supersedes a proposal from 2015-11-30.
Commit message
Description of the change
uosci-testing-bot (uosci-testing-bot) wrote : Posted in a previous version of this proposal | # |
uosci-testing-bot (uosci-testing-bot) wrote : Posted in a previous version of this proposal | # |
charm_unit_test #13702 ceph-radosgw-next for hopem mp279006
UNIT OK: passed
uosci-testing-bot (uosci-testing-bot) wrote : Posted in a previous version of this proposal | # |
charm_amulet_test #8067 ceph-radosgw-next for hopem mp279006
AMULET FAIL: amulet-test failed
AMULET Results (max last 2 lines):
make: *** [functional_test] Error 1
ERROR:root:Make target returned non-zero.
Full amulet test output: http://
Build: http://
uosci-testing-bot (uosci-testing-bot) wrote : Posted in a previous version of this proposal | # |
charm_lint_check #15039 ceph-radosgw-next for hopem mp279006
LINT OK: passed
Build: http://
uosci-testing-bot (uosci-testing-bot) wrote : Posted in a previous version of this proposal | # |
charm_unit_test #14027 ceph-radosgw-next for hopem mp279006
UNIT OK: passed
uosci-testing-bot (uosci-testing-bot) wrote : Posted in a previous version of this proposal | # |
charm_amulet_test #8204 ceph-radosgw-next for hopem mp279006
AMULET FAIL: amulet-test failed
AMULET Results (max last 2 lines):
make: *** [functional_test] Error 1
ERROR:root:Make target returned non-zero.
Full amulet test output: http://
Build: http://
Ryan Beisner (1chb1n) wrote : Posted in a previous version of this proposal | # |
FYI:
19:43:42 unit: ceph-radosgw/0: machine: 4 agent-state: error details: hook failed: "identity-
uosci-testing-bot (uosci-testing-bot) wrote : Posted in a previous version of this proposal | # |
charm_amulet_test #8217 ceph-radosgw-next for hopem mp279006
AMULET FAIL: amulet-test failed
AMULET Results (max last 2 lines):
make: *** [functional_test] Error 1
ERROR:root:Make target returned non-zero.
Full amulet test output: http://
Build: http://
Ryan Beisner (1chb1n) wrote : Posted in a previous version of this proposal | # |
^ Just reconfirming hook error with 2nd run. Indeed:
19:43:42 unit: ceph-radosgw/0: machine: 4 agent-state: error details: hook failed: "identity-
Edward Hope-Morley (hopem) wrote : Posted in a previous version of this proposal | # |
@1chb1n this seems to be a dep issue i.e. for some reason python-six in that env is not compatible with python-
Ryan Beisner (1chb1n) wrote : Posted in a previous version of this proposal | # |
@hopem, that message is from the juju unit, so all pkgs present are installed by either Juju or by the charm.
Ryan Beisner (1chb1n) wrote : Posted in a previous version of this proposal | # |
Here is the ceph-radosgw/0 unit log trace:
uosci-testing-bot (uosci-testing-bot) wrote : Posted in a previous version of this proposal | # |
charm_lint_check #15771 ceph-radosgw-next for hopem mp279006
LINT OK: passed
Build: http://
uosci-testing-bot (uosci-testing-bot) wrote : Posted in a previous version of this proposal | # |
charm_unit_test #14719 ceph-radosgw-next for hopem mp279006
UNIT OK: passed
uosci-testing-bot (uosci-testing-bot) wrote : Posted in a previous version of this proposal | # |
charm_amulet_test #8385 ceph-radosgw-next for hopem mp279006
AMULET FAIL: amulet-test failed
AMULET Results (max last 2 lines):
make: *** [functional_test] Error 1
ERROR:root:Make target returned non-zero.
Full amulet test output: http://
Build: http://
uosci-testing-bot (uosci-testing-bot) wrote : Posted in a previous version of this proposal | # |
charm_lint_check #15877 ceph-radosgw-next for hopem mp279006
LINT OK: passed
Build: http://
uosci-testing-bot (uosci-testing-bot) wrote : Posted in a previous version of this proposal | # |
charm_unit_test #14819 ceph-radosgw-next for hopem mp279006
UNIT OK: passed
uosci-testing-bot (uosci-testing-bot) wrote : Posted in a previous version of this proposal | # |
charm_amulet_test #8387 ceph-radosgw-next for hopem mp279006
AMULET FAIL: amulet-test failed
AMULET Results (max last 2 lines):
make: *** [functional_test] Error 1
ERROR:root:Make target returned non-zero.
Full amulet test output: http://
Build: http://
uosci-testing-bot (uosci-testing-bot) wrote : Posted in a previous version of this proposal | # |
charm_lint_check #15878 ceph-radosgw-next for hopem mp279006
LINT OK: passed
Build: http://
uosci-testing-bot (uosci-testing-bot) wrote : Posted in a previous version of this proposal | # |
charm_unit_test #14820 ceph-radosgw-next for hopem mp279006
UNIT OK: passed
uosci-testing-bot (uosci-testing-bot) wrote : Posted in a previous version of this proposal | # |
charm_amulet_test #8388 ceph-radosgw-next for hopem mp279006
AMULET FAIL: amulet-test failed
AMULET Results (max last 2 lines):
make: *** [functional_test] Error 1
ERROR:root:Make target returned non-zero.
Full amulet test output: http://
Build: http://
uosci-testing-bot (uosci-testing-bot) wrote : Posted in a previous version of this proposal | # |
charm_lint_check #16036 ceph-radosgw-next for hopem mp279006
LINT OK: passed
Build: http://
uosci-testing-bot (uosci-testing-bot) wrote : Posted in a previous version of this proposal | # |
charm_unit_test #14969 ceph-radosgw-next for hopem mp279006
UNIT OK: passed
uosci-testing-bot (uosci-testing-bot) wrote : Posted in a previous version of this proposal | # |
charm_amulet_test #8390 ceph-radosgw-next for hopem mp279006
AMULET FAIL: amulet-test failed
AMULET Results (max last 2 lines):
make: *** [functional_test] Error 1
ERROR:root:Make target returned non-zero.
Full amulet test output: http://
Build: http://
uosci-testing-bot (uosci-testing-bot) wrote : Posted in a previous version of this proposal | # |
charm_unit_test #14970 ceph-radosgw-next for hopem mp279006
UNIT OK: passed
uosci-testing-bot (uosci-testing-bot) wrote : Posted in a previous version of this proposal | # |
charm_lint_check #16037 ceph-radosgw-next for hopem mp279006
LINT OK: passed
Build: http://
uosci-testing-bot (uosci-testing-bot) wrote : Posted in a previous version of this proposal | # |
charm_amulet_test #8391 ceph-radosgw-next for hopem mp279006
AMULET OK: passed
Build: http://
uosci-testing-bot (uosci-testing-bot) wrote : Posted in a previous version of this proposal | # |
charm_lint_check #16090 ceph-radosgw-next for hopem mp279006
LINT OK: passed
Build: http://
uosci-testing-bot (uosci-testing-bot) wrote : Posted in a previous version of this proposal | # |
charm_unit_test #15020 ceph-radosgw-next for hopem mp279006
UNIT OK: passed
uosci-testing-bot (uosci-testing-bot) wrote : Posted in a previous version of this proposal | # |
charm_amulet_test #8392 ceph-radosgw-next for hopem mp279006
AMULET OK: passed
Build: http://
uosci-testing-bot (uosci-testing-bot) wrote : | # |
charm_unit_test #15021 ceph-radosgw-next for hopem mp281372
UNIT OK: passed
uosci-testing-bot (uosci-testing-bot) wrote : | # |
charm_lint_check #16091 ceph-radosgw-next for hopem mp281372
LINT OK: passed
Build: http://
uosci-testing-bot (uosci-testing-bot) wrote : | # |
charm_amulet_test #8393 ceph-radosgw-next for hopem mp281372
AMULET OK: passed
Build: http://
uosci-testing-bot (uosci-testing-bot) wrote : | # |
charm_lint_check #16582 ceph-radosgw-next for hopem mp281372
LINT OK: passed
Build: http://
uosci-testing-bot (uosci-testing-bot) wrote : | # |
charm_unit_test #15487 ceph-radosgw-next for hopem mp281372
UNIT OK: passed
uosci-testing-bot (uosci-testing-bot) wrote : | # |
charm_amulet_test #8501 ceph-radosgw-next for hopem mp281372
AMULET OK: passed
Build: http://
Preview Diff
1 | === modified file 'hooks/ceph_radosgw_context.py' |
2 | --- hooks/ceph_radosgw_context.py 2015-11-26 16:20:26 +0000 |
3 | +++ hooks/ceph_radosgw_context.py 2015-12-27 05:01:17 +0000 |
4 | @@ -13,6 +13,7 @@ |
5 | relation_get, |
6 | unit_get, |
7 | ) |
8 | +import os |
9 | import socket |
10 | import dns.resolver |
11 | |
12 | @@ -102,6 +103,12 @@ |
13 | 'loglevel': config('loglevel'), |
14 | } |
15 | |
16 | + certs_path = '/var/lib/ceph/nss' |
17 | + paths = [os.path.join(certs_path, 'ca.pem'), |
18 | + os.path.join(certs_path, 'signing_certificate.pem')] |
19 | + if all([os.path.isfile(p) for p in paths]): |
20 | + ctxt['cms'] = True |
21 | + |
22 | if self.context_complete(ctxt): |
23 | return ctxt |
24 | |
25 | |
26 | === modified file 'hooks/hooks.py' |
27 | --- hooks/hooks.py 2015-10-08 12:13:08 +0000 |
28 | +++ hooks/hooks.py 2015-12-27 05:01:17 +0000 |
29 | @@ -13,14 +13,19 @@ |
30 | import glob |
31 | import os |
32 | import ceph |
33 | + |
34 | from charmhelpers.core.hookenv import ( |
35 | relation_get, |
36 | relation_ids, |
37 | + related_units, |
38 | config, |
39 | unit_get, |
40 | open_port, |
41 | relation_set, |
42 | - log, ERROR, |
43 | + log, |
44 | + DEBUG, |
45 | + WARNING, |
46 | + ERROR, |
47 | Hooks, UnregisteredHookError, |
48 | status_set, |
49 | ) |
50 | @@ -43,9 +48,11 @@ |
51 | REQUIRED_INTERFACES, |
52 | check_optional_relations, |
53 | ) |
54 | - |
55 | from charmhelpers.payload.execd import execd_preinstall |
56 | -from charmhelpers.core.host import cmp_pkgrevno |
57 | +from charmhelpers.core.host import ( |
58 | + cmp_pkgrevno, |
59 | + mkdir, |
60 | +) |
61 | |
62 | from charmhelpers.contrib.network.ip import ( |
63 | get_iface_for_address, |
64 | @@ -89,6 +96,11 @@ |
65 | 'radosgw', |
66 | 'ntp', |
67 | 'haproxy', |
68 | + 'libnss3-tools', |
69 | + 'python-keystoneclient', |
70 | + 'python-six', # Ensures correct version is installed for precise |
71 | + # since python-keystoneclient does not pull in icehouse |
72 | + # version |
73 | ] |
74 | |
75 | APACHE_PACKAGES = [ |
76 | @@ -155,6 +167,99 @@ |
77 | shutil.copy('files/ports.conf', '/etc/apache2/ports.conf') |
78 | |
79 | |
80 | +def setup_keystone_certs(unit=None, rid=None): |
81 | + """ |
82 | + Get CA and signing certs from Keystone used to decrypt revoked token list. |
83 | + """ |
84 | + import requests |
85 | + try: |
86 | + # Kilo and newer |
87 | + from keystoneclient.exceptions import ConnectionRefused |
88 | + except ImportError: |
89 | + # Juno and older |
90 | + from keystoneclient.exceptions import ConnectionError as \ |
91 | + ConnectionRefused |
92 | + |
93 | + from keystoneclient.v2_0 import client |
94 | + |
95 | + certs_path = '/var/lib/ceph/nss' |
96 | + mkdir(certs_path) |
97 | + |
98 | + rdata = relation_get(unit=unit, rid=rid) |
99 | + auth_protocol = rdata.get('auth_protocol', 'http') |
100 | + |
101 | + required_keys = ['admin_token', 'auth_host', 'auth_port'] |
102 | + settings = {} |
103 | + for key in required_keys: |
104 | + settings[key] = rdata.get(key) |
105 | + |
106 | + if not all(settings.values()): |
107 | + log("Missing relation settings (%s) - skipping cert setup" % |
108 | + (', '.join([k for k in settings.keys() if not settings[k]])), |
109 | + level=DEBUG) |
110 | + return |
111 | + |
112 | + auth_endpoint = "%s://%s:%s/v2.0" % (auth_protocol, settings['auth_host'], |
113 | + settings['auth_port']) |
114 | + keystone = client.Client(token=settings['admin_token'], |
115 | + endpoint=auth_endpoint) |
116 | + |
117 | + # CA |
118 | + try: |
119 | + # Kilo and newer |
120 | + ca_cert = keystone.certificates.get_ca_certificate() |
121 | + except AttributeError: |
122 | + # Juno and older |
123 | + ca_cert = requests.request('GET', auth_endpoint + |
124 | + '/certificates/ca').text |
125 | + except ConnectionRefused: |
126 | + log("Error connecting to keystone - skipping ca/signing cert setup", |
127 | + level=WARNING) |
128 | + return |
129 | + |
130 | + if ca_cert: |
131 | + log("Updating ca cert from keystone", level=DEBUG) |
132 | + ca = os.path.join(certs_path, 'ca.pem') |
133 | + with open(ca, 'w') as fd: |
134 | + fd.write(ca_cert) |
135 | + |
136 | + out = subprocess.check_output(['openssl', 'x509', '-in', ca, |
137 | + '-pubkey']) |
138 | + p = subprocess.Popen(['certutil', '-d', certs_path, '-A', '-n', 'ca', |
139 | + '-t', 'TCu,Cu,Tuw'], stdin=subprocess.PIPE) |
140 | + p.communicate(out) |
141 | + else: |
142 | + log("No ca cert available from keystone", level=DEBUG) |
143 | + |
144 | + # Signing cert |
145 | + try: |
146 | + # Kilo and newer |
147 | + signing_cert = keystone.certificates.get_signing_certificate() |
148 | + except AttributeError: |
149 | + # Juno and older |
150 | + signing_cert = requests.request('GET', auth_endpoint + |
151 | + '/certificates/signing').text |
152 | + except ConnectionRefused: |
153 | + log("Error connecting to keystone - skipping ca/signing cert setup", |
154 | + level=WARNING) |
155 | + return |
156 | + |
157 | + if signing_cert: |
158 | + log("Updating signing cert from keystone", level=DEBUG) |
159 | + signing_cert_path = os.path.join(certs_path, 'signing_certificate.pem') |
160 | + with open(signing_cert_path, 'w') as fd: |
161 | + fd.write(signing_cert) |
162 | + |
163 | + out = subprocess.check_output(['openssl', 'x509', '-in', |
164 | + signing_cert_path, '-pubkey']) |
165 | + p = subprocess.Popen(['certutil', '-A', '-d', certs_path, '-n', |
166 | + 'signing_cert', '-t', 'P,P,P'], |
167 | + stdin=subprocess.PIPE) |
168 | + p.communicate(out) |
169 | + else: |
170 | + log("No signing cert available from keystone", level=DEBUG) |
171 | + |
172 | + |
173 | @hooks.hook('upgrade-charm', |
174 | 'config-changed') |
175 | @restart_on_change({'/etc/ceph/ceph.conf': ['radosgw'], |
176 | @@ -170,8 +275,9 @@ |
177 | apache_modules() |
178 | apache_ports() |
179 | apache_reload() |
180 | + |
181 | for r_id in relation_ids('identity-service'): |
182 | - identity_joined(relid=r_id) |
183 | + identity_changed(relid=r_id) |
184 | |
185 | |
186 | @hooks.hook('mon-relation-departed', |
187 | @@ -225,10 +331,17 @@ |
188 | requested_roles=config('operator-roles'), |
189 | relation_id=relid) |
190 | |
191 | + if relid: |
192 | + for unit in related_units(relid): |
193 | + setup_keystone_certs(unit=unit, rid=relid) |
194 | + else: |
195 | + setup_keystone_certs() |
196 | + |
197 | |
198 | @hooks.hook('identity-service-relation-changed') |
199 | @restart_on_change({'/etc/ceph/ceph.conf': ['radosgw']}) |
200 | -def identity_changed(): |
201 | +def identity_changed(relid=None): |
202 | + identity_joined(relid) |
203 | CONFIGS.write_all() |
204 | restart() |
205 | |
206 | |
207 | === modified file 'templates/ceph.conf' |
208 | --- templates/ceph.conf 2015-11-26 16:20:26 +0000 |
209 | +++ templates/ceph.conf 2015-12-27 05:01:17 +0000 |
210 | @@ -31,5 +31,7 @@ |
211 | rgw keystone token cache size = {{ cache_size }} |
212 | rgw keystone revocation interval = {{ revocation_check_interval }} |
213 | rgw s3 auth use keystone = true |
214 | -#nss db path = /var/lib/ceph/nss |
215 | +{% if cms -%} |
216 | +nss db path = /var/lib/ceph/nss |
217 | +{% endif %} |
218 | {% endif %} |
219 | |
220 | === modified file 'unit_tests/test_hooks.py' |
221 | --- unit_tests/test_hooks.py 2015-11-03 11:58:54 +0000 |
222 | +++ unit_tests/test_hooks.py 2015-12-27 05:01:17 +0000 |
223 | @@ -43,6 +43,7 @@ |
224 | 'relation_ids', |
225 | 'relation_set', |
226 | 'relation_get', |
227 | + 'related_units', |
228 | 'render_template', |
229 | 'shutil', |
230 | 'status_set', |
231 | @@ -108,9 +109,8 @@ |
232 | self.add_source.assert_called_with('distro', 'secretkey') |
233 | self.assertTrue(self.apt_update.called) |
234 | self.assertFalse(_install_packages.called) |
235 | - self.apt_install.assert_called_with(['radosgw', |
236 | - 'ntp', |
237 | - 'haproxy'], fatal=True) |
238 | + self.apt_install.assert_called_with(ceph_hooks.PACKAGES, |
239 | + fatal=True) |
240 | self.apt_purge.assert_called_with(['libapache2-mod-fastcgi', |
241 | 'apache2']) |
242 | |
243 | @@ -167,6 +167,7 @@ |
244 | ] |
245 | self.subprocess.call.assert_has_calls(calls) |
246 | |
247 | + @patch.object(ceph_hooks, 'mkdir', lambda *args: None) |
248 | def test_config_changed(self): |
249 | _install_packages = self.patch('install_packages') |
250 | _emit_apacheconf = self.patch('emit_apacheconf') |
251 | @@ -221,12 +222,15 @@ |
252 | cmd = ['service', 'radosgw', 'restart'] |
253 | self.subprocess.call.assert_called_with(cmd) |
254 | |
255 | + @patch.object(ceph_hooks, 'setup_keystone_certs') |
256 | @patch('charmhelpers.contrib.openstack.ip.service_name', |
257 | lambda *args: 'ceph-radosgw') |
258 | @patch('charmhelpers.contrib.openstack.ip.config') |
259 | - def test_identity_joined_early_version(self, _config): |
260 | + def test_identity_joined_early_version(self, _config, |
261 | + mock_setup_keystone_certs): |
262 | self.cmp_pkgrevno.return_value = -1 |
263 | ceph_hooks.identity_joined() |
264 | + self.assertTrue(mock_setup_keystone_certs.called) |
265 | self.sys.exit.assert_called_with(1) |
266 | |
267 | @patch('charmhelpers.contrib.openstack.ip.service_name', |
268 | @@ -234,6 +238,7 @@ |
269 | @patch('charmhelpers.contrib.openstack.ip.resolve_address') |
270 | @patch('charmhelpers.contrib.openstack.ip.config') |
271 | def test_identity_joined(self, _config, _resolve_address): |
272 | + self.related_units = ['unit/0'] |
273 | self.cmp_pkgrevno.return_value = 1 |
274 | _resolve_address.return_value = 'myserv' |
275 | _config.side_effect = self.test_config.get |
276 | @@ -257,6 +262,7 @@ |
277 | @patch('charmhelpers.contrib.openstack.ip.config') |
278 | def test_identity_joined_public_name(self, _config, _unit_get, |
279 | _is_clustered): |
280 | + self.related_units = ['unit/0'] |
281 | _config.side_effect = self.test_config.get |
282 | self.test_config.set('os-public-hostname', 'files.example.com') |
283 | _unit_get.return_value = 'myserv' |
284 | @@ -271,11 +277,13 @@ |
285 | relation_id='rid', |
286 | admin_url='http://myserv:80/swift') |
287 | |
288 | - def test_identity_changed(self): |
289 | + @patch.object(ceph_hooks, 'identity_joined') |
290 | + def test_identity_changed(self, mock_identity_joined): |
291 | _restart = self.patch('restart') |
292 | ceph_hooks.identity_changed() |
293 | self.CONFIGS.write_all.assert_called_with() |
294 | self.assertTrue(_restart.called) |
295 | + self.assertTrue(mock_identity_joined.called) |
296 | |
297 | @patch('charmhelpers.contrib.openstack.ip.is_clustered') |
298 | @patch('charmhelpers.contrib.openstack.ip.unit_get') |
charm_lint_check #14695 ceph-radosgw-next for hopem mp279006
LINT OK: passed
Build: http:// 10.245. 162.77: 8080/job/ charm_lint_ check/14695/