Merge lp:~johnsca/charms/precise/chamilo/services-framework into lp:charms/chamilo
- Precise Pangolin (12.04)
- services-framework
- Merge into trunk
Status: | Merged |
---|---|
Merged at revision: | 11 |
Proposed branch: | lp:~johnsca/charms/precise/chamilo/services-framework |
Merge into: | lp:charms/chamilo |
Diff against target: |
893 lines (+594/-222) 15 files modified
.bzrignore (+3/-0) Makefile (+60/-0) hooks/actions.py (+56/-0) hooks/config-changed (+3/-51) hooks/db-relation-changed (+3/-80) hooks/db-relation-departed (+3/-23) hooks/install (+53/-45) hooks/services.py (+37/-0) hooks/setup.py (+17/-0) hooks/start (+3/-10) hooks/stop (+3/-10) hooks/website-relation-joined (+3/-3) templates/apache-site.j2 (+41/-0) templates/configuration.php.j2 (+207/-0) tests/test_actions.py (+102/-0) |
To merge this branch: | bzr merge lp:~johnsca/charms/precise/chamilo/services-framework |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Charles Butler (community) | Approve | ||
Review Queue (community) | automated testing | Approve | |
Review via email: mp+235698@code.launchpad.net |
Commit message
Description of the change
Converted charm to python, charmhelpers, and the services framework.
This charm was a great candidate for showing what a good charm looks like before and after using the new framework. This should both improve the readability of the charm and give a good showcase of the benefits of the framework.
Main points:
* Remove manual management of dot-files for tracking partial progress
* Explicit, declarative code describing the mandatory requirements (config, relations, etc)
* Encourages splitting steps / actions into discrete, testable chunks
* Encourages using templates instead of hard-to-read sed commands
Review Queue (review-queue) wrote : | # |
- 17. By Cory Johns
-
Fixed lint errors
Review Queue (review-queue) wrote : | # |
The results (PASS) are in and available here: http://
Charles Butler (lazypower) wrote : | # |
Great re-imagining of the chamilo charm with the services framework Cory. Thank you for the great submission. I've gone ahead an approved this and pushed to the store. This will be available in the next 20 to 30 minutes.
Thanks again!
Preview Diff
1 | === added file '.bzrignore' |
2 | --- .bzrignore 1970-01-01 00:00:00 +0000 |
3 | +++ .bzrignore 2014-11-11 14:52:49 +0000 |
4 | @@ -0,0 +1,3 @@ |
5 | +venv |
6 | +*.pyc |
7 | +.coverage |
8 | |
9 | === added file 'Makefile' |
10 | --- Makefile 1970-01-01 00:00:00 +0000 |
11 | +++ Makefile 2014-11-11 14:52:49 +0000 |
12 | @@ -0,0 +1,60 @@ |
13 | +PY := venv/bin/python |
14 | +# If the bin version does not exist look in venv/local/bin |
15 | +ifeq ($(wildcard venv/bin/pip),) |
16 | + PIP = venv/local/bin/pip |
17 | +else |
18 | + PIP = venv/bin/pip |
19 | +endif |
20 | +# If the bin version does not exist look in venv/local/bin |
21 | +NOSE = venv/bin/nosetests |
22 | +# ########### |
23 | +# Build |
24 | +# ########### |
25 | + |
26 | +.PHONY: install |
27 | +install: venv test_deps |
28 | + |
29 | +venv: $(PY) |
30 | +$(PY): |
31 | + virtualenv venv |
32 | + |
33 | +test_deps: $(PY) |
34 | + $(PIP) install nose coverage mock pyyaml -e bzr+lp:~johnsca/charm-helpers/contexts#egg=charmhelpers |
35 | + |
36 | +.PHONY: clean_all |
37 | +clean_all: clean clean_venv clean_db |
38 | + |
39 | +.PHONY: clean_venv |
40 | +clean_venv: |
41 | + rm -rf venv |
42 | + |
43 | +.PHONY: clean |
44 | +clean: |
45 | + find . -name '*.pyc' -delete |
46 | + find . -name '*.bak' -delete |
47 | + rm -f .coverage |
48 | + |
49 | +.PHONY: sysdeps |
50 | +sysdeps: |
51 | + sudo apt-get $(shell tty -s || echo -y) install python3-dev virtualenv |
52 | + |
53 | +.PHONY: test |
54 | +test: unit_test |
55 | + |
56 | +unit_test: $(NOSE) |
57 | + @$(NOSE) --nologcapture |
58 | + |
59 | +.PHONY: coverage |
60 | +coverage: $(NOSE) |
61 | + @echo Testing with coverage... |
62 | + @$(NOSE) --nologcapture --with-coverage --cover-package=hooks |
63 | + |
64 | +.PHONY: lint |
65 | +lint: |
66 | + @find $(sources) -type f \( -iname '*.py' ! -iname '__init__.py' ! -iwholename '*venv/*' \) -print0 | xargs -r0 flake8 |
67 | + |
68 | +.PHONY: check |
69 | +check: test lint |
70 | + |
71 | +.PHONY: all |
72 | +all: clean venv coverage lint |
73 | |
74 | === added file 'hooks/__init__.py' |
75 | === added file 'hooks/actions.py' |
76 | --- hooks/actions.py 1970-01-01 00:00:00 +0000 |
77 | +++ hooks/actions.py 2014-11-11 14:52:49 +0000 |
78 | @@ -0,0 +1,56 @@ |
79 | +import subprocess |
80 | + |
81 | +from charmhelpers.core import hookenv |
82 | +from charmhelpers.core.services import helpers |
83 | + |
84 | + |
85 | +def init_database(service_name): |
86 | + """ |
87 | + Load SQL file to set up all of the database tables. |
88 | + """ |
89 | + config = hookenv.config() |
90 | + if config.previous('db_initialized'): |
91 | + return |
92 | + |
93 | + hookenv.log('Initializing database') |
94 | + mysql = helpers.MysqlRelation()['db'][0] |
95 | + with open('data/chamilo-default-db.sql') as sql: |
96 | + exec_sql(sql, mysql) |
97 | + config['db_initialized'] = True |
98 | + config.save() |
99 | + |
100 | + |
101 | +def update_admin_account(service_name): |
102 | + """ |
103 | + Update the admin username and password in the database directly. |
104 | + """ |
105 | + config = hookenv.config() |
106 | + mysql = helpers.MysqlRelation()['db'][0] |
107 | + |
108 | + hookenv.log('Updating admin username') |
109 | + exec_sql("UPDATE user SET username = '%s' " |
110 | + "WHERE user_id = 1;".format(config['user']), mysql) |
111 | + |
112 | + hookenv.log('Updating admin password') |
113 | + exec_sql("UPDATE user SET password = SHA1('{}') " |
114 | + "WHERE user_id = 1;".format(config['pass']), mysql) |
115 | + |
116 | + |
117 | +def exec_sql(sql, mysql_cfg): |
118 | + """ |
119 | + Execute SQL against a MySQL instance |
120 | + """ |
121 | + sql_cmd = [ |
122 | + 'mysql', |
123 | + '-u{}'.format(mysql_cfg['user']), |
124 | + '-p{}'.format(mysql_cfg['password']), |
125 | + '-h', mysql_cfg['host'], |
126 | + mysql_cfg['database'], |
127 | + ] |
128 | + |
129 | + if not hasattr(sql, 'read'): |
130 | + sql_cmd.extend(['-e', sql]) |
131 | + stdin = None |
132 | + else: |
133 | + stdin = sql |
134 | + subprocess.check_call(sql_cmd, stdin=stdin) |
135 | |
136 | === modified file 'hooks/config-changed' |
137 | --- hooks/config-changed 2014-06-25 23:43:23 +0000 |
138 | +++ hooks/config-changed 2014-11-11 14:52:49 +0000 |
139 | @@ -1,51 +1,3 @@ |
140 | -#!/bin/bash |
141 | - |
142 | -set -eux |
143 | - |
144 | -DOMAIN=`config-get domain` |
145 | -USERNAME=`config-get user` |
146 | -PASS=`config-get pass` |
147 | - |
148 | -if [ -f .dbset ]; then |
149 | - HOST=`cat .host` |
150 | - DB=`cat .db` |
151 | - USER=`cat .user` |
152 | - PASSWORD=`cat .password` |
153 | -fi |
154 | - |
155 | -if [ -z "$DOMAIN" ]; then |
156 | - juju-log "Domain hasn't been set, exiting silently." |
157 | - exit 0 |
158 | -fi |
159 | - |
160 | -if [ -f .domainnotset ]; then |
161 | - hooks/db-relation-changed |
162 | - rm .domainnotset |
163 | -fi |
164 | - |
165 | -if [ -z "$PASS" ]; then |
166 | - juju-log "Password hasn't been set, exiting silently." |
167 | - exit 0 |
168 | -fi |
169 | - |
170 | -if [ -f .configured ] && [ `cat .domain` != "$DOMAIN" ]; then |
171 | - juju-log "Updating domain" |
172 | - CURDOM=`cat .domain` |
173 | - sed -i "s/$CURDOM/$DOMAIN/" /var/www/main/inc/conf/configuration.php |
174 | - echo "$DOMAIN" > .domain |
175 | -fi |
176 | - |
177 | -if [ -f .dbset ] && [ `cat .username` != "$USERNAME" ]; then |
178 | - juju-log "Updating username" |
179 | - mysql -u $USER -p$PASSWORD -h $HOST $DB -e "UPDATE user SET username = '$USERNAME' WHERE user_id = 1;" |
180 | - echo "$USERNAME" > .username |
181 | -fi |
182 | - |
183 | -if [ -f .dbset ] && [ `cat .pass` != "$PASS" ]; then |
184 | - juju-log "Updating password" |
185 | - mysql -u $USER -p$PASSWORD -h $HOST $DB -e "UPDATE user SET password = SHA1('$PASS') WHERE user_id = 1;" |
186 | - echo "$PASS" > .pass |
187 | -fi |
188 | - |
189 | -juju-log "Restarting server" |
190 | -service apache2 restart |
191 | +#!/usr/bin/env python |
192 | +import services |
193 | +services.manage() |
194 | |
195 | === modified file 'hooks/db-relation-changed' |
196 | --- hooks/db-relation-changed 2014-06-23 05:08:55 +0000 |
197 | +++ hooks/db-relation-changed 2014-11-11 14:52:49 +0000 |
198 | @@ -1,80 +1,3 @@ |
199 | -#!/bin/bash |
200 | - |
201 | -set -eux |
202 | - |
203 | -if [ -f .domainnotset ]; then |
204 | - HOST=`cat .host` |
205 | - DB=`cat .db` |
206 | - USER=`cat .user` |
207 | - PASSWORD=`cat .password` |
208 | -else |
209 | - HOST=`relation-get private-address` |
210 | - DB=`relation-get database` |
211 | - USER=`relation-get user` |
212 | - PASSWORD=`relation-get password` |
213 | -fi |
214 | -DOMAIN=`config-get domain` |
215 | -KEY=`makepasswd` |
216 | -VERSION="1.9.8.2" |
217 | -USERNAME=`config-get user` |
218 | -PASS=`config-get pass` |
219 | - |
220 | -if [ -z "$DB" ]; then |
221 | - juju-log "Data hasn't been set yet! Exiting silently" |
222 | - exit 0 |
223 | -fi |
224 | - |
225 | -echo "$HOST" > .host |
226 | -echo "$USER" > .user |
227 | -echo "$PASSWORD" > .password |
228 | -echo "$DB" > .db |
229 | - |
230 | -if [ -z "$DOMAIN" ]; then |
231 | - juju-log "Domain hasn't been set! Exiting silently" |
232 | - touch .domainnotset |
233 | - exit 0 |
234 | -fi |
235 | - |
236 | -if [ ! -f /var/www/main/inc/conf/configuration.php.bak ]; then |
237 | - juju-log "Making backup of Chamilo config file" |
238 | - cp /var/www/main/inc/conf/configuration.php /var/www/main/inc/conf/configuration.php.bak |
239 | -fi |
240 | - |
241 | -juju-log "Configuring Chamilo" |
242 | -sed -i "s/{DATABASE_HOST}/$HOST/" /var/www/main/inc/conf/configuration.php |
243 | -sed -i "s/{DATABASE_USER}/$USER/" /var/www/main/inc/conf/configuration.php |
244 | -sed -i "s/{DATABASE_PASSWORD}/$PASSWORD/" /var/www/main/inc/conf/configuration.php |
245 | -sed -i "s/{COURSE_TABLE_PREFIX}//" /var/www/main/inc/conf/configuration.php |
246 | -sed -i "s/{ROOT_WEB}/http:\/\/$DOMAIN\//" /var/www/main/inc/conf/configuration.php |
247 | -sed -i "s/{ROOT_SYS}/\/var\/www\//" /var/www/main/inc/conf/configuration.php |
248 | -sed -i "s/{DATABASE_MAIN}/$DB/" /var/www/main/inc/conf/configuration.php |
249 | -sed -i "s/{DATABASE_STATS}/$DB/" /var/www/main/inc/conf/configuration.php |
250 | -sed -i "s/{DATABASE_PERSONAL}/$DB/" /var/www/main/inc/conf/configuration.php |
251 | -sed -i "s/{URL_APPEND_PATH}//" /var/www/main/inc/conf/configuration.php |
252 | -sed -i "s/{DATABASE_PREFIX}//" /var/www/main/inc/conf/configuration.php |
253 | -sed -i "s/{DATABASE_GLUE}/\`.\`/" /var/www/main/inc/conf/configuration.php |
254 | -sed -i "s/{ENCRYPT_PASSWORD}/sha1/" /var/www/main/inc/conf/configuration.php |
255 | -sed -i "s/{SECURITY_KEY}/$KEY/" /var/www/main/inc/conf/configuration.php |
256 | -sed -i "s/{NEW_VERSION}/$VERSION/" /var/www/main/inc/conf/configuration.php |
257 | -sed -i "s/TRACKING_ENABLED/true/" /var/www/main/inc/conf/configuration.php |
258 | -sed -i "s/SINGLE_DATABASE/false/" /var/www/main/inc/conf/configuration.php |
259 | -sed -i "s/SESSION_LIFETIME/360000/" /var/www/main/inc/conf/configuration.php |
260 | -touch .configured |
261 | -echo "$DOMAIN" > .domain |
262 | - |
263 | -if [ ! -f .dbset ]; then |
264 | - juju-log "Importing base database" |
265 | - mysql -u $USER -p$PASSWORD -h $HOST $DB < data/chamilo-default-db.sql |
266 | - mysql -u $USER -p$PASSWORD -h $HOST $DB -e "UPDATE user SET username = '$USERNAME', password = SHA1('$PASS') WHERE user_id = 1;" |
267 | - echo "$USERNAME" > .username |
268 | - echo "$PASS" > .pass |
269 | - touch .dbset |
270 | -fi |
271 | - |
272 | -if [ ! -f .started ]; then |
273 | - juju-log "Starting service..." |
274 | - hooks/start |
275 | -fi |
276 | - |
277 | -juju-log "Configuration has been successful." |
278 | - |
279 | +#!/usr/bin/env python |
280 | +import services |
281 | +services.manage() |
282 | |
283 | === modified file 'hooks/db-relation-departed' |
284 | --- hooks/db-relation-departed 2014-06-04 00:29:03 +0000 |
285 | +++ hooks/db-relation-departed 2014-11-11 14:52:49 +0000 |
286 | @@ -1,23 +1,3 @@ |
287 | -#!/bin/bash |
288 | - |
289 | -set -eux |
290 | - |
291 | -juju-log "Database is departing. Removing all configuration data and info and restoring backup..." |
292 | -rm /var/www/main/inc/conf/configuration.php |
293 | -cp /var/www/main/inc/conf/configuration.php.bak /var/www/main/inc/conf/configuration.php |
294 | -rm .configured |
295 | -rm .dbset |
296 | -rm .host |
297 | -rm .domain |
298 | -rm .user |
299 | -rm .password |
300 | -rm .db |
301 | -rm .username |
302 | -rm .pass |
303 | - |
304 | -if [ -f .started ]; then |
305 | - juju-log "Stopping service" |
306 | - hooks/stop |
307 | -fi |
308 | - |
309 | -juju-log "Database relation has been successfully removed. Please relate a database to start using Chamilo again." |
310 | +#!/usr/bin/env python |
311 | +import services |
312 | +services.manage() |
313 | |
314 | === modified file 'hooks/install' |
315 | --- hooks/install 2014-06-23 05:08:55 +0000 |
316 | +++ hooks/install 2014-11-11 14:52:49 +0000 |
317 | @@ -1,45 +1,53 @@ |
318 | -#!/bin/bash |
319 | - |
320 | -set -eux |
321 | - |
322 | -juju-log "Installing dependencies" |
323 | -apt-get install -y apache2 php5 php5-mysqlnd php5-gd makepasswd mysql-client php5-intl php5-curl |
324 | - |
325 | -juju-log "Downloading Chamilo and verifying integrity" |
326 | -wget https://campus.chamilo.org/chamilo-1.9.8.tar.gz |
327 | -if [ `sha1sum chamilo-1.9.8.tar.gz` != "2d2e0a5f96f3dcffc9466dda682a2e533eec7cd0 chamilo-1.9.8.tar.gz" ]; then |
328 | - juju-log "There was an error when downloading Chamilo and the tarball is corrupt. Exiting." |
329 | - exit 1 |
330 | -fi |
331 | - |
332 | -juju-log "Extracting/copying Chamilo to the right directory and setting necessary permissions" |
333 | -tar -zxf chamilo-1.9.8.tar.gz |
334 | -rm /var/www/index.html |
335 | -cp -al chamilo-1.9.8.2/* /var/www/ |
336 | -chown -R www-data:www-data /var/www/main/inc/conf/ |
337 | -chown -R www-data:www-data /var/www/main/upload/users/ |
338 | -chown -R www-data:www-data /var/www/main/default_course_document/ |
339 | -chown -R www-data:www-data /var/www/archive/ |
340 | -chown -R www-data:www-data /var/www/courses/ |
341 | -chown -R www-data:www-data /var/www/home/ |
342 | - |
343 | -juju-log "Copying boilerplate configuration files and setting permissions" |
344 | -cp /var/www/main/install/configuration.dist.php /var/www/main/inc/conf/configuration.php |
345 | -rm -r /var/www/main/install/ |
346 | -cp /var/www/main/inc/conf/add_course.conf.dist.php /var/www/main/inc/conf/add_course.conf.php |
347 | -cp /var/www/main/inc/conf/auth.conf.dist.php /var/www/main/inc/conf/auth.conf.php |
348 | -cp /var/www/main/inc/conf/course_info.conf.dist.php /var/www/main/inc/conf/course_info.conf.php |
349 | -cp /var/www/main/inc/conf/events.conf.dist.php /var/www/main/inc/conf/events.conf.php |
350 | -cp /var/www/main/inc/conf/mail.conf.dist.php /var/www/main/inc/conf/mail.conf.php |
351 | -cp /var/www/main/inc/conf/portfolio.conf.dist.php /var/www/main/inc/conf/portfolio.conf.php |
352 | -cp /var/www/main/inc/conf/profile.conf.dist.php /var/www/main/inc/conf/profile.conf.php |
353 | -chmod 777 /var/www/main/inc/conf/ |
354 | - |
355 | -touch .db |
356 | -touch .host |
357 | -touch .user |
358 | -touch .password |
359 | - |
360 | -service apache2 stop |
361 | - |
362 | -juju-log "Install successful" |
363 | +#!/usr/bin/python |
364 | + |
365 | +import setup |
366 | +setup.pre_install() |
367 | + |
368 | +import os |
369 | +import shutil |
370 | +from charmhelpers.core import host |
371 | +from charmhelpers.core import hookenv |
372 | +from charmhelpers import fetch |
373 | + |
374 | + |
375 | +def install(): |
376 | + hookenv.log('Installing chamilo') |
377 | + # install base dependencies |
378 | + fetch.apt_install([ |
379 | + 'apache2', |
380 | + 'php5', |
381 | + 'php5-mysqlnd', |
382 | + 'php5-gd', |
383 | + 'makepasswd', |
384 | + 'mysql-client', |
385 | + 'php5-intl', |
386 | + 'php5-curl', |
387 | + ]) |
388 | + |
389 | + # install site files |
390 | + fetch.install_remote('https://campus.chamilo.org/chamilo-1.9.8.tar.gz', |
391 | + dest='/var/www', |
392 | + checksum='2d2e0a5f96f3dcffc9466dda682a2e533eec7cd0', |
393 | + hash_type='sha1') |
394 | + |
395 | + # ensure site files are owned properly |
396 | + host.chownr('/var/www', owner='www-data', group='www-data') |
397 | + |
398 | + # place boilerplate config files |
399 | + # (remaining config will be placed during later hooks) |
400 | + boilerplate_config_files = [ |
401 | + 'add_course.conf.dist.php', |
402 | + 'auth.conf.dist.php', |
403 | + 'course_info.conf.dist.php', |
404 | + 'events.conf.dist.php', |
405 | + 'mail.conf.dist.php', |
406 | + 'portfolio.conf.dist.php', |
407 | + 'profile.conf.dist.php', |
408 | + ] |
409 | + with host.chdir('/var/www/chamilo-1.9.8.2/main/inc/conf/'): |
410 | + for config_file in boilerplate_config_files: |
411 | + shutil.copy2(config_file, config_file.replace('.dist', '')) |
412 | + |
413 | + |
414 | +if __name__ == "__main__": |
415 | + install() |
416 | |
417 | === added file 'hooks/services.py' |
418 | --- hooks/services.py 1970-01-01 00:00:00 +0000 |
419 | +++ hooks/services.py 2014-11-11 14:52:49 +0000 |
420 | @@ -0,0 +1,37 @@ |
421 | +from charmhelpers.core import host |
422 | +from charmhelpers.core.services.base import ServiceManager |
423 | +from charmhelpers.core.services import helpers |
424 | + |
425 | +import actions |
426 | + |
427 | + |
428 | +CHAMILO_VERSION = '1.9.8.2' |
429 | + |
430 | + |
431 | +def manage(): |
432 | + manager = ServiceManager([ |
433 | + { |
434 | + 'service': 'apache2', |
435 | + 'ports': [80], |
436 | + 'provided_data': [helpers.HttpRelation()], |
437 | + 'required_data': [ |
438 | + helpers.RequiredConfig('domain', 'pass'), |
439 | + helpers.MysqlRelation(), |
440 | + helpers.StoredContext('chamilo-secret.json', { |
441 | + 'key': host.pwgen(7), |
442 | + 'version': CHAMILO_VERSION, |
443 | + }), |
444 | + ], |
445 | + 'data_ready': [ |
446 | + helpers.render_template(source='configuration.php.j2', |
447 | + target="/var/www/main/inc/conf/" |
448 | + "configuration.php"), |
449 | + helpers.render_template(source='apache-site.j2', |
450 | + target="/etc/apache2/sites-available/" |
451 | + "default"), |
452 | + actions.init_database, |
453 | + actions.update_admin_account, |
454 | + ], |
455 | + }, |
456 | + ]) |
457 | + manager.manage() |
458 | |
459 | === added file 'hooks/setup.py' |
460 | --- hooks/setup.py 1970-01-01 00:00:00 +0000 |
461 | +++ hooks/setup.py 2014-11-11 14:52:49 +0000 |
462 | @@ -0,0 +1,17 @@ |
463 | +def pre_install(): |
464 | + """ |
465 | + Do any setup required before the install hook. |
466 | + """ |
467 | + install_charmhelpers() |
468 | + |
469 | + |
470 | +def install_charmhelpers(): |
471 | + """ |
472 | + Install the charmhelpers library, if not present. |
473 | + """ |
474 | + try: |
475 | + import charmhelpers # noqa |
476 | + except ImportError: |
477 | + import subprocess |
478 | + subprocess.check_call(['apt-get', 'install', '-y', 'python-pip']) |
479 | + subprocess.check_call(['pip', 'install', 'charmhelpers']) |
480 | |
481 | === modified file 'hooks/start' |
482 | --- hooks/start 2014-05-03 04:31:38 +0000 |
483 | +++ hooks/start 2014-11-11 14:52:49 +0000 |
484 | @@ -1,10 +1,3 @@ |
485 | -#!/bin/bash |
486 | - |
487 | -set -eux |
488 | - |
489 | -if [ -f .configured ]; then |
490 | - service apache2 start |
491 | - open-port 80 |
492 | - touch .started |
493 | - juju-log "Woohoo! Chamilo has started!" |
494 | -fi |
495 | +#!/usr/bin/env python |
496 | +import services |
497 | +services.manage() |
498 | |
499 | === modified file 'hooks/stop' |
500 | --- hooks/stop 2014-06-03 22:33:59 +0000 |
501 | +++ hooks/stop 2014-11-11 14:52:49 +0000 |
502 | @@ -1,10 +1,3 @@ |
503 | -#!/bin/bash |
504 | - |
505 | -set -eux |
506 | - |
507 | -if [ -f .started ]; then |
508 | - service apache2 stop |
509 | - close-port 80 |
510 | - rm .started |
511 | - juju-log "Chamilo has stopped." |
512 | -fi |
513 | +#!/usr/bin/env python |
514 | +import services |
515 | +services.manage() |
516 | |
517 | === modified file 'hooks/website-relation-joined' |
518 | --- hooks/website-relation-joined 2014-05-03 04:31:38 +0000 |
519 | +++ hooks/website-relation-joined 2014-11-11 14:52:49 +0000 |
520 | @@ -1,3 +1,3 @@ |
521 | -#!/bin/bash |
522 | - |
523 | -relation-set "port=80" |
524 | +#!/usr/bin/env python |
525 | +import services |
526 | +services.manage() |
527 | |
528 | === added directory 'templates' |
529 | === added file 'templates/apache-site.j2' |
530 | --- templates/apache-site.j2 1970-01-01 00:00:00 +0000 |
531 | +++ templates/apache-site.j2 2014-11-11 14:52:49 +0000 |
532 | @@ -0,0 +1,41 @@ |
533 | +<VirtualHost *:80> |
534 | + ServerAdmin webmaster@localhost |
535 | + |
536 | + DocumentRoot /var/www/chamilo-1.9.8.2 |
537 | + <Directory /> |
538 | + Options FollowSymLinks |
539 | + AllowOverride None |
540 | + </Directory> |
541 | + <Directory /var/www/chmailo-1.9.8.2/> |
542 | + Options Indexes FollowSymLinks MultiViews |
543 | + AllowOverride None |
544 | + Order allow,deny |
545 | + allow from all |
546 | + </Directory> |
547 | + |
548 | + ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/ |
549 | + <Directory "/usr/lib/cgi-bin"> |
550 | + AllowOverride None |
551 | + Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch |
552 | + Order allow,deny |
553 | + Allow from all |
554 | + </Directory> |
555 | + |
556 | + ErrorLog ${APACHE_LOG_DIR}/error.log |
557 | + |
558 | + # Possible values include: debug, info, notice, warn, error, crit, |
559 | + # alert, emerg. |
560 | + LogLevel warn |
561 | + |
562 | + CustomLog ${APACHE_LOG_DIR}/access.log combined |
563 | + |
564 | + Alias /doc/ "/usr/share/doc/" |
565 | + <Directory "/usr/share/doc/"> |
566 | + Options Indexes MultiViews FollowSymLinks |
567 | + AllowOverride None |
568 | + Order deny,allow |
569 | + Deny from all |
570 | + Allow from 127.0.0.0/255.0.0.0 ::1/128 |
571 | + </Directory> |
572 | + |
573 | +</VirtualHost> |
574 | |
575 | === added file 'templates/configuration.php.j2' |
576 | --- templates/configuration.php.j2 1970-01-01 00:00:00 +0000 |
577 | +++ templates/configuration.php.j2 2014-11-11 14:52:49 +0000 |
578 | @@ -0,0 +1,207 @@ |
579 | +<?php |
580 | +// Chamilo version {NEW_VERSION} |
581 | +// File generated by /install/index.php script - {DATE_GENERATED} |
582 | +/* For licensing terms, see /license.txt */ |
583 | +/** |
584 | + * Campus configuration |
585 | + * |
586 | + * This file contains a list of variables that can be modified by the campus |
587 | + * site's server administrator. Pay attention when changing these variables, |
588 | + * some changes may cause Chamilo to stop working. |
589 | + * If you changed some settings and want to restore them, please have a look at |
590 | + * configuration.dist.php. That file is an exact copy of the config file at |
591 | + * install time. |
592 | + */ |
593 | + |
594 | +/** |
595 | + * $_configuration define only the bare essential variables |
596 | + * for configuring the platform (paths, database connections, ...). |
597 | + * Changing a $_configuration variable CAN generally break the installation. |
598 | + * Besides the $_configuration, a $_settings array also exists, that |
599 | + * contains variables that can be changed and will not break the platform. |
600 | + * These optional settings are defined in the database, now |
601 | + * (table settings_current). |
602 | + * example: $_configuration['tracking_enabled'] (assuming that the install |
603 | + * script creates the necessary tables anyway). |
604 | + */ |
605 | + |
606 | +/** |
607 | + * MYSQL connection settings |
608 | + */ |
609 | +// Your MySQL server |
610 | +$_configuration['db_host'] = '{{db[0]['host']}}'; |
611 | +// Your MySQL username |
612 | +$_configuration['db_user'] = '{{db[0]['user']}}'; |
613 | +// Your MySQL password |
614 | +$_configuration['db_password'] = '{{db[0]['password']}}'; |
615 | + |
616 | +/** |
617 | + * Database settings |
618 | + */ |
619 | +// Is tracking enabled? |
620 | +$_configuration['tracking_enabled'] = true; |
621 | +// Is single database enabled (DO NOT MODIFY THIS) |
622 | +$_configuration['single_database'] = false; |
623 | +// Prefix for course tables (IF NOT EMPTY, can be replaced by another prefix, else leave empty) |
624 | +$_configuration['table_prefix'] = ''; |
625 | +// Separator between database and table name (DO NOT MODIFY THIS) |
626 | +$_configuration['db_glue'] = '`.`'; |
627 | +// prefix all created bases (for courses) with this string |
628 | +$_configuration['db_prefix'] = ''; |
629 | +// main Chamilo database |
630 | +$_configuration['main_database'] = '{{db[0]['db']}}'; |
631 | +// stats Chamilo database |
632 | +$_configuration['statistics_database'] ='{{db[0]['db']}}'; |
633 | +// User Personal Database (where all the personal stuff of the user is stored |
634 | +// (personal agenda items, course sorting) |
635 | +$_configuration['user_personal_database']='{{db[0]['db']}}'; |
636 | +// Enable access to database management for platform admins. |
637 | +$_configuration['db_manager_enabled'] = false; |
638 | + |
639 | +/** |
640 | + * Directory settings |
641 | + */ |
642 | +// URL to the root of your Chamilo installation, e.g.: http://www.mychamilo.com/ |
643 | +$_configuration['root_web'] = '{{config['domain']}}'; |
644 | + |
645 | +// Path to the webroot of system, example: /var/www/ |
646 | +$_configuration['root_sys'] = '/var/www/'; |
647 | + |
648 | +// Path from your WWW-root to the root of your Chamilo installation, example: chamilo (this means chamilo is installed in /var/www/chamilo/ |
649 | +$_configuration['url_append'] = ''; |
650 | + |
651 | +// Directory of the Chamilo code. You could change this but it is not advised since this has not been tested yet. |
652 | +$_configuration['code_append'] = "main/"; |
653 | + |
654 | +// Directory to store all course-related files. You could change this but it is not advised since this has not been tested yet. |
655 | +$_configuration['course_folder'] = "courses/"; |
656 | + |
657 | +// URL to your phpMyAdmin installation. |
658 | +// If not empty, a link will be available in the Platform Administration |
659 | +$_configuration['db_admin_path'] = ''; |
660 | + |
661 | +/** |
662 | + * Login modules settings |
663 | + */ |
664 | +// CAS IMPLEMENTATION |
665 | +// -> Go to your portal Chamilo > Administration > CAS to activate CAS |
666 | +// You can leave these lines uncommented even if you don't use CAS authentification |
667 | +$extAuthSource["cas"]["login"] = $_configuration['root_sys'].$_configuration['code_append']."auth/cas/login.php"; |
668 | +$extAuthSource["cas"]["newUser"] = $_configuration['root_sys'].$_configuration['code_append']."auth/cas/newUser.php"; |
669 | +// |
670 | +// NEW LDAP IMPLEMENTATION BASED ON external_login info |
671 | +// -> Uncomment the two lines bellow to activate LDAP AND edit main/auth/external_login/ldap.conf.php for configuration |
672 | +// $extAuthSource["extldap"]["login"] = $_configuration['root_sys'].$_configuration['code_append']."auth/external_login/login.ldap.php"; |
673 | +// $extAuthSource["extldap"]["newUser"] = $_configuration['root_sys'].$_configuration['code_append']."auth/external_login/newUser.ldap.php"; |
674 | +// |
675 | +// FACEBOOK IMPLEMENTATION BASED ON external_login info |
676 | +// -> Uncomment the line bellow to activate Facebook Auth AND edit main/auth/external_login/ldap.conf.php for configuration |
677 | +// $_configuration['facebook_auth'] = 1; |
678 | +// |
679 | +// OTHER EXTERNAL LOGIN INFORMATION |
680 | +// To fetch external login information, uncomment those 2 lines and modify files auth/external_login/newUser.php and auth/external_login/updateUser.php files |
681 | +// $extAuthSource["external_login"]["newUser"] = $_configuration['root_sys'].$_configuration['code_append']."auth/external_login/newUser.php"; |
682 | +// $extAuthSource["external_login"]["updateUser"] = $_configuration['root_sys'].$_configuration['code_append']."auth/external_login/updateUser.php"; |
683 | + |
684 | +/** |
685 | + * |
686 | + * Hosting settings - Allows you to set limits to the Chamilo portal when |
687 | + * hosting it for a third party. These settings can be overwritten by an |
688 | + * optionally-loaded extension file with only the settings (no comments). |
689 | + * The settings use an index at the first level to represent the ID of the |
690 | + * URL in case you use multi-url (otherwise it will always use 1, which is |
691 | + * the ID of the only URL inside the access_url table). |
692 | + */ |
693 | +// Set a maximum number of users. Default (0) = no limit |
694 | +$_configuration[1]['hosting_limit_users'] = 0; |
695 | +// Set a maximum number of teachers. Default (0) = no limit |
696 | +$_configuration[1]['hosting_limit_teachers'] = 0; |
697 | +// Set a maximum number of courses. Default (0) = no limit |
698 | +$_configuration[1]['hosting_limit_courses'] = 0; |
699 | +// Set a maximum number of sessions. Default (0) = no limit |
700 | +$_configuration[1]['hosting_limit_sessions'] = 0; |
701 | +// Set a maximum disk space used, in MB (set to 1024 for 1GB, 5120 for 5GB). |
702 | +// Default (0) = no limit |
703 | +$_configuration[1]['hosting_limit_disk_space'] = 0; |
704 | + |
705 | +/** |
706 | + * Content Delivery Network (CDN) settings. Only use if you need a separate |
707 | + * server to serve your static data. If you don't know what a CDN is, you |
708 | + * don't need it. These settings are for simple Origin Pull CDNs and are |
709 | + * experimental. Enable only if you really know what you're doing. |
710 | + * This might conflict with multiple-access urls. |
711 | + */ |
712 | +// Set the following setting to true to start using the CDN |
713 | +$_configuration['cdn_enable'] = false; |
714 | +// The following setting will be ignored if the previous one is set to false |
715 | +$_configuration['cdn'] = array( |
716 | + //You can define several CDNs and split them by extensions |
717 | + //Replace the following by your full CDN URL, which should point to |
718 | + // your Chamilo's root directory. DO NOT INCLUDE a final slash! (won't work) |
719 | + 'http://cdn.chamilo.org' => array('.css','.js','.jpg','.jpeg','.png','.gif','.avi','.flv'), |
720 | + // copy the line above and modify following your needs |
721 | +); |
722 | + |
723 | +/** |
724 | + * Misc. settings |
725 | + */ |
726 | +// Verbose backup |
727 | +$_configuration['verbose_backup'] = false; |
728 | +// security word for password recovery |
729 | +$_configuration['security_key'] = '{{key}}'; |
730 | +// Hash function method |
731 | +$_configuration['password_encryption'] = 'sha1'; |
732 | +// You may have to restart your web server if you change this |
733 | +$_configuration['session_stored_in_db'] = false; |
734 | +// Session lifetime |
735 | +$_configuration['session_lifetime'] = 360000; |
736 | +// Activation for multi-url access |
737 | +//$_configuration['multiple_access_urls'] = true; |
738 | +$_configuration['software_name'] = 'Chamilo'; |
739 | +$_configuration['software_url'] = 'http://www.chamilo.org/'; |
740 | +//Deny the elimination of users |
741 | +$_configuration['deny_delete_users'] = false; |
742 | +// Version settings |
743 | +$_configuration['system_version'] = '{{version}}'; |
744 | +$_configuration['system_stable'] = NEW_VERSION_STABLE; |
745 | + |
746 | +/** |
747 | + * Settings to be included as settings_current in future versions |
748 | + */ |
749 | +// Hide the main home section for connected users (to show announcements instead) |
750 | +//$_configuration['hide_home_top_when_connected'] = true; |
751 | +// Hide the global announcements for non-connected users |
752 | +//$_configuration['hide_global_announcements_when_not_connected'] = true; |
753 | +// Use this course as template for all new courses (define course real ID as value) |
754 | +//$_configuration['course_creation_use_template'] = 14; |
755 | +// Uncomment the following to prevent all admins to use the "login as" feature |
756 | +//$_configuration['login_as_forbidden_globally'] = true; |
757 | +// Add password strength checker |
758 | +//$_configuration['allow_strength_pass_checker'] = true; |
759 | +// Enable captcha |
760 | +//$_configuration['enable_captcha'] = true; |
761 | +//$_configuration['allow_captcha'] = true; |
762 | +// Prevent account from logging in for a certain amount of time if captcha is wrong for the specified number of times |
763 | +//$_configuration['captcha_number_mistakes_to_block_account'] = 5; |
764 | +// Prevent account from logging in for the specified number of minutes |
765 | +//$_configuration['captcha_time_to_block'] = 5;//minutes |
766 | +// Allow DRH role to access all content and users from the sessions he follows |
767 | +//$_configuration['drh_can_access_all_session_content'] = true; |
768 | +// Display group's forum in general forum tool |
769 | +//$_configuration['display_groups_forum_in_general_tool'] = true; |
770 | +// Boost query on last connection time |
771 | +//$_configuration['save_user_last_login'] = true; |
772 | +// Allow course tutors in sessions to add existing students to their session |
773 | +//$_configuration['allow_tutors_to_assign_students_to_session'] = 'false'; |
774 | +// Allow select the return link in the LP view |
775 | +//$_configuration['allow_lp_return_link'] = false; |
776 | +// If true the export link is blocked. |
777 | +//$_configuration['hide_scorm_export_link'] = false; |
778 | +// If true the copy link is blocked. |
779 | +//$_configuration['hide_scorm_copy_link'] = false; |
780 | +// If true the pdf export link is blocked. |
781 | +//$_configuration['hide_scorm_pdf_link'] = false; |
782 | +// Default session days before coach access |
783 | +//$_configuration['session_days_before_coach_access'] = 0; |
784 | +// Default session days after coach access |
785 | +//$_configuration['session_days_after_coach_access'] = 0; |
786 | |
787 | === added directory 'tests' |
788 | === added file 'tests/test_actions.py' |
789 | --- tests/test_actions.py 1970-01-01 00:00:00 +0000 |
790 | +++ tests/test_actions.py 2014-11-11 14:52:49 +0000 |
791 | @@ -0,0 +1,102 @@ |
792 | +import os |
793 | +import shutil |
794 | +import tempfile |
795 | +import unittest |
796 | +import StringIO |
797 | +import contextlib |
798 | + |
799 | +from mock import patch, Mock |
800 | +from hooks import actions |
801 | + |
802 | +from charmhelpers.core.hookenv import Config |
803 | + |
804 | +MYSQL_CFG = { |
805 | + 'user': '__user', |
806 | + 'password': 'pass', |
807 | + 'host': '0.0.0.0', |
808 | + 'port': 3306, |
809 | + 'database': 'test' |
810 | +} |
811 | + |
812 | + |
813 | +@contextlib.contextmanager |
814 | +def charm_dir(): |
815 | + temp_dir = tempfile.mkdtemp() |
816 | + with patch.dict(os.environ, {'CHARM_DIR': temp_dir}): |
817 | + yield |
818 | + shutil.rmtree(temp_dir) |
819 | + |
820 | + |
821 | +class TestHelpers(unittest.TestCase): |
822 | + @patch('hooks.actions.subprocess.check_call') |
823 | + def test_exec_sql_string(self, mchk): |
824 | + actions.exec_sql('SELECT * FROM Something', MYSQL_CFG) |
825 | + mchk.assert_called_with([ |
826 | + 'mysql', |
827 | + '-u__user', |
828 | + '-ppass', |
829 | + '-h', '0.0.0.0', |
830 | + 'test', |
831 | + '-e', 'SELECT * FROM Something', |
832 | + ], stdin=None) |
833 | + |
834 | + @patch('hooks.actions.subprocess.check_call') |
835 | + def test_exec_sql_file(self, mchk): |
836 | + sql_file = StringIO.StringIO('SELECT * FROM Something') |
837 | + actions.exec_sql(sql_file, MYSQL_CFG) |
838 | + mchk.assert_called_with([ |
839 | + 'mysql', |
840 | + '-u__user', |
841 | + '-ppass', |
842 | + '-h', '0.0.0.0', |
843 | + 'test', |
844 | + ], stdin=sql_file) |
845 | + |
846 | + @patch('hooks.actions.exec_sql') |
847 | + @patch('hooks.actions.hookenv.config') |
848 | + def test_init_database_initd(self, mcfg, mexc): |
849 | + with charm_dir(): |
850 | + config = Config() |
851 | + config._prev_dict = {'db_initialized': True} |
852 | + mcfg.return_value = config |
853 | + actions.init_database('foo') |
854 | + mexc.assert_not_called() |
855 | + |
856 | + @patch('hooks.actions.hookenv.log', Mock()) |
857 | + @patch('hooks.actions.hookenv.config') |
858 | + @patch('hooks.actions.helpers.MysqlRelation') |
859 | + @patch('hooks.actions.exec_sql') |
860 | + def test_init_database(self, mexc, mrel, mcfg): |
861 | + mrel.return_value = {'db': [MYSQL_CFG]} |
862 | + |
863 | + with charm_dir(): |
864 | + mcfg.return_value = Config() |
865 | + actions.init_database('foo') |
866 | + self.assertEqual(True, mcfg.return_value['db_initialized']) |
867 | + mexc.assert_called_once() |
868 | + |
869 | + @patch('hooks.actions.hookenv.log', Mock()) |
870 | + @patch('hooks.actions.hookenv.config') |
871 | + @patch('hooks.actions.helpers.MysqlRelation') |
872 | + @patch('hooks.actions.exec_sql') |
873 | + def test_update_admin_acct(self, mexc, mrel, mcfg): |
874 | + mrel.return_value = {'db': [MYSQL_CFG]} |
875 | + |
876 | + with charm_dir(): |
877 | + mcfg.return_value = Config({'user': 'what', 'pass': 'going on'}) |
878 | + actions.update_admin_account('foo') |
879 | + mexc.assert_not_called() |
880 | + |
881 | + @patch('hooks.actions.hookenv.log', Mock()) |
882 | + @patch('hooks.actions.hookenv.config') |
883 | + @patch('hooks.actions.helpers.MysqlRelation') |
884 | + @patch('hooks.actions.exec_sql') |
885 | + def test_update_admin_no_change(self, mexc, mrel, mcfg): |
886 | + mrel.return_value = {'db': [MYSQL_CFG]} |
887 | + |
888 | + with charm_dir(): |
889 | + config = Config({'pass': 'hey', 'user': 'hey'}) |
890 | + config._prev_dict = {'pass': 'hey', 'user': 'hey'} |
891 | + mcfg.return_value = config |
892 | + actions.init_database('foo') |
893 | + mexc.assert_called() |
This items has failed automated testing! Results available here http:// reports. vapour. ws/charm- tests/charm- bundle- test-1258- results