Merge lp:~jamesbeedy/charms/trusty/fiche/next into lp:~jamesbeedy/charms/trusty/fiche/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
Reviewer Review Type Date Requested Status
james beedy Pending
Review via email: mp+287549@code.launchpad.net

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'
812Binary 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'
814Binary 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'
816Binary 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'
818Binary 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

Subscribers

People subscribed via source and target branches

to all changes: