Merge lp:~gnuoy/charms/trusty/glance/1453940-stable into lp:~openstack-charmers-archive/charms/trusty/glance/trunk

Proposed by Liam Young
Status: Merged
Merged at revision: 122
Proposed branch: lp:~gnuoy/charms/trusty/glance/1453940-stable
Merge into: lp:~openstack-charmers-archive/charms/trusty/glance/trunk
Diff against target: 623 lines (+294/-73)
11 files modified
hooks/charmhelpers/cli/__init__.py (+1/-5)
hooks/charmhelpers/cli/commands.py (+4/-4)
hooks/charmhelpers/cli/hookenv.py (+23/-0)
hooks/charmhelpers/contrib/openstack/context.py (+8/-9)
hooks/charmhelpers/contrib/openstack/utils.py (+7/-5)
hooks/charmhelpers/contrib/storage/linux/ceph.py (+224/-2)
hooks/charmhelpers/core/hookenv.py (+1/-20)
hooks/charmhelpers/core/host.py (+2/-2)
hooks/glance_relations.py (+13/-19)
templates/ceph.conf (+2/-1)
unit_tests/test_glance_relations.py (+9/-6)
To merge this branch: bzr merge lp:~gnuoy/charms/trusty/glance/1453940-stable
Reviewer Review Type Date Requested Status
Chris Glass (community) Approve
Review via email: mp+271262@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 #10410 glance for gnuoy mp271262
    LINT OK: passed

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

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

charm_amulet_test #6555 glance for gnuoy mp271262
    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/12514441/
Build: http://10.245.162.77:8080/job/charm_amulet_test/6555/

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

charm_unit_test #9626 glance for gnuoy mp271262
    UNIT OK: passed

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

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

charm_lint_check #10437 glance for gnuoy mp271262
    LINT OK: passed

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

125. By Liam Young

Empty commit to trigger osci

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

charm_lint_check #10458 glance for gnuoy mp271262
    LINT OK: passed

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

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

charm_unit_test #9648 glance for gnuoy mp271262
    UNIT OK: passed

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

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

charm_amulet_test #6582 glance for gnuoy mp271262
    AMULET OK: passed

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

Revision history for this message
Chris Glass (tribaal) wrote :

Looks good! +1

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

charm_amulet_test #6602 glance for gnuoy mp271262
    AMULET OK: passed

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

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'hooks/charmhelpers/cli/__init__.py'
2--- hooks/charmhelpers/cli/__init__.py 2015-08-10 16:34:51 +0000
3+++ hooks/charmhelpers/cli/__init__.py 2015-09-22 15:21:44 +0000
4@@ -152,15 +152,11 @@
5 arguments = self.argument_parser.parse_args()
6 argspec = inspect.getargspec(arguments.func)
7 vargs = []
8- kwargs = {}
9 for arg in argspec.args:
10 vargs.append(getattr(arguments, arg))
11 if argspec.varargs:
12 vargs.extend(getattr(arguments, argspec.varargs))
13- if argspec.keywords:
14- for kwarg in argspec.keywords.items():
15- kwargs[kwarg] = getattr(arguments, kwarg)
16- output = arguments.func(*vargs, **kwargs)
17+ output = arguments.func(*vargs)
18 if getattr(arguments.func, '_cli_test_command', False):
19 self.exit_code = 0 if output else 1
20 output = ''
21
22=== modified file 'hooks/charmhelpers/cli/commands.py'
23--- hooks/charmhelpers/cli/commands.py 2015-08-10 16:34:51 +0000
24+++ hooks/charmhelpers/cli/commands.py 2015-09-22 15:21:44 +0000
25@@ -26,7 +26,7 @@
26 """
27 Import the sub-modules which have decorated subcommands to register with chlp.
28 """
29-import host # noqa
30-import benchmark # noqa
31-import unitdata # noqa
32-from charmhelpers.core import hookenv # noqa
33+from . import host # noqa
34+from . import benchmark # noqa
35+from . import unitdata # noqa
36+from . import hookenv # noqa
37
38=== added file 'hooks/charmhelpers/cli/hookenv.py'
39--- hooks/charmhelpers/cli/hookenv.py 1970-01-01 00:00:00 +0000
40+++ hooks/charmhelpers/cli/hookenv.py 2015-09-22 15:21:44 +0000
41@@ -0,0 +1,23 @@
42+# Copyright 2014-2015 Canonical Limited.
43+#
44+# This file is part of charm-helpers.
45+#
46+# charm-helpers is free software: you can redistribute it and/or modify
47+# it under the terms of the GNU Lesser General Public License version 3 as
48+# published by the Free Software Foundation.
49+#
50+# charm-helpers is distributed in the hope that it will be useful,
51+# but WITHOUT ANY WARRANTY; without even the implied warranty of
52+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
53+# GNU Lesser General Public License for more details.
54+#
55+# You should have received a copy of the GNU Lesser General Public License
56+# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
57+
58+from . import cmdline
59+from charmhelpers.core import hookenv
60+
61+
62+cmdline.subcommand('relation-id')(hookenv.relation_id._wrapped)
63+cmdline.subcommand('service-name')(hookenv.service_name)
64+cmdline.subcommand('remote-service-name')(hookenv.remote_service_name._wrapped)
65
66=== modified file 'hooks/charmhelpers/contrib/openstack/context.py'
67--- hooks/charmhelpers/contrib/openstack/context.py 2015-08-10 16:34:51 +0000
68+++ hooks/charmhelpers/contrib/openstack/context.py 2015-09-22 15:21:44 +0000
69@@ -483,13 +483,15 @@
70
71 log('Generating template context for ceph', level=DEBUG)
72 mon_hosts = []
73- auth = None
74- key = None
75- use_syslog = str(config('use-syslog')).lower()
76+ ctxt = {
77+ 'use_syslog': str(config('use-syslog')).lower()
78+ }
79 for rid in relation_ids('ceph'):
80 for unit in related_units(rid):
81- auth = relation_get('auth', rid=rid, unit=unit)
82- key = relation_get('key', rid=rid, unit=unit)
83+ if not ctxt.get('auth'):
84+ ctxt['auth'] = relation_get('auth', rid=rid, unit=unit)
85+ if not ctxt.get('key'):
86+ ctxt['key'] = relation_get('key', rid=rid, unit=unit)
87 ceph_pub_addr = relation_get('ceph-public-address', rid=rid,
88 unit=unit)
89 unit_priv_addr = relation_get('private-address', rid=rid,
90@@ -498,10 +500,7 @@
91 ceph_addr = format_ipv6_addr(ceph_addr) or ceph_addr
92 mon_hosts.append(ceph_addr)
93
94- ctxt = {'mon_hosts': ' '.join(sorted(mon_hosts)),
95- 'auth': auth,
96- 'key': key,
97- 'use_syslog': use_syslog}
98+ ctxt['mon_hosts'] = ' '.join(sorted(mon_hosts))
99
100 if not os.path.isdir('/etc/ceph'):
101 os.mkdir('/etc/ceph')
102
103=== modified file 'hooks/charmhelpers/contrib/openstack/utils.py'
104--- hooks/charmhelpers/contrib/openstack/utils.py 2015-08-10 16:34:51 +0000
105+++ hooks/charmhelpers/contrib/openstack/utils.py 2015-09-22 15:21:44 +0000
106@@ -1,5 +1,3 @@
107-#!/usr/bin/python
108-
109 # Copyright 2014-2015 Canonical Limited.
110 #
111 # This file is part of charm-helpers.
112@@ -167,9 +165,9 @@
113 error_out(e)
114
115
116-def get_os_version_codename(codename):
117+def get_os_version_codename(codename, version_map=OPENSTACK_CODENAMES):
118 '''Determine OpenStack version number from codename.'''
119- for k, v in six.iteritems(OPENSTACK_CODENAMES):
120+ for k, v in six.iteritems(version_map):
121 if v == codename:
122 return k
123 e = 'Could not derive OpenStack version for '\
124@@ -392,7 +390,11 @@
125 import apt_pkg as apt
126 src = config('openstack-origin')
127 cur_vers = get_os_version_package(package)
128- available_vers = get_os_version_install_source(src)
129+ if "swift" in package:
130+ codename = get_os_codename_install_source(src)
131+ available_vers = get_os_version_codename(codename, SWIFT_CODENAMES)
132+ else:
133+ available_vers = get_os_version_install_source(src)
134 apt.init()
135 return apt.version_compare(available_vers, cur_vers) == 1
136
137
138=== modified file 'hooks/charmhelpers/contrib/storage/linux/ceph.py'
139--- hooks/charmhelpers/contrib/storage/linux/ceph.py 2015-08-10 16:34:51 +0000
140+++ hooks/charmhelpers/contrib/storage/linux/ceph.py 2015-09-22 15:21:44 +0000
141@@ -28,6 +28,7 @@
142 import shutil
143 import json
144 import time
145+import uuid
146
147 from subprocess import (
148 check_call,
149@@ -35,8 +36,10 @@
150 CalledProcessError,
151 )
152 from charmhelpers.core.hookenv import (
153+ local_unit,
154 relation_get,
155 relation_ids,
156+ relation_set,
157 related_units,
158 log,
159 DEBUG,
160@@ -411,17 +414,52 @@
161
162 The API is versioned and defaults to version 1.
163 """
164- def __init__(self, api_version=1):
165+ def __init__(self, api_version=1, request_id=None):
166 self.api_version = api_version
167+ if request_id:
168+ self.request_id = request_id
169+ else:
170+ self.request_id = str(uuid.uuid1())
171 self.ops = []
172
173 def add_op_create_pool(self, name, replica_count=3):
174 self.ops.append({'op': 'create-pool', 'name': name,
175 'replicas': replica_count})
176
177+ def set_ops(self, ops):
178+ """Set request ops to provided value.
179+
180+ Useful for injecting ops that come from a previous request
181+ to allow comparisons to ensure validity.
182+ """
183+ self.ops = ops
184+
185 @property
186 def request(self):
187- return json.dumps({'api-version': self.api_version, 'ops': self.ops})
188+ return json.dumps({'api-version': self.api_version, 'ops': self.ops,
189+ 'request-id': self.request_id})
190+
191+ def _ops_equal(self, other):
192+ if len(self.ops) == len(other.ops):
193+ for req_no in range(0, len(self.ops)):
194+ for key in ['replicas', 'name', 'op']:
195+ if self.ops[req_no][key] != other.ops[req_no][key]:
196+ return False
197+ else:
198+ return False
199+ return True
200+
201+ def __eq__(self, other):
202+ if not isinstance(other, self.__class__):
203+ return False
204+ if self.api_version == other.api_version and \
205+ self._ops_equal(other):
206+ return True
207+ else:
208+ return False
209+
210+ def __ne__(self, other):
211+ return not self.__eq__(other)
212
213
214 class CephBrokerRsp(object):
215@@ -431,14 +469,198 @@
216
217 The API is versioned and defaults to version 1.
218 """
219+
220 def __init__(self, encoded_rsp):
221 self.api_version = None
222 self.rsp = json.loads(encoded_rsp)
223
224 @property
225+ def request_id(self):
226+ return self.rsp.get('request-id')
227+
228+ @property
229 def exit_code(self):
230 return self.rsp.get('exit-code')
231
232 @property
233 def exit_msg(self):
234 return self.rsp.get('stderr')
235+
236+
237+# Ceph Broker Conversation:
238+# If a charm needs an action to be taken by ceph it can create a CephBrokerRq
239+# and send that request to ceph via the ceph relation. The CephBrokerRq has a
240+# unique id so that the client can identity which CephBrokerRsp is associated
241+# with the request. Ceph will also respond to each client unit individually
242+# creating a response key per client unit eg glance/0 will get a CephBrokerRsp
243+# via key broker-rsp-glance-0
244+#
245+# To use this the charm can just do something like:
246+#
247+# from charmhelpers.contrib.storage.linux.ceph import (
248+# send_request_if_needed,
249+# is_request_complete,
250+# CephBrokerRq,
251+# )
252+#
253+# @hooks.hook('ceph-relation-changed')
254+# def ceph_changed():
255+# rq = CephBrokerRq()
256+# rq.add_op_create_pool(name='poolname', replica_count=3)
257+#
258+# if is_request_complete(rq):
259+# <Request complete actions>
260+# else:
261+# send_request_if_needed(get_ceph_request())
262+#
263+# CephBrokerRq and CephBrokerRsp are serialized into JSON. Below is an example
264+# of glance having sent a request to ceph which ceph has successfully processed
265+# 'ceph:8': {
266+# 'ceph/0': {
267+# 'auth': 'cephx',
268+# 'broker-rsp-glance-0': '{"request-id": "0bc7dc54", "exit-code": 0}',
269+# 'broker_rsp': '{"request-id": "0da543b8", "exit-code": 0}',
270+# 'ceph-public-address': '10.5.44.103',
271+# 'key': 'AQCLDttVuHXINhAAvI144CB09dYchhHyTUY9BQ==',
272+# 'private-address': '10.5.44.103',
273+# },
274+# 'glance/0': {
275+# 'broker_req': ('{"api-version": 1, "request-id": "0bc7dc54", '
276+# '"ops": [{"replicas": 3, "name": "glance", '
277+# '"op": "create-pool"}]}'),
278+# 'private-address': '10.5.44.109',
279+# },
280+# }
281+
282+def get_previous_request(rid):
283+ """Return the last ceph broker request sent on a given relation
284+
285+ @param rid: Relation id to query for request
286+ """
287+ request = None
288+ broker_req = relation_get(attribute='broker_req', rid=rid,
289+ unit=local_unit())
290+ if broker_req:
291+ request_data = json.loads(broker_req)
292+ request = CephBrokerRq(api_version=request_data['api-version'],
293+ request_id=request_data['request-id'])
294+ request.set_ops(request_data['ops'])
295+
296+ return request
297+
298+
299+def get_request_states(request):
300+ """Return a dict of requests per relation id with their corresponding
301+ completion state.
302+
303+ This allows a charm, which has a request for ceph, to see whether there is
304+ an equivalent request already being processed and if so what state that
305+ request is in.
306+
307+ @param request: A CephBrokerRq object
308+ """
309+ complete = []
310+ requests = {}
311+ for rid in relation_ids('ceph'):
312+ complete = False
313+ previous_request = get_previous_request(rid)
314+ if request == previous_request:
315+ sent = True
316+ complete = is_request_complete_for_rid(previous_request, rid)
317+ else:
318+ sent = False
319+ complete = False
320+
321+ requests[rid] = {
322+ 'sent': sent,
323+ 'complete': complete,
324+ }
325+
326+ return requests
327+
328+
329+def is_request_sent(request):
330+ """Check to see if a functionally equivalent request has already been sent
331+
332+ Returns True if a similair request has been sent
333+
334+ @param request: A CephBrokerRq object
335+ """
336+ states = get_request_states(request)
337+ for rid in states.keys():
338+ if not states[rid]['sent']:
339+ return False
340+
341+ return True
342+
343+
344+def is_request_complete(request):
345+ """Check to see if a functionally equivalent request has already been
346+ completed
347+
348+ Returns True if a similair request has been completed
349+
350+ @param request: A CephBrokerRq object
351+ """
352+ states = get_request_states(request)
353+ for rid in states.keys():
354+ if not states[rid]['complete']:
355+ return False
356+
357+ return True
358+
359+
360+def is_request_complete_for_rid(request, rid):
361+ """Check if a given request has been completed on the given relation
362+
363+ @param request: A CephBrokerRq object
364+ @param rid: Relation ID
365+ """
366+ broker_key = get_broker_rsp_key()
367+ for unit in related_units(rid):
368+ rdata = relation_get(rid=rid, unit=unit)
369+ if rdata.get(broker_key):
370+ rsp = CephBrokerRsp(rdata.get(broker_key))
371+ if rsp.request_id == request.request_id:
372+ if not rsp.exit_code:
373+ return True
374+ else:
375+ # The remote unit sent no reply targeted at this unit so either the
376+ # remote ceph cluster does not support unit targeted replies or it
377+ # has not processed our request yet.
378+ if rdata.get('broker_rsp'):
379+ request_data = json.loads(rdata['broker_rsp'])
380+ if request_data.get('request-id'):
381+ log('Ignoring legacy broker_rsp without unit key as remote '
382+ 'service supports unit specific replies', level=DEBUG)
383+ else:
384+ log('Using legacy broker_rsp as remote service does not '
385+ 'supports unit specific replies', level=DEBUG)
386+ rsp = CephBrokerRsp(rdata['broker_rsp'])
387+ if not rsp.exit_code:
388+ return True
389+
390+ return False
391+
392+
393+def get_broker_rsp_key():
394+ """Return broker response key for this unit
395+
396+ This is the key that ceph is going to use to pass request status
397+ information back to this unit
398+ """
399+ return 'broker-rsp-' + local_unit().replace('/', '-')
400+
401+
402+def send_request_if_needed(request):
403+ """Send broker request if an equivalent request has not already been sent
404+
405+ @param request: A CephBrokerRq object
406+ """
407+ if is_request_sent(request):
408+ log('Request already sent but not complete, not sending new request',
409+ level=DEBUG)
410+ else:
411+ for rid in relation_ids('ceph'):
412+ log('Sending request {}'.format(request.request_id), level=DEBUG)
413+ relation_set(relation_id=rid, broker_req=request.request)
414
415=== modified file 'hooks/charmhelpers/core/hookenv.py'
416--- hooks/charmhelpers/core/hookenv.py 2015-08-10 16:34:51 +0000
417+++ hooks/charmhelpers/core/hookenv.py 2015-09-22 15:21:44 +0000
418@@ -34,23 +34,6 @@
419 import tempfile
420 from subprocess import CalledProcessError
421
422-try:
423- from charmhelpers.cli import cmdline
424-except ImportError as e:
425- # due to the anti-pattern of partially synching charmhelpers directly
426- # into charms, it's possible that charmhelpers.cli is not available;
427- # if that's the case, they don't really care about using the cli anyway,
428- # so mock it out
429- if str(e) == 'No module named cli':
430- class cmdline(object):
431- @classmethod
432- def subcommand(cls, *args, **kwargs):
433- def _wrap(func):
434- return func
435- return _wrap
436- else:
437- raise
438-
439 import six
440 if not six.PY3:
441 from UserDict import UserDict
442@@ -91,6 +74,7 @@
443 res = func(*args, **kwargs)
444 cache[key] = res
445 return res
446+ wrapper._wrapped = func
447 return wrapper
448
449
450@@ -190,7 +174,6 @@
451 return os.environ.get('JUJU_RELATION', None)
452
453
454-@cmdline.subcommand()
455 @cached
456 def relation_id(relation_name=None, service_or_unit=None):
457 """The relation ID for the current or a specified relation"""
458@@ -216,13 +199,11 @@
459 return os.environ.get('JUJU_REMOTE_UNIT', None)
460
461
462-@cmdline.subcommand()
463 def service_name():
464 """The name service group this unit belongs to"""
465 return local_unit().split('/')[0]
466
467
468-@cmdline.subcommand()
469 @cached
470 def remote_service_name(relid=None):
471 """The remote service name for a given relation-id (or the current relation)"""
472
473=== modified file 'hooks/charmhelpers/core/host.py'
474--- hooks/charmhelpers/core/host.py 2015-08-10 16:34:51 +0000
475+++ hooks/charmhelpers/core/host.py 2015-09-22 15:21:44 +0000
476@@ -72,7 +72,7 @@
477 stopped = service_stop(service_name)
478 # XXX: Support systemd too
479 override_path = os.path.join(
480- init_dir, '{}.conf.override'.format(service_name))
481+ init_dir, '{}.override'.format(service_name))
482 with open(override_path, 'w') as fh:
483 fh.write("manual\n")
484 return stopped
485@@ -86,7 +86,7 @@
486 if init_dir is None:
487 init_dir = "/etc/init"
488 override_path = os.path.join(
489- init_dir, '{}.conf.override'.format(service_name))
490+ init_dir, '{}.override'.format(service_name))
491 if os.path.exists(override_path):
492 os.unlink(override_path)
493 started = service_start(service_name)
494
495=== modified file 'hooks/glance_relations.py'
496--- hooks/glance_relations.py 2015-08-10 16:34:51 +0000
497+++ hooks/glance_relations.py 2015-09-22 15:21:44 +0000
498@@ -29,7 +29,6 @@
499 config,
500 Hooks,
501 log as juju_log,
502- INFO,
503 ERROR,
504 open_port,
505 is_relation_made,
506@@ -66,9 +65,10 @@
507 sync_db_with_multi_ipv6_addresses,
508 )
509 from charmhelpers.contrib.storage.linux.ceph import (
510+ send_request_if_needed,
511+ is_request_complete,
512 ensure_ceph_keyring,
513 CephBrokerRq,
514- CephBrokerRsp,
515 delete_keyring,
516 )
517 from charmhelpers.payload.execd import (
518@@ -240,6 +240,14 @@
519 apt_install(['ceph-common', 'python-ceph'])
520
521
522+def get_ceph_request():
523+ service = service_name()
524+ rq = CephBrokerRq()
525+ replicas = config('ceph-osd-replication-count')
526+ rq.add_op_create_pool(name=service, replica_count=replicas)
527+ return rq
528+
529+
530 @hooks.hook('ceph-relation-changed')
531 @restart_on_change(restart_map())
532 def ceph_changed():
533@@ -253,29 +261,15 @@
534 juju_log('Could not create ceph keyring: peer not ready?')
535 return
536
537- settings = relation_get()
538- if settings and 'broker_rsp' in settings:
539- rsp = CephBrokerRsp(settings['broker_rsp'])
540- # Non-zero return code implies failure
541- if rsp.exit_code:
542- juju_log("Ceph broker request failed (rc=%s, msg=%s)" %
543- (rsp.exit_code, rsp.exit_msg), level=ERROR)
544- return
545-
546- juju_log("Ceph broker request succeeded (rc=%s, msg=%s)" %
547- (rsp.exit_code, rsp.exit_msg), level=INFO)
548+ if is_request_complete(get_ceph_request()):
549+ juju_log('Request complete')
550 CONFIGS.write(GLANCE_API_CONF)
551 CONFIGS.write(ceph_config_file())
552 # Ensure that glance-api is restarted since only now can we
553 # guarantee that ceph resources are ready.
554 service_restart('glance-api')
555 else:
556- rq = CephBrokerRq()
557- replicas = config('ceph-osd-replication-count')
558- rq.add_op_create_pool(name=service, replica_count=replicas)
559- for rid in relation_ids('ceph'):
560- relation_set(relation_id=rid, broker_req=rq.request)
561- juju_log("Request(s) sent to Ceph broker (rid=%s)" % (rid))
562+ send_request_if_needed(get_ceph_request())
563
564
565 @hooks.hook('ceph-relation-broken')
566
567=== modified file 'templates/ceph.conf'
568--- templates/ceph.conf 2014-03-25 18:44:22 +0000
569+++ templates/ceph.conf 2015-09-22 15:21:44 +0000
570@@ -10,7 +10,8 @@
571 keyring = /etc/ceph/ceph.$name.keyring
572 mon host = {{ mon_hosts }}
573 {% endif -%}
574+{% if use_syslog -%}
575 log to syslog = {{ use_syslog }}
576 err to syslog = {{ use_syslog }}
577 clog to syslog = {{ use_syslog }}
578-
579+{% endif -%}
580
581=== modified file 'unit_tests/test_glance_relations.py'
582--- unit_tests/test_glance_relations.py 2015-08-10 16:34:51 +0000
583+++ unit_tests/test_glance_relations.py 2015-09-22 15:21:44 +0000
584@@ -68,6 +68,9 @@
585 'get_ipv6_addr',
586 'sync_db_with_multi_ipv6_addresses',
587 'delete_keyring',
588+ 'is_request_complete',
589+ 'send_request_if_needed',
590+ 'CephBrokerRq',
591 ]
592
593
594@@ -398,24 +401,24 @@
595 'Could not create ceph keyring: peer not ready?'
596 )
597
598+ @patch("glance_relations.get_ceph_request")
599 @patch("glance_relations.relation_set")
600 @patch("glance_relations.relation_get")
601 @patch.object(relations, 'CONFIGS')
602 def test_ceph_changed_broker_send_rq(self, configs, mock_relation_get,
603- mock_relation_set):
604+ mock_relation_set,
605+ mock_get_ceph_request):
606+ mock_get_ceph_request.return_value = "CephRequest"
607 configs.complete_contexts.return_value = ['ceph']
608 self.service_name.return_value = 'glance'
609 self.ensure_ceph_keyring.return_value = True
610 self.relation_ids.return_value = ['ceph:0']
611+ self.is_request_complete.return_value = False
612 relations.hooks.execute(['hooks/ceph-relation-changed'])
613 self.ensure_ceph_keyring.assert_called_with(service='glance',
614 user='glance',
615 group='glance')
616- req = {'api-version': 1,
617- 'ops': [{"op": "create-pool", "name": "glance", "replicas": 3}]}
618- broker_dict = json.dumps(req)
619- mock_relation_set.assert_called_with(broker_req=broker_dict,
620- relation_id='ceph:0')
621+ self.send_request_if_needed.assert_called_with("CephRequest")
622 for c in [call('/etc/glance/glance.conf')]:
623 self.assertNotIn(c, configs.write.call_args_list)
624

Subscribers

People subscribed via source and target branches