Merge lp:~hopem/charms/trusty/cinder/lp1493931-stable into lp:~openstack-charmers-archive/charms/trusty/cinder/trunk

Proposed by Edward Hope-Morley
Status: Merged
Merged at revision: 99
Proposed branch: lp:~hopem/charms/trusty/cinder/lp1493931-stable
Merge into: lp:~openstack-charmers-archive/charms/trusty/cinder/trunk
Diff against target: 292 lines (+252/-2)
3 files modified
hooks/cinder_contexts.py (+45/-1)
hooks/cinder_utils.py (+1/-1)
unit_tests/test_cinder_contexts.py (+206/-0)
To merge this branch: bzr merge lp:~hopem/charms/trusty/cinder/lp1493931-stable
Reviewer Review Type Date Requested Status
Liam Young (community) Approve
Review via email: mp+271296@code.launchpad.net
To post a comment you must log in.
Revision history for this message
uosci-testing-bot (uosci-testing-bot) wrote :

charm_lint_check #10185 cinder for hopem mp271296
    LINT OK: passed

Build: http://10.245.162.77:8080/job/charm_lint_check/10185/

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

charm_unit_test #9343 cinder for hopem mp271296
    UNIT OK: passed

Build: http://10.245.162.77:8080/job/charm_unit_test/9343/

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

charm_amulet_test #6474 cinder for hopem mp271296
    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://paste.ubuntu.com/12437382/
Build: http://10.245.162.77:8080/job/charm_amulet_test/6474/

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

charm_lint_check #10423 cinder for hopem mp271296
    LINT OK: passed

Build: http://10.245.162.77:8080/job/charm_lint_check/10423/

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

charm_unit_test #9616 cinder for hopem mp271296
    UNIT OK: passed

Build: http://10.245.162.77:8080/job/charm_unit_test/9616/

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

charm_amulet_test #6570 cinder for hopem mp271296
    AMULET OK: passed

Build: http://10.245.162.77:8080/job/charm_amulet_test/6570/

Revision history for this message
Liam Young (gnuoy) wrote :

Approve

review: Approve
Revision history for this message
Liam Young (gnuoy) wrote :

