Merge lp:~billy-olsen/charms/trusty/rabbitmq-server/ch-sync-cli-fix into lp:~openstack-charmers-archive/charms/trusty/rabbitmq-server/next
- Trusty Tahr (14.04)
- ch-sync-cli-fix
- Merge into next
Status: | Merged |
---|---|
Merged at revision: | 104 |
Proposed branch: | lp:~billy-olsen/charms/trusty/rabbitmq-server/ch-sync-cli-fix |
Merge into: | lp:~openstack-charmers-archive/charms/trusty/rabbitmq-server/next |
Diff against target: |
424 lines (+366/-2) 8 files modified
charm-helpers-tests.yaml (+1/-0) hooks/charmhelpers/core/hookenv.py (+16/-1) tests/charmhelpers/cli/__init__.py (+195/-0) tests/charmhelpers/cli/benchmark.py (+36/-0) tests/charmhelpers/cli/commands.py (+32/-0) tests/charmhelpers/cli/host.py (+31/-0) tests/charmhelpers/cli/unitdata.py (+39/-0) tests/charmhelpers/core/hookenv.py (+16/-1) |
To merge this branch: | bzr merge lp:~billy-olsen/charms/trusty/rabbitmq-server/ch-sync-cli-fix |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Edward Hope-Morley | Approve | ||
Ryan Beisner (community) | Approve | ||
Review via email: mp+266619@code.launchpad.net |
Commit message
Description of the change
uosci-testing-bot (uosci-testing-bot) wrote : | # |
uosci-testing-bot (uosci-testing-bot) wrote : | # |
charm_unit_test #6843 rabbitmq-
UNIT OK: passed
uosci-testing-bot (uosci-testing-bot) wrote : | # |
charm_amulet_test #5546 rabbitmq-
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://
- 104. By Billy Olsen
-
Include cli in the rmq amulet
uosci-testing-bot (uosci-testing-bot) wrote : | # |
charm_lint_check #7376 rabbitmq-
LINT OK: passed
uosci-testing-bot (uosci-testing-bot) wrote : | # |
charm_unit_test #6844 rabbitmq-
UNIT OK: passed
uosci-testing-bot (uosci-testing-bot) wrote : | # |
charm_amulet_test #5548 rabbitmq-
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 : | # |
I would suggest merging this, even though the amulet test fails. It was previously failing that functional test.
This merge proposal resolves an import error, introduced by a charm-helpers CLI.
Ryan Beisner (1chb1n) wrote : | # |
PS FYI, this is the only os-charm which had an amulet test affected by the CLI helper addition.
Ryan Beisner (1chb1n) wrote : | # |
Regarding the pre-existing test failure, we will still need to address that separately.
Edward Hope-Morley (hopem) wrote : | # |
Lets get this landed. It does not touch any code outside of amulet tests (which are broken anyway).
Preview Diff
1 | === modified file 'charm-helpers-tests.yaml' | |||
2 | --- charm-helpers-tests.yaml 2015-04-13 22:11:34 +0000 | |||
3 | +++ charm-helpers-tests.yaml 2015-07-31 22:01:37 +0000 | |||
4 | @@ -2,4 +2,5 @@ | |||
5 | 2 | branch: lp:charm-helpers | 2 | branch: lp:charm-helpers |
6 | 3 | include: | 3 | include: |
7 | 4 | - core | 4 | - core |
8 | 5 | - cli | ||
9 | 5 | - contrib.ssl | 6 | - contrib.ssl |
10 | 6 | 7 | ||
11 | === modified file 'hooks/charmhelpers/core/hookenv.py' | |||
12 | --- hooks/charmhelpers/core/hookenv.py 2015-07-31 13:11:07 +0000 | |||
13 | +++ hooks/charmhelpers/core/hookenv.py 2015-07-31 22:01:37 +0000 | |||
14 | @@ -34,7 +34,22 @@ | |||
15 | 34 | import tempfile | 34 | import tempfile |
16 | 35 | from subprocess import CalledProcessError | 35 | from subprocess import CalledProcessError |
17 | 36 | 36 | ||
19 | 37 | from charmhelpers.cli import cmdline | 37 | try: |
20 | 38 | from charmhelpers.cli import cmdline | ||
21 | 39 | except ImportError as e: | ||
22 | 40 | # due to the anti-pattern of partially synching charmhelpers directly | ||
23 | 41 | # into charms, it's possible that charmhelpers.cli is not available; | ||
24 | 42 | # if that's the case, they don't really care about using the cli anyway, | ||
25 | 43 | # so mock it out | ||
26 | 44 | if str(e) == 'No module named cli': | ||
27 | 45 | class cmdline(object): | ||
28 | 46 | @classmethod | ||
29 | 47 | def subcommand(cls, *args, **kwargs): | ||
30 | 48 | def _wrap(func): | ||
31 | 49 | return func | ||
32 | 50 | return _wrap | ||
33 | 51 | else: | ||
34 | 52 | raise | ||
35 | 38 | 53 | ||
36 | 39 | import six | 54 | import six |
37 | 40 | if not six.PY3: | 55 | if not six.PY3: |
38 | 41 | 56 | ||
39 | === added directory 'tests/charmhelpers/cli' | |||
40 | === added file 'tests/charmhelpers/cli/__init__.py' | |||
41 | --- tests/charmhelpers/cli/__init__.py 1970-01-01 00:00:00 +0000 | |||
42 | +++ tests/charmhelpers/cli/__init__.py 2015-07-31 22:01:37 +0000 | |||
43 | @@ -0,0 +1,195 @@ | |||
44 | 1 | # Copyright 2014-2015 Canonical Limited. | ||
45 | 2 | # | ||
46 | 3 | # This file is part of charm-helpers. | ||
47 | 4 | # | ||
48 | 5 | # charm-helpers is free software: you can redistribute it and/or modify | ||
49 | 6 | # it under the terms of the GNU Lesser General Public License version 3 as | ||
50 | 7 | # published by the Free Software Foundation. | ||
51 | 8 | # | ||
52 | 9 | # charm-helpers is distributed in the hope that it will be useful, | ||
53 | 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
54 | 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
55 | 12 | # GNU Lesser General Public License for more details. | ||
56 | 13 | # | ||
57 | 14 | # You should have received a copy of the GNU Lesser General Public License | ||
58 | 15 | # along with charm-helpers. If not, see <http://www.gnu.org/licenses/>. | ||
59 | 16 | |||
60 | 17 | import inspect | ||
61 | 18 | import argparse | ||
62 | 19 | import sys | ||
63 | 20 | |||
64 | 21 | from six.moves import zip | ||
65 | 22 | |||
66 | 23 | from charmhelpers.core import unitdata | ||
67 | 24 | |||
68 | 25 | |||
69 | 26 | class OutputFormatter(object): | ||
70 | 27 | def __init__(self, outfile=sys.stdout): | ||
71 | 28 | self.formats = ( | ||
72 | 29 | "raw", | ||
73 | 30 | "json", | ||
74 | 31 | "py", | ||
75 | 32 | "yaml", | ||
76 | 33 | "csv", | ||
77 | 34 | "tab", | ||
78 | 35 | ) | ||
79 | 36 | self.outfile = outfile | ||
80 | 37 | |||
81 | 38 | def add_arguments(self, argument_parser): | ||
82 | 39 | formatgroup = argument_parser.add_mutually_exclusive_group() | ||
83 | 40 | choices = self.supported_formats | ||
84 | 41 | formatgroup.add_argument("--format", metavar='FMT', | ||
85 | 42 | help="Select output format for returned data, " | ||
86 | 43 | "where FMT is one of: {}".format(choices), | ||
87 | 44 | choices=choices, default='raw') | ||
88 | 45 | for fmt in self.formats: | ||
89 | 46 | fmtfunc = getattr(self, fmt) | ||
90 | 47 | formatgroup.add_argument("-{}".format(fmt[0]), | ||
91 | 48 | "--{}".format(fmt), action='store_const', | ||
92 | 49 | const=fmt, dest='format', | ||
93 | 50 | help=fmtfunc.__doc__) | ||
94 | 51 | |||
95 | 52 | @property | ||
96 | 53 | def supported_formats(self): | ||
97 | 54 | return self.formats | ||
98 | 55 | |||
99 | 56 | def raw(self, output): | ||
100 | 57 | """Output data as raw string (default)""" | ||
101 | 58 | if isinstance(output, (list, tuple)): | ||
102 | 59 | output = '\n'.join(map(str, output)) | ||
103 | 60 | self.outfile.write(str(output)) | ||
104 | 61 | |||
105 | 62 | def py(self, output): | ||
106 | 63 | """Output data as a nicely-formatted python data structure""" | ||
107 | 64 | import pprint | ||
108 | 65 | pprint.pprint(output, stream=self.outfile) | ||
109 | 66 | |||
110 | 67 | def json(self, output): | ||
111 | 68 | """Output data in JSON format""" | ||
112 | 69 | import json | ||
113 | 70 | json.dump(output, self.outfile) | ||
114 | 71 | |||
115 | 72 | def yaml(self, output): | ||
116 | 73 | """Output data in YAML format""" | ||
117 | 74 | import yaml | ||
118 | 75 | yaml.safe_dump(output, self.outfile) | ||
119 | 76 | |||
120 | 77 | def csv(self, output): | ||
121 | 78 | """Output data as excel-compatible CSV""" | ||
122 | 79 | import csv | ||
123 | 80 | csvwriter = csv.writer(self.outfile) | ||
124 | 81 | csvwriter.writerows(output) | ||
125 | 82 | |||
126 | 83 | def tab(self, output): | ||
127 | 84 | """Output data in excel-compatible tab-delimited format""" | ||
128 | 85 | import csv | ||
129 | 86 | csvwriter = csv.writer(self.outfile, dialect=csv.excel_tab) | ||
130 | 87 | csvwriter.writerows(output) | ||
131 | 88 | |||
132 | 89 | def format_output(self, output, fmt='raw'): | ||
133 | 90 | fmtfunc = getattr(self, fmt) | ||
134 | 91 | fmtfunc(output) | ||
135 | 92 | |||
136 | 93 | |||
137 | 94 | class CommandLine(object): | ||
138 | 95 | argument_parser = None | ||
139 | 96 | subparsers = None | ||
140 | 97 | formatter = None | ||
141 | 98 | exit_code = 0 | ||
142 | 99 | |||
143 | 100 | def __init__(self): | ||
144 | 101 | if not self.argument_parser: | ||
145 | 102 | self.argument_parser = argparse.ArgumentParser(description='Perform common charm tasks') | ||
146 | 103 | if not self.formatter: | ||
147 | 104 | self.formatter = OutputFormatter() | ||
148 | 105 | self.formatter.add_arguments(self.argument_parser) | ||
149 | 106 | if not self.subparsers: | ||
150 | 107 | self.subparsers = self.argument_parser.add_subparsers(help='Commands') | ||
151 | 108 | |||
152 | 109 | def subcommand(self, command_name=None): | ||
153 | 110 | """ | ||
154 | 111 | Decorate a function as a subcommand. Use its arguments as the | ||
155 | 112 | command-line arguments""" | ||
156 | 113 | def wrapper(decorated): | ||
157 | 114 | cmd_name = command_name or decorated.__name__ | ||
158 | 115 | subparser = self.subparsers.add_parser(cmd_name, | ||
159 | 116 | description=decorated.__doc__) | ||
160 | 117 | for args, kwargs in describe_arguments(decorated): | ||
161 | 118 | subparser.add_argument(*args, **kwargs) | ||
162 | 119 | subparser.set_defaults(func=decorated) | ||
163 | 120 | return decorated | ||
164 | 121 | return wrapper | ||
165 | 122 | |||
166 | 123 | def test_command(self, decorated): | ||
167 | 124 | """ | ||
168 | 125 | Subcommand is a boolean test function, so bool return values should be | ||
169 | 126 | converted to a 0/1 exit code. | ||
170 | 127 | """ | ||
171 | 128 | decorated._cli_test_command = True | ||
172 | 129 | return decorated | ||
173 | 130 | |||
174 | 131 | def no_output(self, decorated): | ||
175 | 132 | """ | ||
176 | 133 | Subcommand is not expected to return a value, so don't print a spurious None. | ||
177 | 134 | """ | ||
178 | 135 | decorated._cli_no_output = True | ||
179 | 136 | return decorated | ||
180 | 137 | |||
181 | 138 | def subcommand_builder(self, command_name, description=None): | ||
182 | 139 | """ | ||
183 | 140 | Decorate a function that builds a subcommand. Builders should accept a | ||
184 | 141 | single argument (the subparser instance) and return the function to be | ||
185 | 142 | run as the command.""" | ||
186 | 143 | def wrapper(decorated): | ||
187 | 144 | subparser = self.subparsers.add_parser(command_name) | ||
188 | 145 | func = decorated(subparser) | ||
189 | 146 | subparser.set_defaults(func=func) | ||
190 | 147 | subparser.description = description or func.__doc__ | ||
191 | 148 | return wrapper | ||
192 | 149 | |||
193 | 150 | def run(self): | ||
194 | 151 | "Run cli, processing arguments and executing subcommands." | ||
195 | 152 | arguments = self.argument_parser.parse_args() | ||
196 | 153 | argspec = inspect.getargspec(arguments.func) | ||
197 | 154 | vargs = [] | ||
198 | 155 | kwargs = {} | ||
199 | 156 | for arg in argspec.args: | ||
200 | 157 | vargs.append(getattr(arguments, arg)) | ||
201 | 158 | if argspec.varargs: | ||
202 | 159 | vargs.extend(getattr(arguments, argspec.varargs)) | ||
203 | 160 | if argspec.keywords: | ||
204 | 161 | for kwarg in argspec.keywords.items(): | ||
205 | 162 | kwargs[kwarg] = getattr(arguments, kwarg) | ||
206 | 163 | output = arguments.func(*vargs, **kwargs) | ||
207 | 164 | if getattr(arguments.func, '_cli_test_command', False): | ||
208 | 165 | self.exit_code = 0 if output else 1 | ||
209 | 166 | output = '' | ||
210 | 167 | if getattr(arguments.func, '_cli_no_output', False): | ||
211 | 168 | output = '' | ||
212 | 169 | self.formatter.format_output(output, arguments.format) | ||
213 | 170 | if unitdata._KV: | ||
214 | 171 | unitdata._KV.flush() | ||
215 | 172 | |||
216 | 173 | |||
217 | 174 | cmdline = CommandLine() | ||
218 | 175 | |||
219 | 176 | |||
220 | 177 | def describe_arguments(func): | ||
221 | 178 | """ | ||
222 | 179 | Analyze a function's signature and return a data structure suitable for | ||
223 | 180 | passing in as arguments to an argparse parser's add_argument() method.""" | ||
224 | 181 | |||
225 | 182 | argspec = inspect.getargspec(func) | ||
226 | 183 | # we should probably raise an exception somewhere if func includes **kwargs | ||
227 | 184 | if argspec.defaults: | ||
228 | 185 | positional_args = argspec.args[:-len(argspec.defaults)] | ||
229 | 186 | keyword_names = argspec.args[-len(argspec.defaults):] | ||
230 | 187 | for arg, default in zip(keyword_names, argspec.defaults): | ||
231 | 188 | yield ('--{}'.format(arg),), {'default': default} | ||
232 | 189 | else: | ||
233 | 190 | positional_args = argspec.args | ||
234 | 191 | |||
235 | 192 | for arg in positional_args: | ||
236 | 193 | yield (arg,), {} | ||
237 | 194 | if argspec.varargs: | ||
238 | 195 | yield (argspec.varargs,), {'nargs': '*'} | ||
239 | 0 | 196 | ||
240 | === added file 'tests/charmhelpers/cli/benchmark.py' | |||
241 | --- tests/charmhelpers/cli/benchmark.py 1970-01-01 00:00:00 +0000 | |||
242 | +++ tests/charmhelpers/cli/benchmark.py 2015-07-31 22:01:37 +0000 | |||
243 | @@ -0,0 +1,36 @@ | |||
244 | 1 | # Copyright 2014-2015 Canonical Limited. | ||
245 | 2 | # | ||
246 | 3 | # This file is part of charm-helpers. | ||
247 | 4 | # | ||
248 | 5 | # charm-helpers is free software: you can redistribute it and/or modify | ||
249 | 6 | # it under the terms of the GNU Lesser General Public License version 3 as | ||
250 | 7 | # published by the Free Software Foundation. | ||
251 | 8 | # | ||
252 | 9 | # charm-helpers is distributed in the hope that it will be useful, | ||
253 | 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
254 | 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
255 | 12 | # GNU Lesser General Public License for more details. | ||
256 | 13 | # | ||
257 | 14 | # You should have received a copy of the GNU Lesser General Public License | ||
258 | 15 | # along with charm-helpers. If not, see <http://www.gnu.org/licenses/>. | ||
259 | 16 | |||
260 | 17 | from . import cmdline | ||
261 | 18 | from charmhelpers.contrib.benchmark import Benchmark | ||
262 | 19 | |||
263 | 20 | |||
264 | 21 | @cmdline.subcommand(command_name='benchmark-start') | ||
265 | 22 | def start(): | ||
266 | 23 | Benchmark.start() | ||
267 | 24 | |||
268 | 25 | |||
269 | 26 | @cmdline.subcommand(command_name='benchmark-finish') | ||
270 | 27 | def finish(): | ||
271 | 28 | Benchmark.finish() | ||
272 | 29 | |||
273 | 30 | |||
274 | 31 | @cmdline.subcommand_builder('benchmark-composite', description="Set the benchmark composite score") | ||
275 | 32 | def service(subparser): | ||
276 | 33 | subparser.add_argument("value", help="The composite score.") | ||
277 | 34 | subparser.add_argument("units", help="The units the composite score represents, i.e., 'reads/sec'.") | ||
278 | 35 | subparser.add_argument("direction", help="'asc' if a lower score is better, 'desc' if a higher score is better.") | ||
279 | 36 | return Benchmark.set_composite_score | ||
280 | 0 | 37 | ||
281 | === added file 'tests/charmhelpers/cli/commands.py' | |||
282 | --- tests/charmhelpers/cli/commands.py 1970-01-01 00:00:00 +0000 | |||
283 | +++ tests/charmhelpers/cli/commands.py 2015-07-31 22:01:37 +0000 | |||
284 | @@ -0,0 +1,32 @@ | |||
285 | 1 | # Copyright 2014-2015 Canonical Limited. | ||
286 | 2 | # | ||
287 | 3 | # This file is part of charm-helpers. | ||
288 | 4 | # | ||
289 | 5 | # charm-helpers is free software: you can redistribute it and/or modify | ||
290 | 6 | # it under the terms of the GNU Lesser General Public License version 3 as | ||
291 | 7 | # published by the Free Software Foundation. | ||
292 | 8 | # | ||
293 | 9 | # charm-helpers is distributed in the hope that it will be useful, | ||
294 | 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
295 | 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
296 | 12 | # GNU Lesser General Public License for more details. | ||
297 | 13 | # | ||
298 | 14 | # You should have received a copy of the GNU Lesser General Public License | ||
299 | 15 | # along with charm-helpers. If not, see <http://www.gnu.org/licenses/>. | ||
300 | 16 | |||
301 | 17 | """ | ||
302 | 18 | This module loads sub-modules into the python runtime so they can be | ||
303 | 19 | discovered via the inspect module. In order to prevent flake8 from (rightfully) | ||
304 | 20 | telling us these are unused modules, throw a ' # noqa' at the end of each import | ||
305 | 21 | so that the warning is suppressed. | ||
306 | 22 | """ | ||
307 | 23 | |||
308 | 24 | from . import CommandLine # noqa | ||
309 | 25 | |||
310 | 26 | """ | ||
311 | 27 | Import the sub-modules which have decorated subcommands to register with chlp. | ||
312 | 28 | """ | ||
313 | 29 | import host # noqa | ||
314 | 30 | import benchmark # noqa | ||
315 | 31 | import unitdata # noqa | ||
316 | 32 | from charmhelpers.core import hookenv # noqa | ||
317 | 0 | 33 | ||
318 | === added file 'tests/charmhelpers/cli/host.py' | |||
319 | --- tests/charmhelpers/cli/host.py 1970-01-01 00:00:00 +0000 | |||
320 | +++ tests/charmhelpers/cli/host.py 2015-07-31 22:01:37 +0000 | |||
321 | @@ -0,0 +1,31 @@ | |||
322 | 1 | # Copyright 2014-2015 Canonical Limited. | ||
323 | 2 | # | ||
324 | 3 | # This file is part of charm-helpers. | ||
325 | 4 | # | ||
326 | 5 | # charm-helpers is free software: you can redistribute it and/or modify | ||
327 | 6 | # it under the terms of the GNU Lesser General Public License version 3 as | ||
328 | 7 | # published by the Free Software Foundation. | ||
329 | 8 | # | ||
330 | 9 | # charm-helpers is distributed in the hope that it will be useful, | ||
331 | 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
332 | 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
333 | 12 | # GNU Lesser General Public License for more details. | ||
334 | 13 | # | ||
335 | 14 | # You should have received a copy of the GNU Lesser General Public License | ||
336 | 15 | # along with charm-helpers. If not, see <http://www.gnu.org/licenses/>. | ||
337 | 16 | |||
338 | 17 | from . import cmdline | ||
339 | 18 | from charmhelpers.core import host | ||
340 | 19 | |||
341 | 20 | |||
342 | 21 | @cmdline.subcommand() | ||
343 | 22 | def mounts(): | ||
344 | 23 | "List mounts" | ||
345 | 24 | return host.mounts() | ||
346 | 25 | |||
347 | 26 | |||
348 | 27 | @cmdline.subcommand_builder('service', description="Control system services") | ||
349 | 28 | def service(subparser): | ||
350 | 29 | subparser.add_argument("action", help="The action to perform (start, stop, etc...)") | ||
351 | 30 | subparser.add_argument("service_name", help="Name of the service to control") | ||
352 | 31 | return host.service | ||
353 | 0 | 32 | ||
354 | === added file 'tests/charmhelpers/cli/unitdata.py' | |||
355 | --- tests/charmhelpers/cli/unitdata.py 1970-01-01 00:00:00 +0000 | |||
356 | +++ tests/charmhelpers/cli/unitdata.py 2015-07-31 22:01:37 +0000 | |||
357 | @@ -0,0 +1,39 @@ | |||
358 | 1 | # Copyright 2014-2015 Canonical Limited. | ||
359 | 2 | # | ||
360 | 3 | # This file is part of charm-helpers. | ||
361 | 4 | # | ||
362 | 5 | # charm-helpers is free software: you can redistribute it and/or modify | ||
363 | 6 | # it under the terms of the GNU Lesser General Public License version 3 as | ||
364 | 7 | # published by the Free Software Foundation. | ||
365 | 8 | # | ||
366 | 9 | # charm-helpers is distributed in the hope that it will be useful, | ||
367 | 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
368 | 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
369 | 12 | # GNU Lesser General Public License for more details. | ||
370 | 13 | # | ||
371 | 14 | # You should have received a copy of the GNU Lesser General Public License | ||
372 | 15 | # along with charm-helpers. If not, see <http://www.gnu.org/licenses/>. | ||
373 | 16 | |||
374 | 17 | from . import cmdline | ||
375 | 18 | from charmhelpers.core import unitdata | ||
376 | 19 | |||
377 | 20 | |||
378 | 21 | @cmdline.subcommand_builder('unitdata', description="Store and retrieve data") | ||
379 | 22 | def unitdata_cmd(subparser): | ||
380 | 23 | nested = subparser.add_subparsers() | ||
381 | 24 | get_cmd = nested.add_parser('get', help='Retrieve data') | ||
382 | 25 | get_cmd.add_argument('key', help='Key to retrieve the value of') | ||
383 | 26 | get_cmd.set_defaults(action='get', value=None) | ||
384 | 27 | set_cmd = nested.add_parser('set', help='Store data') | ||
385 | 28 | set_cmd.add_argument('key', help='Key to set') | ||
386 | 29 | set_cmd.add_argument('value', help='Value to store') | ||
387 | 30 | set_cmd.set_defaults(action='set') | ||
388 | 31 | |||
389 | 32 | def _unitdata_cmd(action, key, value): | ||
390 | 33 | if action == 'get': | ||
391 | 34 | return unitdata.kv().get(key) | ||
392 | 35 | elif action == 'set': | ||
393 | 36 | unitdata.kv().set(key, value) | ||
394 | 37 | unitdata.kv().flush() | ||
395 | 38 | return '' | ||
396 | 39 | return _unitdata_cmd | ||
397 | 0 | 40 | ||
398 | === modified file 'tests/charmhelpers/core/hookenv.py' | |||
399 | --- tests/charmhelpers/core/hookenv.py 2015-07-31 13:11:07 +0000 | |||
400 | +++ tests/charmhelpers/core/hookenv.py 2015-07-31 22:01:37 +0000 | |||
401 | @@ -34,7 +34,22 @@ | |||
402 | 34 | import tempfile | 34 | import tempfile |
403 | 35 | from subprocess import CalledProcessError | 35 | from subprocess import CalledProcessError |
404 | 36 | 36 | ||
406 | 37 | from charmhelpers.cli import cmdline | 37 | try: |
407 | 38 | from charmhelpers.cli import cmdline | ||
408 | 39 | except ImportError as e: | ||
409 | 40 | # due to the anti-pattern of partially synching charmhelpers directly | ||
410 | 41 | # into charms, it's possible that charmhelpers.cli is not available; | ||
411 | 42 | # if that's the case, they don't really care about using the cli anyway, | ||
412 | 43 | # so mock it out | ||
413 | 44 | if str(e) == 'No module named cli': | ||
414 | 45 | class cmdline(object): | ||
415 | 46 | @classmethod | ||
416 | 47 | def subcommand(cls, *args, **kwargs): | ||
417 | 48 | def _wrap(func): | ||
418 | 49 | return func | ||
419 | 50 | return _wrap | ||
420 | 51 | else: | ||
421 | 52 | raise | ||
422 | 38 | 53 | ||
423 | 39 | import six | 54 | import six |
424 | 40 | if not six.PY3: | 55 | if not six.PY3: |
charm_lint_check #7375 rabbitmq- server- next for billy-olsen mp266619
LINT OK: passed
Build: http:// 10.245. 162.77: 8080/job/ charm_lint_ check/7375/