Merge lp:~stub/charms/precise/postgresql-psql/devel into lp:charms/postgresql-psql

Proposed by Stuart Bishop
Status: Merged
Approved by: Mark Mims
Approved revision: 26
Merged at revision: 17
Proposed branch: lp:~stub/charms/precise/postgresql-psql/devel
Merge into: lp:charms/postgresql-psql
Diff against target: 226 lines (+86/-32)
4 files modified
hooks/charmhelpers/core/hookenv.py (+1/-0)
hooks/charmhelpers/core/host.py (+21/-10)
hooks/hooks.py (+64/-14)
hooks/install (+0/-8)
To merge this branch: bzr merge lp:~stub/charms/precise/postgresql-psql/devel
Reviewer Review Type Date Requested Status
Mark Mims (community) Approve
Review via email: mp+180849@code.launchpad.net

Commit message

Move generated scripts and credentials out of the charm directory

Description of the change

Per Bug #1205286, we shouldn't be generating scripts and storing credentials in the charm directory.

To post a comment you must log in.
24. By Stuart Bishop

Missing hook registrations

25. By Stuart Bishop

Update charmhelpers

26. By Stuart Bishop

Update system PATH correctly

Revision history for this message
Mark Mims (mark-mims) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'hooks/charmhelpers/core/hookenv.py'
2--- hooks/charmhelpers/core/hookenv.py 2013-07-15 12:48:49 +0000
3+++ hooks/charmhelpers/core/hookenv.py 2013-08-23 11:49:26 +0000
4@@ -335,5 +335,6 @@
5 return decorated
6 return wrapper
7
8+
9 def charm_dir():
10 return os.environ.get('CHARM_DIR')
11
12=== modified file 'hooks/charmhelpers/core/host.py'
13--- hooks/charmhelpers/core/host.py 2013-07-15 12:48:49 +0000
14+++ hooks/charmhelpers/core/host.py 2013-08-23 11:49:26 +0000
15@@ -9,12 +9,14 @@
16 import os
17 import pwd
18 import grp
19+import random
20+import string
21 import subprocess
22 import hashlib
23
24 from collections import OrderedDict
25
26-from hookenv import log, execution_environment
27+from hookenv import log
28
29
30 def service_start(service_name):
31@@ -86,36 +88,33 @@
32
33 def rsync(from_path, to_path, flags='-r', options=None):
34 """Replicate the contents of a path"""
35- context = execution_environment()
36 options = options or ['--delete', '--executability']
37 cmd = ['/usr/bin/rsync', flags]
38 cmd.extend(options)
39- cmd.append(from_path.format(**context))
40- cmd.append(to_path.format(**context))
41+ cmd.append(from_path)
42+ cmd.append(to_path)
43 log(" ".join(cmd))
44 return subprocess.check_output(cmd).strip()
45
46
47 def symlink(source, destination):
48 """Create a symbolic link"""
49- context = execution_environment()
50 log("Symlinking {} as {}".format(source, destination))
51 cmd = [
52 'ln',
53 '-sf',
54- source.format(**context),
55- destination.format(**context)
56+ source,
57+ destination,
58 ]
59 subprocess.check_call(cmd)
60
61
62 def mkdir(path, owner='root', group='root', perms=0555, force=False):
63 """Create a directory"""
64- context = execution_environment()
65 log("Making dir {} {}:{} {:o}".format(path, owner, group,
66 perms))
67- uid = pwd.getpwnam(owner.format(**context)).pw_uid
68- gid = grp.getgrnam(group.format(**context)).gr_gid
69+ uid = pwd.getpwnam(owner).pw_uid
70+ gid = grp.getgrnam(group).gr_gid
71 realpath = os.path.abspath(path)
72 if os.path.exists(realpath):
73 if force and not os.path.isdir(realpath):
74@@ -270,3 +269,15 @@
75 k, v = l.split('=')
76 d[k.strip()] = v.strip()
77 return d
78+
79+
80+def pwgen(length=None):
81+ '''Generate a random pasword.'''
82+ if length is None:
83+ length = random.choice(range(35, 45))
84+ alphanumeric_chars = [
85+ l for l in (string.letters + string.digits)
86+ if l not in 'l0QD1vAEIOUaeiou']
87+ random_chars = [
88+ random.choice(alphanumeric_chars) for _ in range(length)]
89+ return(''.join(random_chars))
90
91=== modified file 'hooks/hooks.py'
92--- hooks/hooks.py 2013-07-15 13:08:40 +0000
93+++ hooks/hooks.py 2013-08-23 11:49:26 +0000
94@@ -1,6 +1,7 @@
95 #!/usr/bin/env python
96
97 import os.path
98+import re
99 import shutil
100 import sys
101 from textwrap import dedent
102@@ -11,6 +12,28 @@
103
104 CLIENT_RELATION_TYPES = frozenset(['db', 'db-admin'])
105
106+DATA_DIR = os.path.join(
107+ '/var/lib/units', hookenv.local_unit().replace('/', '-'))
108+SCRIPT_DIR = os.path.join(DATA_DIR, 'bin')
109+PGPASS_DIR = os.path.join(DATA_DIR, 'pgpass')
110+
111+
112+def update_system_path():
113+ org_lines = open('/etc/environment', 'rb').readlines()
114+ env_lines = []
115+
116+ for line in org_lines:
117+ if line.startswith('PATH=') and SCRIPT_DIR not in line:
118+ line = re.sub(
119+ """(['"]?)$""",
120+ ":{}\\1".format(SCRIPT_DIR),
121+ line, 1)
122+ env_lines.append(line)
123+
124+ if org_lines != env_lines:
125+ content = '\n'.join(env_lines)
126+ host.write_file('/etc/environment', content, perms=0o644)
127+
128
129 def all_relations(relation_types=CLIENT_RELATION_TYPES):
130 for reltype in relation_types:
131@@ -19,22 +42,18 @@
132 yield reltype, relid, unit, hookenv.relation_get(
133 unit=unit, rid=relid)
134
135-hooks = hookenv.Hooks()
136
137-@hooks.hook(
138- 'config-changed', 'upgrade-charm',
139- 'db-relation-changed', 'db-relation-joined',
140- 'db-admin-relation-changed', 'db-admin-relation-joined')
141 def rebuild_all_relations():
142 config = hookenv.config()
143
144 # Clear out old scripts and pgpass files
145- if os.path.exists('bin'):
146- shutil.rmtree('bin')
147- if os.path.exists('pgpass'):
148- shutil.rmtree('pgpass')
149- host.mkdir('bin', perms=0o755)
150- host.mkdir('pgpass', group='ubuntu', perms=0o750)
151+ if os.path.exists(SCRIPT_DIR):
152+ shutil.rmtree(SCRIPT_DIR)
153+ if os.path.exists(PGPASS_DIR):
154+ shutil.rmtree(PGPASS_DIR)
155+ host.mkdir(DATA_DIR, perms=0o755)
156+ host.mkdir(SCRIPT_DIR, perms=0o755)
157+ host.mkdir(PGPASS_DIR, group='ubuntu', perms=0o750)
158
159 for _, relid, unit, relation in all_relations(relation_types=['db']):
160 log("{} {} {!r}".format(relid, unit, relation), DEBUG)
161@@ -72,8 +91,8 @@
162 def build_script(script_name, relation):
163 # Install a wrapper to psql that connects it to the desired database
164 # by default. One wrapper per unit per relation.
165- script_path = os.path.abspath(os.path.join('bin', script_name))
166- pgpass_path = os.path.abspath(os.path.join('pgpass', script_name))
167+ script_path = os.path.abspath(os.path.join(SCRIPT_DIR, script_name))
168+ pgpass_path = os.path.abspath(os.path.join(PGPASS_DIR, script_name))
169 script = dedent("""\
170 #!/bin/sh
171 exec env \\
172@@ -96,7 +115,38 @@
173 pgpass = "*:*:*:{user}:{password}".format(
174 user=relation['user'], password=relation['password'])
175 host.write_file(
176- pgpass_path, pgpass, owner="ubuntu", group="ubuntu", mode=0o400)
177+ pgpass_path, pgpass, owner="ubuntu", group="ubuntu", perms=0o400)
178+
179+
180+hooks = hookenv.Hooks()
181+
182+
183+@hooks.hook()
184+def install():
185+ host.apt_install(
186+ ['language-pack-en', 'postgresql-client', 'python-psycopg2'],
187+ fatal=True)
188+ update_system_path()
189+
190+
191+@hooks.hook()
192+def upgrade_charm():
193+ # Per Bug #1205286, we can't store scripts and passwords in the
194+ # charm directory.
195+ if os.path.exists('bin'):
196+ shutil.rmtree('bin')
197+ if os.path.exists('pgpass'):
198+ shutil.rmtree('pgpass')
199+ update_system_path()
200+ return rebuild_all_relations()
201+
202+
203+@hooks.hook(
204+ 'config-changed', 'db-admin-relation-broken',
205+ 'db-admin-relation-changed', 'db-admin-relation-joined',
206+ 'db-relation-broken', 'db-relation-changed', 'db-relation-joined')
207+def rebuild_hook():
208+ return rebuild_all_relations()
209
210
211 if __name__ == '__main__':
212
213=== modified file 'hooks/install'
214--- hooks/install 2013-06-17 16:50:51 +0000
215+++ hooks/install 1970-01-01 00:00:00 +0000
216@@ -1,8 +0,0 @@
217-#!/bin/sh -e
218-
219-PACKAGES="postgresql-client python-psycopg2 language-pack-en"
220-juju-log "Installing ${PACKAGES}"
221-apt-get -y install -qq ${PACKAGES}
222-
223-juju-log "Adding ${PWD}/bin to \$PATH"
224-sed -e "/^PATH/s|\"\$|:${PWD}/bin\"|g" -i.bak /etc/environment
225
226=== target is u'./hooks.py'

Subscribers

People subscribed via source and target branches