Approve

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'hooks/cinder_contexts.py'
2--- hooks/cinder_contexts.py 2014-11-25 10:19:07 +0000
3+++ hooks/cinder_contexts.py 2015-09-16 12:59:43 +0000
4@@ -3,12 +3,15 @@
5 relation_ids,
6 service_name,
7 related_units,
8- relation_get
9+ relation_get,
10+ log,
11+ WARNING,
12 )
13
14 from charmhelpers.contrib.openstack.context import (
15 OSContextGenerator,
16 ApacheSSLContext as SSLContext,
17+ SubordinateConfigContext,
18 )
19
20 from charmhelpers.contrib.openstack.utils import (
21@@ -110,3 +113,44 @@
22
23 def __call__(self):
24 return {'debug': config('debug'), 'verbose': config('verbose')}
25+
26+
27+class CinderSubordinateConfigContext(SubordinateConfigContext):
28+
29+ def __call__(self):
30+ ctxt = super(CinderSubordinateConfigContext, self).__call__()
31+
32+ # If all backends are stateless we can allow host setting to be set
33+ # across hosts/units to allow for HA volume failover but otherwise we
34+ # have to leave it as unique (LP: #1493931).
35+ rids = []
36+ for interface in self.interfaces:
37+ rids.extend(relation_ids(interface))
38+
39+ stateless = None
40+ any_stateless = False
41+ for rid in rids:
42+ for unit in related_units(rid):
43+ val = relation_get('stateless', rid=rid, unit=unit) or ""
44+ if val.lower() == 'true':
45+ if stateless is None:
46+ stateless = True
47+ else:
48+ stateless = stateless and True
49+ else:
50+ stateless = False
51+
52+ any_stateless = any_stateless or stateless
53+
54+ if stateless:
55+ if 'DEFAULT' in ctxt['sections']:
56+ ctxt['sections']['DEFAULT'].append(('host', service_name()))
57+ else:
58+ ctxt['sections']['DEFAULT'] = [('host', service_name())]
59+
60+ elif any_stateless:
61+ log("One or more stateless backends configured but unable to "
62+ "set host param since there appear to also be stateful "
63+ "backends configured.", level=WARNING)
64+
65+ return ctxt
66
67=== modified file 'hooks/cinder_utils.py'
68--- hooks/cinder_utils.py 2015-08-10 16:34:04 +0000
69+++ hooks/cinder_utils.py 2015-09-16 12:59:43 +0000
70@@ -172,7 +172,7 @@
71 cinder_contexts.CephContext(),
72 cinder_contexts.HAProxyContext(),
73 cinder_contexts.ImageServiceContext(),
74- context.SubordinateConfigContext(
75+ cinder_contexts.CinderSubordinateConfigContext(
76 interface='storage-backend',
77 service='cinder',
78 config_file=CINDER_CONF),
79
80=== modified file 'unit_tests/test_cinder_contexts.py'
81--- unit_tests/test_cinder_contexts.py 2014-10-01 22:07:44 +0000
82+++ unit_tests/test_cinder_contexts.py 2015-09-16 12:59:43 +0000
83@@ -135,3 +135,209 @@
84 'namespace': 'cinder'})
85 self.assertTrue(mock_https.called)
86 mock_unit_get.assert_called_with('private-address')
87+
88+ @patch('%s.relation_get' % (mod_ch_context))
89+ @patch('%s.related_units' % (mod_ch_context))
90+ @patch('%s.relation_ids' % (mod_ch_context))
91+ @patch('%s.log' % (mod_ch_context), lambda *args, **kwargs: None)
92+ def test_subordinate_config_context_stateless(self, mock_rel_ids,
93+ mock_rel_units,
94+ mock_rel_get):
95+ mock_rel_ids.return_value = ['storage-backend:0']
96+ self.relation_ids.return_value = ['storage-backend:0']
97+
98+ mock_rel_units.return_value = ['cinder-ceph/0']
99+ self.related_units.return_value = ['cinder-ceph/0']
100+
101+ self.service_name.return_value = 'cinder'
102+
103+ settings = \
104+ {'backend_name': 'cinder-ceph',
105+ 'private-address': '10.5.8.191',
106+ 'stateless': 'True',
107+ 'subordinate_configuration':
108+ '{"cinder": '
109+ '{"/etc/cinder/cinder.conf": '
110+ '{"sections": '
111+ '{"cinder-ceph": '
112+ '[["volume_backend_name", '
113+ '"cinder-ceph"], '
114+ '["volume_driver", '
115+ '"cinder.volume.drivers.rbd.RBDDriver"], '
116+ '["rbd_pool", '
117+ '"cinder-ceph"], '
118+ '["rbd_user", '
119+ '"cinder-ceph"]]}}}}'}
120+
121+ def fake_rel_get(attribute=None, unit=None, rid=None):
122+ return settings.get(attribute)
123+
124+ mock_rel_get.side_effect = fake_rel_get
125+ self.relation_get.side_effect = fake_rel_get
126+
127+ ctxt = contexts.CinderSubordinateConfigContext(
128+ interface='storage-backend',
129+ service='cinder',
130+ config_file='/etc/cinder/cinder.conf')()
131+
132+ exp = {'sections': {'DEFAULT': [('host', 'cinder')],
133+ u'cinder-ceph': [[u'volume_backend_name', u'cinder-ceph'],
134+ [u'volume_driver',
135+ u'cinder.volume.drivers.rbd.RBDDriver'],
136+ [u'rbd_pool', u'cinder-ceph'],
137+ [u'rbd_user', u'cinder-ceph']]}}
138+
139+ self.assertEquals(ctxt, exp)
140+
141+ @patch('%s.relation_get' % (mod_ch_context))
142+ @patch('%s.related_units' % (mod_ch_context))
143+ @patch('%s.relation_ids' % (mod_ch_context))
144+ @patch('%s.log' % (mod_ch_context), lambda *args, **kwargs: None)
145+ def test_subordinate_config_context_statefull(self, mock_rel_ids,
146+ mock_rel_units,
147+ mock_rel_get):
148+ mock_rel_ids.return_value = ['storage-backend:0']
149+ self.relation_ids.return_value = ['storage-backend:0']
150+
151+ mock_rel_units.return_value = ['cinder-ceph/0']
152+ self.related_units.return_value = ['cinder-ceph/0']
153+
154+ self.service_name.return_value = 'cinder'
155+
156+ settings = \
157+ {'backend_name': 'cinder-ceph',
158+ 'private-address': '10.5.8.191',
159+ 'stateless': 'False',
160+ 'subordinate_configuration':
161+ '{"cinder": '
162+ '{"/etc/cinder/cinder.conf": '
163+ '{"sections": '
164+ '{"cinder-ceph": '
165+ '[["volume_backend_name", '
166+ '"cinder-ceph"], '
167+ '["volume_driver", '
168+ '"cinder.volume.drivers.rbd.RBDDriver"], '
169+ '["rbd_pool", '
170+ '"cinder-ceph"], '
171+ '["rbd_user", '
172+ '"cinder-ceph"]]}}}}'}
173+
174+ def fake_rel_get(attribute=None, unit=None, rid=None):
175+ return settings.get(attribute)
176+
177+ mock_rel_get.side_effect = fake_rel_get
178+ self.relation_get.side_effect = fake_rel_get
179+
180+ ctxt = contexts.CinderSubordinateConfigContext(
181+ interface='storage-backend',
182+ service='cinder',
183+ config_file='/etc/cinder/cinder.conf')()
184+
185+ exp = {'sections':
186+ {u'cinder-ceph': [[u'volume_backend_name',
187+ u'cinder-ceph'],
188+ [u'volume_driver',
189+ u'cinder.volume.drivers.rbd.RBDDriver'],
190+ [u'rbd_pool', u'cinder-ceph'],
191+ [u'rbd_user', u'cinder-ceph']]}}
192+
193+ self.assertEquals(ctxt, exp)
194+
195+ del settings['stateless']
196+
197+ ctxt = contexts.CinderSubordinateConfigContext(
198+ interface='storage-backend',
199+ service='cinder',
200+ config_file='/etc/cinder/cinder.conf')()
201+
202+ exp = {'sections':
203+ {u'cinder-ceph': [[u'volume_backend_name',
204+ u'cinder-ceph'],
205+ [u'volume_driver',
206+ u'cinder.volume.drivers.rbd.RBDDriver'],
207+ [u'rbd_pool', u'cinder-ceph'],
208+ [u'rbd_user', u'cinder-ceph']]}}
209+
210+ self.assertEquals(ctxt, exp)
211+
212+ @patch('%s.relation_get' % (mod_ch_context))
213+ @patch('%s.related_units' % (mod_ch_context))
214+ @patch('%s.relation_ids' % (mod_ch_context))
215+ @patch.object(contexts, 'log', lambda *args, **kwargs: None)
216+ @patch('%s.log' % (mod_ch_context), lambda *args, **kwargs: None)
217+ def test_subordinate_config_context_mixed(self, mock_rel_ids,
218+ mock_rel_units,
219+ mock_rel_get):
220+ mock_rel_ids.return_value = ['storage-backend:0', 'storage-backend:1']
221+ self.relation_ids.return_value = ['storage-backend:0',
222+ 'storage-backend:1']
223+
224+ def fake_rel_units(rid):
225+ if rid == 'storage-backend:0':
226+ return ['cinder-ceph/0']
227+ else:
228+ return ['cinder-other/0']
229+
230+ mock_rel_units.side_effect = fake_rel_units
231+ self.related_units.side_effect = fake_rel_units
232+
233+ self.service_name.return_value = 'cinder'
234+
235+ cinder_ceph_settings = \
236+ {'backend_name': 'cinder-ceph',
237+ 'private-address': '10.5.8.191',
238+ 'stateless': 'True',
239+ 'subordinate_configuration':
240+ '{"cinder": '
241+ '{"/etc/cinder/cinder.conf": '
242+ '{"sections": '
243+ '{"cinder-ceph": '
244+ '[["volume_backend_name", '
245+ '"cinder-ceph"], '
246+ '["volume_driver", '
247+ '"cinder.volume.drivers.rbd.RBDDriver"], '
248+ '["rbd_pool", '
249+ '"cinder-ceph"], '
250+ '["rbd_user", '
251+ '"cinder-ceph"]]}}}}'}
252+
253+ cinder_other_settings = \
254+ {'backend_name': 'cinder-other',
255+ 'private-address': '10.5.8.192',
256+ 'subordinate_configuration':
257+ '{"cinder": '
258+ '{"/etc/cinder/cinder.conf": '
259+ '{"sections": '
260+ '{"cinder-other": '
261+ '[["volume_backend_name", '
262+ '"cinder-other"], '
263+ '["volume_driver", '
264+ '"cinder.volume.drivers.OtherDriver"]]}}}}'}
265+
266+ def fake_rel_get(attribute=None, unit=None, rid=None):
267+ if unit == 'cinder-ceph/0':
268+ return cinder_ceph_settings.get(attribute)
269+ elif unit == 'cinder-other/0':
270+ return cinder_other_settings.get(attribute)
271+
272+ mock_rel_get.side_effect = fake_rel_get
273+ self.relation_get.side_effect = fake_rel_get
274+
275+ ctxt = contexts.CinderSubordinateConfigContext(
276+ interface='storage-backend',
277+ service='cinder',
278+ config_file='/etc/cinder/cinder.conf')()
279+
280+ exp = {'sections':
281+ {u'cinder-ceph': [[u'volume_backend_name',
282+ u'cinder-ceph'],
283+ [u'volume_driver',
284+ u'cinder.volume.drivers.rbd.RBDDriver'],
285+ [u'rbd_pool', u'cinder-ceph'],
286+ [u'rbd_user', u'cinder-ceph']],
287+ u'cinder-other': [[u'volume_backend_name',
288+ u'cinder-other'],
289+ [u'volume_driver',
290+ u'cinder.volume.drivers.OtherDriver']]}}
291+
292+ self.assertEquals(ctxt, exp)

Subscribers

People subscribed via source and target branches