Merge lp:~tribaal/charms/trusty/keystone/update-stable-charm-helpers into lp:~openstack-charmers-archive/charms/trusty/keystone/trunk
- Trusty Tahr (14.04)
- update-stable-charm-helpers
- Merge into trunk
Status: | Rejected | ||||
---|---|---|---|---|---|
Rejected by: | Chris Glass | ||||
Proposed branch: | lp:~tribaal/charms/trusty/keystone/update-stable-charm-helpers | ||||
Merge into: | lp:~openstack-charmers-archive/charms/trusty/keystone/trunk | ||||
Diff against target: |
534 lines (+257/-53) 10 files modified
hooks/charmhelpers/cli/__init__.py (+1/-5) hooks/charmhelpers/cli/commands.py (+4/-4) hooks/charmhelpers/contrib/network/ip.py (+5/-3) hooks/charmhelpers/contrib/openstack/context.py (+8/-9) hooks/charmhelpers/contrib/openstack/templating.py (+2/-1) hooks/charmhelpers/contrib/openstack/utils.py (+7/-5) hooks/charmhelpers/contrib/storage/linux/ceph.py (+224/-2) hooks/charmhelpers/contrib/storage/linux/utils.py (+3/-2) hooks/charmhelpers/core/hookenv.py (+1/-20) hooks/charmhelpers/core/host.py (+2/-2) |
||||
To merge this branch: | bzr merge lp:~tribaal/charms/trusty/keystone/update-stable-charm-helpers | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
OpenStack Charmers | Pending | ||
Review via email:
|
Commit message
Description of the change
This syncs charm-helpers from lp:~openstack-charmers/charm-helpers/stable (using "make sync").
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
uosci-testing-bot (uosci-testing-bot) wrote : | # |
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
uosci-testing-bot (uosci-testing-bot) wrote : | # |
charm_unit_test #9405 keystone for tribaal mp271661
UNIT OK: passed
- 156. By Chris Glass
-
Updated charm-helpers again.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
uosci-testing-bot (uosci-testing-bot) wrote : | # |
charm_amulet_test #6491 keystone for tribaal mp271661
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://
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
uosci-testing-bot (uosci-testing-bot) wrote : | # |
charm_lint_check #10251 keystone for tribaal mp271661
LINT OK: passed
Build: http://
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
uosci-testing-bot (uosci-testing-bot) wrote : | # |
charm_unit_test #9406 keystone for tribaal mp271661
UNIT OK: passed
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
uosci-testing-bot (uosci-testing-bot) wrote : | # |
charm_amulet_test #6493 keystone for tribaal mp271661
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://
Unmerged revisions
- 156. By Chris Glass
-
Updated charm-helpers again.
- 155. By Chris Glass
-
Updated charm-helpers from lp:~openstack-charmers/charm-helpers/stable
Preview Diff
1 | === modified file 'hooks/charmhelpers/cli/__init__.py' | |||
2 | --- hooks/charmhelpers/cli/__init__.py 2015-08-10 16:35:40 +0000 | |||
3 | +++ hooks/charmhelpers/cli/__init__.py 2015-09-18 14:18:53 +0000 | |||
4 | @@ -152,15 +152,11 @@ | |||
5 | 152 | arguments = self.argument_parser.parse_args() | 152 | arguments = self.argument_parser.parse_args() |
6 | 153 | argspec = inspect.getargspec(arguments.func) | 153 | argspec = inspect.getargspec(arguments.func) |
7 | 154 | vargs = [] | 154 | vargs = [] |
8 | 155 | kwargs = {} | ||
9 | 156 | for arg in argspec.args: | 155 | for arg in argspec.args: |
10 | 157 | vargs.append(getattr(arguments, arg)) | 156 | vargs.append(getattr(arguments, arg)) |
11 | 158 | if argspec.varargs: | 157 | if argspec.varargs: |
12 | 159 | vargs.extend(getattr(arguments, argspec.varargs)) | 158 | vargs.extend(getattr(arguments, argspec.varargs)) |
17 | 160 | if argspec.keywords: | 159 | output = arguments.func(*vargs) |
14 | 161 | for kwarg in argspec.keywords.items(): | ||
15 | 162 | kwargs[kwarg] = getattr(arguments, kwarg) | ||
16 | 163 | output = arguments.func(*vargs, **kwargs) | ||
18 | 164 | if getattr(arguments.func, '_cli_test_command', False): | 160 | if getattr(arguments.func, '_cli_test_command', False): |
19 | 165 | self.exit_code = 0 if output else 1 | 161 | self.exit_code = 0 if output else 1 |
20 | 166 | output = '' | 162 | output = '' |
21 | 167 | 163 | ||
22 | === modified file 'hooks/charmhelpers/cli/commands.py' | |||
23 | --- hooks/charmhelpers/cli/commands.py 2015-08-10 16:35:40 +0000 | |||
24 | +++ hooks/charmhelpers/cli/commands.py 2015-09-18 14:18:53 +0000 | |||
25 | @@ -26,7 +26,7 @@ | |||
26 | 26 | """ | 26 | """ |
27 | 27 | Import the sub-modules which have decorated subcommands to register with chlp. | 27 | Import the sub-modules which have decorated subcommands to register with chlp. |
28 | 28 | """ | 28 | """ |
33 | 29 | import host # noqa | 29 | from . import host # noqa |
34 | 30 | import benchmark # noqa | 30 | from . import benchmark # noqa |
35 | 31 | import unitdata # noqa | 31 | from . import unitdata # noqa |
36 | 32 | from charmhelpers.core import hookenv # noqa | 32 | from . import hookenv # noqa |
37 | 33 | 33 | ||
38 | === modified file 'hooks/charmhelpers/contrib/network/ip.py' | |||
39 | --- hooks/charmhelpers/contrib/network/ip.py 2015-03-11 11:45:09 +0000 | |||
40 | +++ hooks/charmhelpers/contrib/network/ip.py 2015-09-18 14:18:53 +0000 | |||
41 | @@ -23,7 +23,7 @@ | |||
42 | 23 | from functools import partial | 23 | from functools import partial |
43 | 24 | 24 | ||
44 | 25 | from charmhelpers.core.hookenv import unit_get | 25 | from charmhelpers.core.hookenv import unit_get |
46 | 26 | from charmhelpers.fetch import apt_install | 26 | from charmhelpers.fetch import apt_install, apt_update |
47 | 27 | from charmhelpers.core.hookenv import ( | 27 | from charmhelpers.core.hookenv import ( |
48 | 28 | log, | 28 | log, |
49 | 29 | WARNING, | 29 | WARNING, |
50 | @@ -32,13 +32,15 @@ | |||
51 | 32 | try: | 32 | try: |
52 | 33 | import netifaces | 33 | import netifaces |
53 | 34 | except ImportError: | 34 | except ImportError: |
55 | 35 | apt_install('python-netifaces') | 35 | apt_update(fatal=True) |
56 | 36 | apt_install('python-netifaces', fatal=True) | ||
57 | 36 | import netifaces | 37 | import netifaces |
58 | 37 | 38 | ||
59 | 38 | try: | 39 | try: |
60 | 39 | import netaddr | 40 | import netaddr |
61 | 40 | except ImportError: | 41 | except ImportError: |
63 | 41 | apt_install('python-netaddr') | 42 | apt_update(fatal=True) |
64 | 43 | apt_install('python-netaddr', fatal=True) | ||
65 | 42 | import netaddr | 44 | import netaddr |
66 | 43 | 45 | ||
67 | 44 | 46 | ||
68 | 45 | 47 | ||
69 | === modified file 'hooks/charmhelpers/contrib/openstack/context.py' | |||
70 | --- hooks/charmhelpers/contrib/openstack/context.py 2015-08-10 16:35:40 +0000 | |||
71 | +++ hooks/charmhelpers/contrib/openstack/context.py 2015-09-18 14:18:53 +0000 | |||
72 | @@ -483,13 +483,15 @@ | |||
73 | 483 | 483 | ||
74 | 484 | log('Generating template context for ceph', level=DEBUG) | 484 | log('Generating template context for ceph', level=DEBUG) |
75 | 485 | mon_hosts = [] | 485 | mon_hosts = [] |
79 | 486 | auth = None | 486 | ctxt = { |
80 | 487 | key = None | 487 | 'use_syslog': str(config('use-syslog')).lower() |
81 | 488 | use_syslog = str(config('use-syslog')).lower() | 488 | } |
82 | 489 | for rid in relation_ids('ceph'): | 489 | for rid in relation_ids('ceph'): |
83 | 490 | for unit in related_units(rid): | 490 | for unit in related_units(rid): |
86 | 491 | auth = relation_get('auth', rid=rid, unit=unit) | 491 | if not ctxt.get('auth'): |
87 | 492 | key = relation_get('key', rid=rid, unit=unit) | 492 | ctxt['auth'] = relation_get('auth', rid=rid, unit=unit) |
88 | 493 | if not ctxt.get('key'): | ||
89 | 494 | ctxt['key'] = relation_get('key', rid=rid, unit=unit) | ||
90 | 493 | ceph_pub_addr = relation_get('ceph-public-address', rid=rid, | 495 | ceph_pub_addr = relation_get('ceph-public-address', rid=rid, |
91 | 494 | unit=unit) | 496 | unit=unit) |
92 | 495 | unit_priv_addr = relation_get('private-address', rid=rid, | 497 | unit_priv_addr = relation_get('private-address', rid=rid, |
93 | @@ -498,10 +500,7 @@ | |||
94 | 498 | ceph_addr = format_ipv6_addr(ceph_addr) or ceph_addr | 500 | ceph_addr = format_ipv6_addr(ceph_addr) or ceph_addr |
95 | 499 | mon_hosts.append(ceph_addr) | 501 | mon_hosts.append(ceph_addr) |
96 | 500 | 502 | ||
101 | 501 | ctxt = {'mon_hosts': ' '.join(sorted(mon_hosts)), | 503 | ctxt['mon_hosts'] = ' '.join(sorted(mon_hosts)) |
98 | 502 | 'auth': auth, | ||
99 | 503 | 'key': key, | ||
100 | 504 | 'use_syslog': use_syslog} | ||
102 | 505 | 504 | ||
103 | 506 | if not os.path.isdir('/etc/ceph'): | 505 | if not os.path.isdir('/etc/ceph'): |
104 | 507 | os.mkdir('/etc/ceph') | 506 | os.mkdir('/etc/ceph') |
105 | 508 | 507 | ||
106 | === modified file 'hooks/charmhelpers/contrib/openstack/templating.py' | |||
107 | --- hooks/charmhelpers/contrib/openstack/templating.py 2015-08-10 16:35:40 +0000 | |||
108 | +++ hooks/charmhelpers/contrib/openstack/templating.py 2015-09-18 14:18:53 +0000 | |||
109 | @@ -18,7 +18,7 @@ | |||
110 | 18 | 18 | ||
111 | 19 | import six | 19 | import six |
112 | 20 | 20 | ||
114 | 21 | from charmhelpers.fetch import apt_install | 21 | from charmhelpers.fetch import apt_install, apt_update |
115 | 22 | from charmhelpers.core.hookenv import ( | 22 | from charmhelpers.core.hookenv import ( |
116 | 23 | log, | 23 | log, |
117 | 24 | ERROR, | 24 | ERROR, |
118 | @@ -29,6 +29,7 @@ | |||
119 | 29 | try: | 29 | try: |
120 | 30 | from jinja2 import FileSystemLoader, ChoiceLoader, Environment, exceptions | 30 | from jinja2 import FileSystemLoader, ChoiceLoader, Environment, exceptions |
121 | 31 | except ImportError: | 31 | except ImportError: |
122 | 32 | apt_update(fatal=True) | ||
123 | 32 | apt_install('python-jinja2', fatal=True) | 33 | apt_install('python-jinja2', fatal=True) |
124 | 33 | from jinja2 import FileSystemLoader, ChoiceLoader, Environment, exceptions | 34 | from jinja2 import FileSystemLoader, ChoiceLoader, Environment, exceptions |
125 | 34 | 35 | ||
126 | 35 | 36 | ||
127 | === modified file 'hooks/charmhelpers/contrib/openstack/utils.py' | |||
128 | --- hooks/charmhelpers/contrib/openstack/utils.py 2015-08-10 16:35:40 +0000 | |||
129 | +++ hooks/charmhelpers/contrib/openstack/utils.py 2015-09-18 14:18:53 +0000 | |||
130 | @@ -1,5 +1,3 @@ | |||
131 | 1 | #!/usr/bin/python | ||
132 | 2 | |||
133 | 3 | # Copyright 2014-2015 Canonical Limited. | 1 | # Copyright 2014-2015 Canonical Limited. |
134 | 4 | # | 2 | # |
135 | 5 | # This file is part of charm-helpers. | 3 | # This file is part of charm-helpers. |
136 | @@ -167,9 +165,9 @@ | |||
137 | 167 | error_out(e) | 165 | error_out(e) |
138 | 168 | 166 | ||
139 | 169 | 167 | ||
141 | 170 | def get_os_version_codename(codename): | 168 | def get_os_version_codename(codename, version_map=OPENSTACK_CODENAMES): |
142 | 171 | '''Determine OpenStack version number from codename.''' | 169 | '''Determine OpenStack version number from codename.''' |
144 | 172 | for k, v in six.iteritems(OPENSTACK_CODENAMES): | 170 | for k, v in six.iteritems(version_map): |
145 | 173 | if v == codename: | 171 | if v == codename: |
146 | 174 | return k | 172 | return k |
147 | 175 | e = 'Could not derive OpenStack version for '\ | 173 | e = 'Could not derive OpenStack version for '\ |
148 | @@ -392,7 +390,11 @@ | |||
149 | 392 | import apt_pkg as apt | 390 | import apt_pkg as apt |
150 | 393 | src = config('openstack-origin') | 391 | src = config('openstack-origin') |
151 | 394 | cur_vers = get_os_version_package(package) | 392 | cur_vers = get_os_version_package(package) |
153 | 395 | available_vers = get_os_version_install_source(src) | 393 | if "swift" in package: |
154 | 394 | codename = get_os_codename_install_source(src) | ||
155 | 395 | available_vers = get_os_version_codename(codename, SWIFT_CODENAMES) | ||
156 | 396 | else: | ||
157 | 397 | available_vers = get_os_version_install_source(src) | ||
158 | 396 | apt.init() | 398 | apt.init() |
159 | 397 | return apt.version_compare(available_vers, cur_vers) == 1 | 399 | return apt.version_compare(available_vers, cur_vers) == 1 |
160 | 398 | 400 | ||
161 | 399 | 401 | ||
162 | === modified file 'hooks/charmhelpers/contrib/storage/linux/ceph.py' | |||
163 | --- hooks/charmhelpers/contrib/storage/linux/ceph.py 2015-08-10 16:35:40 +0000 | |||
164 | +++ hooks/charmhelpers/contrib/storage/linux/ceph.py 2015-09-18 14:18:53 +0000 | |||
165 | @@ -28,6 +28,7 @@ | |||
166 | 28 | import shutil | 28 | import shutil |
167 | 29 | import json | 29 | import json |
168 | 30 | import time | 30 | import time |
169 | 31 | import uuid | ||
170 | 31 | 32 | ||
171 | 32 | from subprocess import ( | 33 | from subprocess import ( |
172 | 33 | check_call, | 34 | check_call, |
173 | @@ -35,8 +36,10 @@ | |||
174 | 35 | CalledProcessError, | 36 | CalledProcessError, |
175 | 36 | ) | 37 | ) |
176 | 37 | from charmhelpers.core.hookenv import ( | 38 | from charmhelpers.core.hookenv import ( |
177 | 39 | local_unit, | ||
178 | 38 | relation_get, | 40 | relation_get, |
179 | 39 | relation_ids, | 41 | relation_ids, |
180 | 42 | relation_set, | ||
181 | 40 | related_units, | 43 | related_units, |
182 | 41 | log, | 44 | log, |
183 | 42 | DEBUG, | 45 | DEBUG, |
184 | @@ -411,17 +414,52 @@ | |||
185 | 411 | 414 | ||
186 | 412 | The API is versioned and defaults to version 1. | 415 | The API is versioned and defaults to version 1. |
187 | 413 | """ | 416 | """ |
189 | 414 | def __init__(self, api_version=1): | 417 | def __init__(self, api_version=1, request_id=None): |
190 | 415 | self.api_version = api_version | 418 | self.api_version = api_version |
191 | 419 | if request_id: | ||
192 | 420 | self.request_id = request_id | ||
193 | 421 | else: | ||
194 | 422 | self.request_id = str(uuid.uuid1()) | ||
195 | 416 | self.ops = [] | 423 | self.ops = [] |
196 | 417 | 424 | ||
197 | 418 | def add_op_create_pool(self, name, replica_count=3): | 425 | def add_op_create_pool(self, name, replica_count=3): |
198 | 419 | self.ops.append({'op': 'create-pool', 'name': name, | 426 | self.ops.append({'op': 'create-pool', 'name': name, |
199 | 420 | 'replicas': replica_count}) | 427 | 'replicas': replica_count}) |
200 | 421 | 428 | ||
201 | 429 | def set_ops(self, ops): | ||
202 | 430 | """Set request ops to provided value. | ||
203 | 431 | |||
204 | 432 | Useful for injecting ops that come from a previous request | ||
205 | 433 | to allow comparisons to ensure validity. | ||
206 | 434 | """ | ||
207 | 435 | self.ops = ops | ||
208 | 436 | |||
209 | 422 | @property | 437 | @property |
210 | 423 | def request(self): | 438 | def request(self): |
212 | 424 | return json.dumps({'api-version': self.api_version, 'ops': self.ops}) | 439 | return json.dumps({'api-version': self.api_version, 'ops': self.ops, |
213 | 440 | 'request-id': self.request_id}) | ||
214 | 441 | |||
215 | 442 | def _ops_equal(self, other): | ||
216 | 443 | if len(self.ops) == len(other.ops): | ||
217 | 444 | for req_no in range(0, len(self.ops)): | ||
218 | 445 | for key in ['replicas', 'name', 'op']: | ||
219 | 446 | if self.ops[req_no][key] != other.ops[req_no][key]: | ||
220 | 447 | return False | ||
221 | 448 | else: | ||
222 | 449 | return False | ||
223 | 450 | return True | ||
224 | 451 | |||
225 | 452 | def __eq__(self, other): | ||
226 | 453 | if not isinstance(other, self.__class__): | ||
227 | 454 | return False | ||
228 | 455 | if self.api_version == other.api_version and \ | ||
229 | 456 | self._ops_equal(other): | ||
230 | 457 | return True | ||
231 | 458 | else: | ||
232 | 459 | return False | ||
233 | 460 | |||
234 | 461 | def __ne__(self, other): | ||
235 | 462 | return not self.__eq__(other) | ||
236 | 425 | 463 | ||
237 | 426 | 464 | ||
238 | 427 | class CephBrokerRsp(object): | 465 | class CephBrokerRsp(object): |
239 | @@ -431,14 +469,198 @@ | |||
240 | 431 | 469 | ||
241 | 432 | The API is versioned and defaults to version 1. | 470 | The API is versioned and defaults to version 1. |
242 | 433 | """ | 471 | """ |
243 | 472 | |||
244 | 434 | def __init__(self, encoded_rsp): | 473 | def __init__(self, encoded_rsp): |
245 | 435 | self.api_version = None | 474 | self.api_version = None |
246 | 436 | self.rsp = json.loads(encoded_rsp) | 475 | self.rsp = json.loads(encoded_rsp) |
247 | 437 | 476 | ||
248 | 438 | @property | 477 | @property |
249 | 478 | def request_id(self): | ||
250 | 479 | return self.rsp.get('request-id') | ||
251 | 480 | |||
252 | 481 | @property | ||
253 | 439 | def exit_code(self): | 482 | def exit_code(self): |
254 | 440 | return self.rsp.get('exit-code') | 483 | return self.rsp.get('exit-code') |
255 | 441 | 484 | ||
256 | 442 | @property | 485 | @property |
257 | 443 | def exit_msg(self): | 486 | def exit_msg(self): |
258 | 444 | return self.rsp.get('stderr') | 487 | return self.rsp.get('stderr') |
259 | 488 | |||
260 | 489 | |||
261 | 490 | # Ceph Broker Conversation: | ||
262 | 491 | # If a charm needs an action to be taken by ceph it can create a CephBrokerRq | ||
263 | 492 | # and send that request to ceph via the ceph relation. The CephBrokerRq has a | ||
264 | 493 | # unique id so that the client can identity which CephBrokerRsp is associated | ||
265 | 494 | # with the request. Ceph will also respond to each client unit individually | ||
266 | 495 | # creating a response key per client unit eg glance/0 will get a CephBrokerRsp | ||
267 | 496 | # via key broker-rsp-glance-0 | ||
268 | 497 | # | ||
269 | 498 | # To use this the charm can just do something like: | ||
270 | 499 | # | ||
271 | 500 | # from charmhelpers.contrib.storage.linux.ceph import ( | ||
272 | 501 | # send_request_if_needed, | ||
273 | 502 | # is_request_complete, | ||
274 | 503 | # CephBrokerRq, | ||
275 | 504 | # ) | ||
276 | 505 | # | ||
277 | 506 | # @hooks.hook('ceph-relation-changed') | ||
278 | 507 | # def ceph_changed(): | ||
279 | 508 | # rq = CephBrokerRq() | ||
280 | 509 | # rq.add_op_create_pool(name='poolname', replica_count=3) | ||
281 | 510 | # | ||
282 | 511 | # if is_request_complete(rq): | ||
283 | 512 | # <Request complete actions> | ||
284 | 513 | # else: | ||
285 | 514 | # send_request_if_needed(get_ceph_request()) | ||
286 | 515 | # | ||
287 | 516 | # CephBrokerRq and CephBrokerRsp are serialized into JSON. Below is an example | ||
288 | 517 | # of glance having sent a request to ceph which ceph has successfully processed | ||
289 | 518 | # 'ceph:8': { | ||
290 | 519 | # 'ceph/0': { | ||
291 | 520 | # 'auth': 'cephx', | ||
292 | 521 | # 'broker-rsp-glance-0': '{"request-id": "0bc7dc54", "exit-code": 0}', | ||
293 | 522 | # 'broker_rsp': '{"request-id": "0da543b8", "exit-code": 0}', | ||
294 | 523 | # 'ceph-public-address': '10.5.44.103', | ||
295 | 524 | # 'key': 'AQCLDttVuHXINhAAvI144CB09dYchhHyTUY9BQ==', | ||
296 | 525 | # 'private-address': '10.5.44.103', | ||
297 | 526 | # }, | ||
298 | 527 | # 'glance/0': { | ||
299 | 528 | # 'broker_req': ('{"api-version": 1, "request-id": "0bc7dc54", ' | ||
300 | 529 | # '"ops": [{"replicas": 3, "name": "glance", ' | ||
301 | 530 | # '"op": "create-pool"}]}'), | ||
302 | 531 | # 'private-address': '10.5.44.109', | ||
303 | 532 | # }, | ||
304 | 533 | # } | ||
305 | 534 | |||
306 | 535 | def get_previous_request(rid): | ||
307 | 536 | """Return the last ceph broker request sent on a given relation | ||
308 | 537 | |||
309 | 538 | @param rid: Relation id to query for request | ||
310 | 539 | """ | ||
311 | 540 | request = None | ||
312 | 541 | broker_req = relation_get(attribute='broker_req', rid=rid, | ||
313 | 542 | unit=local_unit()) | ||
314 | 543 | if broker_req: | ||
315 | 544 | request_data = json.loads(broker_req) | ||
316 | 545 | request = CephBrokerRq(api_version=request_data['api-version'], | ||
317 | 546 | request_id=request_data['request-id']) | ||
318 | 547 | request.set_ops(request_data['ops']) | ||
319 | 548 | |||
320 | 549 | return request | ||
321 | 550 | |||
322 | 551 | |||
323 | 552 | def get_request_states(request): | ||
324 | 553 | """Return a dict of requests per relation id with their corresponding | ||
325 | 554 | completion state. | ||
326 | 555 | |||
327 | 556 | This allows a charm, which has a request for ceph, to see whether there is | ||
328 | 557 | an equivalent request already being processed and if so what state that | ||
329 | 558 | request is in. | ||
330 | 559 | |||
331 | 560 | @param request: A CephBrokerRq object | ||
332 | 561 | """ | ||
333 | 562 | complete = [] | ||
334 | 563 | requests = {} | ||
335 | 564 | for rid in relation_ids('ceph'): | ||
336 | 565 | complete = False | ||
337 | 566 | previous_request = get_previous_request(rid) | ||
338 | 567 | if request == previous_request: | ||
339 | 568 | sent = True | ||
340 | 569 | complete = is_request_complete_for_rid(previous_request, rid) | ||
341 | 570 | else: | ||
342 | 571 | sent = False | ||
343 | 572 | complete = False | ||
344 | 573 | |||
345 | 574 | requests[rid] = { | ||
346 | 575 | 'sent': sent, | ||
347 | 576 | 'complete': complete, | ||
348 | 577 | } | ||
349 | 578 | |||
350 | 579 | return requests | ||
351 | 580 | |||
352 | 581 | |||
353 | 582 | def is_request_sent(request): | ||
354 | 583 | """Check to see if a functionally equivalent request has already been sent | ||
355 | 584 | |||
356 | 585 | Returns True if a similair request has been sent | ||
357 | 586 | |||
358 | 587 | @param request: A CephBrokerRq object | ||
359 | 588 | """ | ||
360 | 589 | states = get_request_states(request) | ||
361 | 590 | for rid in states.keys(): | ||
362 | 591 | if not states[rid]['sent']: | ||
363 | 592 | return False | ||
364 | 593 | |||
365 | 594 | return True | ||
366 | 595 | |||
367 | 596 | |||
368 | 597 | def is_request_complete(request): | ||
369 | 598 | """Check to see if a functionally equivalent request has already been | ||
370 | 599 | completed | ||
371 | 600 | |||
372 | 601 | Returns True if a similair request has been completed | ||
373 | 602 | |||
374 | 603 | @param request: A CephBrokerRq object | ||
375 | 604 | """ | ||
376 | 605 | states = get_request_states(request) | ||
377 | 606 | for rid in states.keys(): | ||
378 | 607 | if not states[rid]['complete']: | ||
379 | 608 | return False | ||
380 | 609 | |||
381 | 610 | return True | ||
382 | 611 | |||
383 | 612 | |||
384 | 613 | def is_request_complete_for_rid(request, rid): | ||
385 | 614 | """Check if a given request has been completed on the given relation | ||
386 | 615 | |||
387 | 616 | @param request: A CephBrokerRq object | ||
388 | 617 | @param rid: Relation ID | ||
389 | 618 | """ | ||
390 | 619 | broker_key = get_broker_rsp_key() | ||
391 | 620 | for unit in related_units(rid): | ||
392 | 621 | rdata = relation_get(rid=rid, unit=unit) | ||
393 | 622 | if rdata.get(broker_key): | ||
394 | 623 | rsp = CephBrokerRsp(rdata.get(broker_key)) | ||
395 | 624 | if rsp.request_id == request.request_id: | ||
396 | 625 | if not rsp.exit_code: | ||
397 | 626 | return True | ||
398 | 627 | else: | ||
399 | 628 | # The remote unit sent no reply targeted at this unit so either the | ||
400 | 629 | # remote ceph cluster does not support unit targeted replies or it | ||
401 | 630 | # has not processed our request yet. | ||
402 | 631 | if rdata.get('broker_rsp'): | ||
403 | 632 | request_data = json.loads(rdata['broker_rsp']) | ||
404 | 633 | if request_data.get('request-id'): | ||
405 | 634 | log('Ignoring legacy broker_rsp without unit key as remote ' | ||
406 | 635 | 'service supports unit specific replies', level=DEBUG) | ||
407 | 636 | else: | ||
408 | 637 | log('Using legacy broker_rsp as remote service does not ' | ||
409 | 638 | 'supports unit specific replies', level=DEBUG) | ||
410 | 639 | rsp = CephBrokerRsp(rdata['broker_rsp']) | ||
411 | 640 | if not rsp.exit_code: | ||
412 | 641 | return True | ||
413 | 642 | |||
414 | 643 | return False | ||
415 | 644 | |||
416 | 645 | |||
417 | 646 | def get_broker_rsp_key(): | ||
418 | 647 | """Return broker response key for this unit | ||
419 | 648 | |||
420 | 649 | This is the key that ceph is going to use to pass request status | ||
421 | 650 | information back to this unit | ||
422 | 651 | """ | ||
423 | 652 | return 'broker-rsp-' + local_unit().replace('/', '-') | ||
424 | 653 | |||
425 | 654 | |||
426 | 655 | def send_request_if_needed(request): | ||
427 | 656 | """Send broker request if an equivalent request has not already been sent | ||
428 | 657 | |||
429 | 658 | @param request: A CephBrokerRq object | ||
430 | 659 | """ | ||
431 | 660 | if is_request_sent(request): | ||
432 | 661 | log('Request already sent but not complete, not sending new request', | ||
433 | 662 | level=DEBUG) | ||
434 | 663 | else: | ||
435 | 664 | for rid in relation_ids('ceph'): | ||
436 | 665 | log('Sending request {}'.format(request.request_id), level=DEBUG) | ||
437 | 666 | relation_set(relation_id=rid, broker_req=request.request) | ||
438 | 445 | 667 | ||
439 | === modified file 'hooks/charmhelpers/contrib/storage/linux/utils.py' | |||
440 | --- hooks/charmhelpers/contrib/storage/linux/utils.py 2015-08-10 16:35:40 +0000 | |||
441 | +++ hooks/charmhelpers/contrib/storage/linux/utils.py 2015-09-18 14:18:53 +0000 | |||
442 | @@ -43,9 +43,10 @@ | |||
443 | 43 | 43 | ||
444 | 44 | :param block_device: str: Full path of block device to clean. | 44 | :param block_device: str: Full path of block device to clean. |
445 | 45 | ''' | 45 | ''' |
446 | 46 | # https://github.com/ceph/ceph/commit/fdd7f8d83afa25c4e09aaedd90ab93f3b64a677b | ||
447 | 46 | # sometimes sgdisk exits non-zero; this is OK, dd will clean up | 47 | # sometimes sgdisk exits non-zero; this is OK, dd will clean up |
450 | 47 | call(['sgdisk', '--zap-all', '--mbrtogpt', | 48 | call(['sgdisk', '--zap-all', '--', block_device]) |
451 | 48 | '--clear', block_device]) | 49 | call(['sgdisk', '--clear', '--mbrtogpt', '--', block_device]) |
452 | 49 | dev_end = check_output(['blockdev', '--getsz', | 50 | dev_end = check_output(['blockdev', '--getsz', |
453 | 50 | block_device]).decode('UTF-8') | 51 | block_device]).decode('UTF-8') |
454 | 51 | gpt_end = int(dev_end.split()[0]) - 100 | 52 | gpt_end = int(dev_end.split()[0]) - 100 |
455 | 52 | 53 | ||
456 | === modified file 'hooks/charmhelpers/core/hookenv.py' | |||
457 | --- hooks/charmhelpers/core/hookenv.py 2015-08-10 16:35:40 +0000 | |||
458 | +++ hooks/charmhelpers/core/hookenv.py 2015-09-18 14:18:53 +0000 | |||
459 | @@ -34,23 +34,6 @@ | |||
460 | 34 | import tempfile | 34 | import tempfile |
461 | 35 | from subprocess import CalledProcessError | 35 | from subprocess import CalledProcessError |
462 | 36 | 36 | ||
463 | 37 | try: | ||
464 | 38 | from charmhelpers.cli import cmdline | ||
465 | 39 | except ImportError as e: | ||
466 | 40 | # due to the anti-pattern of partially synching charmhelpers directly | ||
467 | 41 | # into charms, it's possible that charmhelpers.cli is not available; | ||
468 | 42 | # if that's the case, they don't really care about using the cli anyway, | ||
469 | 43 | # so mock it out | ||
470 | 44 | if str(e) == 'No module named cli': | ||
471 | 45 | class cmdline(object): | ||
472 | 46 | @classmethod | ||
473 | 47 | def subcommand(cls, *args, **kwargs): | ||
474 | 48 | def _wrap(func): | ||
475 | 49 | return func | ||
476 | 50 | return _wrap | ||
477 | 51 | else: | ||
478 | 52 | raise | ||
479 | 53 | |||
480 | 54 | import six | 37 | import six |
481 | 55 | if not six.PY3: | 38 | if not six.PY3: |
482 | 56 | from UserDict import UserDict | 39 | from UserDict import UserDict |
483 | @@ -91,6 +74,7 @@ | |||
484 | 91 | res = func(*args, **kwargs) | 74 | res = func(*args, **kwargs) |
485 | 92 | cache[key] = res | 75 | cache[key] = res |
486 | 93 | return res | 76 | return res |
487 | 77 | wrapper._wrapped = func | ||
488 | 94 | return wrapper | 78 | return wrapper |
489 | 95 | 79 | ||
490 | 96 | 80 | ||
491 | @@ -190,7 +174,6 @@ | |||
492 | 190 | return os.environ.get('JUJU_RELATION', None) | 174 | return os.environ.get('JUJU_RELATION', None) |
493 | 191 | 175 | ||
494 | 192 | 176 | ||
495 | 193 | @cmdline.subcommand() | ||
496 | 194 | @cached | 177 | @cached |
497 | 195 | def relation_id(relation_name=None, service_or_unit=None): | 178 | def relation_id(relation_name=None, service_or_unit=None): |
498 | 196 | """The relation ID for the current or a specified relation""" | 179 | """The relation ID for the current or a specified relation""" |
499 | @@ -216,13 +199,11 @@ | |||
500 | 216 | return os.environ.get('JUJU_REMOTE_UNIT', None) | 199 | return os.environ.get('JUJU_REMOTE_UNIT', None) |
501 | 217 | 200 | ||
502 | 218 | 201 | ||
503 | 219 | @cmdline.subcommand() | ||
504 | 220 | def service_name(): | 202 | def service_name(): |
505 | 221 | """The name service group this unit belongs to""" | 203 | """The name service group this unit belongs to""" |
506 | 222 | return local_unit().split('/')[0] | 204 | return local_unit().split('/')[0] |
507 | 223 | 205 | ||
508 | 224 | 206 | ||
509 | 225 | @cmdline.subcommand() | ||
510 | 226 | @cached | 207 | @cached |
511 | 227 | def remote_service_name(relid=None): | 208 | def remote_service_name(relid=None): |
512 | 228 | """The remote service name for a given relation-id (or the current relation)""" | 209 | """The remote service name for a given relation-id (or the current relation)""" |
513 | 229 | 210 | ||
514 | === modified file 'hooks/charmhelpers/core/host.py' | |||
515 | --- hooks/charmhelpers/core/host.py 2015-08-10 16:35:40 +0000 | |||
516 | +++ hooks/charmhelpers/core/host.py 2015-09-18 14:18:53 +0000 | |||
517 | @@ -72,7 +72,7 @@ | |||
518 | 72 | stopped = service_stop(service_name) | 72 | stopped = service_stop(service_name) |
519 | 73 | # XXX: Support systemd too | 73 | # XXX: Support systemd too |
520 | 74 | override_path = os.path.join( | 74 | override_path = os.path.join( |
522 | 75 | init_dir, '{}.conf.override'.format(service_name)) | 75 | init_dir, '{}.override'.format(service_name)) |
523 | 76 | with open(override_path, 'w') as fh: | 76 | with open(override_path, 'w') as fh: |
524 | 77 | fh.write("manual\n") | 77 | fh.write("manual\n") |
525 | 78 | return stopped | 78 | return stopped |
526 | @@ -86,7 +86,7 @@ | |||
527 | 86 | if init_dir is None: | 86 | if init_dir is None: |
528 | 87 | init_dir = "/etc/init" | 87 | init_dir = "/etc/init" |
529 | 88 | override_path = os.path.join( | 88 | override_path = os.path.join( |
531 | 89 | init_dir, '{}.conf.override'.format(service_name)) | 89 | init_dir, '{}.override'.format(service_name)) |
532 | 90 | if os.path.exists(override_path): | 90 | if os.path.exists(override_path): |
533 | 91 | os.unlink(override_path) | 91 | os.unlink(override_path) |
534 | 92 | started = service_start(service_name) | 92 | started = service_start(service_name) |
charm_lint_check #10249 keystone for tribaal mp271661
LINT OK: passed
Build: http:// 10.245. 162.77: 8080/job/ charm_lint_ check/10249/