Merge lp:~fwereade/pyjuju/late-command-change into lp:pyjuju

Proposed by William Reade
Status: Merged
Merged at revision: 350
Proposed branch: lp:~fwereade/pyjuju/late-command-change
Merge into: lp:pyjuju
Diff against target: 208 lines (+17/-82)
6 files modified
juju/providers/orchestra/launch.py (+2/-40)
juju/providers/orchestra/tests/common.py (+12/-19)
juju/providers/orchestra/tests/data/bootstrap_user_data (+0/-10)
juju/providers/orchestra/tests/data/launch_user_data (+0/-10)
juju/providers/orchestra/tests/test_bootstrap.py (+2/-2)
juju/providers/orchestra/tests/test_launch.py (+1/-1)
To merge this branch: bzr merge lp:~fwereade/pyjuju/late-command-change
Reviewer Review Type Date Requested Status
Gustavo Niemeyer Approve
Review via email: mp+75593@code.launchpad.net

Description of the change

Equivalent to lp:~andreserl/juju/cloud-init-orchestra-lp850260, but with unit tests.

To post a comment you must log in.
Revision history for this message
Andres Rodriguez (andreserl) wrote :

I have tested this with lp:juju and it works as expected. Merging the changes into orchestra in a few moments. Please go ahead and merge this otherwise we would end-up with a released orchestra not working with juju.

Thanks!

Revision history for this message
Andres Rodriguez (andreserl) wrote :

Fixes into orchestra have been committed. Waiting on juju side to be able to release into Oneiric!

350. By William Reade

merge trunk

351. By William Reade

don't depend on precise yaml output; compare loaded data instead

Revision history for this message
Gustavo Niemeyer (niemeyer) wrote :

This looks great, thanks guys!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'juju/providers/orchestra/launch.py'
2--- juju/providers/orchestra/launch.py 2011-09-15 18:50:23 +0000
3+++ juju/providers/orchestra/launch.py 2011-09-16 14:25:15 +0000
4@@ -1,6 +1,4 @@
5 from base64 import b64encode
6-from cStringIO import StringIO
7-from gzip import GzipFile
8
9 from twisted.internet.defer import inlineCallbacks, returnValue
10
11@@ -8,35 +6,6 @@
12
13 from .machine import machine_from_dict
14
15-_LATE_COMMAND_TEMPLATE = """
16-seed_d=/var/lib/cloud/seed/nocloud-net
17-mkdir -p "$seed_d"
18-cat > "$seed_d"/meta-data <<"EOF"
19-instance-id: %s
20-EOF
21-
22-cat > "$seed_d"/user-data <<"EOF"
23-%s
24-EOF
25-"""
26-
27-_KSMETA_LATE_COMMAND_TEMPLATE = (
28- "in-target sh -c '"
29- "f=$1; "
30- "shift; "
31- "echo $0 | base64 --decode | gunzip > $f "
32- "&& chmod u+x $f "
33- "&& $f $*"
34- "' %s /root/late-command")
35-
36-
37-def _base64_gzip(content):
38- gzipped = StringIO()
39- gzip_file = GzipFile(fileobj=gzipped, mode="wb", compresslevel=9)
40- gzip_file.write(content)
41- gzip_file.close()
42- return b64encode(gzipped.getvalue())
43-
44
45 def _ks_meta(**kwargs):
46 return " ".join('%s="%s"' % item for item in kwargs.items())
47@@ -67,17 +36,10 @@
48 cloud_init = self._create_cloud_init(machine_id, zookeepers)
49 cloud_init.set_provider_type("orchestra")
50 cloud_init.set_instance_id_accessor(instance_id)
51- ks_meta = self._build_ks_meta(
52- cloud_init.render(), machine_id, instance_id)
53+ ks_meta = _ks_meta(MACHINE_ID=machine_id,
54+ USER_DATA_BASE64=b64encode(cloud_init.render()))
55
56 yield cobbler.set_on_system(instance_id, "ks_meta", ks_meta)
57 yield cobbler.start_system(instance_id)
58 (info,) = yield cobbler.describe_systems(instance_id)
59 returnValue([machine_from_dict(info)])
60-
61- def _build_ks_meta(self, user_data, machine_id, instance_id):
62- late_command = _LATE_COMMAND_TEMPLATE % (instance_id, user_data)
63- encoded = _base64_gzip(late_command)
64- juju_late_command = _KSMETA_LATE_COMMAND_TEMPLATE % encoded
65- return _ks_meta(
66- MACHINE_ID=machine_id, JUJU_LATE_COMMAND=juju_late_command)
67
68=== modified file 'juju/providers/orchestra/tests/common.py'
69--- juju/providers/orchestra/tests/common.py 2011-09-15 18:50:23 +0000
70+++ juju/providers/orchestra/tests/common.py 2011-09-16 14:25:15 +0000
71@@ -1,10 +1,8 @@
72 from base64 import b64decode
73-from cStringIO import StringIO
74-from gzip import GzipFile
75 import os
76 import re
77 from xmlrpclib import Fault
78-from yaml import dump
79+from yaml import dump, load
80
81 from twisted.internet.defer import fail, succeed
82 from twisted.web.error import Error
83@@ -25,15 +23,10 @@
84 "authorized-keys": "this-is-a-public-key"}
85
86
87-def _extract_late_command(ks_meta_leftover):
88- unpack = re.escape(
89- "in-target sh -c 'f=$1; shift; "
90- "echo $0 | base64 --decode | gunzip > $f && chmod u+x $f && $f $*' ")
91- encoded_re = re.compile(
92- '^JUJU_LATE_COMMAND="%s([^ ]*) /root/late-command"$' % unpack)
93+def _extract_user_data(ks_meta_leftover):
94+ encoded_re = re.compile('^USER_DATA_BASE64="([^ ]*)"$')
95 encoded = encoded_re.match(ks_meta_leftover).group(1)
96- gzipped = b64decode(encoded)
97- return GzipFile(fileobj=StringIO(gzipped)).read()
98+ return load(b64decode(encoded))
99
100
101 class OrchestraTestMixin(object):
102@@ -98,19 +91,19 @@
103 self.proxy_m.callRemote("save_system", "smith", "TOKEN")
104 self.mocker.result(succeed(True))
105
106- def get_verify_ks_meta(self, machine_id, late_command_filename):
107+ def get_verify_ks_meta(self, machine_id, user_data_filename):
108
109 def verify(ks_meta):
110- machine_id_re = re.compile(
111- '([ ]?MACHINE_ID="%s"[ ]?)' % machine_id)
112- self.assertTrue(machine_id_re.match(ks_meta))
113+ seek = '([ ]?MACHINE_ID="%s"[ ]?)' % machine_id
114+ machine_id_re = re.compile(seek)
115+ self.assertTrue(machine_id_re.search(ks_meta))
116 leftover = machine_id_re.sub("", ks_meta)
117- late_command = _extract_late_command(leftover)
118+ user_data = _extract_user_data(leftover)
119
120- expect_path = os.path.join(DATA_DIR, late_command_filename)
121+ expect_path = os.path.join(DATA_DIR, user_data_filename)
122 with open(expect_path) as f:
123- expect_late_command = f.read()
124- self.assertEquals(late_command, expect_late_command)
125+ expect_user_data = load(f.read())
126+ self.assertEquals(user_data, expect_user_data)
127 return True
128 return verify
129
130
131=== renamed file 'juju/providers/orchestra/tests/data/bootstrap_late_command' => 'juju/providers/orchestra/tests/data/bootstrap_user_data'
132--- juju/providers/orchestra/tests/data/bootstrap_late_command 2011-09-16 00:36:31 +0000
133+++ juju/providers/orchestra/tests/data/bootstrap_user_data 2011-09-16 14:25:15 +0000
134@@ -1,11 +1,3 @@
135-
136-seed_d=/var/lib/cloud/seed/nocloud-net
137-mkdir -p "$seed_d"
138-cat > "$seed_d"/meta-data <<"EOF"
139-instance-id: winston-uid
140-EOF
141-
142-cat > "$seed_d"/user-data <<"EOF"
143 #cloud-config
144 apt-update: true
145 apt-upgrade: true
146@@ -23,5 +15,3 @@
147 'JUJU_ZOOKEEPER=localhost:2181 python -m juju.agents.provision -n --logfile=/var/log/juju/provision-agent.log
148 --pidfile=/var/run/juju/provision-agent.pid']
149 ssh_authorized_keys: [this-is-a-public-key]
150-
151-EOF
152
153=== renamed file 'juju/providers/orchestra/tests/data/launch_late_command' => 'juju/providers/orchestra/tests/data/launch_user_data'
154--- juju/providers/orchestra/tests/data/launch_late_command 2011-09-16 00:36:31 +0000
155+++ juju/providers/orchestra/tests/data/launch_user_data 2011-09-16 14:25:15 +0000
156@@ -1,11 +1,3 @@
157-
158-seed_d=/var/lib/cloud/seed/nocloud-net
159-mkdir -p "$seed_d"
160-cat > "$seed_d"/meta-data <<"EOF"
161-instance-id: winston-uid
162-EOF
163-
164-cat > "$seed_d"/user-data <<"EOF"
165 #cloud-config
166 apt-update: true
167 apt-upgrade: true
168@@ -20,5 +12,3 @@
169 /var/log/juju, 'JUJU_MACHINE_ID=42 JUJU_ZOOKEEPER=jennifer:2181 python -m juju.agents.machine
170 -n --logfile=/var/log/juju/machine-agent.log --pidfile=/var/run/juju/machine-agent.pid']
171 ssh_authorized_keys: [this-is-a-public-key]
172-
173-EOF
174
175=== modified file 'juju/providers/orchestra/tests/test_bootstrap.py'
176--- juju/providers/orchestra/tests/test_bootstrap.py 2011-09-15 18:50:23 +0000
177+++ juju/providers/orchestra/tests/test_bootstrap.py 2011-09-16 14:25:15 +0000
178@@ -67,7 +67,7 @@
179 self.mock_get_systems()
180 self.mock_acquire_system()
181 self.mock_set_ks_meta(
182- self.get_verify_ks_meta(0, "bootstrap_late_command"), **kwargs)
183+ self.get_verify_ks_meta(0, "bootstrap_user_data"), **kwargs)
184 self.mocker.replay()
185 d = self.get_provider().bootstrap()
186 self.assertFailure(d, ProviderError)
187@@ -85,7 +85,7 @@
188 self.mock_get_systems()
189 self.mock_acquire_system()
190 self.mock_set_ks_meta(
191- self.get_verify_ks_meta(0, "bootstrap_late_command"))
192+ self.get_verify_ks_meta(0, "bootstrap_user_data"))
193 self.mock_start_system()
194 self.mock_describe_systems(succeed([{
195 "uid": "winston-uid",
196
197=== modified file 'juju/providers/orchestra/tests/test_launch.py'
198--- juju/providers/orchestra/tests/test_launch.py 2011-09-15 18:50:23 +0000
199+++ juju/providers/orchestra/tests/test_launch.py 2011-09-16 14:25:15 +0000
200@@ -68,7 +68,7 @@
201 self.mock_get_systems()
202 self.mock_acquire_system()
203 self.mock_set_ks_meta(
204- self.get_verify_ks_meta(42, "launch_late_command"))
205+ self.get_verify_ks_meta(42, "launch_user_data"))
206 self.mock_start_system()
207 self.mock_describe_systems(succeed([{
208 "uid": "winston-uid",

Subscribers

People subscribed via source and target branches

to status/vote changes: