Merge lp:~abentley/charms/precise/charmworld/multi-mongo into lp:~juju-jitsu/charms/precise/charmworld/trunk

Proposed by Aaron Bentley
Status: Merged
Merged at revision: 43
Proposed branch: lp:~abentley/charms/precise/charmworld/multi-mongo
Merge into: lp:~juju-jitsu/charms/precise/charmworld/trunk
Diff against target: 295 lines (+89/-80)
9 files modified
common (+7/-2)
hooks/config-changed (+17/-17)
hooks/database-relation-broken (+0/-7)
hooks/database-relation-changed (+14/-19)
hooks/install (+1/-0)
hooks/upgrade-charm (+5/-8)
production_overrides.ini (+0/-1)
revision (+1/-1)
scripts/write_config.py (+44/-25)
To merge this branch: bzr merge lp:~abentley/charms/precise/charmworld/multi-mongo
Reviewer Review Type Date Requested Status
Juju-Jitsu Hackers Pending
Review via email: mp+148552@code.launchpad.net

Description of the change

Allow multiple mongodb instances

Change functionality of write_config so that it directly interrogates the
environment to determine the juju hosts, instead of accepting commandline
parameters or reading previous config. Use mongo.url setting instead of
host/port, and stop setting session.secret (it's now unused). write_config
moves into scripts/ partly for cleanliness and partly to access charmsupport.

With this change to write_config, config-changed now handles db relation
changes as well as setting changes, so invoke it in every db relation hook
(except join, since -changed will follow join). database-relation-changed is
now essentially a wrapper to ensure that ingest is run when a database becomes
available.

Flatten the refresh function back into the body of config-changed, since it
would be invoked unconditionally.

Delete ~webops_deploy/charmworld on install if present, since it may
contain incorrect or invalid config data.

https://codereview.appspot.com/7314102/

To post a comment you must log in.
Revision history for this message
j.c.sackett (jcsackett) wrote :

On 2013/02/14 20:27:24, abentley wrote:
> Please take a look.

lgtm.

https://codereview.appspot.com/7314102/

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'common'
2--- common 2013-02-07 21:09:02 +0000
3+++ common 2013-02-14 20:27:37 +0000
4@@ -4,6 +4,11 @@
5 project_dir="$webops_home/charmworld"
6 CONFIG_FILE="$project_dir/production.ini"
7 configure(){
8- ./write_config.py $project_dir/default.ini production_overrides.ini\
9- $CONFIG_FILE "$@"
10+ scripts/write_config.py $project_dir/default.ini production_overrides.ini\
11+ $CONFIG_FILE
12+}
13+maybe_rmtree(){
14+ if [ -d $1 ]; then
15+ rm $1 -R
16+ fi
17 }
18
19=== modified file 'hooks/config-changed'
20--- hooks/config-changed 2013-02-12 18:49:31 +0000
21+++ hooks/config-changed 2013-02-14 20:27:37 +0000
22@@ -12,6 +12,8 @@
23 fi
24
25
26+hooks/stop || true
27+
28 if [ -z "$source_url" ]; then
29 exit 0
30 fi
31@@ -35,28 +37,27 @@
32 cd $charm_dir
33 }
34
35-
36-refresh(){
37- configure
38- chown webops_deploy.webops_deploy $project_dir -R
39- if grep -E 'mongo.host = .+' $CONFIG_FILE; then
40- cd $project_dir
41- INI=$CONFIG_FILE bin/migrations upgrade
42- cd $charm_dir
43- hooks/start
44- fi
45-}
46-
47-
48 juju-log "Disable ingest..."
49 rm -f /etc/cron.d/charmworld
50-hooks/stop || true
51 if [ "$source_url" != "$current_source_url" ]; then
52 update_source
53 elif [ "$revno" -ge 0 -a $revno != $(bzr revno $project_dir) ]; then
54 update_source
55 fi
56-refresh
57+configure
58+chown webops_deploy.webops_deploy $project_dir -R
59+
60+# nagios_context may have changed.
61+scripts/update-nrpe.py
62+if grep -E 'mongo.url = .+' $CONFIG_FILE; then
63+ cd $project_dir
64+ su charmworld -c "INI=$CONFIG_FILE bin/migrations upgrade --init"
65+ cd $charm_dir
66+ hooks/start
67+else
68+ # avoid setting up ingest if no db available.
69+ exit 0
70+fi
71
72 interval=`config-get execute-ingest-every`
73 : ${interval:-0}
74@@ -89,5 +90,4 @@
75 EOF
76
77 fi
78-# nagios_context may have changed.
79-scripts/update-nrpe.py
80+
81
82=== modified file 'hooks/database-relation-broken'
83--- hooks/database-relation-broken 2013-01-29 15:32:47 +0000
84+++ hooks/database-relation-broken 1970-01-01 00:00:00 +0000
85@@ -1,7 +0,0 @@
86-#!/bin/bash
87-set -eux
88-
89-hooks/stop || true
90-source common
91-
92-configure '' ''
93
94=== target is u'config-changed'
95=== modified file 'hooks/database-relation-changed'
96--- hooks/database-relation-changed 2013-02-07 21:09:02 +0000
97+++ hooks/database-relation-changed 2013-02-14 20:27:37 +0000
98@@ -3,31 +3,26 @@
99 source common
100 set -x
101
102-DB_HOST=`relation-get private-address`
103 HOME=$webops_home
104
105-if [ -z "$DB_HOST" ]; then
106- juju-log "Waiting for handshake from mongodb"
107+set +e
108+grep -E 'mongo.url = .+' $CONFIG_FILE
109+had_url=$?
110+set -e
111+
112+hooks/config-changed
113+
114+if ! grep -E 'mongo.url = [^ ]+' $CONFIG_FILE; then
115 exit 0
116 fi
117
118-if [ ! -f "$CONFIG_FILE" ]; then
119- hooks/config-changed
120+if [ $had_url != 0 ]; then
121+ juju-log "Hey, we're ingesting over here. This WILL take a while."
122+ # Perform an initial ingest
123+ su charmworld -c "INI=$CONFIG_FILE HOME=$charmworld_home \
124+ LOGDIR=$log_dir PYTHON_BIN=$project_dir/bin/python \
125+ $project_dir/scripts/ingest"
126 fi
127-
128-relation_port=`relation-get port`
129-DB_PORT=${relation_port:-27017}
130-
131-configure $DB_HOST $DB_PORT
132-
133-su charmworld -c "export INI=$CONFIG_FILE; $project_dir/bin/migrations upgrade --init"
134-
135-juju-log "Hey, we're ingesting over here. This WILL take a while."
136-# Perform an initial ingest
137-su charmworld -c "INI=$CONFIG_FILE HOME=$charmworld_home \
138- LOGDIR=$log_dir PYTHON_BIN=$project_dir/bin/python \
139- $project_dir/scripts/ingest"
140-
141 open-port 80
142
143 source hooks/restart
144
145=== added symlink 'hooks/database-relation-departed'
146=== target is u'config-changed'
147=== modified file 'hooks/install'
148--- hooks/install 2013-02-07 21:09:02 +0000
149+++ hooks/install 2013-02-14 20:27:37 +0000
150@@ -34,3 +34,4 @@
151 install -o charmworld -g charmworld -m 0755 -d $charmworld_home/var/charms
152 $INSTALL scripts/run-write-errors $webops_home
153 python scripts/gen_deploymgr.py
154+maybe_rmtree $project_dir
155
156=== modified file 'hooks/upgrade-charm'
157--- hooks/upgrade-charm 2013-02-07 21:09:02 +0000
158+++ hooks/upgrade-charm 2013-02-14 20:27:37 +0000
159@@ -1,15 +1,12 @@
160 #!/bin/bash
161-set -eux
162+set -eu
163+source common
164+set -x
165
166 hooks/stop || true
167 hooks/install
168-maybe_rm(){
169- if [ -d $1 ]; then
170- rm $1 -R
171- fi
172-}
173-maybe_rm ~ubuntu/charmworld
174-maybe_rm ~ubuntu/var
175+maybe_rmtree ~ubuntu/charmworld
176+maybe_rmtree ~ubuntu/var
177 hooks/config-changed
178 hooks/restart
179 maybe_rm ~ubuntu/shhh.py
180
181=== modified file 'production_overrides.ini'
182--- production_overrides.ini 2013-02-12 18:30:49 +0000
183+++ production_overrides.ini 2013-02-14 20:27:37 +0000
184@@ -5,7 +5,6 @@
185 mongo.host =
186 mongo.port =
187 mongo.url =
188-session.secret =
189
190 [server:main]
191 port = 6543
192
193=== modified file 'revision'
194--- revision 2013-02-13 19:45:57 +0000
195+++ revision 2013-02-14 20:27:37 +0000
196@@ -1,1 +1,1 @@
197-24
198+25
199
200=== renamed file 'write_config.py' => 'scripts/write_config.py'
201--- write_config.py 2013-01-29 15:45:19 +0000
202+++ scripts/write_config.py 2013-02-14 20:27:37 +0000
203@@ -1,16 +1,12 @@
204 #!/usr/bin/env python
205
206-from ConfigParser import ConfigParser, NoSectionError
207-from random import getrandbits
208+from ConfigParser import ConfigParser
209+import json
210+import subprocess
211 import sys
212
213-
214-def update_config(parser, items):
215- configurable = set(['session.secret', 'mongo.host', 'mongo.port'])
216- for key, value in items:
217- if key not in configurable:
218- continue
219- parser.set('app:main', key, value)
220+from charmsupport.hookenv import related_units
221+from charmsupport.hookenv import relation_ids
222
223
224 def read_config(files):
225@@ -19,33 +15,56 @@
226 return new_config
227
228
229-def write_new_config(changes, default, override, target):
230+def write_new_config(mongo_url, default, override, target):
231 new_config = read_config([default, override])
232- old_config = read_config(target)
233- try:
234- update_config(new_config, old_config.items('app:main', raw=True))
235- except NoSectionError:
236- pass
237- update_config(new_config, changes)
238- if new_config.get('app:main', 'session.secret') == '':
239- new_config.set('app:main', 'session.secret', str(getrandbits(32)))
240+ new_config.set('app:main', 'mongo.url', mongo_url)
241 with open(target, 'w') as output:
242 new_config.write(output)
243
244
245+def get_relation_id_data(relation_id, unit):
246+ """Return a dictionary containing relation settings.
247+
248+ :param relation_id: The relation id specifying the relation.
249+ :param unit: The name of the unit participating in the relation.
250+ """
251+ cmd = ['relation-get', '--format=json', '-r', relation_id, '-', unit]
252+ return json.loads(subprocess.check_output(cmd))
253+
254+
255+def get_mongo_url():
256+ """Use the 'database' relation settings to build a mongodb url.
257+
258+ If mongodb units are present, return an empty string.
259+ """
260+ host_ports = []
261+ replset = None
262+ for relation_id in relation_ids('database'):
263+ for unit in related_units(relation_id):
264+ relation_data = get_relation_id_data(relation_id, unit)
265+ # Consider configuration incomplete until port is supplied.
266+ if relation_data is None or 'port' not in relation_data:
267+ continue
268+ if replset is None:
269+ replset = relation_data['replset']
270+ # All units should be members of the same replication set.
271+ elif replset != relation_data['replset']:
272+ raise AssertionError('DB instances are from different sets!')
273+ host_ports.append(
274+ '%(private-address)s:%(port)s' % relation_data)
275+ if len(host_ports) == 0:
276+ return ''
277+ return 'mongodb://%s/?replicaSet=%s' % (','.join(host_ports), replset)
278+
279+
280 class UsageError(Exception):
281 """An error triggered by incorrect usage"""
282
283
284 def main():
285 if len(sys.argv) < 4:
286- raise UsageError('Usage: %s DEFAULTS OVERRIDES TARGET [HOST [PORT]]')
287- changes = {}
288- if len(sys.argv) > 4:
289- changes['mongo.host'] = sys.argv[4]
290- if len(sys.argv) > 5:
291- changes['mongo.port'] = sys.argv[5]
292- parser = write_new_config(changes.items(), default=sys.argv[1],
293+ raise UsageError('Usage: %s DEFAULTS OVERRIDES TARGET')
294+ parser = write_new_config(get_mongo_url(), default=sys.argv[1],
295 override=sys.argv[2], target=sys.argv[3])
296
297

Subscribers

People subscribed via source and target branches

to all changes: