Merge lp:~jml/libdep-service/juju into lp:libdep-service

Proposed by Jonathan Lange on 2012-06-21
Status: Merged
Merged at revision: 12
Proposed branch: lp:~jml/libdep-service/juju
Merge into: lp:libdep-service
Diff against target: 773 lines (+564/-80)
23 files modified
.bzrignore (+1/-0)
charms/precise/libdep-service/README (+38/-0)
charms/precise/libdep-service/copyright (+17/-0)
charms/precise/libdep-service/dev-config/apply (+52/-0)
charms/precise/libdep-service/dev-config/manifests/libdep_service.pp (+110/-0)
charms/precise/libdep-service/dev-config/templates/django.wsgi.erb (+21/-0)
charms/precise/libdep-service/dev-config/templates/httpd.conf.erb (+12/-0)
charms/precise/libdep-service/dev-config/templates/nondev_credentials.cfg.erb (+19/-0)
charms/precise/libdep-service/dev-config/templates/pkgme-devportal.conf.erb (+3/-0)
charms/precise/libdep-service/hooks/install (+92/-0)
charms/precise/libdep-service/hooks/relation-name-relation-broken (+2/-0)
charms/precise/libdep-service/hooks/relation-name-relation-changed (+9/-0)
charms/precise/libdep-service/hooks/relation-name-relation-departed (+5/-0)
charms/precise/libdep-service/hooks/relation-name-relation-joined (+5/-0)
charms/precise/libdep-service/hooks/start (+4/-0)
charms/precise/libdep-service/hooks/stop (+7/-0)
charms/precise/libdep-service/metadata.yaml (+6/-0)
charms/precise/libdep-service/revision (+1/-0)
django_project/dev.cfg (+18/-0)
django_project/main.cfg (+70/-0)
django_project/manage.py (+9/-0)
django_project/schema.py (+13/-0)
django_project/settings.py (+50/-80)
To merge this branch: bzr merge lp:~jml/libdep-service/juju
Reviewer Review Type Date Requested Status
James Westby (community) 2012-06-21 Approve on 2012-06-22
Clint Byrum (community) 2012-06-21 Needs Fixing on 2012-06-21
Review via email: mp+111396@code.launchpad.net

Commit Message

Add a Juju charm for deploying libdep-service.

Description of the Change

Juju charm for deploying libdep-service.

It's a bit rough-and-ready at this stage, but it works, and that's a good point for review.

Derived from lp:pkgme-service's fabric deploy task. I stripped out everything that pkgme-service has that libdep-service doesn't (oops, preflight, postgres support). All of these things will need to be added back in eventually.

Obvious things I'm missing right now:
 * making poor use of juju's config, partly because I don't know how, more because I don't know why
 * really bad use of interfaces

The branch also converts libdep-service to use django-configglue. Arguably this should be put into a separate branch. I'd be happy to do that if anyone else actually cares.

The XXXs should all be self-explanatory. Feedback on any of them would be appreciated.

Obviously this duplicates stuff (e.g. add_if_present) from lp:pkgme-service, which is bad. Not sure what to do about that.

I'm quite new to puppet, wsgi, django and juju, so I'm guessing there's plenty to improve.

http://paste.ubuntu.com/1053013/ has notes from my Juju experiences that should probably be converted into something more useful. Have also filed heaps of bugs on various tools.

Thanks,
jml

To post a comment you must log in.
Clint Byrum (clint-fewbar) wrote :

First, you will want to run 'charm proof' to see any policy or format errors:

E: no copyright file
E: template relations should be renamed to fit charm: relation-name
E: template interface names should be changed: interface-name
E: template relations should be renamed to fit charm: relation-name
E: template interface names should be changed: interface-name
E: template relations should be renamed to fit charm: relation-name
E: template interface names should be changed: interface-name

All of those need to be addressed before charm store inclusion.

For the interfaces, better to leave those out entirely until you know what they are and can provide an implementation.

* hooks/install: DEBIAN_FRONTEND=noninteractive is assumed to be set now in all charms (since the version in Ubuntu precise anyway).

* hooks/install: better way to do cd's is to use pushd/popd so you don'at have to track BASE_DIR. Otherwise, no.

* dev-config/apply: get_public_hostname() can be deleted, as PUBLIC_HOSTNAME must be changed to just $(unit-get public-address). This way it will work the same on all providers.

* dev-config/apply: I love the way puppet is used, as this is far more reliable than hand-coded shell to do everything in an idempotent way. I do think the whole package list from install could also be put into the puppet manifest.

* hooks/start, stop: These are actually important for the future. Eventually they'll be used when units are migrated or rebooted. Make sure to consider what needs to be run in those instances and put them here.

Otherwise, this looks great. You might consider just embedding exports in the charm, rather than bzr branching from launchpad, as that will eliminate a dependency to have launchpad available.

review: Needs Fixing
James Westby (james-w) wrote :

170 +file { "$::basedir/libdep.log":

Is that actually written to by pkgme-devportal (or any other code)? Not so
important, but I don't think we currently log anything in that code.

311 +# XXX: Would be great to depend on more stable URLs. e.g. /+branch/foo.

You can just use

  bzr branch https://code.launchpad.net/libdep-service

392 +# XXX: Is there a better way to do this ``cd`` business?
393 +BASE_DIR=${PWD}
394 +cd libdep-service/sourcecode/pkgme && python setup.py build

Doing this as

(cd libdep-service/sourcecode/pkgme && python setup.py build)

does the cd in a sub-shell, and so the main shell's CWD is unaffected,
saving the cd back.

750 + # TODO: remove the production_credentials.cfg fallback once it is no
751 + # longer in use on production. It's left here now to ease rollouts.
752 + if not add_if_present('production_credentials.cfg', also_add='nondev.cfg'):

That's gone in pkgme-service trunk, and isn't needed here.

This is shaping up pretty well to get something green.

Thanks,

James

review: Needs Fixing
lp:~jml/libdep-service/juju updated on 2012-06-22
38. By Jonathan Lange on 2012-06-22

Remove interfaces.

39. By Jonathan Lange on 2012-06-22

Add a copyright file to cure lint warnings. Don't worry, we'll GPL soon.

40. By Jonathan Lange on 2012-06-22

Better way of getting the public host name.

41. By Jonathan Lange on 2012-06-22

Strip all the sudo, hopefully revealing Juju's own native DEBIAN_FRONTEND=noninteractive
Run 'cd' commands in a subshell

42. By Jonathan Lange on 2012-06-22

Right revision number. Actually drop all the 'sudo'.

43. By Jonathan Lange on 2012-06-22

More stable URLs for branches.

44. By Jonathan Lange on 2012-06-22

Remove not-needed production_credentials fallback.

45. By Jonathan Lange on 2012-06-22

Last cleanup

46. By Jonathan Lange on 2012-06-22

Rebase revision

Jonathan Lange (jml) wrote :

Thanks Clint & James. I've applied the suggested fixes. Would appreciate follow-up.

Note that the goal is not to enter the charm store yet. We need a useful service for that first.

lp:~jml/libdep-service/juju updated on 2012-06-22
47. By Jonathan Lange on 2012-06-22

Correct license file for Canonical charms.

James Westby (james-w) wrote :

Hi,

I think this looks good as a first cut now, thanks.

a "bzr ignore sourcecode/*" would be appreciated by webops.

Thanks,

James

review: Approve
lp:~jml/libdep-service/juju updated on 2012-06-22
48. By Jonathan Lange on 2012-06-22

The webops will appreciate this, I'm told.

49. By Jonathan Lange on 2012-06-22

Correct copyright.

Jonathan Lange (jml) wrote :

Done.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file '.bzrignore'
2--- .bzrignore 2012-06-15 14:59:04 +0000
3+++ .bzrignore 2012-06-22 13:06:20 +0000
4@@ -1,2 +1,3 @@
5 virtualenv
6 libdep_service.egg-info
7+sourcecode/*
8
9=== added directory 'charms'
10=== added directory 'charms/precise'
11=== added directory 'charms/precise/libdep-service'
12=== added file 'charms/precise/libdep-service/README'
13--- charms/precise/libdep-service/README 1970-01-01 00:00:00 +0000
14+++ charms/precise/libdep-service/README 2012-06-22 13:06:20 +0000
15@@ -0,0 +1,38 @@
16+Overview
17+--------
18+
19+This charm provides (service) from (service homepage). Add a description here
20+of what the service itself actually does.
21+
22+
23+Usage
24+-----
25+
26+Step by step instructions on using the charm:
27+
28+ juju deploy servicename
29+
30+and so on. If you're providing a web service or something that the end user
31+needs to go to, tell them here, especially if you're deploying a service that
32+might listen to a non-default port.
33+
34+You can then browse to http://ip-address to configure the service.
35+
36+Configuration
37+-------------
38+
39+The configuration options will be listed on the charm store, however If you're
40+making assumptions or opinionated decisions in the charm (like setting a
41+default administrator password), you should detail that here so the user knows
42+how to change it immediately, etc.
43+
44+
45+Contact Information
46+-------------------
47+
48+Though this will be listed in the charm store itself don't assume a user will
49+know that, so include that information here:
50+
51+Author: Jonathan Lange <jml@canonical.com>
52+Report bugs at: http://bugs.launchpad.net/libdep-service
53+Location: http://jujucharms.com
54
55=== added file 'charms/precise/libdep-service/copyright'
56--- charms/precise/libdep-service/copyright 1970-01-01 00:00:00 +0000
57+++ charms/precise/libdep-service/copyright 2012-06-22 13:06:20 +0000
58@@ -0,0 +1,17 @@
59+Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
60+
61+Files: *
62+Copyright: Copyright 2012, Canonical Ltd., All Rights Reserved.
63+License: GPL-3
64+ This program is free software: you can redistribute it and/or modify
65+ it under the terms of the GNU General Public License as published by
66+ the Free Software Foundation, either version 3 of the License.
67+ .
68+ This program is distributed in the hope that it will be useful,
69+ but WITHOUT ANY WARRANTY; without even the implied warranty of
70+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
71+ GNU General Public License for more details.
72+ .
73+ You should have received a copy of the GNU General Public License
74+ along with this program. If not, see <http://www.gnu.org/licenses/>.
75+
76
77=== added directory 'charms/precise/libdep-service/dev-config'
78=== added file 'charms/precise/libdep-service/dev-config/apply'
79--- charms/precise/libdep-service/dev-config/apply 1970-01-01 00:00:00 +0000
80+++ charms/precise/libdep-service/dev-config/apply 2012-06-22 13:06:20 +0000
81@@ -0,0 +1,52 @@
82+#!/bin/bash
83+# Beware running this on a system you care about, it may overwrite anything
84+# on that system. Generally this should only be used on throwaway or dedicated
85+# systems.
86+
87+set -e
88+
89+CREDS_FILE="${HOME}/credentials"
90+
91+has_cred() {
92+ CRED="$1"
93+ if [ -f "$CREDS_FILE" ]; then
94+ if grep -q "$CRED" "$CREDS_FILE"; then
95+ return 0
96+ fi
97+ fi
98+ return 1
99+}
100+
101+get_cred() {
102+ CRED="$1"
103+ VALUE="$(grep "$CRED" "$CREDS_FILE" | sed -e 's/[^=]*=//')"
104+ echo $VALUE
105+}
106+
107+generate_cred() {
108+ CRED="$1"
109+ VALUE="${RANDOM}"
110+ echo "${CRED}=${VALUE}" >> $CREDS_FILE
111+ get_cred $CRED
112+}
113+
114+get_cred_or_generate() {
115+ CRED="$1"
116+ if has_cred "$CRED"; then
117+ get_cred "$CRED"
118+ else
119+ generate_cred "$CRED"
120+ fi
121+}
122+
123+
124+DJANGO_SECRET_KEY=$(get_cred_or_generate "DJANGO_SECRET_KEY")
125+PUBLIC_HOSTNAME=$(unit-get public-address)
126+
127+# Export these things to puppet (via facter)
128+export FACTER_basedir="`pwd`/libdep-service"
129+export FACTER_django_secret_key=$DJANGO_SECRET_KEY
130+export FACTER_public_hostname=$PUBLIC_HOSTNAME
131+export FACTER_sqlite_database="jml-is-lazy.db"
132+
133+sudo -E puppet apply --templatedir "$(pwd)/dev-config/templates" "$(pwd)/dev-config/manifests/libdep_service.pp"
134
135=== added directory 'charms/precise/libdep-service/dev-config/manifests'
136=== added file 'charms/precise/libdep-service/dev-config/manifests/libdep_service.pp'
137--- charms/precise/libdep-service/dev-config/manifests/libdep_service.pp 1970-01-01 00:00:00 +0000
138+++ charms/precise/libdep-service/dev-config/manifests/libdep_service.pp 2012-06-22 13:06:20 +0000
139@@ -0,0 +1,110 @@
140+$wsgi_user = "libdep"
141+$wsgi_processes = 2
142+$wsgi_threads = 2
143+
144+$unix_user = "libdep"
145+
146+group {$unix_user:
147+ ensure => 'present',
148+}
149+
150+user {$unix_user:
151+ comment => 'This user was created by Puppet',
152+ ensure => 'present',
153+ gid => $unix_user,
154+ require => Group[$unix_user],
155+ # Needed to create /home/libdep, which is 'needed' by pkgme.
156+ managehome => true,
157+}
158+
159+file { "$::basedir/django_project/nondev_credentials.cfg":
160+ content => template("nondev_credentials.cfg.erb"),
161+ owner => $unix_user,
162+ group => $unix_user,
163+ mode => 640,
164+ require => [
165+ Group[$unix_user],
166+ File["$::basedir/django_project/"],
167+ ],
168+}
169+
170+file { [ "/home/$unix_user/.config",
171+ "/home/$unix_user/.config/pkgme-binary" ]:
172+ ensure => directory,
173+}
174+
175+file { "/home/$unix_user/.config/pkgme-binary/conf":
176+ content => template("pkgme-devportal.conf.erb"),
177+ owner => $unix_user,
178+ group => www-data,
179+ mode => 640,
180+ require => [
181+ File["/home/$unix_user/.config/pkgme-binary"],
182+ ],
183+}
184+
185+file { "$::basedir/django_project/":
186+ owner => $unix_user,
187+ group => $unix_user,
188+ mode => 644,
189+ require => [
190+ Group[$unix_user],
191+ ],
192+ ensure => directory,
193+}
194+
195+file { "$::basedir/libdep.log":
196+ owner => $unix_user,
197+ group => $unix_user,
198+ mode => 644,
199+ ensure => present,
200+}
201+
202+file { "$::basedir/django.log":
203+ owner => $unix_user,
204+ group => $unix_user,
205+ mode => 644,
206+ ensure => present,
207+}
208+
209+exec { "django-syncdb":
210+ command => "python ./manage.py syncdb --noinput",
211+ cwd => "$::basedir/django_project",
212+ path => ["/usr/bin"],
213+ user => $unix_user,
214+ require => [
215+ File["$::basedir/django_project/nondev_credentials.cfg"],
216+ File["$::basedir/libdep.log"],
217+ File["$::basedir/django.log"],
218+ ],
219+ logoutput => on_failure,
220+ loglevel => err,
221+}
222+
223+exec { "django-migrate":
224+ command => "python ./manage.py migrate",
225+ cwd => "$::basedir/django_project",
226+ path => ["/usr/bin"],
227+ user => $unix_user,
228+ environment => "HOME=$::basedir",
229+ require => Exec["django-syncdb"],
230+}
231+
232+file { "$::basedir/django_project/django.wsgi":
233+ content => template("django.wsgi.erb"),
234+ require => [
235+ File["$::basedir/django_project/nondev_credentials.cfg"],
236+ ]
237+}
238+
239+file { "/etc/apache2/httpd.conf":
240+ content => template("httpd.conf.erb"),
241+}
242+
243+exec { "/etc/init.d/apache2 reload":
244+ user => root,
245+ require => [
246+ File["/etc/apache2/httpd.conf"],
247+ File["$::basedir/django_project/django.wsgi"],
248+ ],
249+}
250
251=== added directory 'charms/precise/libdep-service/dev-config/templates'
252=== added file 'charms/precise/libdep-service/dev-config/templates/django.wsgi.erb'
253--- charms/precise/libdep-service/dev-config/templates/django.wsgi.erb 1970-01-01 00:00:00 +0000
254+++ charms/precise/libdep-service/dev-config/templates/django.wsgi.erb 2012-06-22 13:06:20 +0000
255@@ -0,0 +1,21 @@
256+import os
257+import sys
258+
259+basepath = '<%= basedir %>'
260+extra_paths = [basepath, '<%= basedir %>/django_project']
261+
262+sourcecode_path = os.path.abspath(os.path.join(basepath, 'sourcecode'))
263+for filename in os.listdir(sourcecode_path):
264+ dependency_path = os.path.join(sourcecode_path, filename)
265+ if os.path.isdir(dependency_path):
266+ extra_paths.append(dependency_path)
267+
268+for path in extra_paths:
269+ if path not in sys.path:
270+ sys.path.insert(0, path)
271+
272+os.environ['LIBDEP_LOG_DIR'] = '<%= basedir %>'
273+os.environ['DJANGO_SETTINGS_MODULE'] = 'django_project.settings'
274+
275+import django.core.handlers.wsgi
276+application = django.core.handlers.wsgi.WSGIHandler()
277
278=== added file 'charms/precise/libdep-service/dev-config/templates/httpd.conf.erb'
279--- charms/precise/libdep-service/dev-config/templates/httpd.conf.erb 1970-01-01 00:00:00 +0000
280+++ charms/precise/libdep-service/dev-config/templates/httpd.conf.erb 2012-06-22 13:06:20 +0000
281@@ -0,0 +1,12 @@
282+#Alias /assets/ /srv/<%= basedir %>/project/static/
283+#
284+#<Directory /srv/<%= basedir %>/project/static>
285+#Order deny,allow
286+#Allow from all
287+#</Directory>
288+
289+WSGIDaemonProcess <%= basedir %> user=<%= wsgi_user %> processes=<%= wsgi_processes %> threads=<%= wsgi_threads %>
290+WSGIProcessGroup <%= basedir %>
291+WSGIPassAuthorization On
292+
293+WSGIScriptAlias / <%= basedir %>/django_project/django.wsgi
294
295=== added file 'charms/precise/libdep-service/dev-config/templates/nondev_credentials.cfg.erb'
296--- charms/precise/libdep-service/dev-config/templates/nondev_credentials.cfg.erb 1970-01-01 00:00:00 +0000
297+++ charms/precise/libdep-service/dev-config/templates/nondev_credentials.cfg.erb 2012-06-22 13:06:20 +0000
298@@ -0,0 +1,19 @@
299+[django]
300+databases = databases
301+secret_key = <%= django_secret_key %>
302+
303+[databases]
304+default = default_database
305+
306+[default_database]
307+engine = django.db.backends.sqlite3
308+name = <%= sqlite_database %>
309+
310+[djlibdep]
311+libdep_log_dir = <%= basedir %>
312+
313+[django_file_logging_handler]
314+level = INFO
315+class = logging.handlers.WatchedFileHandler
316+formatter = verbose
317+filename = <%= basedir %>/django.log
318
319=== added file 'charms/precise/libdep-service/dev-config/templates/pkgme-devportal.conf.erb'
320--- charms/precise/libdep-service/dev-config/templates/pkgme-devportal.conf.erb 1970-01-01 00:00:00 +0000
321+++ charms/precise/libdep-service/dev-config/templates/pkgme-devportal.conf.erb 2012-06-22 13:06:20 +0000
322@@ -0,0 +1,3 @@
323+[database]
324+db_type = sqlite
325+path = <%= basedir %>/django_project/<%= sqlite_database %>
326
327=== added directory 'charms/precise/libdep-service/hooks'
328=== added file 'charms/precise/libdep-service/hooks/install'
329--- charms/precise/libdep-service/hooks/install 1970-01-01 00:00:00 +0000
330+++ charms/precise/libdep-service/hooks/install 2012-06-22 13:06:20 +0000
331@@ -0,0 +1,92 @@
332+#!/bin/bash
333+
334+LP="https://code.launchpad.net"
335+LIBDEP_BRANCH="${LP}/libdep-service"
336+PKGME_BRANCH="${LP}/pkgme"
337+PKGME_DEVPORTAL_BRANCH="${LP}/pkgme-devportal"
338+CONFIGGLUE_BRANCH="${LP}/configglue"
339+DJANGO_CONFIGGLUE_BRANCH="${LP}/django-configglue"
340+
341+# Don't install recommends, as Canonical IS don't either.
342+echo APT::Install-Recommends "false"\; | tee /etc/apt/apt.conf.d/30-no-install-recommends
343+
344+apt-get update -q
345+
346+# Upgrade the base system in case we are shipping any updates in our PPAs.
347+
348+# XXX: initscript fails in lxc instances:
349+# http://permalink.gmane.org/gmane.linux.kernel.containers.lxc.general/3724
350+# This is a work-around.
351+rmdir /dev/shm
352+ln -s /run/shm /dev/shm
353+
354+apt-get dist-upgrade -q -y
355+
356+# Install the dependencies needed to get puppet going
357+# TODO: move the rest of the dependencies to puppet
358+# XXX: Should this list be stored as config data somewhere?
359+
360+# What you might call "deployment process dependencies"
361+apt-get install -q -y --force-yes bzr apache2 libapache2-mod-wsgi puppet wget
362+
363+# XXX: This list probably over-specifies. Is meant to include:
364+# - libdep-service direct dependencies
365+# - pkgme-devportal direct dependencies (because we install it from branch)
366+# - pkgme direct dependencies (because pkgme is a dependency of
367+# pkgme-devportal that we install from a branch)
368+#
369+# XXX: Using sqlite3 just to get this damn charm going, but actually want
370+# postgresql-9.1
371+#
372+# TODO: Move these into puppet. Requires moving the 'setup.py build' calls as well.
373+apt-get install -q -y --force-yes \
374+ sqlite3 \
375+ python-django \
376+ python-django-south \
377+ python-launchpadlib \
378+ python-fixtures \
379+ python-storm \
380+ python-cheetah \
381+ python-markdown \
382+ python-testtools \
383+ python-xdg \
384+ python-httplib2 \
385+ python-keyring \
386+ python-lazr.restfulclient \
387+ python-lazr.uri \
388+ python-oauth \
389+ python-simplejson \
390+ python-testresources \
391+ python-wadllib \
392+ python-wsgi-intercept \
393+ python-zope.interface
394+
395+# XXX: ERROR: Couldn't get a file descriptor referring to the console
396+# Is this actually a problem?
397+
398+# Grab the branches
399+# TODO: investigate re-using IS' config-manager config
400+# XXX: can we store this as config data somewhere?
401+bzr branch -q $LIBDEP_BRANCH libdep-service
402+bzr branch -q $PKGME_BRANCH libdep-service/sourcecode/pkgme
403+bzr branch -q $PKGME_DEVPORTAL_BRANCH libdep-service/sourcecode/pkgme-devportal
404+bzr branch -q $CONFIGGLUE_BRANCH libdep-service/sourcecode/configglue
405+bzr branch -q $DJANGO_CONFIGGLUE_BRANCH libdep-service/sourcecode/django-configglue
406+
407+# XXX: Heaps of setup.py warnings
408+# /usr/lib/python2.7/distutils/dist.py:267: UserWarning: Unknown distribution option: 'entry_points'
409+# /usr/lib/python2.7/distutils/dist.py:267: UserWarning: Unknown distribution option: 'convert_2to3_doctests'
410+# /usr/lib/python2.7/distutils/dist.py:267: UserWarning: Unknown distribution option: 'use_2to3'
411+# /usr/lib/python2.7/distutils/dist.py:267: UserWarning: Unknown distribution option: 'include_package_data'
412+# /usr/lib/python2.7/distutils/dist.py:267: UserWarning: Unknown distribution option: 'install_requires'
413+# /usr/lib/python2.7/distutils/dist.py:267: UserWarning: Unknown distribution option: 'test_suite'
414+#
415+# Do they matter?
416+
417+(cd libdep-service/sourcecode/pkgme && python setup.py build)
418+(cd libdep-service/sourcecode/pkgme-devportal && python setup.py build)
419+
420+# Grab canonical-memento and use it?
421+
422+# Run puppet to set everything else up.
423+./dev-config/apply
424
425=== added file 'charms/precise/libdep-service/hooks/relation-name-relation-broken'
426--- charms/precise/libdep-service/hooks/relation-name-relation-broken 1970-01-01 00:00:00 +0000
427+++ charms/precise/libdep-service/hooks/relation-name-relation-broken 2012-06-22 13:06:20 +0000
428@@ -0,0 +1,2 @@
429+#!/bin/sh
430+# This hook runs when the full relation is removed (not just a single member)
431
432=== added file 'charms/precise/libdep-service/hooks/relation-name-relation-changed'
433--- charms/precise/libdep-service/hooks/relation-name-relation-changed 1970-01-01 00:00:00 +0000
434+++ charms/precise/libdep-service/hooks/relation-name-relation-changed 2012-06-22 13:06:20 +0000
435@@ -0,0 +1,9 @@
436+#!/bin/bash
437+# This must be renamed to the name of the relation. The goal here is to
438+# affect any change needed by relationships being formed, modified, or broken
439+# This script should be idempotent.
440+juju-log $JUJU_REMOTE_UNIT modified its settings
441+juju-log Relation settings:
442+relation-get
443+juju-log Relation members:
444+relation-list
445
446=== added file 'charms/precise/libdep-service/hooks/relation-name-relation-departed'
447--- charms/precise/libdep-service/hooks/relation-name-relation-departed 1970-01-01 00:00:00 +0000
448+++ charms/precise/libdep-service/hooks/relation-name-relation-departed 2012-06-22 13:06:20 +0000
449@@ -0,0 +1,5 @@
450+#!/bin/sh
451+# This must be renamed to the name of the relation. The goal here is to
452+# affect any change needed by the remote unit leaving the relationship.
453+# This script should be idempotent.
454+juju-log $JUJU_REMOTE_UNIT departed
455
456=== added file 'charms/precise/libdep-service/hooks/relation-name-relation-joined'
457--- charms/precise/libdep-service/hooks/relation-name-relation-joined 1970-01-01 00:00:00 +0000
458+++ charms/precise/libdep-service/hooks/relation-name-relation-joined 2012-06-22 13:06:20 +0000
459@@ -0,0 +1,5 @@
460+#!/bin/sh
461+# This must be renamed to the name of the relation. The goal here is to
462+# affect any change needed by relationships being formed
463+# This script should be idempotent.
464+juju-log $JUJU_REMOTE_UNIT joined
465
466=== added file 'charms/precise/libdep-service/hooks/start'
467--- charms/precise/libdep-service/hooks/start 1970-01-01 00:00:00 +0000
468+++ charms/precise/libdep-service/hooks/start 2012-06-22 13:06:20 +0000
469@@ -0,0 +1,4 @@
470+#!/bin/bash
471+# Here put anything that is needed to start the service.
472+# Note that currently this is run directly after install
473+# i.e. 'service apache2 start'
474
475=== added file 'charms/precise/libdep-service/hooks/stop'
476--- charms/precise/libdep-service/hooks/stop 1970-01-01 00:00:00 +0000
477+++ charms/precise/libdep-service/hooks/stop 2012-06-22 13:06:20 +0000
478@@ -0,0 +1,7 @@
479+#!/bin/bash
480+# This will be run when the service is being torn down, allowing you to disable
481+# it in various ways..
482+# For example, if your web app uses a text file to signal to the load balancer
483+# that it is live... you could remove it and sleep for a bit to allow the load
484+# balancer to stop sending traffic.
485+# rm /srv/webroot/server-live.txt && sleep 30
486
487=== added file 'charms/precise/libdep-service/metadata.yaml'
488--- charms/precise/libdep-service/metadata.yaml 1970-01-01 00:00:00 +0000
489+++ charms/precise/libdep-service/metadata.yaml 2012-06-22 13:06:20 +0000
490@@ -0,0 +1,6 @@
491+name: libdep-service
492+summary: Web services that tells you which binary packages provide a dependency.
493+maintainer: Jonathan Lange <jml@canonical.com>
494+description: |
495+ Sometimes you want to be able to tell what binary packages offer a given
496+ library. This service does that.
497
498=== added file 'charms/precise/libdep-service/revision'
499--- charms/precise/libdep-service/revision 1970-01-01 00:00:00 +0000
500+++ charms/precise/libdep-service/revision 2012-06-22 13:06:20 +0000
501@@ -0,0 +1,1 @@
502+1
503
504=== added file 'django_project/dev.cfg'
505--- django_project/dev.cfg 1970-01-01 00:00:00 +0000
506+++ django_project/dev.cfg 2012-06-22 13:06:20 +0000
507@@ -0,0 +1,18 @@
508+[django]
509+databases = databases
510+
511+[django_file_logging_handler]
512+level = INFO
513+class = logging.handlers.WatchedFileHandler
514+formatter = verbose
515+filename = django.log
516+
517+[databases]
518+default = default_database
519+
520+[default_database]
521+engine = django.db.backends.sqlite3
522+name = test.db
523+
524+[djlibdep]
525+libdep_log_dir = .
526
527=== added file 'django_project/main.cfg'
528--- django_project/main.cfg 1970-01-01 00:00:00 +0000
529+++ django_project/main.cfg 2012-06-22 13:06:20 +0000
530@@ -0,0 +1,70 @@
531+[django]
532+debug = true
533+template_debug = %(debug)s
534+installed_apps =
535+ django.contrib.auth
536+ django.contrib.contenttypes
537+ django.contrib.sessions
538+ django.contrib.sites
539+ django.contrib.messages
540+ django.contrib.staticfiles
541+ django.contrib.admin
542+ djlibdep
543+ south
544+ django_configglue
545+time_zone = UTC
546+language_code = en-us
547+site_id = 1
548+use_i18n = false
549+use_l10n = false
550+middleware_classes =
551+ django.middleware.common.CommonMiddleware
552+ django.contrib.sessions.middleware.SessionMiddleware
553+ django.middleware.csrf.CsrfViewMiddleware
554+ django.contrib.auth.middleware.AuthenticationMiddleware
555+ django.contrib.messages.middleware.MessageMiddleware
556+root_urlconf = django_project.urls
557+logging = django_logging
558+authentication_backends = django_openid_auth.auth.OpenIDBackend
559+ django.contrib.auth.backends.ModelBackend
560+template_context_processors = django.contrib.auth.context_processors.auth
561+ django.core.context_processors.request
562+
563+[django_logging]
564+version = 1
565+disable_existing_loggers = True
566+formatters = django_logging_formatters
567+handlers = django_logging_handlers
568+loggers = django_logging_loggers
569+root = django_logging_root
570+
571+[django_logging_root]
572+level = WARNING
573+
574+[django_logging_loggers]
575+django = django_logger
576+djpkgme = djpkgme_logger
577+
578+[django_logger]
579+handlers = file
580+level = WARNING
581+
582+[djpkgme_logger]
583+handlers = file
584+level = INFO
585+
586+[django_logging_handlers]
587+file = django_file_logging_handler
588+null = django_null_logging_handler
589+
590+[django_null_logging_handler]
591+level = DEBUG
592+class = django.utils.log.NullHandler
593+
594+[django_logging_formatters]
595+verbose = django_verbose_logging_formatter
596+
597+[django_verbose_logging_formatter]
598+# Double escaped as configglue interpolates once, and we need the rest to survive
599+# until django interpolates.
600+format = %%(levelname)s %%(asctime)s %%(module)s %%(process)d %%(thread)d %%(message)s
601
602=== modified file 'django_project/manage.py'
603--- django_project/manage.py 2012-06-08 14:41:29 +0000
604+++ django_project/manage.py 2012-06-22 13:06:20 +0000
605@@ -1,4 +1,13 @@
606 #!/usr/bin/python
607+import os
608+import sys
609+
610+sourcecode_path = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'sourcecode')
611+for filename in os.listdir(sourcecode_path) + ['..', '../django_project']:
612+ dependency_path = os.path.join(sourcecode_path, filename)
613+ if os.path.isdir(dependency_path):
614+ sys.path.insert(0, dependency_path)
615+
616 from django.core.management import execute_manager
617 try:
618 import settings # Assumed to be in the same directory.
619
620=== added file 'django_project/schema.py'
621--- django_project/schema.py 1970-01-01 00:00:00 +0000
622+++ django_project/schema.py 2012-06-22 13:06:20 +0000
623@@ -0,0 +1,13 @@
624+import django
625+from configglue import schema
626+from django_configglue.schema import schemas
627+
628+
629+DjangoSchema = schemas.get(django.get_version())
630+
631+
632+class DjlibdepSchema(DjangoSchema):
633+
634+ class djlibdep(schema.Section):
635+
636+ libdep_log_dir = schema.StringOption()
637
638=== modified file 'django_project/settings.py'
639--- django_project/settings.py 2012-06-08 15:25:12 +0000
640+++ django_project/settings.py 2012-06-22 13:06:20 +0000
641@@ -1,80 +1,50 @@
642-# Django settings for django_project project.
643-
644-DEBUG = True
645-TEMPLATE_DEBUG = DEBUG
646-
647-ADMINS = (
648- # ('Your Name', 'your_email@domain.com'),
649-)
650-
651-MANAGERS = ADMINS
652-
653-DATABASE_ENGINE = 'sqlite3' # 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
654-DATABASE_NAME = 'test.db' # Or path to database file if using sqlite3.
655-DATABASE_USER = '' # Not used with sqlite3.
656-DATABASE_PASSWORD = '' # Not used with sqlite3.
657-DATABASE_HOST = '' # Set to empty string for localhost. Not used with sqlite3.
658-DATABASE_PORT = '' # Set to empty string for default. Not used with sqlite3.
659-
660-# Local time zone for this installation. Choices can be found here:
661-# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
662-# although not all choices may be available on all operating systems.
663-# If running in a Windows environment this must be set to the same as your
664-# system time zone.
665-TIME_ZONE = 'America/Chicago'
666-
667-# Language code for this installation. All choices can be found here:
668-# http://www.i18nguy.com/unicode/language-identifiers.html
669-LANGUAGE_CODE = 'en-us'
670-
671-SITE_ID = 1
672-
673-# If you set this to False, Django will make some optimizations so as not
674-# to load the internationalization machinery.
675-USE_I18N = True
676-
677-# Absolute path to the directory that holds media.
678-# Example: "/home/media/media.lawrence.com/"
679-MEDIA_ROOT = ''
680-
681-# URL that handles the media served from MEDIA_ROOT. Make sure to use a
682-# trailing slash if there is a path component (optional in other cases).
683-# Examples: "http://media.lawrence.com", "http://example.com/media/"
684-MEDIA_URL = ''
685-
686-# URL prefix for admin media -- CSS, JavaScript and images. Make sure to use a
687-# trailing slash.
688-# Examples: "http://foo.com/media/", "/media/".
689-ADMIN_MEDIA_PREFIX = '/media/'
690-
691-# Make this unique, and don't share it with anybody.
692-SECRET_KEY = ')wpm+3!fok#gq4@pjw=(-4yvcrfl93zp398c^b8$k)cek1rd)o'
693-
694-# List of callables that know how to import templates from various sources.
695-TEMPLATE_LOADERS = (
696- 'django.template.loaders.filesystem.load_template_source',
697- 'django.template.loaders.app_directories.load_template_source',
698-# 'django.template.loaders.eggs.load_template_source',
699-)
700-
701-MIDDLEWARE_CLASSES = (
702- 'django.middleware.common.CommonMiddleware',
703- 'django.contrib.sessions.middleware.SessionMiddleware',
704- 'django.contrib.auth.middleware.AuthenticationMiddleware',
705-)
706-
707-ROOT_URLCONF = 'django_project.urls'
708-
709-TEMPLATE_DIRS = (
710- # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
711- # Always use forward slashes, even on Windows.
712- # Don't forget to use absolute paths, not relative paths.
713-)
714-
715-INSTALLED_APPS = (
716- 'django.contrib.auth',
717- 'django.contrib.contenttypes',
718- 'django.contrib.sessions',
719- 'django.contrib.sites',
720- 'djlibdep',
721-)
722+import os
723+
724+from django_configglue.utils import configglue
725+from schema import DjlibdepSchema
726+
727+basedir = os.path.abspath(os.path.dirname(__file__))
728+paths = [os.path.join(basedir, 'main.cfg')]
729+
730+
731+def add_if_present(path, also_add=None):
732+ """Add a path to the global `paths` list if it is present on disk.
733+
734+ If `path` is present on disk then it adds it to the global `paths`
735+ list and returns True.
736+
737+ If `path` is not present on disk then it does nothing and returns
738+ False.
739+
740+ If `also_add` is not None and `path` is added to `paths` then
741+ `also_add` will also be added to `paths`. If `path` is not added
742+ then neither will `also_add`.
743+
744+ :param path: the path to check and add
745+ :type path: str
746+ :param also_add: a path to also add if `path` is added, or
747+ None to only add the one path. The default is None.
748+ :type path: str or None
749+ """
750+ global paths
751+ new_path = os.path.join(basedir, path)
752+ if os.path.exists(new_path):
753+ if also_add:
754+ paths.append(os.path.join(basedir, also_add))
755+ paths.append(new_path)
756+ return True
757+ return False
758+
759+
760+# Used to choose between dev and non-dev settings.
761+if not add_if_present('nondev_credentials.cfg', also_add='nondev.cfg'):
762+ add_if_present('dev.cfg')
763+
764+
765+# Used to override settings in tests.
766+test_settings_path = os.environ.get('DJLIBDEP_TEST_SETTINGS_PATH', None)
767+if test_settings_path:
768+ paths.append(test_settings_path)
769+
770+# make django aware of configglue-based configuration
771+configglue(DjlibdepSchema, paths, __name__)
772
773=== added directory 'sourcecode'

Subscribers

People subscribed via source and target branches