Merge lp:~jamesbeedy/charms/trusty/fiche/next into lp:~jamesbeedy/charms/trusty/fiche/trunk
- Trusty Tahr (14.04)
- next
- Merge into trunk
Proposed by
james beedy
Status: | Merged |
---|---|
Merged at revision: | 4 |
Proposed branch: | lp:~jamesbeedy/charms/trusty/fiche/next |
Merge into: | lp:~jamesbeedy/charms/trusty/fiche/trunk |
Diff against target: |
818 lines (+348/-112) 22 files modified
.gitignore (+60/-0) Makefile (+1/-1) hooks/config-changed (+4/-3) hooks/hook.template (+4/-3) hooks/install (+4/-3) hooks/leader-elected (+4/-3) hooks/leader-settings-changed (+4/-3) hooks/start (+4/-3) hooks/stop (+4/-3) hooks/update-status (+4/-3) hooks/upgrade-charm (+10/-4) hooks/website-relation-broken (+4/-3) hooks/website-relation-changed (+4/-3) hooks/website-relation-departed (+4/-3) hooks/website-relation-joined (+4/-3) layer.yaml (+2/-0) lib/charms/layer/__init__.py (+21/-0) lib/charms/layer/basic.py (+114/-0) metadata.yaml (+1/-1) reactive/fiche.py (+65/-22) tests/10-deploy (+26/-27) unit_tests/test_actions.py (+0/-21) |
To merge this branch: | bzr merge lp:~jamesbeedy/charms/trusty/fiche/next |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
james beedy | Pending | ||
Review via email: mp+287549@code.launchpad.net |
Commit message
Description of the change
Merge next.
To post a comment you must log in.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === added file '.gitignore' |
2 | --- .gitignore 1970-01-01 00:00:00 +0000 |
3 | +++ .gitignore 2016-02-29 23:22:49 +0000 |
4 | @@ -0,0 +1,60 @@ |
5 | +#### joe made this: http://goel.io/joe |
6 | + |
7 | +#####=== Python ===##### |
8 | + |
9 | +# Byte-compiled / optimized / DLL files |
10 | +__pycache__/ |
11 | +*.py[cod] |
12 | + |
13 | +# C extensions |
14 | +*.so |
15 | + |
16 | +# Distribution / packaging |
17 | +.Python |
18 | +env/ |
19 | +build/ |
20 | +develop-eggs/ |
21 | +dist/ |
22 | +downloads/ |
23 | +eggs/ |
24 | +lib64/ |
25 | +parts/ |
26 | +sdist/ |
27 | +var/ |
28 | +*.egg-info/ |
29 | +.installed.cfg |
30 | +*.egg |
31 | + |
32 | +# PyInstaller |
33 | +# Usually these files are written by a python script from a template |
34 | +# before PyInstaller builds the exe, so as to inject date/other infos into it. |
35 | +*.manifest |
36 | +*.spec |
37 | + |
38 | +# Installer logs |
39 | +pip-log.txt |
40 | +pip-delete-this-directory.txt |
41 | + |
42 | +# Unit test / coverage reports |
43 | +htmlcov/ |
44 | +.tox/ |
45 | +.coverage |
46 | +.cache |
47 | +nosetests.xml |
48 | +coverage.xml |
49 | + |
50 | +# Translations |
51 | +*.mo |
52 | +*.pot |
53 | + |
54 | +# Django stuff: |
55 | +*.log |
56 | + |
57 | +# Sphinx documentation |
58 | +docs/_build/ |
59 | + |
60 | +# PyBuilder |
61 | +target/ |
62 | + |
63 | +deps |
64 | +trusty |
65 | |
66 | === modified file 'Makefile' |
67 | --- Makefile 2016-01-12 22:40:14 +0000 |
68 | +++ Makefile 2016-02-29 23:22:49 +0000 |
69 | @@ -8,7 +8,7 @@ |
70 | juju-compose -o ~/charms . |
71 | |
72 | lint: |
73 | - @flake8 --exclude hooks/charmhelpers hooks unit_tests tests |
74 | + @flake8 $(wildcard hooks unit_tests tests) |
75 | @charm proof |
76 | |
77 | unit_test: |
78 | |
79 | === modified file 'hooks/config-changed' |
80 | --- hooks/config-changed 2016-01-12 22:40:14 +0000 |
81 | +++ hooks/config-changed 2016-02-29 23:22:49 +0000 |
82 | @@ -4,15 +4,16 @@ |
83 | import sys |
84 | sys.path.append('lib') |
85 | |
86 | -from charms.bootstrap import bootstrap_charm_deps |
87 | -bootstrap_charm_deps() |
88 | +from charms.layer import basic |
89 | +basic.bootstrap_charm_deps() |
90 | +basic.init_config_states() |
91 | |
92 | |
93 | # This will load and run the appropriate @hook and other decorated |
94 | # handlers from $CHARM_DIR/reactive, $CHARM_DIR/hooks/reactive, |
95 | # and $CHARM_DIR/hooks/relations. |
96 | # |
97 | -# See https://jujucharms.com/docs/stable/getting-started-with-charms-reactive |
98 | +# See https://jujucharms.com/docs/stable/authors-charm-building |
99 | # for more information on this pattern. |
100 | from charms.reactive import main |
101 | main() |
102 | |
103 | === modified file 'hooks/hook.template' |
104 | --- hooks/hook.template 2016-01-12 22:40:14 +0000 |
105 | +++ hooks/hook.template 2016-02-29 23:22:49 +0000 |
106 | @@ -4,15 +4,16 @@ |
107 | import sys |
108 | sys.path.append('lib') |
109 | |
110 | -from charms.bootstrap import bootstrap_charm_deps |
111 | -bootstrap_charm_deps() |
112 | +from charms.layer import basic |
113 | +basic.bootstrap_charm_deps() |
114 | +basic.init_config_states() |
115 | |
116 | |
117 | # This will load and run the appropriate @hook and other decorated |
118 | # handlers from $CHARM_DIR/reactive, $CHARM_DIR/hooks/reactive, |
119 | # and $CHARM_DIR/hooks/relations. |
120 | # |
121 | -# See https://jujucharms.com/docs/stable/getting-started-with-charms-reactive |
122 | +# See https://jujucharms.com/docs/stable/authors-charm-building |
123 | # for more information on this pattern. |
124 | from charms.reactive import main |
125 | main() |
126 | |
127 | === modified file 'hooks/install' |
128 | --- hooks/install 2016-01-12 22:40:14 +0000 |
129 | +++ hooks/install 2016-02-29 23:22:49 +0000 |
130 | @@ -4,15 +4,16 @@ |
131 | import sys |
132 | sys.path.append('lib') |
133 | |
134 | -from charms.bootstrap import bootstrap_charm_deps |
135 | -bootstrap_charm_deps() |
136 | +from charms.layer import basic |
137 | +basic.bootstrap_charm_deps() |
138 | +basic.init_config_states() |
139 | |
140 | |
141 | # This will load and run the appropriate @hook and other decorated |
142 | # handlers from $CHARM_DIR/reactive, $CHARM_DIR/hooks/reactive, |
143 | # and $CHARM_DIR/hooks/relations. |
144 | # |
145 | -# See https://jujucharms.com/docs/stable/getting-started-with-charms-reactive |
146 | +# See https://jujucharms.com/docs/stable/authors-charm-building |
147 | # for more information on this pattern. |
148 | from charms.reactive import main |
149 | main() |
150 | |
151 | === modified file 'hooks/leader-elected' |
152 | --- hooks/leader-elected 2016-01-12 22:40:14 +0000 |
153 | +++ hooks/leader-elected 2016-02-29 23:22:49 +0000 |
154 | @@ -4,15 +4,16 @@ |
155 | import sys |
156 | sys.path.append('lib') |
157 | |
158 | -from charms.bootstrap import bootstrap_charm_deps |
159 | -bootstrap_charm_deps() |
160 | +from charms.layer import basic |
161 | +basic.bootstrap_charm_deps() |
162 | +basic.init_config_states() |
163 | |
164 | |
165 | # This will load and run the appropriate @hook and other decorated |
166 | # handlers from $CHARM_DIR/reactive, $CHARM_DIR/hooks/reactive, |
167 | # and $CHARM_DIR/hooks/relations. |
168 | # |
169 | -# See https://jujucharms.com/docs/stable/getting-started-with-charms-reactive |
170 | +# See https://jujucharms.com/docs/stable/authors-charm-building |
171 | # for more information on this pattern. |
172 | from charms.reactive import main |
173 | main() |
174 | |
175 | === modified file 'hooks/leader-settings-changed' |
176 | --- hooks/leader-settings-changed 2016-01-12 22:40:14 +0000 |
177 | +++ hooks/leader-settings-changed 2016-02-29 23:22:49 +0000 |
178 | @@ -4,15 +4,16 @@ |
179 | import sys |
180 | sys.path.append('lib') |
181 | |
182 | -from charms.bootstrap import bootstrap_charm_deps |
183 | -bootstrap_charm_deps() |
184 | +from charms.layer import basic |
185 | +basic.bootstrap_charm_deps() |
186 | +basic.init_config_states() |
187 | |
188 | |
189 | # This will load and run the appropriate @hook and other decorated |
190 | # handlers from $CHARM_DIR/reactive, $CHARM_DIR/hooks/reactive, |
191 | # and $CHARM_DIR/hooks/relations. |
192 | # |
193 | -# See https://jujucharms.com/docs/stable/getting-started-with-charms-reactive |
194 | +# See https://jujucharms.com/docs/stable/authors-charm-building |
195 | # for more information on this pattern. |
196 | from charms.reactive import main |
197 | main() |
198 | |
199 | === modified file 'hooks/start' |
200 | --- hooks/start 2016-01-12 22:40:14 +0000 |
201 | +++ hooks/start 2016-02-29 23:22:49 +0000 |
202 | @@ -4,15 +4,16 @@ |
203 | import sys |
204 | sys.path.append('lib') |
205 | |
206 | -from charms.bootstrap import bootstrap_charm_deps |
207 | -bootstrap_charm_deps() |
208 | +from charms.layer import basic |
209 | +basic.bootstrap_charm_deps() |
210 | +basic.init_config_states() |
211 | |
212 | |
213 | # This will load and run the appropriate @hook and other decorated |
214 | # handlers from $CHARM_DIR/reactive, $CHARM_DIR/hooks/reactive, |
215 | # and $CHARM_DIR/hooks/relations. |
216 | # |
217 | -# See https://jujucharms.com/docs/stable/getting-started-with-charms-reactive |
218 | +# See https://jujucharms.com/docs/stable/authors-charm-building |
219 | # for more information on this pattern. |
220 | from charms.reactive import main |
221 | main() |
222 | |
223 | === modified file 'hooks/stop' |
224 | --- hooks/stop 2016-01-12 22:40:14 +0000 |
225 | +++ hooks/stop 2016-02-29 23:22:49 +0000 |
226 | @@ -4,15 +4,16 @@ |
227 | import sys |
228 | sys.path.append('lib') |
229 | |
230 | -from charms.bootstrap import bootstrap_charm_deps |
231 | -bootstrap_charm_deps() |
232 | +from charms.layer import basic |
233 | +basic.bootstrap_charm_deps() |
234 | +basic.init_config_states() |
235 | |
236 | |
237 | # This will load and run the appropriate @hook and other decorated |
238 | # handlers from $CHARM_DIR/reactive, $CHARM_DIR/hooks/reactive, |
239 | # and $CHARM_DIR/hooks/relations. |
240 | # |
241 | -# See https://jujucharms.com/docs/stable/getting-started-with-charms-reactive |
242 | +# See https://jujucharms.com/docs/stable/authors-charm-building |
243 | # for more information on this pattern. |
244 | from charms.reactive import main |
245 | main() |
246 | |
247 | === modified file 'hooks/update-status' |
248 | --- hooks/update-status 2016-01-12 22:40:14 +0000 |
249 | +++ hooks/update-status 2016-02-29 23:22:49 +0000 |
250 | @@ -4,15 +4,16 @@ |
251 | import sys |
252 | sys.path.append('lib') |
253 | |
254 | -from charms.bootstrap import bootstrap_charm_deps |
255 | -bootstrap_charm_deps() |
256 | +from charms.layer import basic |
257 | +basic.bootstrap_charm_deps() |
258 | +basic.init_config_states() |
259 | |
260 | |
261 | # This will load and run the appropriate @hook and other decorated |
262 | # handlers from $CHARM_DIR/reactive, $CHARM_DIR/hooks/reactive, |
263 | # and $CHARM_DIR/hooks/relations. |
264 | # |
265 | -# See https://jujucharms.com/docs/stable/getting-started-with-charms-reactive |
266 | +# See https://jujucharms.com/docs/stable/authors-charm-building |
267 | # for more information on this pattern. |
268 | from charms.reactive import main |
269 | main() |
270 | |
271 | === modified file 'hooks/upgrade-charm' |
272 | --- hooks/upgrade-charm 2016-01-12 22:40:14 +0000 |
273 | +++ hooks/upgrade-charm 2016-02-29 23:22:49 +0000 |
274 | @@ -6,17 +6,23 @@ |
275 | sys.path.append('lib') |
276 | |
277 | # This is an upgrade-charm context, make sure we install latest deps |
278 | -os.unlink('wheelhouse/.bootstrapped') |
279 | +if not os.path.exists('wheelhouse/.upgrade'): |
280 | + open('wheelhouse/.upgrade', 'w').close() |
281 | + if os.path.exists('wheelhouse/.bootstrapped'): |
282 | + os.unlink('wheelhouse/.bootstrapped') |
283 | +else: |
284 | + os.unlink('wheelhouse/.upgrade') |
285 | |
286 | -from charms.bootstrap import bootstrap_charm_deps |
287 | -bootstrap_charm_deps() |
288 | +from charms.layer import basic |
289 | +basic.bootstrap_charm_deps() |
290 | +basic.init_config_states() |
291 | |
292 | |
293 | # This will load and run the appropriate @hook and other decorated |
294 | # handlers from $CHARM_DIR/reactive, $CHARM_DIR/hooks/reactive, |
295 | # and $CHARM_DIR/hooks/relations. |
296 | # |
297 | -# See https://jujucharms.com/docs/stable/getting-started-with-charms-reactive |
298 | +# See https://jujucharms.com/docs/stable/authors-charm-building |
299 | # for more information on this pattern. |
300 | from charms.reactive import main |
301 | main() |
302 | |
303 | === modified file 'hooks/website-relation-broken' |
304 | --- hooks/website-relation-broken 2016-01-12 22:40:14 +0000 |
305 | +++ hooks/website-relation-broken 2016-02-29 23:22:49 +0000 |
306 | @@ -4,15 +4,16 @@ |
307 | import sys |
308 | sys.path.append('lib') |
309 | |
310 | -from charms.bootstrap import bootstrap_charm_deps |
311 | -bootstrap_charm_deps() |
312 | +from charms.layer import basic |
313 | +basic.bootstrap_charm_deps() |
314 | +basic.init_config_states() |
315 | |
316 | |
317 | # This will load and run the appropriate @hook and other decorated |
318 | # handlers from $CHARM_DIR/reactive, $CHARM_DIR/hooks/reactive, |
319 | # and $CHARM_DIR/hooks/relations. |
320 | # |
321 | -# See https://jujucharms.com/docs/stable/getting-started-with-charms-reactive |
322 | +# See https://jujucharms.com/docs/stable/authors-charm-building |
323 | # for more information on this pattern. |
324 | from charms.reactive import main |
325 | main() |
326 | |
327 | === modified file 'hooks/website-relation-changed' |
328 | --- hooks/website-relation-changed 2016-01-12 22:40:14 +0000 |
329 | +++ hooks/website-relation-changed 2016-02-29 23:22:49 +0000 |
330 | @@ -4,15 +4,16 @@ |
331 | import sys |
332 | sys.path.append('lib') |
333 | |
334 | -from charms.bootstrap import bootstrap_charm_deps |
335 | -bootstrap_charm_deps() |
336 | +from charms.layer import basic |
337 | +basic.bootstrap_charm_deps() |
338 | +basic.init_config_states() |
339 | |
340 | |
341 | # This will load and run the appropriate @hook and other decorated |
342 | # handlers from $CHARM_DIR/reactive, $CHARM_DIR/hooks/reactive, |
343 | # and $CHARM_DIR/hooks/relations. |
344 | # |
345 | -# See https://jujucharms.com/docs/stable/getting-started-with-charms-reactive |
346 | +# See https://jujucharms.com/docs/stable/authors-charm-building |
347 | # for more information on this pattern. |
348 | from charms.reactive import main |
349 | main() |
350 | |
351 | === modified file 'hooks/website-relation-departed' |
352 | --- hooks/website-relation-departed 2016-01-12 22:40:14 +0000 |
353 | +++ hooks/website-relation-departed 2016-02-29 23:22:49 +0000 |
354 | @@ -4,15 +4,16 @@ |
355 | import sys |
356 | sys.path.append('lib') |
357 | |
358 | -from charms.bootstrap import bootstrap_charm_deps |
359 | -bootstrap_charm_deps() |
360 | +from charms.layer import basic |
361 | +basic.bootstrap_charm_deps() |
362 | +basic.init_config_states() |
363 | |
364 | |
365 | # This will load and run the appropriate @hook and other decorated |
366 | # handlers from $CHARM_DIR/reactive, $CHARM_DIR/hooks/reactive, |
367 | # and $CHARM_DIR/hooks/relations. |
368 | # |
369 | -# See https://jujucharms.com/docs/stable/getting-started-with-charms-reactive |
370 | +# See https://jujucharms.com/docs/stable/authors-charm-building |
371 | # for more information on this pattern. |
372 | from charms.reactive import main |
373 | main() |
374 | |
375 | === modified file 'hooks/website-relation-joined' |
376 | --- hooks/website-relation-joined 2016-01-12 22:40:14 +0000 |
377 | +++ hooks/website-relation-joined 2016-02-29 23:22:49 +0000 |
378 | @@ -4,15 +4,16 @@ |
379 | import sys |
380 | sys.path.append('lib') |
381 | |
382 | -from charms.bootstrap import bootstrap_charm_deps |
383 | -bootstrap_charm_deps() |
384 | +from charms.layer import basic |
385 | +basic.bootstrap_charm_deps() |
386 | +basic.init_config_states() |
387 | |
388 | |
389 | # This will load and run the appropriate @hook and other decorated |
390 | # handlers from $CHARM_DIR/reactive, $CHARM_DIR/hooks/reactive, |
391 | # and $CHARM_DIR/hooks/relations. |
392 | # |
393 | -# See https://jujucharms.com/docs/stable/getting-started-with-charms-reactive |
394 | +# See https://jujucharms.com/docs/stable/authors-charm-building |
395 | # for more information on this pattern. |
396 | from charms.reactive import main |
397 | main() |
398 | |
399 | === modified file 'layer.yaml' |
400 | --- layer.yaml 2016-01-12 22:40:14 +0000 |
401 | +++ layer.yaml 2016-02-29 23:22:49 +0000 |
402 | @@ -11,6 +11,8 @@ |
403 | - gcc |
404 | - supervisor |
405 | - git |
406 | + use_venv: false |
407 | + include_system_packages: false |
408 | nginx: {} |
409 | fiche: {} |
410 | is: fiche |
411 | |
412 | === added directory 'lib/charms/layer' |
413 | === added file 'lib/charms/layer/__init__.py' |
414 | --- lib/charms/layer/__init__.py 1970-01-01 00:00:00 +0000 |
415 | +++ lib/charms/layer/__init__.py 2016-02-29 23:22:49 +0000 |
416 | @@ -0,0 +1,21 @@ |
417 | +import os |
418 | + |
419 | + |
420 | +class LayerOptions(dict): |
421 | + def __init__(self, layer_file, section=None): |
422 | + import yaml # defer, might not be available until bootstrap |
423 | + with open(layer_file) as f: |
424 | + layer = yaml.safe_load(f.read()) |
425 | + opts = layer.get('options', {}) |
426 | + if section and section in opts: |
427 | + super(LayerOptions, self).__init__(opts.get(section)) |
428 | + else: |
429 | + super(LayerOptions, self).__init__(opts) |
430 | + |
431 | + |
432 | +def options(section=None, layer_file=None): |
433 | + if not layer_file: |
434 | + base_dir = os.environ.get('CHARM_DIR', os.getcwd()) |
435 | + layer_file = os.path.join(base_dir, 'layer.yaml') |
436 | + |
437 | + return LayerOptions(layer_file, section) |
438 | |
439 | === added file 'lib/charms/layer/basic.py' |
440 | --- lib/charms/layer/basic.py 1970-01-01 00:00:00 +0000 |
441 | +++ lib/charms/layer/basic.py 2016-02-29 23:22:49 +0000 |
442 | @@ -0,0 +1,114 @@ |
443 | +import os |
444 | +import sys |
445 | +import shutil |
446 | +from glob import glob |
447 | +from subprocess import check_call |
448 | + |
449 | + |
450 | +def bootstrap_charm_deps(): |
451 | + """ |
452 | + Set up the base charm dependencies so that the reactive system can run. |
453 | + """ |
454 | + venv = os.path.abspath('../.venv') |
455 | + vbin = os.path.join(venv, 'bin') |
456 | + vpip = os.path.join(vbin, 'pip') |
457 | + vpy = os.path.join(vbin, 'python') |
458 | + if os.path.exists('wheelhouse/.bootstrapped'): |
459 | + from charms import layer |
460 | + cfg = layer.options('basic') |
461 | + if cfg.get('use_venv') and '.venv' not in sys.executable: |
462 | + # activate the venv |
463 | + os.environ['PATH'] = ':'.join([vbin, os.environ['PATH']]) |
464 | + reload_interpreter(vpy) |
465 | + return |
466 | + # bootstrap wheelhouse |
467 | + if os.path.exists('wheelhouse'): |
468 | + apt_install(['python3-pip', 'python3-yaml']) |
469 | + from charms import layer |
470 | + cfg = layer.options('basic') |
471 | + # include packages defined in layer.yaml |
472 | + apt_install(cfg.get('packages', [])) |
473 | + # if we're using a venv, set it up |
474 | + if cfg.get('use_venv'): |
475 | + if not os.path.exists(venv): |
476 | + apt_install(['python-virtualenv']) |
477 | + cmd = ['virtualenv', '--python=python3', venv] |
478 | + if cfg.get('include_system_packages'): |
479 | + cmd.append('--system-site-packages') |
480 | + check_call(cmd) |
481 | + os.environ['PATH'] = ':'.join([vbin, os.environ['PATH']]) |
482 | + pip = vpip |
483 | + else: |
484 | + pip = 'pip3' |
485 | + # save a copy of system pip to prevent `pip3 install -U pip` from changing it |
486 | + if os.path.exists('/usr/bin/pip'): |
487 | + shutil.copy2('/usr/bin/pip', '/usr/bin/pip.save') |
488 | + # need newer pip, to fix spurious Double Requirement error https://github.com/pypa/pip/issues/56 |
489 | + check_call([pip, 'install', '-U', '--no-index', '-f', 'wheelhouse', 'pip']) |
490 | + # install the rest of the wheelhouse deps |
491 | + check_call([pip, 'install', '-U', '--no-index', '-f', 'wheelhouse'] + glob('wheelhouse/*')) |
492 | + if not cfg.get('use_venv'): |
493 | + # restore system pip to prevent `pip3 install -U pip` from changing it |
494 | + if os.path.exists('/usr/bin/pip.save'): |
495 | + shutil.copy2('/usr/bin/pip.save', '/usr/bin/pip') |
496 | + os.remove('/usr/bin/pip.save') |
497 | + # flag us as having already bootstrapped so we don't do it again |
498 | + open('wheelhouse/.bootstrapped', 'w').close() |
499 | + # Ensure that the newly bootstrapped libs are available. |
500 | + # Note: this only seems to be an issue with namespace packages. |
501 | + # Non-namespace-package libs (e.g., charmhelpers) are available |
502 | + # without having to reload the interpreter. :/ |
503 | + reload_interpreter(vpy if cfg.get('use_venv') else sys.argv[0]) |
504 | + |
505 | + |
506 | +def reload_interpreter(python): |
507 | + """ |
508 | + Reload the python interpreter to ensure that all deps are available. |
509 | + |
510 | + Newly installed modules in namespace packages sometimes seemt to |
511 | + not be picked up by Python 3. |
512 | + """ |
513 | + os.execle(python, python, sys.argv[0], os.environ) |
514 | + |
515 | + |
516 | +def apt_install(packages): |
517 | + """ |
518 | + Install apt packages. |
519 | + |
520 | + This ensures a consistent set of options that are often missed but |
521 | + should really be set. |
522 | + """ |
523 | + if isinstance(packages, (str, bytes)): |
524 | + packages = [packages] |
525 | + |
526 | + env = os.environ.copy() |
527 | + |
528 | + if 'DEBIAN_FRONTEND' not in env: |
529 | + env['DEBIAN_FRONTEND'] = 'noninteractive' |
530 | + |
531 | + cmd = ['apt-get', |
532 | + '--option=Dpkg::Options::=--force-confold', |
533 | + '--assume-yes', |
534 | + 'install'] |
535 | + check_call(cmd + packages, env=env) |
536 | + |
537 | + |
538 | +def init_config_states(): |
539 | + from charmhelpers.core import hookenv |
540 | + from charms.reactive import set_state |
541 | + config = hookenv.config() |
542 | + for opt in config.keys(): |
543 | + if config.changed(opt): |
544 | + set_state('config.changed') |
545 | + set_state('config.changed.{}'.format(opt)) |
546 | + hookenv.atexit(clear_config_states) |
547 | + |
548 | + |
549 | +def clear_config_states(): |
550 | + from charmhelpers.core import hookenv, unitdata |
551 | + from charms.reactive import remove_state |
552 | + config = hookenv.config() |
553 | + remove_state('config.changed') |
554 | + for opt in config.keys(): |
555 | + remove_state('config.changed.{}'.format(opt)) |
556 | + unitdata.kv().flush() |
557 | |
558 | === modified file 'metadata.yaml' |
559 | --- metadata.yaml 2016-01-12 22:40:14 +0000 |
560 | +++ metadata.yaml 2016-02-29 23:22:49 +0000 |
561 | @@ -1,6 +1,6 @@ |
562 | name: fiche |
563 | summary: Fiche is an open source command line pastebin server. |
564 | -maintainer: James Beedy <James.Beedy@os-deployer.darkhorseint.com> |
565 | +maintainer: James Beedy <jamesbeedy@gmail.com> |
566 | description: | |
567 | Fiche is an open source command line pastebin server. It can be found here: |
568 | https://github.com/solusipse/fiche |
569 | |
570 | === modified file 'reactive/fiche.py' |
571 | --- reactive/fiche.py 2016-01-12 22:40:14 +0000 |
572 | +++ reactive/fiche.py 2016-02-29 23:22:49 +0000 |
573 | @@ -1,5 +1,5 @@ |
574 | -#!/usr/bin/python |
575 | -# Copyright (c) 2015, James Beedy <jamesbeedy@gmail.com> |
576 | +#!/usr/bin/python3 |
577 | +# Copyright (c) 2016, James Beedy <jamesbeedy@gmail.com> |
578 | |
579 | import os |
580 | import sys |
581 | @@ -7,9 +7,10 @@ |
582 | import shutil |
583 | import subprocess |
584 | |
585 | -from charms.reactive import hook |
586 | from charms.reactive import when |
587 | +from charms.reactive import when_not |
588 | from charms.reactive import only_once |
589 | +from charms.reactive import set_state |
590 | from charmhelpers.core.templating import render |
591 | from charmhelpers.core import hookenv |
592 | from charmhelpers.core import host |
593 | @@ -25,7 +26,7 @@ |
594 | config = hookenv.config() |
595 | |
596 | FICHE_SUPERVISOR_CTXT = { |
597 | - 'fiche_server_address': hookenv.unit_get('private-address'), |
598 | + 'fiche_server_address': hookenv.unit_public_ip(), |
599 | 'fiche_server_port': config['fiche-server-port'], |
600 | 'slug_size': config['slug-size'], |
601 | 'buffer_size': config['buffer-size'] |
602 | @@ -68,6 +69,7 @@ |
603 | |
604 | |
605 | @when('nginx.available') |
606 | +@when_not('fiche.available') |
607 | @only_once |
608 | def install_fiche(): |
609 | |
610 | @@ -76,9 +78,6 @@ |
611 | |
612 | hookenv.status_set('maintenance', 'Installing and configuring Fiche.') |
613 | |
614 | - # Configure nginx vhost |
615 | - configure_site('fiche', 'fiche.vhost', app_path=FICHE_CODE_DIR) |
616 | - |
617 | # Clone fiche repo |
618 | hookenv.status_set('maintenance', |
619 | 'Installing and building fiche from github.') |
620 | @@ -94,26 +93,70 @@ |
621 | # Ensure base dir exists |
622 | _ensure_basedir() |
623 | |
624 | + # Configure nginx vhost |
625 | + configure_site('fiche', 'fiche.vhost', app_path=FICHE_CODE_DIR) |
626 | + |
627 | # Render fiche supervisor conf |
628 | _render_fiche_supervisor_conf(FICHE_SUPERVISOR_CTXT) |
629 | - hookenv.status_set('active', 'Fiche is active and ready!') |
630 | - |
631 | + |
632 | + # Open fiche server port |
633 | + hookenv.open_port(config['fiche-server-port']) |
634 | + |
635 | + # Open fiche front-end port |
636 | + hookenv.open_port(config['port']) |
637 | + |
638 | + # Set status |
639 | + hookenv.status_set('active', 'Fiche is active on port %s' % \ |
640 | + config['fiche-server-port']) |
641 | + # Set state |
642 | + set_state('fiche.available') |
643 | + |
644 | |
645 | @when('nginx.available', 'website.available') |
646 | def configure_website(website): |
647 | website.configure(port=config['port']) |
648 | |
649 | |
650 | -@hook('config-changed') |
651 | -def fiche_config_changed(): |
652 | - |
653 | - """ React to fiche config-changed |
654 | - """ |
655 | - hookenv.status_set('maintenance', 'Reconfiguring fiche.') |
656 | - |
657 | - if config.changed('fiche-server-port') or \ |
658 | - config.changed('slug-size') or \ |
659 | - config.changed('buffer-size'): |
660 | - _render_fiche_supervisor_conf(FICHE_SUPERVISOR_CTXT) |
661 | - |
662 | - hookenv.status_set('active', 'Fiche is active and ready!') |
663 | +@when('config.changed.fiche-server-port') |
664 | +def fiche_port_changed(): |
665 | + |
666 | + """ React to fiche-server-port changed |
667 | + """ |
668 | + hookenv.status_set('maintenance', 'Reconfiguring fiche-server-port') |
669 | + |
670 | + # Check and change open port, close prev port |
671 | + if config.previous('fiche-server-port') and \ |
672 | + config.previous('fiche-server-port') != config['fiche-server-port']: |
673 | + hookenv.close_port(config.previous('fiche-server-port')) |
674 | + hookenv.open_port(config['fiche-server-port']) |
675 | + |
676 | + _render_fiche_supervisor_conf(FICHE_SUPERVISOR_CTXT) |
677 | + hookenv.status_set('active', 'Fiche is active on port %s' % \ |
678 | + config['fiche-server-port']) |
679 | + |
680 | + |
681 | +@when('config.changed.slug-size') |
682 | +def fiche_slug_size_changed(): |
683 | + |
684 | + """ React to slug-size changed |
685 | + """ |
686 | + hookenv.status_set('maintenance', 'Reconfiguring slug-size') |
687 | + |
688 | + # Rerender supervisord conf |
689 | + _render_fiche_supervisor_conf(FICHE_SUPERVISOR_CTXT) |
690 | + |
691 | + hookenv.status_set('active', 'Fiche is active on port %s' % \ |
692 | + config['fiche-server-port']) |
693 | + |
694 | +@when('config.changed.buffer-size') |
695 | +def fiche_buffer_size_changed(): |
696 | + |
697 | + """ React to buffer-size changed |
698 | + """ |
699 | + hookenv.status_set('maintenance', 'Reconfiguring buffer-size') |
700 | + |
701 | + # Rerender supervisord conf |
702 | + _render_fiche_supervisor_conf(FICHE_SUPERVISOR_CTXT) |
703 | + |
704 | + hookenv.status_set('active', 'Fiche is active on port %s' % \ |
705 | + config['fiche-server-port']) |
706 | |
707 | === modified file 'tests/10-deploy' |
708 | --- tests/10-deploy 2016-01-12 22:40:14 +0000 |
709 | +++ tests/10-deploy 2016-02-29 23:22:49 +0000 |
710 | @@ -4,13 +4,30 @@ |
711 | import requests |
712 | import unittest |
713 | |
714 | +import socket |
715 | + |
716 | + |
717 | +def netcat(host, port, content): |
718 | + s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) |
719 | + s.connect((host, int(port))) |
720 | + s.sendall(content.encode()) |
721 | + s.shutdown(socket.SHUT_WR) |
722 | + while True: |
723 | + data = s.recv(4096) |
724 | + if not data: |
725 | + break |
726 | + dat = data |
727 | + s.close() |
728 | + return dat |
729 | + |
730 | |
731 | class TestDeployment(unittest.TestCase): |
732 | @classmethod |
733 | def setUpClass(cls): |
734 | - cls.deployment = amulet.Deployment() |
735 | + cls.deployment = amulet.Deployment(series='trusty') |
736 | |
737 | cls.deployment.add('fiche') |
738 | + cls.deployment.configure('fiche', {'fiche-server-port': 9999}) |
739 | cls.deployment.expose('fiche') |
740 | |
741 | try: |
742 | @@ -20,32 +37,14 @@ |
743 | amulet.raise_status(amulet.SKIP, msg="Environment wasn't stood up in time") |
744 | except: |
745 | raise |
746 | - cls.unit = cls.deployment.sentry.unit['fiche/0'] |
747 | - |
748 | - def test_case(self): |
749 | - # Now you can use self.deployment.sentry.unit[UNIT] to address each of |
750 | - # the units and perform more in-depth steps. You can also reference |
751 | - # the first unit as self.unit. |
752 | - # There are three test statuses that can be triggered with |
753 | - # amulet.raise_status(): |
754 | - # - amulet.PASS |
755 | - # - amulet.FAIL |
756 | - # - amulet.SKIP |
757 | - # Each unit has the following methods: |
758 | - # - .info - An array of the information of that unit from Juju |
759 | - # - .file(PATH) - Get the details of a file on that unit |
760 | - # - .file_contents(PATH) - Get plain text output of PATH file from that unit |
761 | - # - .directory(PATH) - Get details of directory |
762 | - # - .directory_contents(PATH) - List files and folders in PATH on that unit |
763 | - # - .relation(relation, service:rel) - Get relation data from return service |
764 | - # add tests here to confirm service is up and working properly |
765 | - # For example, to confirm that it has a functioning HTTP server: |
766 | - # page = requests.get('http://{}'.format(self.unit.info['public-address'])) |
767 | - # page.raise_for_status() |
768 | - # More information on writing Amulet tests can be found at: |
769 | - # https://jujucharms.com/docs/stable/tools-amulet |
770 | - pass |
771 | - |
772 | + cls.unit = cls.deployment.sentry.unit['fiche'][1] |
773 | + cls.ipaddr = cls.unit.info['public-address'] |
774 | + cls.base_url = 'http://%s/' % cls.ipaddr |
775 | + |
776 | + |
777 | + def test_1_verify_base_url(self): |
778 | + response = requests.get(self.base_url) |
779 | + response.raise_for_status() |
780 | |
781 | if __name__ == '__main__': |
782 | unittest.main() |
783 | |
784 | === removed directory 'unit_tests' |
785 | === removed file 'unit_tests/test_actions.py' |
786 | --- unit_tests/test_actions.py 2016-01-12 22:40:14 +0000 |
787 | +++ unit_tests/test_actions.py 1970-01-01 00:00:00 +0000 |
788 | @@ -1,21 +0,0 @@ |
789 | -#!/usr/bin/env python |
790 | - |
791 | -import sys |
792 | -import mock |
793 | -import unittest |
794 | -from pkg_resources import resource_filename |
795 | - |
796 | -# allow importing actions from the hooks directory |
797 | -sys.path.append(resource_filename(__name__, '../hooks')) |
798 | -import actions |
799 | - |
800 | - |
801 | -class TestActions(unittest.TestCase): |
802 | - @mock.patch('charmhelpers.core.hookenv.log') |
803 | - def test_log_start(self, log): |
804 | - actions.log_start('test-service') |
805 | - log.assert_called_once_with('fiche starting') |
806 | - |
807 | - |
808 | -if __name__ == '__main__': |
809 | - unittest.main() |
810 | |
811 | === removed file 'wheelhouse/charmhelpers-0.6.1.tar.gz' |
812 | Binary files wheelhouse/charmhelpers-0.6.1.tar.gz 2016-01-12 22:40:14 +0000 and wheelhouse/charmhelpers-0.6.1.tar.gz 1970-01-01 00:00:00 +0000 differ |
813 | === added file 'wheelhouse/charmhelpers-0.6.2.tar.gz' |
814 | Binary files wheelhouse/charmhelpers-0.6.2.tar.gz 1970-01-01 00:00:00 +0000 and wheelhouse/charmhelpers-0.6.2.tar.gz 2016-02-29 23:22:49 +0000 differ |
815 | === removed file 'wheelhouse/charms.reactive-0.3.7.tar.gz' |
816 | Binary files wheelhouse/charms.reactive-0.3.7.tar.gz 2016-01-12 22:40:14 +0000 and wheelhouse/charms.reactive-0.3.7.tar.gz 1970-01-01 00:00:00 +0000 differ |
817 | === added file 'wheelhouse/charms.reactive-0.3.8.tar.gz' |
818 | Binary files wheelhouse/charms.reactive-0.3.8.tar.gz 1970-01-01 00:00:00 +0000 and wheelhouse/charms.reactive-0.3.8.tar.gz 2016-02-29 23:22:49 +0000 differ |