Merge lp:~hazmat/pyjuju/local-origin-passthrough into lp:pyjuju

Proposed by Kapil Thangavelu
Status: Superseded
Proposed branch: lp:~hazmat/pyjuju/local-origin-passthrough
Merge into: lp:pyjuju
Diff against target: 790 lines (+383/-39)
24 files modified
docs/source/provider-configuration-ec2.rst (+9/-3)
juju/lib/lxc/data/juju-create (+3/-3)
juju/providers/common/cloudinit.py (+78/-2)
juju/providers/common/launch.py (+9/-2)
juju/providers/common/tests/data/cloud_init_bootstrap (+0/-2)
juju/providers/common/tests/data/cloud_init_bootstrap_zookeepers (+0/-2)
juju/providers/common/tests/data/cloud_init_branch_trunk (+17/-0)
juju/providers/common/tests/data/cloud_init_normal (+0/-2)
juju/providers/common/tests/data/cloud_init_ppa (+15/-0)
juju/providers/common/tests/test_cloudinit.py (+109/-3)
juju/providers/ec2/tests/common.py (+1/-0)
juju/providers/ec2/tests/data/bootstrap_cloud_init (+0/-2)
juju/providers/ec2/tests/data/launch_cloud_init (+0/-2)
juju/providers/ec2/tests/data/launch_cloud_init_branch (+20/-0)
juju/providers/ec2/tests/data/launch_cloud_init_ppa (+15/-0)
juju/providers/ec2/tests/test_bootstrap.py (+1/-0)
juju/providers/ec2/tests/test_launch.py (+60/-2)
juju/providers/local/agent.py (+5/-3)
juju/providers/local/tests/test_agent.py (+1/-0)
juju/providers/orchestra/tests/common.py (+3/-1)
juju/providers/orchestra/tests/data/bootstrap_user_data (+0/-2)
juju/providers/orchestra/tests/data/launch_user_data (+0/-2)
juju/state/relation.py (+19/-3)
juju/state/tests/test_relation.py (+18/-3)
To merge this branch: bzr merge lp:~hazmat/pyjuju/local-origin-passthrough
Reviewer Review Type Date Requested Status
Juju Engineering Pending
Review via email: mp+77644@code.launchpad.net

This proposal has been superseded by a proposal from 2011-09-30.

Description of the change

Local provider should respect juju-origin

Minor fixes to pass juju origin to the machine agent, and to juju-create
to utilize jujuorigin for lp branch names.

To post a comment you must log in.
411. By Kapil Thangavelu

use default origin util func if none specified

412. By Kapil Thangavelu

Merged unit-relation-with-addr into local-origin-passthrough.

413. By Kapil Thangavelu

fix some local provider problems

414. By Kapil Thangavelu

unit container deploy pulls origin from environment

415. By Kapil Thangavelu

log master container customization for foresenic analysis, various sundry fixes for juju-origin in a container

416. By Kapil Thangavelu

add python-yaml dep for branch installs, and switch address map s/lxc/local

417. By Kapil Thangavelu

fix up customize log test

418. By Kapil Thangavelu

merge pipeline, resolve conflict

Unmerged revisions

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'docs/source/provider-configuration-ec2.rst'
2--- docs/source/provider-configuration-ec2.rst 2011-09-15 17:41:55 +0000
3+++ docs/source/provider-configuration-ec2.rst 2011-09-30 05:02:23 +0000
4@@ -24,9 +24,15 @@
5 An S3 bucket unique to the environment, where some runtime metadata and
6 charms are stored.
7
8- juju-branch:
9- Allow a juju bzr branch to be utilized for all machines within an
10- environment.
11+ juju-origin:
12+ Defines where juju should be obtained for installing in
13+ machines. Can be set to a "lp:..." branch url, to "ppa" for
14+ getting packages from the official juju PPA, or to "distro"
15+ for using packages from the official Ubuntu repositories.
16+
17+ If this option is not set, juju will attempt to detect the
18+ correct origin based on its run location and the installed
19+ juju package.
20
21 default-instance-type:
22 The instance type to be used for machines launched within the juju
23
24=== modified file 'juju/lib/lxc/data/juju-create'
25--- juju/lib/lxc/data/juju-create 2011-09-30 01:57:00 +0000
26+++ juju/lib/lxc/data/juju-create 2011-09-30 05:02:23 +0000
27@@ -69,7 +69,7 @@
28
29 if [ $JUJU_ORIGIN = "ppa" ]; then
30 echo "Using juju PPA for container"
31- elif [ $JUJU_ORIGIN = "branch" ]; then
32+ elif [[ $JUJU_ORIGIN == lp:* ]]; then
33 echo "Using juju Branch $JUJU_SOURCE"
34 elif [ $JUJU_ORIGIN = "distro" ]; then
35 echo "Using juju distribution packages"
36@@ -87,10 +87,10 @@
37 echo y | apt-add-repository ppa:juju/pkgs
38 apt-get update
39 apt-get install --force-yes -y juju python-txzookeeper
40- elif [ $JUJU_ORIGIN = "branch" ]; then
41+ elif [[ $JUJU_ORIGIN = lp:* ]]; then
42 apt-get install --force-yes -y python-txzookeeper
43 mkdir /usr/lib/juju
44- bzr branch $JUJU_SOURCE /usr/lib/juju/juju
45+ bzr branch $JUJU_ORIGIN /usr/lib/juju/juju
46 bash -c "cd /usr/lib/juju/juju && sudo python setup.py develop"
47 elif [ $JUJU_ORIGIN = "distro" ]; then
48 apt-get install --force-yes -y juju python-txzookeeper
49
50=== modified file 'juju/providers/common/cloudinit.py'
51--- juju/providers/common/cloudinit.py 2011-09-23 20:35:02 +0000
52+++ juju/providers/common/cloudinit.py 2011-09-30 05:02:23 +0000
53@@ -1,3 +1,5 @@
54+from subprocess import Popen, PIPE
55+
56 from juju.errors import CloudInitError
57 from juju.providers.common.utils import format_cloud_init
58 from juju.state.auth import make_identity
59@@ -54,6 +56,80 @@
60 % zookeeper_hosts]
61
62
63+def _get_apt_cache_policy():
64+ return Popen(["apt-cache", "policy", "juju"], stdout=PIPE).\
65+ communicate()[0]
66+
67+
68+def _parse_apt_cache_policy(data):
69+ """Flatten apt-cache policy output to generate (key, value) pairs."""
70+
71+ # Need to parse in two different phases, so set up iterator now
72+ data = iter(data.split("\n"))
73+
74+ # Parse preamble
75+ for row in data:
76+ split = row.split(":", 1)
77+ if len(split) != 2:
78+ yield None, None
79+ k, v = split[0].strip(), split[1].strip()
80+ yield k, v
81+ if k == "Version table":
82+ break
83+
84+ # Parse version table into tag, priorities
85+ tag = None
86+ for row in data:
87+ row = row.strip()
88+ if row.startswith("***"):
89+ tag = row
90+ elif tag:
91+ yield tag, row
92+
93+
94+def parse_juju_origin(data):
95+ """Parse output of apt-cache to determine how juju was installed."""
96+ parse = _parse_apt_cache_policy(data)
97+ k, _ = parse.next()
98+ if k != "juju":
99+ # Sanity check: no record at all, the only possibility is that
100+ # this being run as a branch
101+ return "branch", "lp:juju"
102+
103+ version = None
104+ for k, v in parse:
105+ if k == "Installed":
106+ if v == "(none)":
107+ return "branch", "lp:juju"
108+ version = v
109+ if k == "Version table":
110+ break
111+
112+ for tag, priority in parse:
113+ if (version in tag and
114+ "http://ppa.launchpad.net/juju/pkgs/" in priority):
115+ return "ppa", None
116+
117+ return "distro", None
118+
119+
120+def _get_default_origin():
121+ """Select the best fit for running juju on cloudinit.
122+
123+ Used if not otherwise specified by juju-origin.
124+ """
125+ import juju
126+ if not juju.__file__.startswith("/usr/"):
127+ return "lp:juju"
128+ origin, source = parse_juju_origin(_get_apt_cache_policy())
129+ if origin == "branch":
130+ return source
131+ elif origin == "ppa":
132+ return _PPA
133+ else:
134+ return _DISTRO
135+
136+
137 class CloudInit(object):
138 """Encapsulates juju-specific machine initialisation.
139
140@@ -65,7 +141,7 @@
141 self._machine_id = None
142 self._instance_id = None
143 self._provider_type = None
144- self._source = _PPA
145+ self._source = _get_default_origin()
146 self._ssh_keys = []
147 self._provision = False
148 self._zookeeper = False
149@@ -103,7 +179,7 @@
150 or fewer than one options, are specified.
151
152 Note that you don't need to call this method; the juju source
153- defaults to the juju PPA.
154+ defaults to what is returned by `get_default_origin`.
155 """
156 if len(filter(None, (branch, ppa, distro))) != 1:
157 raise CloudInitError("Please specify one source")
158
159=== modified file 'juju/providers/common/launch.py'
160--- juju/providers/common/launch.py 2011-09-22 13:23:00 +0000
161+++ juju/providers/common/launch.py 2011-09-30 05:02:23 +0000
162@@ -76,8 +76,15 @@
163 cloud_init.add_ssh_key(get_user_authorized_keys(config))
164 cloud_init.set_machine_id(machine_id)
165 cloud_init.set_zookeeper_machines(zookeepers)
166- if config.get("juju-branch"):
167- cloud_init.set_juju_source(config["juju-branch"])
168+ origin = config.get("juju-origin")
169+ if origin:
170+ if origin.startswith("lp:"):
171+ cloud_init.set_juju_source(branch=origin)
172+ elif origin == "ppa":
173+ cloud_init.set_juju_source(ppa=True)
174+ else:
175+ # Ignore other values, just use the distro for sanity
176+ cloud_init.set_juju_source(distro=True)
177 if self._master:
178 cloud_init.enable_bootstrap()
179 cloud_init.set_zookeeper_secret(config["admin-secret"])
180
181=== modified file 'juju/providers/common/tests/data/cloud_init_bootstrap'
182--- juju/providers/common/tests/data/cloud_init_bootstrap 2011-09-23 20:35:02 +0000
183+++ juju/providers/common/tests/data/cloud_init_bootstrap 2011-09-30 05:02:23 +0000
184@@ -1,8 +1,6 @@
185 #cloud-config
186 apt-update: true
187 apt-upgrade: true
188-apt_sources:
189-- {source: 'ppa:juju/pkgs'}
190 machine-data: {juju-provider-type: dummy, juju-zookeeper-hosts: 'localhost:2181',
191 machine-id: passport}
192 output: {all: '| tee -a /var/log/cloud-init-output.log'}
193
194=== modified file 'juju/providers/common/tests/data/cloud_init_bootstrap_zookeepers'
195--- juju/providers/common/tests/data/cloud_init_bootstrap_zookeepers 2011-09-23 20:35:02 +0000
196+++ juju/providers/common/tests/data/cloud_init_bootstrap_zookeepers 2011-09-30 05:02:23 +0000
197@@ -1,8 +1,6 @@
198 #cloud-config
199 apt-update: true
200 apt-upgrade: true
201-apt_sources:
202-- {source: 'ppa:juju/pkgs'}
203 machine-data: {juju-provider-type: dummy, juju-zookeeper-hosts: 'cotswold:2181,longleat:2181,localhost:2181',
204 machine-id: passport}
205 output: {all: '| tee -a /var/log/cloud-init-output.log'}
206
207=== added file 'juju/providers/common/tests/data/cloud_init_branch_trunk'
208--- juju/providers/common/tests/data/cloud_init_branch_trunk 1970-01-01 00:00:00 +0000
209+++ juju/providers/common/tests/data/cloud_init_branch_trunk 2011-09-30 05:02:23 +0000
210@@ -0,0 +1,17 @@
211+#cloud-config
212+apt-update: true
213+apt-upgrade: true
214+apt_sources:
215+- {source: 'ppa:juju/pkgs'}
216+machine-data: {juju-provider-type: dummy, juju-zookeeper-hosts: 'cotswold:2181,longleat:2181',
217+ machine-id: passport}
218+output: {all: '| tee -a /var/log/cloud-init-output.log'}
219+packages: [bzr, byobu, tmux, python-setuptools, python-twisted, python-argparse, python-txaws,
220+ python-zookeeper]
221+runcmd: [sudo apt-get install -y python-txzookeeper, sudo mkdir -p /usr/lib/juju,
222+ 'cd /usr/lib/juju && sudo /usr/bin/bzr co lp:juju juju',
223+ cd /usr/lib/juju/juju && sudo python setup.py develop, sudo mkdir -p /var/lib/juju,
224+ sudo mkdir -p /var/log/juju, 'JUJU_MACHINE_ID=passport JUJU_ZOOKEEPER=cotswold:2181,longleat:2181
225+ python -m juju.agents.machine -n --logfile=/var/log/juju/machine-agent.log
226+ --pidfile=/var/run/juju/machine-agent.pid']
227+ssh_authorized_keys: [chubb]
228
229=== modified file 'juju/providers/common/tests/data/cloud_init_normal'
230--- juju/providers/common/tests/data/cloud_init_normal 2011-09-15 19:29:57 +0000
231+++ juju/providers/common/tests/data/cloud_init_normal 2011-09-30 05:02:23 +0000
232@@ -1,8 +1,6 @@
233 #cloud-config
234 apt-update: true
235 apt-upgrade: true
236-apt_sources:
237-- {source: 'ppa:juju/pkgs'}
238 machine-data: {juju-provider-type: dummy, juju-zookeeper-hosts: 'cotswold:2181,longleat:2181',
239 machine-id: passport}
240 output: {all: '| tee -a /var/log/cloud-init-output.log'}
241
242=== added file 'juju/providers/common/tests/data/cloud_init_ppa'
243--- juju/providers/common/tests/data/cloud_init_ppa 1970-01-01 00:00:00 +0000
244+++ juju/providers/common/tests/data/cloud_init_ppa 2011-09-30 05:02:23 +0000
245@@ -0,0 +1,15 @@
246+#cloud-config
247+apt-update: true
248+apt-upgrade: true
249+apt_sources:
250+- {'source': 'ppa:juju/pkgs'}
251+machine-data: {juju-provider-type: dummy, juju-zookeeper-hosts: 'cotswold:2181,longleat:2181',
252+ machine-id: passport}
253+output: {all: '| tee -a /var/log/cloud-init-output.log'}
254+packages: [bzr, byobu, tmux, python-setuptools, python-twisted, python-argparse, python-txaws,
255+ python-zookeeper]
256+runcmd: [sudo apt-get -y install juju, sudo mkdir -p /var/lib/juju, sudo mkdir
257+ -p /var/log/juju, 'JUJU_MACHINE_ID=passport JUJU_ZOOKEEPER=cotswold:2181,longleat:2181
258+ python -m juju.agents.machine -n --logfile=/var/log/juju/machine-agent.log
259+ --pidfile=/var/run/juju/machine-agent.pid']
260+ssh_authorized_keys: [chubb]
261
262=== modified file 'juju/providers/common/tests/test_cloudinit.py'
263--- juju/providers/common/tests/test_cloudinit.py 2011-09-22 13:23:00 +0000
264+++ juju/providers/common/tests/test_cloudinit.py 2011-09-30 05:02:23 +0000
265@@ -1,12 +1,14 @@
266 import os
267+import stat
268
269 import yaml
270
271 from juju.errors import CloudInitError
272 from juju.lib.testing import TestCase
273-from juju.providers.common.cloudinit import CloudInit
274+from juju.providers.common.cloudinit import CloudInit, parse_juju_origin
275 from juju.providers.dummy import DummyMachine
276
277+
278 DATA_DIR = os.path.join(os.path.abspath(os.path.dirname(__file__)), "data")
279
280
281@@ -30,6 +32,7 @@
282 cloud_init.set_provider_type("dummy")
283 cloud_init.set_instance_id_accessor("token")
284 cloud_init.set_zookeeper_secret("seekrit")
285+ cloud_init.set_juju_source(distro=True)
286 if with_zookeepers:
287 cloud_init.set_zookeeper_machines([
288 DummyMachine("blah", "blah", "cotswold"),
289@@ -74,12 +77,34 @@
290 self.assertEquals(str(error), "Please specify one source")
291
292 def test_render_normal(self):
293- self.assert_render(self.construct_normal(), "cloud_init_normal")
294+ path = os.environ.get("PATH", "")
295+ alt_apt_cache_path = self.makeDir()
296+ filename = os.path.join(alt_apt_cache_path, "apt-cache")
297+ with open(filename, "w") as f:
298+ f.write(
299+ "#!/bin/bash\n"
300+ "cat <<EOF\n"
301+ "juju:\n"
302+ " Installed: good-magic-1.0\n"
303+ " Candidate: good-magic-1.0\n"
304+ " Version table:\n"
305+ " *** good-magic-1.0\n"
306+ " 500 http://us.archive.ubuntu.com/ubuntu/ "
307+ "natty/main amd64 Packages\n"
308+ " 100 /var/lib/dpkg/status\n"
309+ "EOF\n")
310+ os.chmod(filename, stat.S_IEXEC | stat.S_IREAD)
311+ updated_path = alt_apt_cache_path + ":" + path
312+ self.change_environment(PATH=updated_path)
313+ import juju
314+ self.patch(juju, "__file__",
315+ "/usr/lib/pymodules/python2.7/juju/__init__.pyc")
316+ self.assert_render(self.construct_normal(), "cloud_init_distro")
317
318 def test_render_ppa_source(self):
319 cloud_init = self.construct_normal()
320 cloud_init.set_juju_source(ppa=True)
321- self.assert_render(cloud_init, "cloud_init_normal")
322+ self.assert_render(cloud_init, "cloud_init_ppa")
323
324 def test_render_distro_source(self):
325 cloud_init = self.construct_normal()
326@@ -91,9 +116,90 @@
327 cloud_init.set_juju_source(branch="lp:blah/juju/blah-blah")
328 self.assert_render(cloud_init, "cloud_init_branch")
329
330+ def test_render_branch_source_if_not_installed(self):
331+ import juju
332+ self.patch(juju, "__file__", "/not/installed/under/usr")
333+ cloud_init = self.construct_normal()
334+ self.assert_render(cloud_init, "cloud_init_branch_trunk")
335+
336 def test_render_bootstrap(self):
337 self.assert_render(self.construct_bootstrap(), "cloud_init_bootstrap")
338
339 def test_render_bootstrap_with_zookeepers(self):
340 self.assert_render(
341 self.construct_bootstrap(True), "cloud_init_bootstrap_zookeepers")
342+
343+
344+class ParseJujuOriginTest(TestCase):
345+
346+ def test_distro_installed(self):
347+ data = (
348+ "juju:\n"
349+ " Installed: good-magic-1.0\n"
350+ " Candidate: good-magic-1.0\n"
351+ " Version table:\n"
352+ " *** good-magic-1.0 0\n"
353+ " 500 http://us.archive.ubuntu.com/ubuntu/ "
354+ "natty/main amd64 Packages\n"
355+ " 100 /var/lib/dpkg/status\n")
356+
357+ origin, source = parse_juju_origin(data)
358+ self.assertEqual(origin, "distro")
359+ self.assertEqual(source, None)
360+
361+ def test_multiple_versions_available(self):
362+ data = (
363+ "juju:\n"
364+ " Installed: 0.5+bzr366-1juju1~natty1\n"
365+ " Candidate: 0.5+bzr366-1juju1~natty1\n"
366+ " Version table:\n"
367+ " *** bad-magic-0.5 0\n"
368+ " 500 http://us.archive.ubuntu.com/ubuntu/ "
369+ "natty/main amd64 Packages\n"
370+ " 100 /var/lib/dpkg/status\n"
371+ " *** 0.5+bzr366-1juju1~natty1 0\n"
372+ " 500 http://ppa.launchpad.net/juju/pkgs/ubuntu/ "
373+ "natty/main amd64 Packages\n"
374+ " *** 0.5+bzr356-1juju1~natty1 0\n"
375+ " 500 http://ppa.launchpad.net/juju/pkgs/ubuntu/ "
376+ "natty/main amd64 Packages\n")
377+
378+ origin, source = parse_juju_origin(data)
379+ self.assertEqual(origin, "ppa")
380+ self.assertEqual(source, None)
381+
382+ def test_distro_not_installed(self):
383+ data = (
384+ "juju:\n"
385+ " Installed: (none)\n"
386+ " Candidate: good-magic-1.0\n"
387+ " Version table:\n"
388+ " *** good-magic-1.0 0\n"
389+ " 500 http://us.archive.ubuntu.com/ubuntu/ "
390+ "natty/main amd64 Packages\n"
391+ " 100 /var/lib/dpkg/status\n")
392+
393+ origin, source = parse_juju_origin(data)
394+ self.assertEqual(origin, "branch")
395+ self.assertEqual(source, "lp:juju")
396+
397+ def test_ppa_installed(self):
398+ data = (
399+ "juju:\n"
400+ " Installed: 0.5+bzr356-1juju1~natty1\n"
401+ " Candidate: 0.5+bzr356-1juju1~natty1\n"
402+ " Version table:\n"
403+ " *** 0.5+bzr356-1juju1~natty1 0\n"
404+ " 500 http://ppa.launchpad.net/juju/pkgs/ubuntu/ "
405+ "natty/main amd64 Packages\n"
406+ " 100 /var/lib/dpkg/status\n")
407+
408+ origin, source = parse_juju_origin(data)
409+ self.assertEqual(origin, "ppa")
410+ self.assertEqual(source, None)
411+
412+ def test_juju_package_is_unknown(self):
413+ data = "N: Unable to locate package juju"
414+ origin, source = parse_juju_origin(data)
415+ self.assertEqual(origin, "branch")
416+ self.assertEqual(source, "lp:juju")
417
418=== modified file 'juju/providers/ec2/tests/common.py'
419--- juju/providers/ec2/tests/common.py 2011-09-22 13:23:00 +0000
420+++ juju/providers/ec2/tests/common.py 2011-09-30 05:02:23 +0000
421@@ -22,6 +22,7 @@
422
423 def get_config(self):
424 return {"type": "ec2",
425+ "juju-origin": "distro",
426 "admin-secret": "magic-beans",
427 "access-key": "0f62e973d5f8",
428 "secret-key": "3e5a7c653f59",
429
430=== modified file 'juju/providers/ec2/tests/data/bootstrap_cloud_init'
431--- juju/providers/ec2/tests/data/bootstrap_cloud_init 2011-09-23 20:35:02 +0000
432+++ juju/providers/ec2/tests/data/bootstrap_cloud_init 2011-09-30 05:02:23 +0000
433@@ -1,8 +1,6 @@
434 #cloud-config
435 apt-update: true
436 apt-upgrade: true
437-apt_sources:
438-- {source: 'ppa:juju/pkgs'}
439 machine-data: {juju-provider-type: ec2, juju-zookeeper-hosts: 'localhost:2181',
440 machine-id: '0'}
441 output: {all: '| tee -a /var/log/cloud-init-output.log'}
442
443=== modified file 'juju/providers/ec2/tests/data/launch_cloud_init'
444--- juju/providers/ec2/tests/data/launch_cloud_init 2011-09-15 19:29:57 +0000
445+++ juju/providers/ec2/tests/data/launch_cloud_init 2011-09-30 05:02:23 +0000
446@@ -1,8 +1,6 @@
447 #cloud-config
448 apt-update: true
449 apt-upgrade: true
450-apt_sources:
451-- {source: 'ppa:juju/pkgs'}
452 machine-data: {juju-provider-type: ec2, juju-zookeeper-hosts: 'es.example.internal:2181',
453 machine-id: '1'}
454 output: {all: '| tee -a /var/log/cloud-init-output.log'}
455
456=== added file 'juju/providers/ec2/tests/data/launch_cloud_init_branch'
457--- juju/providers/ec2/tests/data/launch_cloud_init_branch 1970-01-01 00:00:00 +0000
458+++ juju/providers/ec2/tests/data/launch_cloud_init_branch 2011-09-30 05:02:23 +0000
459@@ -0,0 +1,20 @@
460+#cloud-config
461+apt-update: true
462+apt-upgrade: true
463+apt_sources:
464+- {source: 'ppa:juju/pkgs'}
465+machine-data: {juju-provider-type: ec2, juju-zookeeper-hosts: 'es.example.internal:2181',
466+ machine-id: '1'}
467+output: {all: '| tee -a /var/log/cloud-init-output.log'}
468+packages: [bzr, byobu, tmux, python-setuptools, python-twisted, python-argparse, python-txaws,
469+ python-zookeeper]
470+runcmd: [sudo apt-get install -y python-txzookeeper,
471+ sudo mkdir -p /usr/lib/juju,
472+ 'cd /usr/lib/juju && sudo /usr/bin/bzr co lp:~wizard/juju-juicebar juju',
473+ cd /usr/lib/juju/juju && sudo python setup.py develop,
474+ sudo mkdir -p /var/lib/juju,
475+ sudo mkdir -p /var/log/juju,
476+ 'JUJU_MACHINE_ID=1 JUJU_ZOOKEEPER=es.example.internal:2181
477+ python -m juju.agents.machine -n --logfile=/var/log/juju/machine-agent.log
478+ --pidfile=/var/run/juju/machine-agent.pid']
479+ssh_authorized_keys: [zebra]
480
481=== added file 'juju/providers/ec2/tests/data/launch_cloud_init_ppa'
482--- juju/providers/ec2/tests/data/launch_cloud_init_ppa 1970-01-01 00:00:00 +0000
483+++ juju/providers/ec2/tests/data/launch_cloud_init_ppa 2011-09-30 05:02:23 +0000
484@@ -0,0 +1,15 @@
485+#cloud-config
486+apt-update: true
487+apt-upgrade: true
488+apt_sources:
489+- {source: 'ppa:juju/pkgs'}
490+machine-data: {juju-provider-type: ec2, juju-zookeeper-hosts: 'es.example.internal:2181',
491+ machine-id: '1'}
492+output: {all: '| tee -a /var/log/cloud-init-output.log'}
493+packages: [bzr, byobu, tmux, python-setuptools, python-twisted, python-argparse, python-txaws,
494+ python-zookeeper]
495+runcmd: [sudo apt-get -y install juju, sudo mkdir -p /var/lib/juju, sudo mkdir
496+ -p /var/log/juju, 'JUJU_MACHINE_ID=1 JUJU_ZOOKEEPER=es.example.internal:2181
497+ python -m juju.agents.machine -n --logfile=/var/log/juju/machine-agent.log
498+ --pidfile=/var/run/juju/machine-agent.pid']
499+ssh_authorized_keys: [zebra]
500
501=== modified file 'juju/providers/ec2/tests/test_bootstrap.py'
502--- juju/providers/ec2/tests/test_bootstrap.py 2011-09-22 13:23:00 +0000
503+++ juju/providers/ec2/tests/test_bootstrap.py 2011-09-30 05:02:23 +0000
504@@ -13,6 +13,7 @@
505
506 from .common import EC2TestMixin, EC2MachineLaunchMixin
507
508+
509 DATA_DIR = os.path.join(os.path.abspath(os.path.dirname(__file__)), "data")
510
511
512
513=== modified file 'juju/providers/ec2/tests/test_launch.py'
514--- juju/providers/ec2/tests/test_launch.py 2011-09-16 00:36:31 +0000
515+++ juju/providers/ec2/tests/test_launch.py 2011-09-30 05:02:23 +0000
516@@ -21,10 +21,11 @@
517 class EC2MachineLaunchTest(EC2TestMixin, EC2MachineLaunchMixin, TestCase):
518
519 def _mock_launch(self, instance, expect_ami="ami-default",
520- expect_instance_type="m1.small"):
521+ expect_instance_type="m1.small",
522+ cloud_init="launch_cloud_init"):
523
524 def verify_user_data(data):
525- expect_path = os.path.join(DATA_DIR, "launch_cloud_init")
526+ expect_path = os.path.join(DATA_DIR, cloud_init)
527 with open(expect_path) as f:
528 expect_cloud_init = yaml.load(f.read())
529 self.assertEquals(yaml.load(data), expect_cloud_init)
530@@ -75,6 +76,63 @@
531 return d
532
533 @inlineCallbacks
534+ def test_provider_launch_using_branch(self):
535+ """Can use a juju branch to launch a machine"""
536+ self.ec2.describe_security_groups()
537+ self.mocker.result(succeed([]))
538+ self._mock_create_group()
539+ self._mock_create_machine_group("1")
540+ self._mock_launch_utils(region="us-east-1")
541+ self._mock_get_zookeeper_hosts()
542+ self._mock_launch(
543+ self.get_instance("i-foobar"),
544+ cloud_init="launch_cloud_init_branch")
545+ self.mocker.replay()
546+
547+ provider = self.get_provider()
548+ provider.config["juju-origin"] = "lp:~wizard/juju-juicebar"
549+ machines = yield provider.start_machine({"machine-id": "1"})
550+ self.assert_machine(machines[0], "i-foobar", "")
551+
552+ @inlineCallbacks
553+ def test_provider_launch_using_ppa(self):
554+ """Can use the juju ppa to launch a machine"""
555+ self.ec2.describe_security_groups()
556+ self.mocker.result(succeed([]))
557+ self._mock_create_group()
558+ self._mock_create_machine_group("1")
559+ self._mock_launch_utils(region="us-east-1")
560+ self._mock_get_zookeeper_hosts()
561+ self._mock_launch(
562+ self.get_instance("i-foobar"),
563+ cloud_init="launch_cloud_init_ppa")
564+ self.mocker.replay()
565+
566+ provider = self.get_provider()
567+ provider.config["juju-origin"] = "ppa"
568+ machines = yield provider.start_machine({"machine-id": "1"})
569+ self.assert_machine(machines[0], "i-foobar", "")
570+
571+ @inlineCallbacks
572+ def test_provider_launch_using_explicit_distro(self):
573+ """Can set juju-origin explicitly to `distro`"""
574+ self.ec2.describe_security_groups()
575+ self.mocker.result(succeed([]))
576+ self._mock_create_group()
577+ self._mock_create_machine_group("1")
578+ self._mock_launch_utils(region="us-east-1")
579+ self._mock_get_zookeeper_hosts()
580+ self._mock_launch(
581+ self.get_instance("i-foobar"),
582+ cloud_init="launch_cloud_init")
583+ self.mocker.replay()
584+
585+ provider = self.get_provider()
586+ provider.config["juju-origin"] = "distro"
587+ machines = yield provider.start_machine({"machine-id": "1"})
588+ self.assert_machine(machines[0], "i-foobar", "")
589+
590+ @inlineCallbacks
591 def test_provider_launch_existing_security_group(self):
592 """Verify that the launch works if the env security group exists"""
593 instance = Instance("i-foobar", "running", dns_name="x1.example.com")
594
595=== modified file 'juju/providers/local/agent.py'
596--- juju/providers/local/agent.py 2011-09-27 16:51:50 +0000
597+++ juju/providers/local/agent.py 2011-09-30 05:02:23 +0000
598@@ -15,8 +15,7 @@
599 def __init__(
600 self, pid_file, zookeeper_hosts=None, machine_id="0",
601 log_file=None, juju_directory="/var/lib/juju",
602- juju_unit_namespace="",
603- public_key=None):
604+ juju_unit_namespace="", public_key=None, juju_origin="ppa"):
605 """
606 :param pid_file: Path to file used to store process id.
607 :param machine_id: machine id for the local machine.
608@@ -37,6 +36,7 @@
609 self._juju_unit_namespace = juju_unit_namespace
610 self._log_file = log_file
611 self._public_key = public_key
612+ self._juju_origin = juju_origin
613
614 @inlineCallbacks
615 def start(self):
616@@ -51,6 +51,7 @@
617 # to the command.
618 args = ["sudo",
619 "JUJU_ZOOKEEPER=%s" % self._zookeeper_hosts,
620+ "JUJU_ORIGIN=%s" % self._juju_origin,
621 "JUJU_MACHINE_ID=%s" % self._machine_id,
622 "JUJU_HOME=%s" % self._juju_directory,
623 "JUJU_UNIT_NS=%s" % self._juju_unit_namespace,
624@@ -60,7 +61,8 @@
625 "--logfile", self._log_file]
626
627 if self._public_key:
628- args.insert(1, "JUJU_PUBLIC_KEY=%s" % pipes.quote(self._public_key))
629+ args.insert(
630+ 1, "JUJU_PUBLIC_KEY=%s" % pipes.quote(self._public_key))
631
632 yield deferToThread(subprocess.check_call, args)
633
634
635=== modified file 'juju/providers/local/tests/test_agent.py'
636--- juju/providers/local/tests/test_agent.py 2011-09-27 16:51:50 +0000
637+++ juju/providers/local/tests/test_agent.py 2011-09-30 05:02:23 +0000
638@@ -47,6 +47,7 @@
639 dict(JUJU_ZOOKEEPER=get_test_zookeeper_address(),
640 JUJU_MACHINE_ID="0",
641 JUJU_HOME=juju_directory,
642+ JUJU_ORIGIN="ppa",
643 JUJU_UNIT_NS="ns1"))
644
645 @inlineCallbacks
646
647=== modified file 'juju/providers/orchestra/tests/common.py'
648--- juju/providers/orchestra/tests/common.py 2011-09-22 13:23:00 +0000
649+++ juju/providers/orchestra/tests/common.py 2011-09-30 05:02:23 +0000
650@@ -13,7 +13,9 @@
651
652 DATA_DIR = os.path.join(os.path.abspath(os.path.dirname(__file__)), "data")
653
654-CONFIG = {"orchestra-server": "somewhe.re",
655+CONFIG = {"type": "orchestra",
656+ "juju-origin": "distro",
657+ "orchestra-server": "somewhe.re",
658 "orchestra-user": "user",
659 "orchestra-pass": "pass",
660 "acquired-mgmt-class": "acquired",
661
662=== modified file 'juju/providers/orchestra/tests/data/bootstrap_user_data'
663--- juju/providers/orchestra/tests/data/bootstrap_user_data 2011-09-23 20:35:02 +0000
664+++ juju/providers/orchestra/tests/data/bootstrap_user_data 2011-09-30 05:02:23 +0000
665@@ -1,8 +1,6 @@
666 #cloud-config
667 apt-update: true
668 apt-upgrade: true
669-apt_sources:
670-- {source: 'ppa:juju/pkgs'}
671 machine-data: {juju-provider-type: orchestra, juju-zookeeper-hosts: 'localhost:2181',
672 machine-id: '0'}
673 output: {all: '| tee -a /var/log/cloud-init-output.log'}
674
675=== modified file 'juju/providers/orchestra/tests/data/launch_user_data'
676--- juju/providers/orchestra/tests/data/launch_user_data 2011-09-16 14:07:03 +0000
677+++ juju/providers/orchestra/tests/data/launch_user_data 2011-09-30 05:02:23 +0000
678@@ -1,8 +1,6 @@
679 #cloud-config
680 apt-update: true
681 apt-upgrade: true
682-apt_sources:
683-- {source: 'ppa:juju/pkgs'}
684 machine-data: {juju-provider-type: orchestra, juju-zookeeper-hosts: 'jennifer:2181',
685 machine-id: '42'}
686 output: {all: '| tee -a /var/log/cloud-init-output.log'}
687
688=== modified file 'juju/state/relation.py'
689--- juju/state/relation.py 2011-09-15 18:50:23 +0000
690+++ juju/state/relation.py 2011-09-30 05:02:23 +0000
691@@ -218,6 +218,10 @@
692 def add_unit_state(self, unit_state):
693 """Add a unit to the service relation.
694
695+ This api is intended for use by the unit agent, as it
696+ also creates an ephemeral presence node, denoting the
697+ active existance of the unit in the relation.
698+
699 returns a unit relation state.
700 """
701 settings_path = "/relations/%s/settings/%s" % (
702@@ -225,11 +229,23 @@
703
704 # We create settings node first, so that presence node events
705 # have a chance to inspect state.
706+
707+ # Prepopulate the relation node with the node's private address.
708+ private_address = yield unit_state.get_private_address()
709 try:
710- yield self._client.create(settings_path)
711+ yield self._client.create(
712+ settings_path,
713+ yaml.safe_dump({"private-address": private_address}))
714 except zookeeper.NodeExistsException:
715- # previous persistent settings are not an error.
716- pass
717+ # previous persistent settings are not an error, but
718+ # update the unit address
719+ def update_address(content, stat):
720+ unit_map = yaml.load(content)
721+ if not unit_map:
722+ unit_map = {}
723+ unit_map["private-address"] = private_address
724+ return yaml.safe_dump(unit_map)
725+ yield retry_change(self._client, settings_path, update_address)
726
727 # Update the unit name -> id mapping on the relation node
728 def update_unit_mapping(content, stat):
729
730=== modified file 'juju/state/tests/test_relation.py'
731--- juju/state/tests/test_relation.py 2011-09-28 10:38:16 +0000
732+++ juju/state/tests/test_relation.py 2011-09-30 05:02:23 +0000
733@@ -577,6 +577,8 @@
734 self.client.exists_and_watch(settings_path)[1].addCallback(
735 lambda result: append_event("settings", result))
736
737+ yield unit_state.set_private_address("foobar.local")
738+
739 # add the unit agent
740 yield self.service1_relation.add_unit_state(unit_state)
741
742@@ -597,6 +599,10 @@
743 unit_map,
744 {unit_state.internal_id: unit_state.unit_name})
745
746+ content, stat = yield self.client.get(settings_path)
747+ self.assertEqual(
748+ yaml.load(content), {"private-address": "foobar.local"})
749+
750 @inlineCallbacks
751 def test_presence_node_is_ephemeral(self):
752 """
753@@ -648,17 +654,26 @@
754
755 @inlineCallbacks
756 def test_add_unit_state_with_preexisting_settings(self):
757- """A unit coming backup retains its existing settings."""
758+ """A unit coming backup retains its existing settings.
759+
760+ With the exception of the unit address, which is always
761+ kept current on subsequent joinings.
762+ """
763 unit_state = yield self.service_state1.add_unit_state()
764 settings_path = "/relations/%s/settings/%s" % (
765 self.relation_state.internal_id,
766 unit_state.internal_id)
767
768- data = {"hello": "world"}
769+ data = {"hello": "world", "private-address": "foobar.local"}
770 yield self.client.create(settings_path, yaml.dump(data))
771+
772+ yield unit_state.set_private_address("northwest.local")
773 yield self.service1_relation.add_unit_state(unit_state)
774
775 node_data, stat = yield self.client.get(settings_path)
776+
777+ # The unit address has been updated to current
778+ data["private-address"] = "northwest.local"
779 self.assertEqual(node_data, yaml.dump(data))
780
781 data, stat = yield self.client.get(
782@@ -731,7 +746,7 @@
783 unit_relation = states["unit_relation"]
784
785 data = yield unit_relation.get_data()
786- self.assertEqual(data, "")
787+ self.assertEqual(yaml.load(data), {"private-address": None})
788
789 unit_relation_path = self.get_unit_settings_path(states)
790 self.client.set(unit_relation_path, yaml.dump(dict(hello="world")))

Subscribers

People subscribed via source and target branches

to status/vote changes: