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
=== modified file 'hooks/charmhelpers/core/hookenv.py'
--- hooks/charmhelpers/core/hookenv.py 2013-07-15 12:48:49 +0000
+++ hooks/charmhelpers/core/hookenv.py 2013-08-23 11:49:26 +0000
@@ -335,5 +335,6 @@
335 return decorated335 return decorated
336 return wrapper336 return wrapper
337337
338
338def charm_dir():339def charm_dir():
339 return os.environ.get('CHARM_DIR')340 return os.environ.get('CHARM_DIR')
340341
=== modified file 'hooks/charmhelpers/core/host.py'
--- hooks/charmhelpers/core/host.py 2013-07-15 12:48:49 +0000
+++ hooks/charmhelpers/core/host.py 2013-08-23 11:49:26 +0000
@@ -9,12 +9,14 @@
9import os9import os
10import pwd10import pwd
11import grp11import grp
12import random
13import string
12import subprocess14import subprocess
13import hashlib15import hashlib
1416
15from collections import OrderedDict17from collections import OrderedDict
1618
17from hookenv import log, execution_environment19from hookenv import log
1820
1921
20def service_start(service_name):22def service_start(service_name):
@@ -86,36 +88,33 @@
8688
87def rsync(from_path, to_path, flags='-r', options=None):89def rsync(from_path, to_path, flags='-r', options=None):
88 """Replicate the contents of a path"""90 """Replicate the contents of a path"""
89 context = execution_environment()
90 options = options or ['--delete', '--executability']91 options = options or ['--delete', '--executability']
91 cmd = ['/usr/bin/rsync', flags]92 cmd = ['/usr/bin/rsync', flags]
92 cmd.extend(options)93 cmd.extend(options)
93 cmd.append(from_path.format(**context))94 cmd.append(from_path)
94 cmd.append(to_path.format(**context))95 cmd.append(to_path)
95 log(" ".join(cmd))96 log(" ".join(cmd))
96 return subprocess.check_output(cmd).strip()97 return subprocess.check_output(cmd).strip()
9798
9899
99def symlink(source, destination):100def symlink(source, destination):
100 """Create a symbolic link"""101 """Create a symbolic link"""
101 context = execution_environment()
102 log("Symlinking {} as {}".format(source, destination))102 log("Symlinking {} as {}".format(source, destination))
103 cmd = [103 cmd = [
104 'ln',104 'ln',
105 '-sf',105 '-sf',
106 source.format(**context),106 source,
107 destination.format(**context)107 destination,
108 ]108 ]
109 subprocess.check_call(cmd)109 subprocess.check_call(cmd)
110110
111111
112def mkdir(path, owner='root', group='root', perms=0555, force=False):112def mkdir(path, owner='root', group='root', perms=0555, force=False):
113 """Create a directory"""113 """Create a directory"""
114 context = execution_environment()
115 log("Making dir {} {}:{} {:o}".format(path, owner, group,114 log("Making dir {} {}:{} {:o}".format(path, owner, group,
116 perms))115 perms))
117 uid = pwd.getpwnam(owner.format(**context)).pw_uid116 uid = pwd.getpwnam(owner).pw_uid
118 gid = grp.getgrnam(group.format(**context)).gr_gid117 gid = grp.getgrnam(group).gr_gid
119 realpath = os.path.abspath(path)118 realpath = os.path.abspath(path)
120 if os.path.exists(realpath):119 if os.path.exists(realpath):
121 if force and not os.path.isdir(realpath):120 if force and not os.path.isdir(realpath):
@@ -270,3 +269,15 @@
270 k, v = l.split('=')269 k, v = l.split('=')
271 d[k.strip()] = v.strip()270 d[k.strip()] = v.strip()
272 return d271 return d
272
273
274def pwgen(length=None):
275 '''Generate a random pasword.'''
276 if length is None:
277 length = random.choice(range(35, 45))
278 alphanumeric_chars = [
279 l for l in (string.letters + string.digits)
280 if l not in 'l0QD1vAEIOUaeiou']
281 random_chars = [
282 random.choice(alphanumeric_chars) for _ in range(length)]
283 return(''.join(random_chars))
273284
=== modified file 'hooks/hooks.py'
--- hooks/hooks.py 2013-07-15 13:08:40 +0000
+++ hooks/hooks.py 2013-08-23 11:49:26 +0000
@@ -1,6 +1,7 @@
1#!/usr/bin/env python1#!/usr/bin/env python
22
3import os.path3import os.path
4import re
4import shutil5import shutil
5import sys6import sys
6from textwrap import dedent7from textwrap import dedent
@@ -11,6 +12,28 @@
1112
12CLIENT_RELATION_TYPES = frozenset(['db', 'db-admin'])13CLIENT_RELATION_TYPES = frozenset(['db', 'db-admin'])
1314
15DATA_DIR = os.path.join(
16 '/var/lib/units', hookenv.local_unit().replace('/', '-'))
17SCRIPT_DIR = os.path.join(DATA_DIR, 'bin')
18PGPASS_DIR = os.path.join(DATA_DIR, 'pgpass')
19
20
21def update_system_path():
22 org_lines = open('/etc/environment', 'rb').readlines()
23 env_lines = []
24
25 for line in org_lines:
26 if line.startswith('PATH=') and SCRIPT_DIR not in line:
27 line = re.sub(
28 """(['"]?)$""",
29 ":{}\\1".format(SCRIPT_DIR),
30 line, 1)
31 env_lines.append(line)
32
33 if org_lines != env_lines:
34 content = '\n'.join(env_lines)
35 host.write_file('/etc/environment', content, perms=0o644)
36
1437
15def all_relations(relation_types=CLIENT_RELATION_TYPES):38def all_relations(relation_types=CLIENT_RELATION_TYPES):
16 for reltype in relation_types:39 for reltype in relation_types:
@@ -19,22 +42,18 @@
19 yield reltype, relid, unit, hookenv.relation_get(42 yield reltype, relid, unit, hookenv.relation_get(
20 unit=unit, rid=relid)43 unit=unit, rid=relid)
2144
22hooks = hookenv.Hooks()
2345
24@hooks.hook(
25 'config-changed', 'upgrade-charm',
26 'db-relation-changed', 'db-relation-joined',
27 'db-admin-relation-changed', 'db-admin-relation-joined')
28def rebuild_all_relations():46def rebuild_all_relations():
29 config = hookenv.config()47 config = hookenv.config()
3048
31 # Clear out old scripts and pgpass files49 # Clear out old scripts and pgpass files
32 if os.path.exists('bin'):50 if os.path.exists(SCRIPT_DIR):
33 shutil.rmtree('bin')51 shutil.rmtree(SCRIPT_DIR)
34 if os.path.exists('pgpass'):52 if os.path.exists(PGPASS_DIR):
35 shutil.rmtree('pgpass')53 shutil.rmtree(PGPASS_DIR)
36 host.mkdir('bin', perms=0o755)54 host.mkdir(DATA_DIR, perms=0o755)
37 host.mkdir('pgpass', group='ubuntu', perms=0o750)55 host.mkdir(SCRIPT_DIR, perms=0o755)
56 host.mkdir(PGPASS_DIR, group='ubuntu', perms=0o750)
3857
39 for _, relid, unit, relation in all_relations(relation_types=['db']):58 for _, relid, unit, relation in all_relations(relation_types=['db']):
40 log("{} {} {!r}".format(relid, unit, relation), DEBUG)59 log("{} {} {!r}".format(relid, unit, relation), DEBUG)
@@ -72,8 +91,8 @@
72def build_script(script_name, relation):91def build_script(script_name, relation):
73 # Install a wrapper to psql that connects it to the desired database92 # Install a wrapper to psql that connects it to the desired database
74 # by default. One wrapper per unit per relation.93 # by default. One wrapper per unit per relation.
75 script_path = os.path.abspath(os.path.join('bin', script_name))94 script_path = os.path.abspath(os.path.join(SCRIPT_DIR, script_name))
76 pgpass_path = os.path.abspath(os.path.join('pgpass', script_name))95 pgpass_path = os.path.abspath(os.path.join(PGPASS_DIR, script_name))
77 script = dedent("""\96 script = dedent("""\
78 #!/bin/sh97 #!/bin/sh
79 exec env \\98 exec env \\
@@ -96,7 +115,38 @@
96 pgpass = "*:*:*:{user}:{password}".format(115 pgpass = "*:*:*:{user}:{password}".format(
97 user=relation['user'], password=relation['password'])116 user=relation['user'], password=relation['password'])
98 host.write_file(117 host.write_file(
99 pgpass_path, pgpass, owner="ubuntu", group="ubuntu", mode=0o400)118 pgpass_path, pgpass, owner="ubuntu", group="ubuntu", perms=0o400)
119
120
121hooks = hookenv.Hooks()
122
123
124@hooks.hook()
125def install():
126 host.apt_install(
127 ['language-pack-en', 'postgresql-client', 'python-psycopg2'],
128 fatal=True)
129 update_system_path()
130
131
132@hooks.hook()
133def upgrade_charm():
134 # Per Bug #1205286, we can't store scripts and passwords in the
135 # charm directory.
136 if os.path.exists('bin'):
137 shutil.rmtree('bin')
138 if os.path.exists('pgpass'):
139 shutil.rmtree('pgpass')
140 update_system_path()
141 return rebuild_all_relations()
142
143
144@hooks.hook(
145 'config-changed', 'db-admin-relation-broken',
146 'db-admin-relation-changed', 'db-admin-relation-joined',
147 'db-relation-broken', 'db-relation-changed', 'db-relation-joined')
148def rebuild_hook():
149 return rebuild_all_relations()
100150
101151
102if __name__ == '__main__':152if __name__ == '__main__':
103153
=== modified file 'hooks/install'
--- hooks/install 2013-06-17 16:50:51 +0000
+++ hooks/install 1970-01-01 00:00:00 +0000
@@ -1,8 +0,0 @@
1#!/bin/sh -e
2
3PACKAGES="postgresql-client python-psycopg2 language-pack-en"
4juju-log "Installing ${PACKAGES}"
5apt-get -y install -qq ${PACKAGES}
6
7juju-log "Adding ${PWD}/bin to \$PATH"
8sed -e "/^PATH/s|\"\$|:${PWD}/bin\"|g" -i.bak /etc/environment
90
=== target is u'./hooks.py'

Subscribers

People subscribed via source and target branches