Merge lp:~franciscosouza/pyjuju/juju-vpc into lp:pyjuju

Proposed by Francisco Souza
Status: Needs review
Proposed branch: lp:~franciscosouza/pyjuju/juju-vpc
Merge into: lp:pyjuju
Diff against target: 1999 lines (+752/-174)
46 files modified
juju/charm/repository.py (+3/-3)
juju/lib/http_client.py (+74/-0)
juju/machine/__init__.py (+2/-1)
juju/machine/tests/data/test_get_container (+1/-1)
juju/machine/tests/test_unit_deployment.py (+71/-1)
juju/machine/unit.py (+35/-15)
juju/providers/common/cloudinit.py (+35/-13)
juju/providers/common/launch.py (+10/-0)
juju/providers/common/tests/data/cloud_init_bootstrap (+2/-2)
juju/providers/common/tests/data/cloud_init_bootstrap_extra_env (+69/-0)
juju/providers/common/tests/data/cloud_init_bootstrap_zookeepers (+2/-2)
juju/providers/common/tests/data/cloud_init_branch (+1/-1)
juju/providers/common/tests/data/cloud_init_branch_trunk (+1/-1)
juju/providers/common/tests/data/cloud_init_distro (+1/-2)
juju/providers/common/tests/data/cloud_init_image (+35/-0)
juju/providers/common/tests/data/cloud_init_image_extra_env (+39/-0)
juju/providers/common/tests/data/cloud_init_no_machine_id (+2/-2)
juju/providers/common/tests/data/cloud_init_normal (+2/-2)
juju/providers/common/tests/data/cloud_init_ppa (+2/-2)
juju/providers/common/tests/data/cloud_init_ppa_apt_proxy (+2/-2)
juju/providers/common/tests/data/cloud_init_proposed (+1/-1)
juju/providers/common/tests/test_cloudinit.py (+36/-0)
juju/providers/ec2/__init__.py (+3/-2)
juju/providers/ec2/launch.py (+34/-18)
juju/providers/ec2/machine.py (+7/-3)
juju/providers/ec2/securitygroup.py (+36/-20)
juju/providers/ec2/tests/common.py (+13/-12)
juju/providers/ec2/tests/data/bootstrap_cloud_init (+2/-2)
juju/providers/ec2/tests/data/launch_cloud_init (+1/-1)
juju/providers/ec2/tests/data/launch_cloud_init_branch (+1/-1)
juju/providers/ec2/tests/data/launch_cloud_init_ip_address (+35/-0)
juju/providers/ec2/tests/data/launch_cloud_init_ppa (+1/-1)
juju/providers/ec2/tests/test_bootstrap.py (+3/-3)
juju/providers/ec2/tests/test_launch.py (+63/-26)
juju/providers/ec2/tests/test_machine.py (+18/-1)
juju/providers/ec2/tests/test_securitygroup.py (+39/-10)
juju/providers/ec2/tests/test_shutdown.py (+15/-10)
juju/providers/ec2/utils.py (+2/-2)
juju/providers/local/files.py (+2/-2)
juju/providers/orchestra/files.py (+2/-2)
juju/providers/orchestra/tests/data/bootstrap_user_data (+2/-2)
juju/providers/orchestra/tests/data/launch_user_data (+1/-1)
juju/unit/address.py (+13/-2)
juju/unit/charm.py (+2/-2)
juju/unit/deploy.py (+5/-0)
juju/unit/tests/test_address.py (+26/-0)
To merge this branch: bzr merge lp:~franciscosouza/pyjuju/juju-vpc
Reviewer Review Type Date Requested Status
Juju Engineering Pending
Review via email: mp+134169@code.launchpad.net

Description of the change

providers/ec2: support VPC

To use VPC, all the user need to do is add two new environment settings: vpc_id
and subnet_id.

This CL depends on three other CLs (related to txaws):

 - https://codereview.appspot.com/6826065/
 - https://codereview.appspot.com/6822097/
 - https://codereview.appspot.com/6814123/

** NOT FOR MERGE **

https://codereview.appspot.com/6850044/

To post a comment you must log in.
Revision history for this message
Chico (franciscossouza) wrote :

Reviewers: mp+134169_code.launchpad.net,

Message:
Please take a look.

Description:
providers/ec2: support VPC

To use VPC, all the user need to do is add two new environment settings:
vpc_id
and subnet_id.

This CL depends on three other CLs (related to txaws):

  - https://codereview.appspot.com/6826065/
  - https://codereview.appspot.com/6822097/
  - https://codereview.appspot.com/6814123/

https://code.launchpad.net/~franciscosouza/juju/juju-vpc/+merge/134169

(do not edit description out of merge proposal)

Please review this at https://codereview.appspot.com/6850044/

Affected files:
   A [revision details]
   M juju/providers/ec2/launch.py
   M juju/providers/ec2/securitygroup.py
   M juju/providers/ec2/tests/common.py
   M juju/providers/ec2/tests/test_bootstrap.py
   M juju/providers/ec2/tests/test_launch.py
   M juju/providers/ec2/tests/test_securitygroup.py
   M juju/providers/ec2/tests/test_shutdown.py

lp:~franciscosouza/pyjuju/juju-vpc updated
605. By Francisco Souza

provides/ec2: removed unused import

Revision history for this message
Chico (franciscossouza) wrote :
lp:~franciscosouza/pyjuju/juju-vpc updated
606. By Francisco Souza

providers/ec2: record machine private_ip_address (for VPC)

607. By Francisco Souza

machine: support private_ip_address

608. By Francisco Souza

providers/common: added private mode to cloudinit

In private mode, it uses private_ip_address for zookeeper.

609. By Francisco Souza

providers/common: use cloudinit's private mode

610. By Francisco Souza

providers/ec2: update launch with subnet to work in private mode

Revision history for this message
Chico (franciscossouza) wrote :
lp:~franciscosouza/pyjuju/juju-vpc updated
611. By Francisco Souza

providers/ec2: added private mode

Also adapt to new txaws api.

Revision history for this message
Chico (franciscossouza) wrote :
lp:~franciscosouza/pyjuju/juju-vpc updated
612. By Francisco Souza

providers/ec2: don't use group_name on describe_security_groups

I know that sucks, but we need a better solution later.

Revision history for this message
Chico (franciscossouza) wrote :
lp:~franciscosouza/pyjuju/juju-vpc updated
613. By Francisco Souza

cloudinit: added image source

This source should be used when juju comes pre-installed in the machine image.

Revision history for this message
Chico (franciscossouza) wrote :
Revision history for this message
Kapil Thangavelu (hazmat) wrote :

one comment regarding correctness.

https://codereview.appspot.com/6850044/diff/7017/juju/providers/ec2/securitygroup.py
File juju/providers/ec2/securitygroup.py (right):

https://codereview.appspot.com/6850044/diff/7017/juju/providers/ec2/securitygroup.py#newcode11
juju/providers/ec2/securitygroup.py:11: for group in d.result:
This is very suspect, deferred results should not be access directly,
this needs a callback registered or inlineCallbacks syntax.

https://codereview.appspot.com/6850044/

Revision history for this message
Chico (franciscossouza) wrote :

https://codereview.appspot.com/6850044/diff/7017/juju/providers/ec2/securitygroup.py
File juju/providers/ec2/securitygroup.py (right):

https://codereview.appspot.com/6850044/diff/7017/juju/providers/ec2/securitygroup.py#newcode11
juju/providers/ec2/securitygroup.py:11: for group in d.result:
On 2012/11/22 13:44:07, hazmat wrote:
> This is very suspect, deferred results should not be access directly,
this needs
> a callback registered or inlineCallbacks syntax.

Thanks, I will fix this.

I will also stop updating this CL using lbox, so you guys stop receiving
notifications. There is more than VPC in this CL now (proxy,
pre-installed juju, etc.), and we will probably keep using this fork. I
hope that we will be able to send smaller patchs for merging in the
(near) future.

https://codereview.appspot.com/6850044/

Revision history for this message
Kapil Thangavelu (hazmat) wrote :

no worries about using lbox, i don't mind having a look on occasion, i
understood from the merge proposal that it wasn't intended for merge. i've
been going through the txaws branches as well, which look good but i'll
need to rope in one more reviewer for them i think. i'd like to get some
additional functionality there for txaws to be able to create vpc, with a
goal that juju can create the vpc itself. cheers.

On Thu, Nov 22, 2012 at 8:58 AM, <email address hidden> wrote:

>
> https://codereview.appspot.**com/6850044/diff/7017/juju/**
> providers/ec2/securitygroup.py<https://codereview.appspot.com/6850044/diff/7017/juju/providers/ec2/securitygroup.py>
> File juju/providers/ec2/**securitygroup.py (right):
>
> https://codereview.appspot.**com/6850044/diff/7017/juju/**
> providers/ec2/securitygroup.**py#newcode11<https://codereview.appspot.com/6850044/diff/7017/juju/providers/ec2/securitygroup.py#newcode11>
> juju/providers/ec2/**securitygroup.py:11: for group in d.result:
> On 2012/11/22 13:44:07, hazmat wrote:
>
>> This is very suspect, deferred results should not be access directly,
>>
> this needs
>
>> a callback registered or inlineCallbacks syntax.
>>
>
> Thanks, I will fix this.
>
> I will also stop updating this CL using lbox, so you guys stop receiving
> notifications. There is more than VPC in this CL now (proxy,
> pre-installed juju, etc.), and we will probably keep using this fork. I
> hope that we will be able to send smaller patchs for merging in the
> (near) future.
>
> https://codereview.appspot.**com/6850044/<https://codereview.appspot.com/6850044/>
>

Revision history for this message
Chico (franciscossouza) wrote :

On 2012/11/22 14:26:33, hazmat wrote:
> no worries about using lbox, i don't mind having a look on occasion, i
> understood from the merge proposal that it wasn't intended for merge.
i've
> been going through the txaws branches as well, which look good but
i'll
> need to rope in one more reviewer for them i think. i'd like to get
some
> additional functionality there for txaws to be able to create vpc,
with a
> goal that juju can create the vpc itself. cheers.

Indeed. txaws branches are there for merging, I think they're quite
there. Are you able to review and merge them? I'd like to move forward
in getting those branches merged.

Regards,
Francisco

https://codereview.appspot.com/6850044/

lp:~franciscosouza/pyjuju/juju-vpc updated
614. By Francisco Souza

providers/ec2: don't use deferred.result

Revision history for this message
Chico (franciscossouza) wrote :

Please take a look.

https://codereview.appspot.com/6850044/diff/7017/juju/providers/ec2/securitygroup.py
File juju/providers/ec2/securitygroup.py (right):

https://codereview.appspot.com/6850044/diff/7017/juju/providers/ec2/securitygroup.py#newcode11
juju/providers/ec2/securitygroup.py:11: for group in d.result:
On 2012/11/22 13:44:07, hazmat wrote:
> This is very suspect, deferred results should not be access directly,
this needs
> a callback registered or inlineCallbacks syntax.

Done.

https://codereview.appspot.com/6850044/

lp:~franciscosouza/pyjuju/juju-vpc updated
615. By Francisco Souza

providers/common: added extra environment support for cloud init

616. By Francisco Souza

machine: added support for extra environment variables in unit deployment

617. By Francisco Souza

providers/common: launching vms with http and https proxy in upstart file

618. By Francisco Souza

unit/deploy: read http_proxy and https_proxy from os environment

These values are used to add new units, setting http_proxy and https_proxy in
upstart config file.

Revision history for this message
Chico (franciscossouza) wrote :
lp:~franciscosouza/pyjuju/juju-vpc updated
619. By Francisco Souza

providers/common: set extra environment on provision agent too

Revision history for this message
Chico (franciscossouza) wrote :
lp:~franciscosouza/pyjuju/juju-vpc updated
620. By Francisco Souza

lib: added http_client

This will wrap getPage and downloadPage from twisted, enabling proxy.

621. By Francisco Souza

all: use download_page and get_page from lib.http_client

Revision history for this message
Chico (franciscossouza) wrote :
lp:~franciscosouza/pyjuju/juju-vpc updated
622. By Francisco Souza

lib/http_client: don't use proxy to connect to localhost, 127.0.0.1 and 169.254.169.254

Revision history for this message
Chico (franciscossouza) wrote :
lp:~franciscosouza/pyjuju/juju-vpc updated
623. By Francisco Souza

lib/http_client: fix stupid error

Revision history for this message
Chico (franciscossouza) wrote :
lp:~franciscosouza/pyjuju/juju-vpc updated
624. By Francisco Souza

providers, unit: added private mode for address

A VPC instance does not have public DNS name, so the metadata url for this data
returns 404.

Revision history for this message
Chico (franciscossouza) wrote :
lp:~franciscosouza/pyjuju/juju-vpc updated
625. By Francisco Souza

unit/deploy: set JUJU_PRIVATE on service upstart file

Revision history for this message
Chico (franciscossouza) wrote :

Unmerged revisions

625. By Francisco Souza

unit/deploy: set JUJU_PRIVATE on service upstart file

624. By Francisco Souza

providers, unit: added private mode for address

A VPC instance does not have public DNS name, so the metadata url for this data
returns 404.

623. By Francisco Souza

lib/http_client: fix stupid error

622. By Francisco Souza

lib/http_client: don't use proxy to connect to localhost, 127.0.0.1 and 169.254.169.254

621. By Francisco Souza

all: use download_page and get_page from lib.http_client

620. By Francisco Souza

lib: added http_client

This will wrap getPage and downloadPage from twisted, enabling proxy.

619. By Francisco Souza

providers/common: set extra environment on provision agent too

618. By Francisco Souza

unit/deploy: read http_proxy and https_proxy from os environment

These values are used to add new units, setting http_proxy and https_proxy in
upstart config file.

617. By Francisco Souza

providers/common: launching vms with http and https proxy in upstart file

616. By Francisco Souza

machine: added support for extra environment variables in unit deployment

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'juju/charm/repository.py'
--- juju/charm/repository.py 2012-08-23 23:57:09 +0000
+++ juju/charm/repository.py 2012-11-23 21:00:27 +0000
@@ -7,7 +7,6 @@
7import yaml7import yaml
88
9from twisted.internet.defer import fail, inlineCallbacks, returnValue, succeed9from twisted.internet.defer import fail, inlineCallbacks, returnValue, succeed
10from twisted.web.client import downloadPage, getPage
11from twisted.web.error import Error10from twisted.web.error import Error
12from txaws.client.ssl import VerifyingContextFactory11from txaws.client.ssl import VerifyingContextFactory
1312
@@ -15,6 +14,7 @@
15from juju.charm.url import CharmURL14from juju.charm.url import CharmURL
16from juju.errors import FileNotFound15from juju.errors import FileNotFound
17from juju.lib import under16from juju.lib import under
17from juju.lib.http_client import download_page, get_page
1818
19from .errors import (19from .errors import (
20 CharmNotFound, CharmError, RepositoryNotFound, ServiceConfigValueError)20 CharmNotFound, CharmError, RepositoryNotFound, ServiceConfigValueError)
@@ -129,7 +129,7 @@
129 self.url_base, urllib.quote(charm_id))129 self.url_base, urllib.quote(charm_id))
130 try:130 try:
131 host = urlparse.urlparse(url).hostname131 host = urlparse.urlparse(url).hostname
132 all_info = json.loads((yield getPage(url, contextFactory=VerifyingContextFactory(host))))132 all_info = json.loads((yield get_page(url, contextFactory=VerifyingContextFactory(host))))
133 charm_info = all_info[charm_id]133 charm_info = all_info[charm_id]
134 for warning in charm_info.get("warnings", []):134 for warning in charm_info.get("warnings", []):
135 log.warning("%s: %s", charm_id, warning)135 log.warning("%s: %s", charm_id, warning)
@@ -152,7 +152,7 @@
152 downloading_path = f.name152 downloading_path = f.name
153 host = urlparse.urlparse(url).hostname153 host = urlparse.urlparse(url).hostname
154 try:154 try:
155 yield downloadPage(url, downloading_path, contextFactory=VerifyingContextFactory(host))155 yield download_page(url, downloading_path, contextFactory=VerifyingContextFactory(host))
156 except Error:156 except Error:
157 raise CharmNotFound(self.url_base, charm_url)157 raise CharmNotFound(self.url_base, charm_url)
158 os.rename(downloading_path, cache_path)158 os.rename(downloading_path, cache_path)
159159
=== added file 'juju/lib/http_client.py'
--- juju/lib/http_client.py 1970-01-01 00:00:00 +0000
+++ juju/lib/http_client.py 2012-11-23 21:00:27 +0000
@@ -0,0 +1,74 @@
1# -*- coding: utf-8 -*-
2import os
3import urlparse
4
5from twisted.internet import reactor
6from twisted.internet.defer import Deferred
7from twisted.internet.endpoints import TCP4ClientEndpoint
8from twisted.internet.protocol import connectionDone, Protocol
9from twisted.web.client import downloadPage, getPage, ProxyAgent, ResponseDone
10from twisted.web.http import PotentialDataLoss
11
12
13class Receiver(Protocol):
14 finished = None
15 _filename = None
16
17 def __init__(self, filename=None):
18 self.received = ""
19 if filename:
20 self._filename = filename
21
22 def dataReceived(self, data):
23 self.received += data
24
25 def connectionLost(self, reason=connectionDone):
26 reason.trap(ResponseDone, PotentialDataLoss, connectionDone)
27 d = self.finished
28 self.finished = None
29 if self._filename:
30 file = open(self._filename, "w")
31 try:
32 file.write(self.received)
33 finally:
34 file.close()
35 d.callback(self.received)
36
37
38def response_saver(path):
39 def save_response(response):
40 receiver = Receiver(path)
41 receiver.finished = d = Deferred()
42 response.deliverBody(receiver)
43 return d
44 return save_response
45
46
47def _deferred_get(url, proxy_endpoint):
48 proxy_url = urlparse.urlparse(proxy_endpoint)
49 endpoint = TCP4ClientEndpoint(reactor, proxy_url.hostname, proxy_url.port)
50 agent = ProxyAgent(endpoint)
51 return agent.request("GET", url)
52
53
54def download_page(url, path, *args, **kwargs):
55 host = urlparse.urlparse(url).hostname
56 proxy_var = url.startswith("https://") and "https_proxy" or "http_proxy"
57 proxy_endpoint = os.environ.get(proxy_var)
58 if proxy_endpoint and host not in ("localhost", "127.0.0.1", "169.254.169.254"):
59 d = _deferred_get(url, proxy_endpoint)
60 d.addCallback(response_saver(path))
61 return d
62 return downloadPage(url, path, *args, **kwargs)
63
64
65def get_page(url, *args, **kwargs):
66 host = urlparse.urlparse(url).hostname
67 proxy_var = url.startswith("https://") and "https_proxy" or "http_proxy"
68 proxy_endpoint = os.environ.get(proxy_var)
69 if proxy_endpoint and host not in ("localhost", "127.0.0.1", "169.254.169.254"):
70 d = _deferred_get(url, proxy_endpoint)
71 d.addCallback(response_saver(None))
72 return d
73 else:
74 return getPage(url, *args, **kwargs)
075
=== modified file 'juju/machine/__init__.py'
--- juju/machine/__init__.py 2012-01-31 19:57:53 +0000
+++ juju/machine/__init__.py 2012-11-23 21:00:27 +0000
@@ -9,9 +9,10 @@
9 """9 """
1010
11 def __init__(self, instance_id, dns_name=None, private_dns_name=None,11 def __init__(self, instance_id, dns_name=None, private_dns_name=None,
12 state="unknown"):12 state="unknown", private_ip_address=None):
13 self.instance_id = instance_id13 self.instance_id = instance_id
14 # ideally this would be ip_address, but txaws doesn't expose it.14 # ideally this would be ip_address, but txaws doesn't expose it.
15 self.dns_name = dns_name15 self.dns_name = dns_name
16 self.private_dns_name = private_dns_name16 self.private_dns_name = private_dns_name
17 self.private_ip_address = private_ip_address
17 self.state = state18 self.state = state
1819
=== modified file 'juju/machine/tests/data/test_get_container'
--- juju/machine/tests/data/test_get_container 2012-10-09 18:55:55 +0000
+++ juju/machine/tests/data/test_get_container 2012-11-23 21:00:27 +0000
@@ -7,7 +7,7 @@
7machine-data: {juju-provider-type: null, juju-zookeeper-hosts: 'localhost:2181',7machine-data: {juju-provider-type: null, juju-zookeeper-hosts: 'localhost:2181',
8 machine-id: null}8 machine-id: null}
9output: {all: '| tee -a /var/log/cloud-init-output.log'}9output: {all: '| tee -a /var/log/cloud-init-output.log'}
10packages: [bzr, byobu, tmux, python-setuptools, python-twisted, python-txaws, python-zookeeper]10packages: [bzr, byobu, tmux, python-setuptools, python-twisted, python-zookeeper, python-txaws]
11runcmd: [sudo apt-get install -y python-txzookeeper, sudo mkdir -p /usr/lib/juju,11runcmd: [sudo apt-get install -y python-txzookeeper, sudo mkdir -p /usr/lib/juju,
12 'cd /usr/lib/juju && sudo /usr/bin/bzr co --lightweight lp:juju 12 'cd /usr/lib/juju && sudo /usr/bin/bzr co --lightweight lp:juju
13 juju', cd /usr/lib/juju/juju && sudo python setup.py develop, sudo mkdir -p /var/lib/juju,13 juju', cd /usr/lib/juju/juju && sudo python setup.py develop, sudo mkdir -p /var/lib/juju,
1414
=== modified file 'juju/machine/tests/test_unit_deployment.py'
--- juju/machine/tests/test_unit_deployment.py 2012-10-05 13:55:09 +0000
+++ juju/machine/tests/test_unit_deployment.py 2012-11-23 21:00:27 +0000
@@ -15,7 +15,7 @@
15from juju.lib.lxc.tests.test_lxc import uses_sudo15from juju.lib.lxc.tests.test_lxc import uses_sudo
16from juju.lib.mocker import ANY, KWARGS, MATCH16from juju.lib.mocker import ANY, KWARGS, MATCH
17from juju.lib.upstart import UpstartService17from juju.lib.upstart import UpstartService
18from juju.machine.unit import UnitMachineDeployment, UnitContainerDeployment18from juju.machine.unit import ExtraEnvironmentDeployment, UnitMachineDeployment, UnitContainerDeployment
19from juju.machine.errors import UnitDeploymentError19from juju.machine.errors import UnitDeploymentError
20from juju.machine import tests20from juju.machine import tests
21from juju.tests.common import get_test_zookeeper_address21from juju.tests.common import get_test_zookeeper_address
@@ -143,6 +143,54 @@
143 d.addCallback(verify_upstart)143 d.addCallback(verify_upstart)
144 return d144 return d
145145
146 def test_service_unit_start_with_extra_environment(self):
147 """
148 Starting a service unit will result in a unit workspace being created
149 if it does not exist and a running service unit agent.
150 """
151 self.setup_mock()
152 self.mock_install()
153 self.mock_is_running(False)
154 self.mock_start()
155 self.mocker.replay()
156
157 self.deployment.set_env("http_proxy", "http://myproxy.com:3128/")
158 d = self.deployment.start(
159 "123", get_test_zookeeper_address(), self.bundle)
160
161 def verify_upstart(_):
162 conf_path = os.path.join(self.init_dir, "juju-wordpress-0.conf")
163 with open(conf_path) as f:
164 lines = f.readlines()
165
166 env = []
167 for line in lines:
168 if line.startswith("env "):
169 env.append(line[4:-1].split("=", 1))
170 if line.startswith("exec "):
171 exec_ = line[5:-1]
172
173 env = dict((k, v.strip('"')) for (k, v) in env)
174 env.pop("PYTHONPATH")
175 self.assertEquals(env, {
176 "JUJU_HOME": self.juju_directory,
177 "JUJU_UNIT_NAME": self.unit_name,
178 "JUJU_ZOOKEEPER": get_test_zookeeper_address(),
179 "JUJU_MACHINE_ID": "123",
180 "http_proxy": "http://myproxy.com:3128/"})
181
182 log_file = os.path.join(
183 self.deployment.directory, "charm.log")
184 command = " ".join([
185 "/usr/bin/python", "-m", "juju.agents.dummy", "--nodaemon",
186 "--logfile", log_file, "--session-file",
187 "/var/run/juju/unit-wordpress-0-agent.zksession",
188 ">> /tmp/juju-wordpress-0.output 2>&1"])
189 self.assertEquals(exec_, command)
190 d.addCallback(verify_upstart)
191 self.deployment.unset_env("http_proxy")
192 return d
193
146 @inlineCallbacks194 @inlineCallbacks
147 def test_service_unit_destroy(self):195 def test_service_unit_destroy(self):
148 """196 """
@@ -426,3 +474,25 @@
426474
427 container, rootfs = yield self.unit_deploy._get_container(475 container, rootfs = yield self.unit_deploy._get_container(
428 "0", cloud_init)476 "0", cloud_init)
477
478
479class ExtraEnvironmentTest(RepositoryTestBase):
480
481 def test_set_env(self):
482 deploy = ExtraEnvironmentDeployment()
483 deploy.set_env("http_proxy", "http://myproxy.com:3128/")
484 self.assertEquals(deploy._extra_environment["http_proxy"], "http://myproxy.com:3128/")
485
486 def test_unset_env(self):
487 deploy = ExtraEnvironmentDeployment()
488 deploy.set_env("http_proxy", "http://myproxy.com:3128/")
489 deploy.unset_env("http_proxy")
490 self.assertNotIn("http_proxy", deploy._extra_environment)
491
492 def test_machine_deployment_extends_extra_environment(self):
493 assert issubclass(UnitMachineDeployment, ExtraEnvironmentDeployment), \
494 "UnitMachineDeployment should inherit from ExtraEnvironmentDeployment!"
495
496 def test_container_deployment_extends_extra_environment(self):
497 assert issubclass(UnitContainerDeployment, ExtraEnvironmentDeployment), \
498 "UnitContainerDeployment should inherit from ExtraEnvironmentDeployment!"
429499
=== modified file 'juju/machine/unit.py'
--- juju/machine/unit.py 2012-09-27 00:42:32 +0000
+++ juju/machine/unit.py 2012-11-23 21:00:27 +0000
@@ -8,7 +8,7 @@
88
9from juju.charm.bundle import CharmBundle9from juju.charm.bundle import CharmBundle
10from juju.errors import ServiceError10from juju.errors import ServiceError
11from juju.lib.lxc import LXCContainer, get_containers, LXCError11from juju.lib.lxc import LXCContainer, get_containers
12from juju.lib.twistutils import get_module_directory12from juju.lib.twistutils import get_module_directory
13from juju.lib.upstart import UpstartService13from juju.lib.upstart import UpstartService
14from juju.providers.common.cloudinit import CloudInit14from juju.providers.common.cloudinit import CloudInit
@@ -27,20 +27,33 @@
27 return UnitMachineDeployment27 return UnitMachineDeployment
2828
2929
30def _get_environment(unit_name, juju_home, machine_id, zookeeper_hosts):30def _get_environment(unit_name, juju_home, machine_id, zookeeper_hosts, base=None):
31 environ = dict()31 if not base:
32 environ["JUJU_MACHINE_ID"] = str(machine_id)32 base = {}
33 environ["JUJU_UNIT_NAME"] = unit_name33 base["JUJU_MACHINE_ID"] = str(machine_id)
34 environ["JUJU_HOME"] = juju_home34 base["JUJU_UNIT_NAME"] = unit_name
35 environ["JUJU_ZOOKEEPER"] = zookeeper_hosts35 base["JUJU_HOME"] = juju_home
36 environ["PYTHONPATH"] = ":".join(36 base["JUJU_ZOOKEEPER"] = zookeeper_hosts
37 base["PYTHONPATH"] = ":".join(
37 filter(None, [38 filter(None, [
38 os.path.dirname(get_module_directory(juju)),39 os.path.dirname(get_module_directory(juju)),
39 os.environ.get("PYTHONPATH")]))40 os.environ.get("PYTHONPATH")]))
40 return environ41 return base
4142
4243
43class UnitMachineDeployment(object):44class ExtraEnvironmentDeployment(object):
45
46 def __init__(self):
47 self._extra_environment = {}
48
49 def set_env(self, name, value):
50 self._extra_environment[name] = value
51
52 def unset_env(self, name):
53 del self._extra_environment[name]
54
55
56class UnitMachineDeployment(ExtraEnvironmentDeployment):
44 """ Deploy a unit directly onto a machine.57 """ Deploy a unit directly onto a machine.
4558
46 A service unit deployed directly to a machine has full access59 A service unit deployed directly to a machine has full access
@@ -54,6 +67,7 @@
54 unit_agent_module = "juju.agents.unit"67 unit_agent_module = "juju.agents.unit"
5568
56 def __init__(self, unit_name, juju_home):69 def __init__(self, unit_name, juju_home):
70 super(UnitMachineDeployment, self).__init__()
57 assert ".." not in unit_name, "Invalid Unit Name"71 assert ".." not in unit_name, "Invalid Unit Name"
58 self.unit_name = unit_name72 self.unit_name = unit_name
59 self.juju_home = juju_home73 self.juju_home = juju_home
@@ -72,7 +86,7 @@
72 self.service.set_description(86 self.service.set_description(
73 "Juju unit agent for %s" % self.unit_name)87 "Juju unit agent for %s" % self.unit_name)
74 self.service.set_environ(_get_environment(88 self.service.set_environ(_get_environment(
75 self.unit_name, self.juju_home, machine_id, zookeeper_hosts))89 self.unit_name, self.juju_home, machine_id, zookeeper_hosts, self._extra_environment))
76 self.service.set_command(" ".join((90 self.service.set_command(" ".join((
77 "/usr/bin/python", "-m", self.unit_agent_module,91 "/usr/bin/python", "-m", self.unit_agent_module,
78 "--nodaemon",92 "--nodaemon",
@@ -130,7 +144,7 @@
130 "juju-%s" % self.unit_path_name, use_sudo=True)144 "juju-%s" % self.unit_path_name, use_sudo=True)
131145
132146
133class UnitContainerDeployment(object):147class UnitContainerDeployment(ExtraEnvironmentDeployment):
134 """Deploy a service unit in a container.148 """Deploy a service unit in a container.
135149
136 Units deployed in a container have strong isolation between150 Units deployed in a container have strong isolation between
@@ -145,6 +159,7 @@
145 """159 """
146160
147 def __init__(self, unit_name, juju_home):161 def __init__(self, unit_name, juju_home):
162 super(UnitContainerDeployment, self).__init__()
148 self.unit_name = unit_name163 self.unit_name = unit_name
149 self.juju_home = juju_home164 self.juju_home = juju_home
150 self.unit_path_name = unit_name.replace("/", "-")165 self.unit_path_name = unit_name.replace("/", "-")
@@ -189,7 +204,7 @@
189 (zk, port) = zk.split(':')204 (zk, port) = zk.split(':')
190 else:205 else:
191 port = 2181206 port = 2181
192 zks.append((zk,port))207 zks.append((zk, port))
193208
194 cloud_init.set_zookeeper_hosts(zks)209 cloud_init.set_zookeeper_hosts(zks)
195 # XXX Very hard to access the provider's notion of network210 # XXX Very hard to access the provider's notion of network
@@ -197,6 +212,9 @@
197 # the apt-cacher-ng since this is meant for local provider.212 # the apt-cacher-ng since this is meant for local provider.
198 cloud_init.set_apt_proxy('http://%s:3142' % zks[0][0])213 cloud_init.set_apt_proxy('http://%s:3142' % zks[0][0])
199214
215 for name, value in self._extra_environment.iteritems():
216 cloud_init.set_env(name, value)
217
200 if self._juju_origin:218 if self._juju_origin:
201 if self._juju_origin.startswith("lp:"):219 if self._juju_origin.startswith("lp:"):
202 cloud_init.set_juju_source(branch=self._juju_origin)220 cloud_init.set_juju_source(branch=self._juju_origin)
@@ -204,6 +222,8 @@
204 cloud_init.set_juju_source(ppa=True)222 cloud_init.set_juju_source(ppa=True)
205 elif self._juju_origin == "proposed":223 elif self._juju_origin == "proposed":
206 cloud_init.set_juju_source(proposed=True)224 cloud_init.set_juju_source(proposed=True)
225 elif self._juju_origin == "image":
226 cloud_init.set_juju_source(image=True)
207 else:227 else:
208 # Ignore other values, just use the distro for sanity228 # Ignore other values, just use the distro for sanity
209 cloud_init.set_juju_source(distro=True)229 cloud_init.set_juju_source(distro=True)
210230
=== modified file 'juju/providers/common/cloudinit.py'
--- juju/providers/common/cloudinit.py 2012-10-09 18:55:55 +0000
+++ juju/providers/common/cloudinit.py 2012-11-23 21:00:27 +0000
@@ -13,6 +13,7 @@
13PPA = "ppa"13PPA = "ppa"
14BRANCH = "branch"14BRANCH = "branch"
15PROPOSED = "proposed"15PROPOSED = "proposed"
16IMAGE = "image"
1617
1718
18def _branch_install_scripts(branch):19def _branch_install_scripts(branch):
@@ -45,11 +46,13 @@
45 b64encode(serializer.dump(constraints.data)), provider_type)]46 b64encode(serializer.dump(constraints.data)), provider_type)]
4647
4748
48def _machine_scripts(machine_id, zookeeper_hosts):49def _machine_scripts(machine_id, zookeeper_hosts, extra_env=None):
49 service = UpstartService("juju-machine-agent")50 service = UpstartService("juju-machine-agent")
50 service.set_description("Juju machine agent")51 service.set_description("Juju machine agent")
51 service.set_environ(52 env = {"JUJU_MACHINE_ID": machine_id, "JUJU_ZOOKEEPER": zookeeper_hosts}
52 {"JUJU_MACHINE_ID": machine_id, "JUJU_ZOOKEEPER": zookeeper_hosts})53 if extra_env:
54 env.update(extra_env)
55 service.set_environ(env)
53 service.set_command(56 service.set_command(
54 "python -m juju.agents.machine --nodaemon "57 "python -m juju.agents.machine --nodaemon "
55 "--logfile /var/log/juju/machine-agent.log "58 "--logfile /var/log/juju/machine-agent.log "
@@ -78,10 +81,13 @@
78 "/var/run/juju/unit-%s-agent.zksession" % unit_path_name]))81 "/var/run/juju/unit-%s-agent.zksession" % unit_path_name]))
79 return service.get_cloud_init_commands()82 return service.get_cloud_init_commands()
8083
81def _provision_scripts(zookeeper_hosts):84def _provision_scripts(zookeeper_hosts, extra_env=None):
82 service = UpstartService("juju-provision-agent")85 service = UpstartService("juju-provision-agent")
83 service.set_description("Juju provisioning agent")86 service.set_description("Juju provisioning agent")
84 service.set_environ({"JUJU_ZOOKEEPER": zookeeper_hosts})87 env = {"JUJU_ZOOKEEPER": zookeeper_hosts}
88 if extra_env:
89 env.update(extra_env)
90 service.set_environ(env)
85 service.set_command(91 service.set_command(
86 "python -m juju.agents.provision --nodaemon "92 "python -m juju.agents.provision --nodaemon "
87 "--logfile /var/log/juju/provision-agent.log "93 "--logfile /var/log/juju/provision-agent.log "
@@ -175,6 +181,8 @@
175 self._unit_name = None181 self._unit_name = None
176 self._juju_home = None182 self._juju_home = None
177 self._apt_proxy = None183 self._apt_proxy = None
184 self._extra_environment = {}
185 self.private = False
178186
179 def add_ssh_key(self, key):187 def add_ssh_key(self, key):
180 """Add an SSH public key.188 """Add an SSH public key.
@@ -190,8 +198,14 @@
190 self._zookeeper = True198 self._zookeeper = True
191 self._provision = True199 self._provision = True
192200
201 def set_env(self, name, value):
202 self._extra_environment[name] = value
203
204 def unset_env(self, name):
205 del self._extra_environment[name]
206
193 def set_juju_source(207 def set_juju_source(
194 self, branch=None, ppa=False, distro=False, proposed=False):208 self, branch=None, ppa=False, distro=False, proposed=False, image=False):
195 """Set the version of juju the machine should run.209 """Set the version of juju the machine should run.
196210
197 :param branch: location from which to check out juju; for example,211 :param branch: location from which to check out juju; for example,
@@ -213,9 +227,12 @@
213 Note that you don't need to call this method; the juju source227 Note that you don't need to call this method; the juju source
214 defaults to what is returned by `get_default_origin`.228 defaults to what is returned by `get_default_origin`.
215 """229 """
216 if len(filter(None, (branch, ppa, distro, proposed))) != 1:230 if len(filter(None, (branch, ppa, distro, proposed, image))) != 1:
217 raise CloudInitError("Please specify one source")231 raise CloudInitError("Please specify one source")
218 if branch:232 if image:
233 self._origin = IMAGE
234 self._origin_url = None
235 elif branch:
219 self._origin = BRANCH236 self._origin = BRANCH
220 self._origin_url = branch237 self._origin_url = branch
221 elif ppa:238 elif ppa:
@@ -282,7 +299,10 @@
282 You don't have to set this, so long as the machine you are starting is299 You don't have to set this, so long as the machine you are starting is
283 itself a zookeeper instance.300 itself a zookeeper instance.
284 """301 """
285 self._zookeeper_hosts = [m.private_dns_name for m in machines]302 if self.private:
303 self._zookeeper_hosts = [m.private_ip_address for m in machines]
304 else:
305 self._zookeeper_hosts = [m.private_dns_name for m in machines]
286306
287 def set_zookeeper_hosts(self, hosts):307 def set_zookeeper_hosts(self, hosts):
288 """Specify master :class:`juju.machine.ProviderMachine` instances.308 """Specify master :class:`juju.machine.ProviderMachine` instances.
@@ -367,18 +387,20 @@
367 def _collect_packages(self):387 def _collect_packages(self):
368 packages = [388 packages = [
369 "bzr", "byobu", "tmux", "python-setuptools", "python-twisted",389 "bzr", "byobu", "tmux", "python-setuptools", "python-twisted",
370 "python-txaws", "python-zookeeper"]390 "python-zookeeper"]
371 if self._zookeeper:391 if self._zookeeper:
372 packages.extend([392 packages.extend([
373 "default-jre-headless", "zookeeper", "zookeeperd"])393 "default-jre-headless", "zookeeper", "zookeeperd"])
374 if self._origin in (DISTRO, PPA, PROPOSED):394 if self._origin in (DISTRO, PPA, PROPOSED):
375 packages.append("juju")395 packages.append("juju")
396 if self._origin != IMAGE:
397 packages.append("python-txaws")
376 return packages398 return packages
377399
378 def _collect_repositories(self):400 def _collect_repositories(self):
379 if self._origin == PROPOSED:401 if self._origin == PROPOSED:
380 return ["deb $MIRROR $RELEASE-proposed main universe"]402 return ["deb $MIRROR $RELEASE-proposed main universe"]
381 if self._origin != DISTRO:403 if self._origin not in (DISTRO, IMAGE):
382 return ["ppa:juju/pkgs"]404 return ["ppa:juju/pkgs"]
383 return []405 return []
384406
@@ -392,7 +414,7 @@
392 self._provider_type))414 self._provider_type))
393 if self._machine_id:415 if self._machine_id:
394 scripts.extend(_machine_scripts(416 scripts.extend(_machine_scripts(
395 self._machine_id, self._join_zookeeper_hosts()))417 self._machine_id, self._join_zookeeper_hosts(), self._extra_environment))
396 if self._unit_name:418 if self._unit_name:
397 scripts.extend(_unit_scripts(419 scripts.extend(_unit_scripts(
398 self._machine_id,420 self._machine_id,
@@ -400,7 +422,7 @@
400 self._join_zookeeper_hosts(),422 self._join_zookeeper_hosts(),
401 self._juju_home))423 self._juju_home))
402 if self._provision:424 if self._provision:
403 scripts.extend(_provision_scripts(self._join_zookeeper_hosts()))425 scripts.extend(_provision_scripts(self._join_zookeeper_hosts(), self._extra_environment))
404 return scripts426 return scripts
405427
406 def _collect_machine_data(self):428 def _collect_machine_data(self):
407429
=== modified file 'juju/providers/common/launch.py'
--- juju/providers/common/launch.py 2012-07-18 20:04:16 +0000
+++ juju/providers/common/launch.py 2012-11-23 21:00:27 +0000
@@ -92,6 +92,7 @@
92 """92 """
93 config = self._provider.config93 config = self._provider.config
94 cloud_init = CloudInit()94 cloud_init = CloudInit()
95 cloud_init.private = config.get("vpc_id") is not None
95 cloud_init.add_ssh_key(get_user_authorized_keys(config))96 cloud_init.add_ssh_key(get_user_authorized_keys(config))
96 cloud_init.set_machine_id(machine_id)97 cloud_init.set_machine_id(machine_id)
97 cloud_init.set_zookeeper_machines(zookeepers)98 cloud_init.set_zookeeper_machines(zookeepers)
@@ -103,9 +104,18 @@
103 cloud_init.set_juju_source(ppa=True)104 cloud_init.set_juju_source(ppa=True)
104 elif origin == "proposed":105 elif origin == "proposed":
105 cloud_init.set_juju_source(proposed=True)106 cloud_init.set_juju_source(proposed=True)
107 elif origin == "image":
108 cloud_init.set_juju_source(image=True)
106 else:109 else:
107 # Ignore other values, just use the distro for sanity110 # Ignore other values, just use the distro for sanity
108 cloud_init.set_juju_source(distro=True)111 cloud_init.set_juju_source(distro=True)
112 proxy = config.get("proxy")
113 if proxy:
114 cloud_init.set_env("http_proxy", proxy)
115 cloud_init.set_env("https_proxy", proxy)
116 private = config.get("vpc_id") is not None
117 if private:
118 cloud_init.set_env("JUJU_PRIVATE", "private")
109 if self._master:119 if self._master:
110 cloud_init.enable_bootstrap()120 cloud_init.enable_bootstrap()
111 cloud_init.set_zookeeper_secret(config["admin-secret"])121 cloud_init.set_zookeeper_secret(config["admin-secret"])
112122
=== modified file 'juju/providers/common/tests/data/cloud_init_bootstrap'
--- juju/providers/common/tests/data/cloud_init_bootstrap 2012-08-23 16:14:42 +0000
+++ juju/providers/common/tests/data/cloud_init_bootstrap 2012-11-23 21:00:27 +0000
@@ -4,8 +4,8 @@
4machine-data: {juju-provider-type: dummy, juju-zookeeper-hosts: 'localhost:2181',4machine-data: {juju-provider-type: dummy, juju-zookeeper-hosts: 'localhost:2181',
5 machine-id: passport}5 machine-id: passport}
6output: {all: '| tee -a /var/log/cloud-init-output.log'}6output: {all: '| tee -a /var/log/cloud-init-output.log'}
7packages: [bzr, byobu, tmux, python-setuptools, python-twisted, python-txaws, python-zookeeper,7packages: [bzr, byobu, tmux, python-setuptools, python-twisted, python-zookeeper,
8 default-jre-headless, zookeeper, zookeeperd, juju]8 default-jre-headless, zookeeper, zookeeperd, juju, python-txaws]
9runcmd: [sudo mkdir -p /var/lib/juju, sudo mkdir -p /var/log/juju, 'juju-admin initialize9runcmd: [sudo mkdir -p /var/lib/juju, sudo mkdir -p /var/log/juju, 'juju-admin initialize
10 --instance-id=token --admin-identity=admin:19vlzY4Vc3q4Ew5OsCwKYqrq1HI= --constraints-data=e2NwdTogJzIwJywgcHJvdmlkZXItdHlwZTogZHVtbXksIHVidW50dS1zZXJpZXM6IGFzdG9uaXNoaW5nfQo=10 --instance-id=token --admin-identity=admin:19vlzY4Vc3q4Ew5OsCwKYqrq1HI= --constraints-data=e2NwdTogJzIwJywgcHJvdmlkZXItdHlwZTogZHVtbXksIHVidW50dS1zZXJpZXM6IGFzdG9uaXNoaW5nfQo=
11 --provider-type=dummy', 'cat >> /etc/init/juju-machine-agent.conf <<EOF11 --provider-type=dummy', 'cat >> /etc/init/juju-machine-agent.conf <<EOF
1212
=== added file 'juju/providers/common/tests/data/cloud_init_bootstrap_extra_env'
--- juju/providers/common/tests/data/cloud_init_bootstrap_extra_env 1970-01-01 00:00:00 +0000
+++ juju/providers/common/tests/data/cloud_init_bootstrap_extra_env 2012-11-23 21:00:27 +0000
@@ -0,0 +1,69 @@
1#cloud-config
2apt_update: true
3apt_upgrade: true
4machine-data: {juju-provider-type: dummy, juju-zookeeper-hosts: 'localhost:2181',
5 machine-id: passport}
6output: {all: '| tee -a /var/log/cloud-init-output.log'}
7packages: [bzr, byobu, tmux, python-setuptools, python-twisted, python-zookeeper,
8 default-jre-headless, zookeeper, zookeeperd, juju, python-txaws]
9runcmd: [sudo mkdir -p /var/lib/juju, sudo mkdir -p /var/log/juju, 'juju-admin initialize
10 --instance-id=token --admin-identity=admin:19vlzY4Vc3q4Ew5OsCwKYqrq1HI= --constraints-data=e2NwdTogJzIwJywgcHJvdmlkZXItdHlwZTogZHVtbXksIHVidW50dS1zZXJpZXM6IGFzdG9uaXNoaW5nfQo=
11 --provider-type=dummy', 'cat >> /etc/init/juju-machine-agent.conf <<EOF
12
13 description "Juju machine agent"
14
15 author "Juju Team <juju@lists.ubuntu.com>"
16
17
18 start on runlevel [2345]
19
20 stop on runlevel [!2345]
21
22 respawn
23
24
25 env JUJU_MACHINE_ID="passport"
26
27 env JUJU_ZOOKEEPER="localhost:2181"
28
29 env http_proxy="http://myproxy.com:3128/"
30
31 env https_proxy="http://myproxy.com:3128/"
32
33
34 exec python -m juju.agents.machine --nodaemon --logfile /var/log/juju/machine-agent.log
35 --session-file /var/run/juju/machine-agent.zksession >> /tmp/juju-machine-agent.output
36 2>&1
37
38 EOF
39
40 ', /sbin/start juju-machine-agent, 'cat >> /etc/init/juju-provision-agent.conf
41 <<EOF
42
43 description "Juju provisioning agent"
44
45 author "Juju Team <juju@lists.ubuntu.com>"
46
47
48 start on runlevel [2345]
49
50 stop on runlevel [!2345]
51
52 respawn
53
54
55 env JUJU_ZOOKEEPER="localhost:2181"
56
57 env http_proxy="http://myproxy.com:3128/"
58
59 env https_proxy="http://myproxy.com:3128/"
60
61
62 exec python -m juju.agents.provision --nodaemon --logfile /var/log/juju/provision-agent.log
63 --session-file /var/run/juju/provision-agent.zksession >> /tmp/juju-provision-agent.output
64 2>&1
65
66 EOF
67
68 ', /sbin/start juju-provision-agent]
69ssh_authorized_keys: [chubb]
070
=== modified file 'juju/providers/common/tests/data/cloud_init_bootstrap_zookeepers'
--- juju/providers/common/tests/data/cloud_init_bootstrap_zookeepers 2012-08-23 16:14:42 +0000
+++ juju/providers/common/tests/data/cloud_init_bootstrap_zookeepers 2012-11-23 21:00:27 +0000
@@ -4,8 +4,8 @@
4machine-data: {juju-provider-type: dummy, juju-zookeeper-hosts: 'cotswold:2181,longleat:2181,localhost:2181',4machine-data: {juju-provider-type: dummy, juju-zookeeper-hosts: 'cotswold:2181,longleat:2181,localhost:2181',
5 machine-id: passport}5 machine-id: passport}
6output: {all: '| tee -a /var/log/cloud-init-output.log'}6output: {all: '| tee -a /var/log/cloud-init-output.log'}
7packages: [bzr, byobu, tmux, python-setuptools, python-twisted, python-txaws, python-zookeeper,7packages: [bzr, byobu, tmux, python-setuptools, python-twisted, python-zookeeper,
8 default-jre-headless, zookeeper, zookeeperd, juju]8 default-jre-headless, zookeeper, zookeeperd, juju, python-txaws]
9runcmd: [sudo mkdir -p /var/lib/juju, sudo mkdir -p /var/log/juju, 'juju-admin initialize9runcmd: [sudo mkdir -p /var/lib/juju, sudo mkdir -p /var/log/juju, 'juju-admin initialize
10 --instance-id=token --admin-identity=admin:19vlzY4Vc3q4Ew5OsCwKYqrq1HI= --constraints-data=e2NwdTogJzIwJywgcHJvdmlkZXItdHlwZTogZHVtbXksIHVidW50dS1zZXJpZXM6IGFzdG9uaXNoaW5nfQo=10 --instance-id=token --admin-identity=admin:19vlzY4Vc3q4Ew5OsCwKYqrq1HI= --constraints-data=e2NwdTogJzIwJywgcHJvdmlkZXItdHlwZTogZHVtbXksIHVidW50dS1zZXJpZXM6IGFzdG9uaXNoaW5nfQo=
11 --provider-type=dummy', 'cat >> /etc/init/juju-machine-agent.conf <<EOF11 --provider-type=dummy', 'cat >> /etc/init/juju-machine-agent.conf <<EOF
1212
=== modified file 'juju/providers/common/tests/data/cloud_init_branch'
--- juju/providers/common/tests/data/cloud_init_branch 2012-10-09 18:55:55 +0000
+++ juju/providers/common/tests/data/cloud_init_branch 2012-11-23 21:00:27 +0000
@@ -6,7 +6,7 @@
6machine-data: {juju-provider-type: dummy, juju-zookeeper-hosts: 'cotswold:2181,longleat:2181',6machine-data: {juju-provider-type: dummy, juju-zookeeper-hosts: 'cotswold:2181,longleat:2181',
7 machine-id: passport}7 machine-id: passport}
8output: {all: '| tee -a /var/log/cloud-init-output.log'}8output: {all: '| tee -a /var/log/cloud-init-output.log'}
9packages: [bzr, byobu, tmux, python-setuptools, python-twisted, python-txaws, python-zookeeper]9packages: [bzr, byobu, tmux, python-setuptools, python-twisted, python-zookeeper, python-txaws]
10runcmd: [sudo apt-get install -y python-txzookeeper, sudo mkdir -p /usr/lib/juju,10runcmd: [sudo apt-get install -y python-txzookeeper, sudo mkdir -p /usr/lib/juju,
11 'cd /usr/lib/juju && sudo /usr/bin/bzr co --lightweight lp:blah/juju/blah-blah juju', cd /usr/lib/juju/juju11 'cd /usr/lib/juju && sudo /usr/bin/bzr co --lightweight lp:blah/juju/blah-blah juju', cd /usr/lib/juju/juju
12 && sudo python setup.py develop, sudo mkdir -p /var/lib/juju, sudo mkdir -p /var/log/juju,12 && sudo python setup.py develop, sudo mkdir -p /var/lib/juju, sudo mkdir -p /var/log/juju,
1313
=== modified file 'juju/providers/common/tests/data/cloud_init_branch_trunk'
--- juju/providers/common/tests/data/cloud_init_branch_trunk 2012-10-09 18:55:55 +0000
+++ juju/providers/common/tests/data/cloud_init_branch_trunk 2012-11-23 21:00:27 +0000
@@ -6,7 +6,7 @@
6machine-data: {juju-provider-type: dummy, juju-zookeeper-hosts: 'cotswold:2181,longleat:2181',6machine-data: {juju-provider-type: dummy, juju-zookeeper-hosts: 'cotswold:2181,longleat:2181',
7 machine-id: passport}7 machine-id: passport}
8output: {all: '| tee -a /var/log/cloud-init-output.log'}8output: {all: '| tee -a /var/log/cloud-init-output.log'}
9packages: [bzr, byobu, tmux, python-setuptools, python-twisted, python-txaws, python-zookeeper]9packages: [bzr, byobu, tmux, python-setuptools, python-twisted, python-zookeeper, python-txaws]
10runcmd: [sudo apt-get install -y python-txzookeeper, sudo mkdir -p /usr/lib/juju,10runcmd: [sudo apt-get install -y python-txzookeeper, sudo mkdir -p /usr/lib/juju,
11 'cd /usr/lib/juju && sudo /usr/bin/bzr co --lightweight lp:juju juju', cd /usr/lib/juju/juju &&11 'cd /usr/lib/juju && sudo /usr/bin/bzr co --lightweight lp:juju juju', cd /usr/lib/juju/juju &&
12 sudo python setup.py develop, sudo mkdir -p /var/lib/juju, sudo mkdir -p /var/log/juju,12 sudo python setup.py develop, sudo mkdir -p /var/lib/juju, sudo mkdir -p /var/log/juju,
1313
=== modified file 'juju/providers/common/tests/data/cloud_init_distro'
--- juju/providers/common/tests/data/cloud_init_distro 2012-08-23 16:14:42 +0000
+++ juju/providers/common/tests/data/cloud_init_distro 2012-11-23 21:00:27 +0000
@@ -4,8 +4,7 @@
4machine-data: {juju-provider-type: dummy, juju-zookeeper-hosts: 'cotswold:2181,longleat:2181',4machine-data: {juju-provider-type: dummy, juju-zookeeper-hosts: 'cotswold:2181,longleat:2181',
5 machine-id: passport}5 machine-id: passport}
6output: {all: '| tee -a /var/log/cloud-init-output.log'}6output: {all: '| tee -a /var/log/cloud-init-output.log'}
7packages: [bzr, byobu, tmux, python-setuptools, python-twisted, python-txaws, python-zookeeper,7packages: [bzr, byobu, tmux, python-setuptools, python-twisted, python-zookeeper, juju, python-txaws]
8 juju]
9runcmd: [sudo mkdir -p /var/lib/juju, sudo mkdir -p /var/log/juju, 'cat >> /etc/init/juju-machine-agent.conf8runcmd: [sudo mkdir -p /var/lib/juju, sudo mkdir -p /var/log/juju, 'cat >> /etc/init/juju-machine-agent.conf
10 <<EOF9 <<EOF
1110
1211
=== added file 'juju/providers/common/tests/data/cloud_init_image'
--- juju/providers/common/tests/data/cloud_init_image 1970-01-01 00:00:00 +0000
+++ juju/providers/common/tests/data/cloud_init_image 2012-11-23 21:00:27 +0000
@@ -0,0 +1,35 @@
1#cloud-config
2apt_update: true
3apt_upgrade: true
4machine-data: {juju-provider-type: dummy, juju-zookeeper-hosts: 'cotswold:2181,longleat:2181',
5 machine-id: passport}
6output: {all: '| tee -a /var/log/cloud-init-output.log'}
7packages: [bzr, byobu, tmux, python-setuptools, python-twisted, python-zookeeper]
8runcmd: [sudo mkdir -p /var/lib/juju, sudo mkdir -p /var/log/juju, 'cat >> /etc/init/juju-machine-agent.conf
9 <<EOF
10
11 description "Juju machine agent"
12
13 author "Juju Team <juju@lists.ubuntu.com>"
14
15
16 start on runlevel [2345]
17
18 stop on runlevel [!2345]
19
20 respawn
21
22
23 env JUJU_MACHINE_ID="passport"
24
25 env JUJU_ZOOKEEPER="cotswold:2181,longleat:2181"
26
27
28 exec python -m juju.agents.machine --nodaemon --logfile /var/log/juju/machine-agent.log
29 --session-file /var/run/juju/machine-agent.zksession >> /tmp/juju-machine-agent.output
30 2>&1
31
32 EOF
33
34 ', /sbin/start juju-machine-agent]
35ssh_authorized_keys: [chubb]
036
=== added file 'juju/providers/common/tests/data/cloud_init_image_extra_env'
--- juju/providers/common/tests/data/cloud_init_image_extra_env 1970-01-01 00:00:00 +0000
+++ juju/providers/common/tests/data/cloud_init_image_extra_env 2012-11-23 21:00:27 +0000
@@ -0,0 +1,39 @@
1#cloud-config
2apt_update: true
3apt_upgrade: true
4machine-data: {juju-provider-type: dummy, juju-zookeeper-hosts: 'cotswold:2181,longleat:2181',
5 machine-id: passport}
6output: {all: '| tee -a /var/log/cloud-init-output.log'}
7packages: [bzr, byobu, tmux, python-setuptools, python-twisted, python-zookeeper]
8runcmd: [sudo mkdir -p /var/lib/juju, sudo mkdir -p /var/log/juju, 'cat >> /etc/init/juju-machine-agent.conf
9 <<EOF
10
11 description "Juju machine agent"
12
13 author "Juju Team <juju@lists.ubuntu.com>"
14
15
16 start on runlevel [2345]
17
18 stop on runlevel [!2345]
19
20 respawn
21
22
23 env JUJU_MACHINE_ID="passport"
24
25 env JUJU_ZOOKEEPER="cotswold:2181,longleat:2181"
26
27 env http_proxy="http://myproxy.com:3128/"
28
29 env https_proxy="http://myproxy.com:3128/"
30
31
32 exec python -m juju.agents.machine --nodaemon --logfile /var/log/juju/machine-agent.log
33 --session-file /var/run/juju/machine-agent.zksession >> /tmp/juju-machine-agent.output
34 2>&1
35
36 EOF
37
38 ', /sbin/start juju-machine-agent]
39ssh_authorized_keys: [chubb]
040
=== modified file 'juju/providers/common/tests/data/cloud_init_no_machine_id'
--- juju/providers/common/tests/data/cloud_init_no_machine_id 2012-09-24 04:04:32 +0000
+++ juju/providers/common/tests/data/cloud_init_no_machine_id 2012-11-23 21:00:27 +0000
@@ -4,7 +4,7 @@
4machine-data: {juju-provider-type: dummy, juju-zookeeper-hosts: 'cotswold:2181,longleat:2181',4machine-data: {juju-provider-type: dummy, juju-zookeeper-hosts: 'cotswold:2181,longleat:2181',
5 machine-id: }5 machine-id: }
6output: {all: '| tee -a /var/log/cloud-init-output.log'}6output: {all: '| tee -a /var/log/cloud-init-output.log'}
7packages: [bzr, byobu, tmux, python-setuptools, python-twisted, python-txaws,7packages: [bzr, byobu, tmux, python-setuptools, python-twisted,
8 python-zookeeper, juju]8 python-zookeeper, juju, python-txaws]
9runcmd: ['sudo mkdir -p /var/lib/juju', 'sudo mkdir -p /var/log/juju']9runcmd: ['sudo mkdir -p /var/lib/juju', 'sudo mkdir -p /var/log/juju']
10ssh_authorized_keys: [chubb]10ssh_authorized_keys: [chubb]
1111
=== modified file 'juju/providers/common/tests/data/cloud_init_normal'
--- juju/providers/common/tests/data/cloud_init_normal 2012-08-23 16:14:42 +0000
+++ juju/providers/common/tests/data/cloud_init_normal 2012-11-23 21:00:27 +0000
@@ -4,8 +4,8 @@
4machine-data: {juju-provider-type: dummy, juju-zookeeper-hosts: 'cotswold:2181,longleat:2181',4machine-data: {juju-provider-type: dummy, juju-zookeeper-hosts: 'cotswold:2181,longleat:2181',
5 machine-id: passport}5 machine-id: passport}
6output: {all: '| tee -a /var/log/cloud-init-output.log'}6output: {all: '| tee -a /var/log/cloud-init-output.log'}
7packages: [bzr, byobu, tmux, python-setuptools, python-twisted, python-txaws,7packages: [bzr, byobu, tmux, python-setuptools, python-twisted,
8 python-zookeeper, juju]8 python-zookeeper, juju, python-txaws]
9runcmd: [sudo mkdir -p /var/lib/juju, sudo mkdir9runcmd: [sudo mkdir -p /var/lib/juju, sudo mkdir
10 -p /var/log/juju, 'JUJU_MACHINE_ID=passport JUJU_ZOOKEEPER=cotswold:2181,longleat:218110 -p /var/log/juju, 'JUJU_MACHINE_ID=passport JUJU_ZOOKEEPER=cotswold:2181,longleat:2181
11 python -m juju.agents.machine -n --logfile=/var/log/juju/machine-agent.log11 python -m juju.agents.machine -n --logfile=/var/log/juju/machine-agent.log
1212
=== modified file 'juju/providers/common/tests/data/cloud_init_ppa'
--- juju/providers/common/tests/data/cloud_init_ppa 2012-10-09 18:55:55 +0000
+++ juju/providers/common/tests/data/cloud_init_ppa 2012-11-23 21:00:27 +0000
@@ -6,8 +6,8 @@
6machine-data: {juju-provider-type: dummy, juju-zookeeper-hosts: 'cotswold:2181,longleat:2181',6machine-data: {juju-provider-type: dummy, juju-zookeeper-hosts: 'cotswold:2181,longleat:2181',
7 machine-id: passport}7 machine-id: passport}
8output: {all: '| tee -a /var/log/cloud-init-output.log'}8output: {all: '| tee -a /var/log/cloud-init-output.log'}
9packages: [bzr, byobu, tmux, python-setuptools, python-twisted, python-txaws, python-zookeeper,9packages: [bzr, byobu, tmux, python-setuptools, python-twisted, python-zookeeper,
10 juju]10 juju, python-txaws]
11runcmd: [sudo mkdir -p /var/lib/juju, sudo mkdir -p /var/log/juju, 'cat >> /etc/init/juju-machine-agent.conf11runcmd: [sudo mkdir -p /var/lib/juju, sudo mkdir -p /var/log/juju, 'cat >> /etc/init/juju-machine-agent.conf
12 <<EOF12 <<EOF
1313
1414
=== modified file 'juju/providers/common/tests/data/cloud_init_ppa_apt_proxy'
--- juju/providers/common/tests/data/cloud_init_ppa_apt_proxy 2012-10-09 18:55:55 +0000
+++ juju/providers/common/tests/data/cloud_init_ppa_apt_proxy 2012-11-23 21:00:27 +0000
@@ -7,8 +7,8 @@
7machine-data: {juju-provider-type: dummy, juju-zookeeper-hosts: 'cotswold:2181,longleat:2181',7machine-data: {juju-provider-type: dummy, juju-zookeeper-hosts: 'cotswold:2181,longleat:2181',
8 machine-id: passport}8 machine-id: passport}
9output: {all: '| tee -a /var/log/cloud-init-output.log'}9output: {all: '| tee -a /var/log/cloud-init-output.log'}
10packages: [bzr, byobu, tmux, python-setuptools, python-twisted, python-txaws, python-zookeeper,10packages: [bzr, byobu, tmux, python-setuptools, python-twisted, python-zookeeper,
11 juju]11 juju, python-txaws]
12runcmd: [sudo mkdir -p /var/lib/juju, sudo mkdir -p /var/log/juju, 'cat >> /etc/init/juju-machine-agent.conf12runcmd: [sudo mkdir -p /var/lib/juju, sudo mkdir -p /var/log/juju, 'cat >> /etc/init/juju-machine-agent.conf
13 <<EOF13 <<EOF
1414
1515
=== modified file 'juju/providers/common/tests/data/cloud_init_proposed'
--- juju/providers/common/tests/data/cloud_init_proposed 2012-08-23 16:14:42 +0000
+++ juju/providers/common/tests/data/cloud_init_proposed 2012-11-23 21:00:27 +0000
@@ -6,7 +6,7 @@
6machine-data: {juju-provider-type: dummy, juju-zookeeper-hosts: 'cotswold:2181,longleat:2181',6machine-data: {juju-provider-type: dummy, juju-zookeeper-hosts: 'cotswold:2181,longleat:2181',
7 machine-id: passport}7 machine-id: passport}
8output: {all: '| tee -a /var/log/cloud-init-output.log'}8output: {all: '| tee -a /var/log/cloud-init-output.log'}
9packages: [bzr, byobu, tmux, python-setuptools, python-twisted, python-txaws, python-zookeeper, juju]9packages: [bzr, byobu, tmux, python-setuptools, python-twisted, python-zookeeper, juju, python-txaws]
10runcmd: [sudo mkdir -p /var/lib/juju, sudo mkdir -p10runcmd: [sudo mkdir -p /var/lib/juju, sudo mkdir -p
11 /var/log/juju, 'cat >> /etc/init/juju-machine-agent.conf <<EOF11 /var/log/juju, 'cat >> /etc/init/juju-machine-agent.conf <<EOF
1212
1313
=== modified file 'juju/providers/common/tests/test_cloudinit.py'
--- juju/providers/common/tests/test_cloudinit.py 2012-10-09 18:55:55 +0000
+++ juju/providers/common/tests/test_cloudinit.py 2012-11-23 21:00:27 +0000
@@ -107,6 +107,18 @@
107 "/usr/lib/pymodules/python2.7/juju/__init__.pyc")107 "/usr/lib/pymodules/python2.7/juju/__init__.pyc")
108 self.assert_render(self.construct_normal(), "cloud_init_distro")108 self.assert_render(self.construct_normal(), "cloud_init_distro")
109109
110 def test_render_image_source(self):
111 cloud_init = self.construct_normal()
112 cloud_init.set_juju_source(image=True)
113 self.assert_render(cloud_init, "cloud_init_image")
114
115 def test_render_extra_environment(self):
116 cloud_init = self.construct_normal()
117 cloud_init.set_juju_source(image=True)
118 cloud_init.set_env("http_proxy", "http://myproxy.com:3128/")
119 cloud_init.set_env("https_proxy", "http://myproxy.com:3128/")
120 self.assert_render(cloud_init, "cloud_init_image_extra_env")
121
110 def test_render_ppa_source(self):122 def test_render_ppa_source(self):
111 cloud_init = self.construct_normal()123 cloud_init = self.construct_normal()
112 cloud_init.set_juju_source(ppa=True)124 cloud_init.set_juju_source(ppa=True)
@@ -135,6 +147,12 @@
135 def test_render_bootstrap(self):147 def test_render_bootstrap(self):
136 self.assert_render(self.construct_bootstrap(), "cloud_init_bootstrap")148 self.assert_render(self.construct_bootstrap(), "cloud_init_bootstrap")
137149
150 def test_render_bootstrap_with_extra_environment(self):
151 cloud_init = self.construct_bootstrap()
152 cloud_init.set_env("http_proxy", "http://myproxy.com:3128/")
153 cloud_init.set_env("https_proxy", "http://myproxy.com:3128/")
154 self.assert_render(cloud_init, "cloud_init_bootstrap_extra_env")
155
138 def test_render_bootstrap_with_zookeepers(self):156 def test_render_bootstrap_with_zookeepers(self):
139 self.assert_render(157 self.assert_render(
140 self.construct_bootstrap(True), "cloud_init_bootstrap_zookeepers")158 self.construct_bootstrap(True), "cloud_init_bootstrap_zookeepers")
@@ -168,6 +186,13 @@
168 cloud_init.set_zookeeper_hosts(['bar1.private', 'bar2.private'])186 cloud_init.set_zookeeper_hosts(['bar1.private', 'bar2.private'])
169 self.assertEqual(['bar1.private', 'bar2.private'], cloud_init._zookeeper_hosts)187 self.assertEqual(['bar1.private', 'bar2.private'], cloud_init._zookeeper_hosts)
170188
189 def test_set_zookeeper_machines_in_private_mode(self):
190 machine = ProviderMachine('i-100', 'foo1', 'foo1.private', private_ip_address='10.0.1.0')
191 cloud_init = CloudInit()
192 cloud_init.private = True
193 cloud_init.set_zookeeper_machines([machine])
194 self.assertEqual(['10.0.1.0'], cloud_init._zookeeper_hosts)
195
171 def test_set_zookeeper_hosts_tuple(self):196 def test_set_zookeeper_hosts_tuple(self):
172 cloud_init = CloudInit()197 cloud_init = CloudInit()
173 cloud_init.set_zookeeper_hosts([('bar1.private', 9999)])198 cloud_init.set_zookeeper_hosts([('bar1.private', 9999)])
@@ -330,3 +355,14 @@
330 self.patch(juju, "__file__",355 self.patch(juju, "__file__",
331 "/usr/lib/pymodules/python2.7/juju/__init__.pyc")356 "/usr/lib/pymodules/python2.7/juju/__init__.pyc")
332 self.assertEquals(get_default_origin(), ("distro", None))357 self.assertEquals(get_default_origin(), ("distro", None))
358
359 def test_set_env(self):
360 cloudinit = CloudInit()
361 cloudinit.set_env("http_proxy", "http://myproxy.com:3128/")
362 self.assertEquals(cloudinit._extra_environment["http_proxy"], "http://myproxy.com:3128/")
363
364 def test_unset_env(self):
365 cloudinit = CloudInit()
366 cloudinit.set_env("http_proxy", "http://myproxy.com:3128/")
367 cloudinit.unset_env("http_proxy")
368 self.assertNotIn("http_proxy", cloudinit._extra_environment)
333369
=== modified file 'juju/providers/ec2/__init__.py'
--- juju/providers/ec2/__init__.py 2012-08-28 16:11:41 +0000
+++ juju/providers/ec2/__init__.py 2012-11-23 21:00:27 +0000
@@ -149,12 +149,13 @@
149 % (", ".join(instance_ids), message))149 % (", ".join(instance_ids), message))
150150
151 machines = []151 machines = []
152 private = self.config.get("vpc_id") is not None
152 for instance in instances:153 for instance in instances:
153 if instance.instance_state not in ("running", "pending"):154 if instance.instance_state not in ("running", "pending"):
154 continue155 continue
155 if group_name not in instance.reservation.groups:156 if group_name not in [g[1] for g in instance.reservation.groups]:
156 continue157 continue
157 machines.append(machine_from_instance(instance))158 machines.append(machine_from_instance(instance, private))
158159
159 if instance_ids:160 if instance_ids:
160 # We were asked for a specific list of machines, and if we can't161 # We were asked for a specific list of machines, and if we can't
161162
=== modified file 'juju/providers/ec2/launch.py'
--- juju/providers/ec2/launch.py 2012-07-05 21:49:12 +0000
+++ juju/providers/ec2/launch.py 2012-11-23 21:00:27 +0000
@@ -38,15 +38,20 @@
38 spec = yield get_machine_spec(self._provider.config, self._constraints)38 spec = yield get_machine_spec(self._provider.config, self._constraints)
39 security_groups = yield self._ensure_groups(machine_id)39 security_groups = yield self._ensure_groups(machine_id)
4040
41 subnet = self._provider.config.get("subnet_id")
42 kw = {
43 'min_count': 1,
44 'max_count': 1,
45 'image_id': spec.image_id,
46 'instance_type': spec.instance_type,
47 'availability_zone': availability_zone,
48 'user_data': user_data,
49 }
50 if subnet:
51 kw['subnet_id'] = subnet
52 kw['security_group_ids'] = security_groups
41 log.debug("Launching with machine spec %s", spec)53 log.debug("Launching with machine spec %s", spec)
42 instances = yield self._provider.ec2.run_instances(54 instances = yield self._provider.ec2.run_instances(**kw)
43 min_count=1,
44 max_count=1,
45 image_id=spec.image_id,
46 instance_type=spec.instance_type,
47 security_groups=security_groups,
48 availability_zone=availability_zone,
49 user_data=user_data)
5055
51 returnValue([machine_from_instance(i) for i in instances])56 returnValue([machine_from_instance(i) for i in instances])
5257
@@ -68,18 +73,24 @@
68 self._provider.environment_name, machine_id)73 self._provider.environment_name, machine_id)
6974
70 security_groups = yield self._provider.ec2.describe_security_groups()75 security_groups = yield self._provider.ec2.describe_security_groups()
71 group_ids = [group.name for group in security_groups]76 group_names = [group.name for group in security_groups]
77 vpc_id = self._provider.config.get("vpc_id")
7278
73 # Create the provider group if doesn't exist.79 # Create the provider group if doesn't exist.
74 if not juju_group in group_ids:80 if juju_group in group_names:
81 for group in security_groups:
82 if group.name == juju_group:
83 juju_group_id = group.id
84 else:
75 log.debug("Creating juju provider group %s", juju_group)85 log.debug("Creating juju provider group %s", juju_group)
76 yield self._provider.ec2.create_security_group(86 juju_group_id = yield self._provider.ec2.create_security_group(
77 juju_group,87 juju_group,
78 "juju group for %s" % self._provider.environment_name)88 "juju group for %s" % self._provider.environment_name,
89 vpc_id=vpc_id)
7990
80 # Authorize SSH.91 # Authorize SSH.
81 yield self._provider.ec2.authorize_security_group(92 yield self._provider.ec2.authorize_security_group(
82 juju_group,93 group_id=juju_group_id,
83 ip_protocol="tcp",94 ip_protocol="tcp",
84 from_port="22", to_port="22",95 from_port="22", to_port="22",
85 cidr_ip="0.0.0.0/0")96 cidr_ip="0.0.0.0/0")
@@ -90,15 +101,20 @@
90101
91 # Authorize Internal ZK Traffic102 # Authorize Internal ZK Traffic
92 yield self._provider.ec2.authorize_security_group(103 yield self._provider.ec2.authorize_security_group(
93 juju_group,104 group_id=juju_group_id,
94 source_group_name=juju_group,105 source_group_name=juju_group,
95 source_group_owner_id=groups_info.pop().owner_id)106 source_group_owner_id=groups_info.pop().owner_id)
96107
97 # Create the machine-specific group if it does not already exist108 # Create the machine-specific group if it does not already exist
98 if not juju_machine_group in group_ids:109 if juju_machine_group in group_names:
99 yield self._provider.ec2.create_security_group(110 for group in security_groups:
111 if group.name == juju_machine_group:
112 juju_machine_group_id = group.id
113 else:
114 juju_machine_group_id = yield self._provider.ec2.create_security_group(
100 juju_machine_group,115 juju_machine_group,
101 "juju group for %s machine %s" % (116 "juju group for %s machine %s" % (
102 self._provider.environment_name, machine_id))117 self._provider.environment_name, machine_id),
118 vpc_id=vpc_id)
103119
104 returnValue([juju_group, juju_machine_group])120 returnValue([juju_group_id, juju_machine_group_id])
105121
=== modified file 'juju/providers/ec2/machine.py'
--- juju/providers/ec2/machine.py 2011-10-11 10:59:04 +0000
+++ juju/providers/ec2/machine.py 2012-11-23 21:00:27 +0000
@@ -8,15 +8,19 @@
8 """8 """
99
1010
11def machine_from_instance(instance):11def machine_from_instance(instance, private=False):
12 """Create an :class:`EC2ProviderMachine` from a txaws :class:`Instance`12 """Create an :class:`EC2ProviderMachine` from a txaws :class:`Instance`
1313
14 :param instance: the EC2 Instance14 :param instance: the EC2 Instance
1515
16 :return: a matching :class:`EC2ProviderMachine`16 :return: a matching :class:`EC2ProviderMachine`
17 """17 """
18 return EC2ProviderMachine(18 params = [
19 instance.instance_id,19 instance.instance_id,
20 instance.dns_name,20 instance.dns_name,
21 instance.private_dns_name,21 instance.private_dns_name,
22 instance.instance_state)22 instance.instance_state,
23 instance.private_ip_address]
24 if private:
25 params[1] = params[2] = instance.private_ip_address
26 return EC2ProviderMachine(*params)
2327
=== modified file 'juju/providers/ec2/securitygroup.py'
--- juju/providers/ec2/securitygroup.py 2012-07-05 21:49:12 +0000
+++ juju/providers/ec2/securitygroup.py 2012-11-23 21:00:27 +0000
@@ -6,14 +6,32 @@
6from .utils import log6from .utils import log
77
88
9@inlineCallbacks
10def _get_security_group_id(group_name, ec2):
11 groups = yield ec2.describe_security_groups()
12 for group in groups:
13 if group.name == group_name:
14 returnValue(group.id)
15
16
9def _get_juju_security_group(provider):17def _get_juju_security_group(provider):
10 """Get EC2 security group name for environment of `provider`."""18 """Get EC2 security group name for environment of `provider`."""
11 return "juju-%s" % provider.environment_name19 return "juju-%s" % provider.environment_name
1220
1321
22def _get_juju_security_group_id(provider):
23 name = "juju-%s" % provider.environment_name
24 return _get_security_group_id(name, provider.ec2)
25
26
14def _get_machine_group_name(provider, machine_id):27def _get_machine_group_name(provider, machine_id):
28 return "juju-%s-%s" % (provider.environment_name, machine_id)
29
30
31def _get_machine_group_id(provider, machine_id):
15 """Get EC2 security group name associated just with `machine_id`."""32 """Get EC2 security group name associated just with `machine_id`."""
16 return "juju-%s-%s" % (provider.environment_name, machine_id)33 name = _get_machine_group_name(provider, machine_id)
34 return _get_security_group_id(name, provider.ec2)
1735
1836
19# TODO These security group functions do not handle the eventual37# TODO These security group functions do not handle the eventual
@@ -34,8 +52,9 @@
34def open_provider_port(provider, machine, machine_id, port, protocol):52def open_provider_port(provider, machine, machine_id, port, protocol):
35 """Authorize `port`/`proto` for the machine security group."""53 """Authorize `port`/`proto` for the machine security group."""
36 try:54 try:
55 group_id = yield _get_machine_group_id(provider, machine_id)
37 yield provider.ec2.authorize_security_group(56 yield provider.ec2.authorize_security_group(
38 _get_machine_group_name(provider, machine_id),57 group_id=group_id,
39 ip_protocol=protocol,58 ip_protocol=protocol,
40 from_port=str(port), to_port=str(port),59 from_port=str(port), to_port=str(port),
41 cidr_ip="0.0.0.0/0")60 cidr_ip="0.0.0.0/0")
@@ -51,8 +70,9 @@
51def close_provider_port(provider, machine, machine_id, port, protocol):70def close_provider_port(provider, machine, machine_id, port, protocol):
52 """Revoke `port`/`proto` for the machine security group."""71 """Revoke `port`/`proto` for the machine security group."""
53 try:72 try:
73 group_id = yield _get_machine_group_id(provider, machine_id)
54 yield provider.ec2.revoke_security_group(74 yield provider.ec2.revoke_security_group(
55 _get_machine_group_name(provider, machine_id),75 group_id=group_id,
56 ip_protocol=protocol,76 ip_protocol=protocol,
57 from_port=str(port), to_port=str(port),77 from_port=str(port), to_port=str(port),
58 cidr_ip="0.0.0.0/0")78 cidr_ip="0.0.0.0/0")
@@ -73,15 +93,20 @@
73 proto) pairs.93 proto) pairs.
74 """94 """
75 try:95 try:
76 security_groups = yield provider.ec2.describe_security_groups(96 security_group = None
77 _get_machine_group_name(provider, machine_id))97 security_groups = yield provider.ec2.describe_security_groups()
98 name = _get_machine_group_name(provider, machine_id)
99 for group in security_groups:
100 if group.name == name:
101 security_group = group
102 break
78 except EC2Error, e:103 except EC2Error, e:
79 raise ProviderInteractionError(104 raise ProviderInteractionError(
80 "Unexpected EC2Error getting open ports on machine %s: %s"105 "Unexpected EC2Error getting open ports on machine %s: %s"
81 % (machine.instance_id, e.get_error_messages()))106 % (machine.instance_id, e.get_error_messages()))
82107
83 opened_ports = set() # made up of (port, protocol) pairs108 opened_ports = set() # made up of (port, protocol) pairs
84 for ip_permission in security_groups[0].allowed_ips:109 for ip_permission in security_group.allowed_ips:
85 if ip_permission.cidr_ip != "0.0.0.0/0":110 if ip_permission.cidr_ip != "0.0.0.0/0":
86 continue111 continue
87 from_port = int(ip_permission.from_port)112 from_port = int(ip_permission.from_port)
@@ -110,24 +135,15 @@
110135
111136
112@inlineCallbacks137@inlineCallbacks
113def _delete_security_group(provider, group):
114 """Wrap EC2 delete_security_group."""
115 try:
116 yield provider.ec2.delete_security_group(group)
117 log.debug("Deleted security group %r", group)
118 except EC2Error, e:
119 raise ProviderInteractionError(
120 "EC2 error when attempting to delete group %s: %s" % (group, e))
121
122
123@inlineCallbacks
124def destroy_environment_security_group(provider):138def destroy_environment_security_group(provider):
125 """Delete the security group for the environment of `provider`"""139 """Delete the security group for the environment of `provider`"""
126 group = _get_juju_security_group(provider)140 group = _get_juju_security_group(provider)
127 try:141 try:
128 yield provider.ec2.delete_security_group(group)142 group_id = yield _get_juju_security_group_id(provider)
129 log.debug("Deleted environment security group %r", group)143 if group_id:
130 returnValue(True)144 yield provider.ec2.delete_security_group(id=group_id)
145 log.debug("Deleted environment security group %r", group)
146 returnValue(True)
131 except EC2Error, e:147 except EC2Error, e:
132 # Ignore, since this is only attempting to cleanup148 # Ignore, since this is only attempting to cleanup
133 log.debug(149 log.debug(
134150
=== modified file 'juju/providers/ec2/tests/common.py'
--- juju/providers/ec2/tests/common.py 2012-09-10 03:20:20 +0000
+++ juju/providers/ec2/tests/common.py 2012-11-23 21:00:27 +0000
@@ -49,8 +49,8 @@
49 def get_instance(self,49 def get_instance(self,
50 instance_id, state="running", machine_id=42, **kwargs):50 instance_id, state="running", machine_id=42, **kwargs):
51 groups = kwargs.pop("groups",51 groups = kwargs.pop("groups",
52 ["juju-%s" % self.env_name,52 [("sg-a1a1a1", "juju-%s" % self.env_name),
53 "juju-%s-%s" % (self.env_name, machine_id)])53 ("sg-b2b2b2", "juju-%s-%s" % (self.env_name, machine_id))])
54 reservation = Reservation("x", "y", groups=groups)54 reservation = Reservation("x", "y", groups=groups)
55 return Instance(instance_id, state, reservation=reservation, **kwargs)55 return Instance(instance_id, state, reservation=reservation, **kwargs)
5656
@@ -108,32 +108,33 @@
108 get_ami(*get_ami_args)108 get_ami(*get_ami_args)
109 self.mocker.result(succeed(ami_name))109 self.mocker.result(succeed(ami_name))
110110
111 def _mock_create_group(self):111 def _mock_create_group(self, vpc_id=None):
112 group_name = "juju-%s" % self.env_name112 group_name = "juju-%s" % self.env_name
113 self.ec2.create_security_group(113 self.ec2.create_security_group(
114 group_name, "juju group for %s" % self.env_name)114 group_name, "juju group for %s" % self.env_name,
115 self.mocker.result(succeed(True))115 vpc_id=vpc_id)
116 self.mocker.result(succeed("sg-a1a1a1a1"))
116117
117 self.ec2.authorize_security_group(118 self.ec2.authorize_security_group(
118 group_name, ip_protocol="tcp", from_port="22",119 group_id="sg-a1a1a1a1", ip_protocol="tcp", from_port="22",
119 to_port="22", cidr_ip="0.0.0.0/0")120 to_port="22", cidr_ip="0.0.0.0/0")
120 self.mocker.result(succeed([self.env_name]))121 self.mocker.result(succeed([self.env_name]))
121122
122 self.ec2.describe_security_groups(group_name)123 self.ec2.describe_security_groups(group_name)
123 self.mocker.result(succeed(124 self.mocker.result(succeed(
124 [SecurityGroup(group_name, "", owner_id="123")]))125 [SecurityGroup("sg-a1a1a1a1", group_name, "", owner_id="123")]))
125126
126 self.ec2.authorize_security_group(127 self.ec2.authorize_security_group(
127 group_name, source_group_name=group_name,128 group_id="sg-a1a1a1a1", source_group_name=group_name,
128 source_group_owner_id="123")129 source_group_owner_id="123")
129 self.mocker.result(succeed(True))130 self.mocker.result(succeed(True))
130131
131 def _mock_create_machine_group(self, machine_id):132 def _mock_create_machine_group(self, machine_id, vpc_id=None):
132 machine_group_name = "juju-%s-%s" % (self.env_name, machine_id)133 machine_group_name = "juju-%s-%s" % (self.env_name, machine_id)
133 self.ec2.create_security_group(134 self.ec2.create_security_group(
134 machine_group_name, "juju group for %s machine %s" % (135 machine_group_name, "juju group for %s machine %s" % (
135 self.env_name, machine_id))136 self.env_name, machine_id), vpc_id=vpc_id)
136 self.mocker.result(succeed(True))137 self.mocker.result(succeed("sg-b2b2b2b2"))
137138
138 def _mock_get_zookeeper_hosts(self, hosts=None):139 def _mock_get_zookeeper_hosts(self, hosts=None):
139 """140 """
@@ -147,7 +148,7 @@
147148
148 if hosts is None:149 if hosts is None:
149 hosts = [self.get_instance(150 hosts = [self.get_instance(
150 "i-es-zoo", private_dns_name="es.example.internal")]151 "i-es-zoo", private_dns_name="es.example.internal", private_ip_address="1.1.1.1")]
151152
152 self.s3.get_object(self.env_name, "provider-state")153 self.s3.get_object(self.env_name, "provider-state")
153 if hosts is False:154 if hosts is False:
154155
=== modified file 'juju/providers/ec2/tests/data/bootstrap_cloud_init'
--- juju/providers/ec2/tests/data/bootstrap_cloud_init 2012-08-23 16:14:42 +0000
+++ juju/providers/ec2/tests/data/bootstrap_cloud_init 2012-11-23 21:00:27 +0000
@@ -3,8 +3,8 @@
3apt_upgrade: true3apt_upgrade: true
4machine-data: {juju-provider-type: ec2, juju-zookeeper-hosts: 'localhost:2181', machine-id: '0'}4machine-data: {juju-provider-type: ec2, juju-zookeeper-hosts: 'localhost:2181', machine-id: '0'}
5output: {all: '| tee -a /var/log/cloud-init-output.log'}5output: {all: '| tee -a /var/log/cloud-init-output.log'}
6packages: [bzr, byobu, tmux, python-setuptools, python-twisted, python-txaws, python-zookeeper,6packages: [bzr, byobu, tmux, python-setuptools, python-twisted, python-zookeeper,
7 default-jre-headless, zookeeper, zookeeperd, juju]7 default-jre-headless, zookeeper, zookeeperd, juju, python-txaws]
8runcmd: [sudo mkdir -p /var/lib/juju, sudo mkdir -p /var/log/juju, 'juju-admin initialize8runcmd: [sudo mkdir -p /var/lib/juju, sudo mkdir -p /var/log/juju, 'juju-admin initialize
9 --instance-id=$(curl http://169.254.169.254/1.0/meta-data/instance-id) --admin-identity=admin:JbJ6sDGV37EHzbG9FPvttk64cmg=9 --instance-id=$(curl http://169.254.169.254/1.0/meta-data/instance-id) --admin-identity=admin:JbJ6sDGV37EHzbG9FPvttk64cmg=
10 --constraints-data=e2NwdTogbnVsbCwgaW5zdGFuY2UtdHlwZTogbTEuc21hbGwsIG1lbTogbnVsbCwgcHJvdmlkZXItdHlwZTogZWMyLCB1YnVudHUtc2VyaWVzOiBzcGxlbmRpZH0K10 --constraints-data=e2NwdTogbnVsbCwgaW5zdGFuY2UtdHlwZTogbTEuc21hbGwsIG1lbTogbnVsbCwgcHJvdmlkZXItdHlwZTogZWMyLCB1YnVudHUtc2VyaWVzOiBzcGxlbmRpZH0K
1111
=== modified file 'juju/providers/ec2/tests/data/launch_cloud_init'
--- juju/providers/ec2/tests/data/launch_cloud_init 2012-08-23 16:14:42 +0000
+++ juju/providers/ec2/tests/data/launch_cloud_init 2012-11-23 21:00:27 +0000
@@ -4,7 +4,7 @@
4machine-data: {juju-provider-type: ec2, juju-zookeeper-hosts: 'es.example.internal:2181',4machine-data: {juju-provider-type: ec2, juju-zookeeper-hosts: 'es.example.internal:2181',
5 machine-id: '1'}5 machine-id: '1'}
6output: {all: '| tee -a /var/log/cloud-init-output.log'}6output: {all: '| tee -a /var/log/cloud-init-output.log'}
7packages: [bzr, byobu, tmux, python-setuptools, python-twisted, python-txaws, python-zookeeper, juju]7packages: [bzr, byobu, tmux, python-setuptools, python-twisted, python-zookeeper, juju, python-txaws]
8runcmd: [sudo mkdir -p /var/lib/juju, sudo mkdir -p8runcmd: [sudo mkdir -p /var/lib/juju, sudo mkdir -p
9 /var/log/juju, 'cat >> /etc/init/juju-machine-agent.conf <<EOF9 /var/log/juju, 'cat >> /etc/init/juju-machine-agent.conf <<EOF
1010
1111
=== modified file 'juju/providers/ec2/tests/data/launch_cloud_init_branch'
--- juju/providers/ec2/tests/data/launch_cloud_init_branch 2012-10-09 18:55:55 +0000
+++ juju/providers/ec2/tests/data/launch_cloud_init_branch 2012-11-23 21:00:27 +0000
@@ -6,7 +6,7 @@
6machine-data: {juju-provider-type: ec2, juju-zookeeper-hosts: 'es.example.internal:2181',6machine-data: {juju-provider-type: ec2, juju-zookeeper-hosts: 'es.example.internal:2181',
7 machine-id: '1'}7 machine-id: '1'}
8output: {all: '| tee -a /var/log/cloud-init-output.log'}8output: {all: '| tee -a /var/log/cloud-init-output.log'}
9packages: [bzr, byobu, tmux, python-setuptools, python-twisted, python-txaws, python-zookeeper]9packages: [bzr, byobu, tmux, python-setuptools, python-twisted, python-zookeeper, python-txaws]
10runcmd: [sudo apt-get install -y python-txzookeeper, sudo mkdir -p /usr/lib/juju,10runcmd: [sudo apt-get install -y python-txzookeeper, sudo mkdir -p /usr/lib/juju,
11 'cd /usr/lib/juju && sudo /usr/bin/bzr co --lightweight lp:~wizard/juju-juicebar juju', cd /usr/lib/juju/juju11 'cd /usr/lib/juju && sudo /usr/bin/bzr co --lightweight lp:~wizard/juju-juicebar juju', cd /usr/lib/juju/juju
12 && sudo python setup.py develop, sudo mkdir -p /var/lib/juju, sudo mkdir -p /var/log/juju,12 && sudo python setup.py develop, sudo mkdir -p /var/lib/juju, sudo mkdir -p /var/log/juju,
1313
=== added file 'juju/providers/ec2/tests/data/launch_cloud_init_ip_address'
--- juju/providers/ec2/tests/data/launch_cloud_init_ip_address 1970-01-01 00:00:00 +0000
+++ juju/providers/ec2/tests/data/launch_cloud_init_ip_address 2012-11-23 21:00:27 +0000
@@ -0,0 +1,35 @@
1#cloud-config
2apt_update: true
3apt_upgrade: true
4machine-data: {juju-provider-type: ec2, juju-zookeeper-hosts: '1.1.1.1:2181',
5 machine-id: '1'}
6output: {all: '| tee -a /var/log/cloud-init-output.log'}
7packages: [bzr, byobu, tmux, python-setuptools, python-twisted, python-txaws, python-zookeeper, juju]
8runcmd: [sudo mkdir -p /var/lib/juju, sudo mkdir -p
9 /var/log/juju, 'cat >> /etc/init/juju-machine-agent.conf <<EOF
10
11 description "Juju machine agent"
12
13 author "Juju Team <juju@lists.ubuntu.com>"
14
15
16 start on runlevel [2345]
17
18 stop on runlevel [!2345]
19
20 respawn
21
22
23 env JUJU_MACHINE_ID="1"
24
25 env JUJU_ZOOKEEPER="1.1.1.1:2181"
26
27
28 exec python -m juju.agents.machine --nodaemon --logfile /var/log/juju/machine-agent.log
29 --session-file /var/run/juju/machine-agent.zksession >> /tmp/juju-machine-agent.output
30 2>&1
31
32 EOF
33
34 ', /sbin/start juju-machine-agent]
35ssh_authorized_keys: [zebra]
036
=== modified file 'juju/providers/ec2/tests/data/launch_cloud_init_ppa'
--- juju/providers/ec2/tests/data/launch_cloud_init_ppa 2012-10-09 18:55:55 +0000
+++ juju/providers/ec2/tests/data/launch_cloud_init_ppa 2012-11-23 21:00:27 +0000
@@ -6,7 +6,7 @@
6machine-data: {juju-provider-type: ec2, juju-zookeeper-hosts: 'es.example.internal:2181',6machine-data: {juju-provider-type: ec2, juju-zookeeper-hosts: 'es.example.internal:2181',
7 machine-id: '1'}7 machine-id: '1'}
8output: {all: '| tee -a /var/log/cloud-init-output.log'}8output: {all: '| tee -a /var/log/cloud-init-output.log'}
9packages: [bzr, byobu, tmux, python-setuptools, python-twisted, python-txaws, python-zookeeper, juju]9packages: [bzr, byobu, tmux, python-setuptools, python-twisted, python-zookeeper, juju, python-txaws]
10runcmd: [sudo mkdir -p /var/lib/juju, sudo mkdir -p10runcmd: [sudo mkdir -p /var/lib/juju, sudo mkdir -p
11 /var/log/juju, 'cat >> /etc/init/juju-machine-agent.conf <<EOF11 /var/log/juju, 'cat >> /etc/init/juju-machine-agent.conf <<EOF
1212
1313
=== modified file 'juju/providers/ec2/tests/test_bootstrap.py'
--- juju/providers/ec2/tests/test_bootstrap.py 2012-09-10 03:20:20 +0000
+++ juju/providers/ec2/tests/test_bootstrap.py 2012-11-23 21:00:27 +0000
@@ -48,7 +48,7 @@
48 instance_type="m1.small",48 instance_type="m1.small",
49 max_count=1,49 max_count=1,
50 min_count=1,50 min_count=1,
51 security_groups=["juju-moon", "juju-moon-0"],51 security_group_ids=["sg-a1a1a1a1", "sg-b2b2b2b2"],
52 availability_zone=None,52 availability_zone=None,
53 user_data=MATCH(verify_user_data))53 user_data=MATCH(verify_user_data))
5454
@@ -90,7 +90,7 @@
90 self._mock_verify()90 self._mock_verify()
91 self.ec2.describe_security_groups()91 self.ec2.describe_security_groups()
92 self.mocker.result(succeed([92 self.mocker.result(succeed([
93 SecurityGroup("juju-%s" % self.env_name, "")]))93 SecurityGroup("sg-a1a1a1a1", "juju-%s" % self.env_name, "")]))
94 self._mock_create_machine_group(0)94 self._mock_create_machine_group(0)
95 self._mock_launch_utils()95 self._mock_launch_utils()
96 self._mock_launch()96 self._mock_launch()
@@ -138,7 +138,7 @@
138 self._mock_verify()138 self._mock_verify()
139 self.ec2.describe_security_groups()139 self.ec2.describe_security_groups()
140 self.mocker.result(succeed([140 self.mocker.result(succeed([
141 SecurityGroup("juju-%s" % self.env_name, "")]))141 SecurityGroup("sg-a1a1a1a1", "juju-%s" % self.env_name, "")]))
142 self._mock_create_machine_group(0)142 self._mock_create_machine_group(0)
143 self._mock_launch_utils()143 self._mock_launch_utils()
144 self._mock_launch()144 self._mock_launch()
145145
=== modified file 'juju/providers/ec2/tests/test_launch.py'
--- juju/providers/ec2/tests/test_launch.py 2012-09-10 03:20:20 +0000
+++ juju/providers/ec2/tests/test_launch.py 2012-11-23 21:00:27 +0000
@@ -31,7 +31,7 @@
31 def _mock_launch(self, instance, expect_ami="ami-default",31 def _mock_launch(self, instance, expect_ami="ami-default",
32 expect_instance_type="m1.small",32 expect_instance_type="m1.small",
33 expect_availability_zone=None,33 expect_availability_zone=None,
34 cloud_init="launch_cloud_init"):34 cloud_init="launch_cloud_init", **extra):
3535
36 def verify_user_data(data):36 def verify_user_data(data):
37 expect_path = os.path.join(DATA_DIR, cloud_init)37 expect_path = os.path.join(DATA_DIR, cloud_init)
@@ -45,12 +45,26 @@
45 instance_type=expect_instance_type,45 instance_type=expect_instance_type,
46 max_count=1,46 max_count=1,
47 min_count=1,47 min_count=1,
48 security_groups=["juju-moon", "juju-moon-1"],
49 availability_zone=expect_availability_zone,48 availability_zone=expect_availability_zone,
50 user_data=MATCH(verify_user_data))49 user_data=MATCH(verify_user_data), **extra)
5150
52 self.mocker.result(succeed([instance]))51 self.mocker.result(succeed([instance]))
5352
53 def _mock_launch_groupname(self, instance, expect_ami="ami-default",
54 expect_instance_type="m1.small",
55 expect_availability_zone=None,
56 cloud_init="launch_cloud_init", **extra):
57 extra["security_group_ids"] = ["sg-a1a1a1a1", "sg-b2b2b2b2"]
58 self._mock_launch(instance, expect_ami, expect_instance_type, expect_availability_zone, cloud_init, **extra)
59
60 def _mock_launch_subnet(self, instance, subnet_id, expect_ami="ami-default",
61 expect_instance_type="m1.small",
62 expect_availability_zone=None,
63 cloud_init="launch_cloud_init", **extra):
64 extra["subnet_id"] = subnet_id
65 extra["security_group_ids"] = ["sg-a1a1a1a1", "sg-b2b2b2b2"]
66 self._mock_launch(instance, expect_ami, expect_instance_type, expect_availability_zone, cloud_init, **extra)
67
54 def test_bad_data(self):68 def test_bad_data(self):
55 self.mocker.replay()69 self.mocker.replay()
56 d = self.get_provider().start_machine({})70 d = self.get_provider().start_machine({})
@@ -74,13 +88,39 @@
74 self._mock_create_machine_group("1")88 self._mock_create_machine_group("1")
75 self._mock_launch_utils()89 self._mock_launch_utils()
76 self._mock_get_zookeeper_hosts()90 self._mock_get_zookeeper_hosts()
77 self._mock_launch(self.get_instance("i-foobar"))91 self._mock_launch_groupname(self.get_instance("i-foobar"))
78 self.mocker.replay()92 self.mocker.replay()
7993
80 def verify_result(result):94 def verify_result(result):
81 (machine,) = result95 (machine,) = result
82 self.assert_machine(machine, "i-foobar", "")96 self.assert_machine(machine, "i-foobar", "")
83 provider = self.get_provider()97 provider = self.get_provider()
98 d = provider.start_machine({
99 "machine-id": "1", "constraints": self.constraints})
100 d.addCallback(verify_result)
101 return d
102
103 def test_provider_launch_with_subnet_and_vpc(self):
104 vpc_id = "vpc-a1d4f2"
105 self.ec2.describe_security_groups()
106 self.mocker.result(succeed([]))
107 self._mock_create_group(vpc_id=vpc_id)
108 self._mock_create_machine_group("1", vpc_id=vpc_id)
109 self._mock_launch_utils()
110 self._mock_get_zookeeper_hosts()
111 self._mock_launch_subnet(
112 self.get_instance("i-foobar", private_ip_address="1.1.1.1"),
113 "subnet-a7f22c3e",
114 cloud_init="launch_cloud_init_ip_address"
115 )
116 self.mocker.replay()
117
118 def verify_result(result):
119 (machine,) = result
120 self.assert_machine(machine, "i-foobar", "")
121 provider = self.get_provider()
122 provider.config["subnet_id"] = "subnet-a7f22c3e"
123 provider.config["vpc_id"] = vpc_id
84 d = provider.start_machine({124 d = provider.start_machine({
85 "machine-id": "1", "constraints": self.constraints})125 "machine-id": "1", "constraints": self.constraints})
86 d.addCallback(verify_result)126 d.addCallback(verify_result)
@@ -104,7 +144,7 @@
104 self._mock_create_machine_group("1")144 self._mock_create_machine_group("1")
105 self._mock_launch_utils()145 self._mock_launch_utils()
106 self._mock_get_zookeeper_hosts()146 self._mock_get_zookeeper_hosts()
107 self._mock_launch(147 self._mock_launch_groupname(
108 self.get_instance("i-foobar"),148 self.get_instance("i-foobar"),
109 cloud_init="launch_cloud_init_branch")149 cloud_init="launch_cloud_init_branch")
110 self.mocker.replay()150 self.mocker.replay()
@@ -124,7 +164,7 @@
124 self._mock_create_machine_group("1")164 self._mock_create_machine_group("1")
125 self._mock_launch_utils()165 self._mock_launch_utils()
126 self._mock_get_zookeeper_hosts()166 self._mock_get_zookeeper_hosts()
127 self._mock_launch(167 self._mock_launch_groupname(
128 self.get_instance("i-foobar"),168 self.get_instance("i-foobar"),
129 cloud_init="launch_cloud_init_ppa")169 cloud_init="launch_cloud_init_ppa")
130 self.mocker.replay()170 self.mocker.replay()
@@ -144,7 +184,7 @@
144 self._mock_create_machine_group("1")184 self._mock_create_machine_group("1")
145 self._mock_launch_utils()185 self._mock_launch_utils()
146 self._mock_get_zookeeper_hosts()186 self._mock_get_zookeeper_hosts()
147 self._mock_launch(187 self._mock_launch_groupname(
148 self.get_instance("i-foobar"),188 self.get_instance("i-foobar"),
149 cloud_init="launch_cloud_init")189 cloud_init="launch_cloud_init")
150 self.mocker.replay()190 self.mocker.replay()
@@ -159,14 +199,15 @@
159 def test_provider_launch_existing_security_group(self):199 def test_provider_launch_existing_security_group(self):
160 """Verify that the launch works if the env security group exists"""200 """Verify that the launch works if the env security group exists"""
161 instance = Instance("i-foobar", "running", dns_name="x1.example.com")201 instance = Instance("i-foobar", "running", dns_name="x1.example.com")
162 security_group = SecurityGroup("juju-moon", "some description")202 security_group = SecurityGroup("sg-a1a1a1a1", "juju-moon", "some description")
163203
164 self.ec2.describe_security_groups()204 self.ec2.describe_security_groups()
165 self.mocker.result(succeed([security_group]))205 self.mocker.result(succeed([security_group]))
206 self.mocker.count(1)
166 self._mock_create_machine_group("1")207 self._mock_create_machine_group("1")
167 self._mock_launch_utils()208 self._mock_launch_utils()
168 self._mock_get_zookeeper_hosts()209 self._mock_get_zookeeper_hosts()
169 self._mock_launch(instance)210 self._mock_launch_groupname(instance)
170 self.mocker.replay()211 self.mocker.replay()
171212
172 provider = self.get_provider()213 provider = self.get_provider()
@@ -180,15 +221,13 @@
180 def test_provider_launch_existing_machine_security_group(self):221 def test_provider_launch_existing_machine_security_group(self):
181 """Verify that the launch works if the machine security group exists"""222 """Verify that the launch works if the machine security group exists"""
182 instance = Instance("i-foobar", "running", dns_name="x1.example.com")223 instance = Instance("i-foobar", "running", dns_name="x1.example.com")
183 machine_group = SecurityGroup(224 machine_group = SecurityGroup("sg-b2b2b2b2", "juju-moon-1", "some description")
184 "juju-moon-1", "some description")
185
186 self.ec2.describe_security_groups()225 self.ec2.describe_security_groups()
187 self.mocker.result(succeed([machine_group]))226 self.mocker.result(succeed([machine_group]))
188 self._mock_create_group()227 self._mock_create_group()
189 self._mock_launch_utils()228 self._mock_launch_utils()
190 self._mock_get_zookeeper_hosts()229 self._mock_get_zookeeper_hosts()
191 self._mock_launch(instance)230 self._mock_launch_groupname(instance)
192 self.mocker.replay()231 self.mocker.replay()
193232
194 provider = self.get_provider()233 provider = self.get_provider()
@@ -206,15 +245,13 @@
206 that security group, generally because it is still shutting245 that security group, generally because it is still shutting
207 down."""246 down."""
208 instance = Instance("i-foobar", "running", dns_name="x1.example.com")247 instance = Instance("i-foobar", "running", dns_name="x1.example.com")
209 machine_group = SecurityGroup(248 machine_group = SecurityGroup("sg-b2b2b2b2", "juju-moon-1", "some description")
210 "juju-moon-1", "some description")
211
212 self.ec2.describe_security_groups()249 self.ec2.describe_security_groups()
213 self.mocker.result(succeed([machine_group]))250 self.mocker.result(succeed([machine_group]))
214 self._mock_create_group()251 self._mock_create_group()
215 self._mock_launch_utils()252 self._mock_launch_utils()
216 self._mock_get_zookeeper_hosts()253 self._mock_get_zookeeper_hosts()
217 self._mock_launch(instance)254 self._mock_launch_groupname(instance)
218 self.mocker.replay()255 self.mocker.replay()
219256
220 provider = self.get_provider()257 provider = self.get_provider()
@@ -266,7 +303,7 @@
266 get_ami_args=(303 get_ami_args=(
267 "splendid", "amd64", "somewhere-else-1", False, False))304 "splendid", "amd64", "somewhere-else-1", False, False))
268 self._mock_get_zookeeper_hosts()305 self._mock_get_zookeeper_hosts()
269 self._mock_launch(self.get_instance("i-foobar"), "ami-regional")306 self._mock_launch_groupname(self.get_instance("i-foobar"), "ami-regional")
270 self.mocker.replay()307 self.mocker.replay()
271308
272 provider = self.get_provider()309 provider = self.get_provider()
@@ -283,7 +320,7 @@
283 ami_name="ami-fancy-cluster",320 ami_name="ami-fancy-cluster",
284 get_ami_args=("vast", "amd64", "us-east-1", True, False))321 get_ami_args=("vast", "amd64", "us-east-1", True, False))
285 self._mock_get_zookeeper_hosts()322 self._mock_get_zookeeper_hosts()
286 self._mock_launch(323 self._mock_launch_groupname(
287 self.get_instance("i-foobar"), "ami-fancy-cluster",324 self.get_instance("i-foobar"), "ami-fancy-cluster",
288 expect_instance_type="cc2.8xlarge",325 expect_instance_type="cc2.8xlarge",
289 expect_availability_zone="us-east-1b")326 expect_availability_zone="us-east-1b")
@@ -302,7 +339,7 @@
302 self._mock_launch_utils(339 self._mock_launch_utils(
303 get_ami_args=("dribbly", "amd64", "us-east-1", False, False))340 get_ami_args=("dribbly", "amd64", "us-east-1", False, False))
304 self._mock_get_zookeeper_hosts()341 self._mock_get_zookeeper_hosts()
305 self._mock_launch(342 self._mock_launch_groupname(
306 self.get_instance("i-foobar"), "ami-default",343 self.get_instance("i-foobar"), "ami-default",
307 expect_instance_type="c1.xlarge")344 expect_instance_type="c1.xlarge")
308 self.mocker.replay()345 self.mocker.replay()
309346
=== modified file 'juju/providers/ec2/tests/test_machine.py'
--- juju/providers/ec2/tests/test_machine.py 2011-10-11 14:03:11 +0000
+++ juju/providers/ec2/tests/test_machine.py 2012-11-23 21:00:27 +0000
@@ -11,7 +11,8 @@
11 instance = Instance(11 instance = Instance(
12 "i-foobar", "oscillating",12 "i-foobar", "oscillating",
13 dns_name="public",13 dns_name="public",
14 private_dns_name="private")14 private_dns_name="private",
15 private_ip_address="10.0.1.10")
1516
16 machine = machine_from_instance(instance)17 machine = machine_from_instance(instance)
17 self.assertTrue(isinstance(machine, EC2ProviderMachine))18 self.assertTrue(isinstance(machine, EC2ProviderMachine))
@@ -19,3 +20,19 @@
19 self.assertEquals(machine.dns_name, "public")20 self.assertEquals(machine.dns_name, "public")
20 self.assertEquals(machine.private_dns_name, "private")21 self.assertEquals(machine.private_dns_name, "private")
21 self.assertEquals(machine.state, "oscillating")22 self.assertEquals(machine.state, "oscillating")
23 self.assertEquals(machine.private_ip_address, "10.0.1.10")
24
25 def test_machine_from_instance_private_mode(self):
26 instance = Instance(
27 "i-foobar", "oscillating",
28 dns_name="public",
29 private_dns_name="private",
30 private_ip_address="10.0.1.10")
31
32 machine = machine_from_instance(instance, True)
33 self.assertTrue(isinstance(machine, EC2ProviderMachine))
34 self.assertEquals(machine.instance_id, "i-foobar")
35 self.assertEquals(machine.dns_name, "10.0.1.10")
36 self.assertEquals(machine.private_dns_name, "10.0.1.10")
37 self.assertEquals(machine.state, "oscillating")
38 self.assertEquals(machine.private_ip_address, "10.0.1.10")
2239
=== modified file 'juju/providers/ec2/tests/test_securitygroup.py'
--- juju/providers/ec2/tests/test_securitygroup.py 2012-07-05 21:49:12 +0000
+++ juju/providers/ec2/tests/test_securitygroup.py 2012-11-23 21:00:27 +0000
@@ -18,9 +18,12 @@
18 def test_open_provider_port(self):18 def test_open_provider_port(self):
19 """Verify open port op will use the correct EC2 API."""19 """Verify open port op will use the correct EC2 API."""
20 log = self.capture_logging("juju.ec2", level=logging.DEBUG)20 log = self.capture_logging("juju.ec2", level=logging.DEBUG)
21 secgroup = SecurityGroup("sg-a1a1a1", "juju-moon-machine-1", "some description")
22 self.ec2.describe_security_groups()
23 self.mocker.result(succeed([secgroup]))
21 machine = ProviderMachine("i-foobar", "x1.example.com")24 machine = ProviderMachine("i-foobar", "x1.example.com")
22 self.ec2.authorize_security_group(25 self.ec2.authorize_security_group(
23 "juju-moon-machine-1", ip_protocol="tcp", from_port="80",26 group_id=secgroup.id, ip_protocol="tcp", from_port="80",
24 to_port="80", cidr_ip="0.0.0.0/0")27 to_port="80", cidr_ip="0.0.0.0/0")
25 self.mocker.result(succeed(True))28 self.mocker.result(succeed(True))
26 self.mocker.replay()29 self.mocker.replay()
@@ -35,9 +38,12 @@
35 def test_close_provider_port(self):38 def test_close_provider_port(self):
36 """Verify close port op will use the correct EC2 API."""39 """Verify close port op will use the correct EC2 API."""
37 log = self.capture_logging("juju.ec2", level=logging.DEBUG)40 log = self.capture_logging("juju.ec2", level=logging.DEBUG)
41 secgroup = SecurityGroup("sg-b2b2b2", "juju-moon-machine-1", "some description")
42 self.ec2.describe_security_groups()
43 self.mocker.result(succeed([secgroup]))
38 machine = ProviderMachine("i-foobar", "x1.example.com")44 machine = ProviderMachine("i-foobar", "x1.example.com")
39 self.ec2.revoke_security_group(45 self.ec2.revoke_security_group(
40 "juju-moon-machine-1", ip_protocol="tcp", from_port="80",46 group_id="sg-b2b2b2", ip_protocol="tcp", from_port="80",
41 to_port="80", cidr_ip="0.0.0.0/0")47 to_port="80", cidr_ip="0.0.0.0/0")
42 self.mocker.result(succeed(True))48 self.mocker.result(succeed(True))
43 self.mocker.replay()49 self.mocker.replay()
@@ -51,9 +57,10 @@
51 @inlineCallbacks57 @inlineCallbacks
52 def test_get_provider_opened_ports(self):58 def test_get_provider_opened_ports(self):
53 """Verify correct parse of IP perms from describe_security_group."""59 """Verify correct parse of IP perms from describe_security_group."""
54 self.ec2.describe_security_groups("juju-moon-machine-1")60 self.ec2.describe_security_groups()
55 self.mocker.result(succeed([61 self.mocker.result(succeed([
56 SecurityGroup(62 SecurityGroup(
63 "sg-a1b2c3d4e5f6",
57 "juju-%s-machine-1" % self.env_name,64 "juju-%s-machine-1" % self.env_name,
58 "a security group name",65 "a security group name",
59 ips=[66 ips=[
@@ -76,9 +83,12 @@
76 @inlineCallbacks83 @inlineCallbacks
77 def test_open_provider_port_unknown_instance(self):84 def test_open_provider_port_unknown_instance(self):
78 """Verify open port op will use the correct EC2 API."""85 """Verify open port op will use the correct EC2 API."""
86 secgroup = SecurityGroup("sg-a1a1a1", "juju-moon-machine-1", "some description")
87 self.ec2.describe_security_groups()
88 self.mocker.result(succeed([secgroup]))
79 machine = ProviderMachine("i-foobar", "x1.example.com")89 machine = ProviderMachine("i-foobar", "x1.example.com")
80 self.ec2.authorize_security_group(90 self.ec2.authorize_security_group(
81 "juju-moon-machine-1", ip_protocol="tcp", from_port="80",91 group_id="sg-a1a1a1", ip_protocol="tcp", from_port="80",
82 to_port="80", cidr_ip="0.0.0.0/0")92 to_port="80", cidr_ip="0.0.0.0/0")
83 self.mocker.result(fail(self.get_ec2_error("i-foobar")))93 self.mocker.result(fail(self.get_ec2_error("i-foobar")))
84 self.mocker.replay()94 self.mocker.replay()
@@ -95,9 +105,12 @@
95 @inlineCallbacks105 @inlineCallbacks
96 def test_close_provider_port_unknown_instance(self):106 def test_close_provider_port_unknown_instance(self):
97 """Verify open port op will use the correct EC2 API."""107 """Verify open port op will use the correct EC2 API."""
108 secgroup = SecurityGroup("sg-b2b2b2", "juju-moon-machine-1", "some description")
109 self.ec2.describe_security_groups()
110 self.mocker.result(succeed([secgroup]))
98 machine = ProviderMachine("i-foobar", "x1.example.com")111 machine = ProviderMachine("i-foobar", "x1.example.com")
99 self.ec2.revoke_security_group(112 self.ec2.revoke_security_group(
100 "juju-moon-machine-1", ip_protocol="tcp", from_port="80",113 group_id="sg-b2b2b2", ip_protocol="tcp", from_port="80",
101 to_port="80", cidr_ip="0.0.0.0/0")114 to_port="80", cidr_ip="0.0.0.0/0")
102 self.mocker.result(fail(self.get_ec2_error("i-foobar")))115 self.mocker.result(fail(self.get_ec2_error("i-foobar")))
103 self.mocker.replay()116 self.mocker.replay()
@@ -114,7 +127,7 @@
114 @inlineCallbacks127 @inlineCallbacks
115 def test_get_provider_opened_ports_unknown_instance(self):128 def test_get_provider_opened_ports_unknown_instance(self):
116 """Verify open port op will use the correct EC2 API."""129 """Verify open port op will use the correct EC2 API."""
117 self.ec2.describe_security_groups("juju-moon-machine-1")130 self.ec2.describe_security_groups()
118 self.mocker.result(fail(self.get_ec2_error("i-foobar")))131 self.mocker.result(fail(self.get_ec2_error("i-foobar")))
119 self.mocker.replay()132 self.mocker.replay()
120133
@@ -134,7 +147,10 @@
134 @inlineCallbacks147 @inlineCallbacks
135 def test_destroy_environment_security_group(self):148 def test_destroy_environment_security_group(self):
136 """Verify the deletion of the security group for the environment"""149 """Verify the deletion of the security group for the environment"""
137 self.ec2.delete_security_group("juju-moon")150 secgroup = SecurityGroup("sg-0e0e0e", "juju-moon", "some description")
151 self.ec2.describe_security_groups()
152 self.mocker.result(succeed([secgroup]))
153 self.ec2.delete_security_group(id="sg-0e0e0e")
138 self.mocker.result(succeed(True))154 self.mocker.result(succeed(True))
139 self.mocker.replay()155 self.mocker.replay()
140156
@@ -143,10 +159,12 @@
143 self.assertTrue(destroyed)159 self.assertTrue(destroyed)
144160
145 @inlineCallbacks161 @inlineCallbacks
146 def test_destroy_environment_security_group_missing(self):162 def test_destroy_environment_security_group_ignores_failure(self):
147 """Verify ignores errors in deleting the env security group"""
148 log = self.capture_logging(level=logging.DEBUG)163 log = self.capture_logging(level=logging.DEBUG)
149 self.ec2.delete_security_group("juju-moon")164 secgroup = SecurityGroup("sg-0e0e0e", "juju-moon", "some description")
165 self.ec2.describe_security_groups()
166 self.mocker.result(succeed([secgroup]))
167 self.ec2.delete_security_group(id="sg-0e0e0e")
150 self.mocker.result(fail(168 self.mocker.result(fail(
151 self.get_ec2_error(169 self.get_ec2_error(
152 "juju-moon",170 "juju-moon",
@@ -162,3 +180,14 @@
162 "juju-moon: Error Message: The security group "180 "juju-moon: Error Message: The security group "
163 "'juju-moon' does not exist",181 "'juju-moon' does not exist",
164 log.getvalue())182 log.getvalue())
183
184 @inlineCallbacks
185 def test_destroy_environment_security_group_missing(self):
186 """Verify ignores errors in deleting the env security group"""
187 self.ec2.describe_security_groups()
188 self.mocker.result(succeed([]))
189 self.mocker.replay()
190
191 provider = self.get_provider()
192 destroyed = yield destroy_environment_security_group(provider)
193 self.assertFalse(destroyed)
165194
=== modified file 'juju/providers/ec2/tests/test_shutdown.py'
--- juju/providers/ec2/tests/test_shutdown.py 2012-07-09 22:59:18 +0000
+++ juju/providers/ec2/tests/test_shutdown.py 2012-11-23 21:00:27 +0000
@@ -2,12 +2,13 @@
22
3from juju.lib.testing import TestCase3from juju.lib.testing import TestCase
4from juju.providers.ec2.tests.common import (4from juju.providers.ec2.tests.common import (
5 EC2TestMixin, MATCH_GROUP, Observed, MockInstanceState)5 EC2TestMixin, MATCH_GROUP, MockInstanceState)
66
7from juju.machine import ProviderMachine7from juju.machine import ProviderMachine
88
9from juju.errors import MachinesNotFound, ProviderError9from juju.errors import MachinesNotFound, ProviderError
10from juju.providers.ec2.machine import EC2ProviderMachine10from juju.providers.ec2.machine import EC2ProviderMachine
11from txaws.ec2.model import SecurityGroup
1112
1213
13class SomeError(Exception):14class SomeError(Exception):
@@ -156,10 +157,11 @@
156 ("i-canbekilled", "running", "shutting-down"),157 ("i-canbekilled", "running", "shutting-down"),
157 ("i-canbekilledtoo", "pending", "shutting-down")]))158 ("i-canbekilledtoo", "pending", "shutting-down")]))
158159
159 self.ec2.delete_security_group(MATCH_GROUP)160 secgroup = SecurityGroup("sg-0a0a0a", "juju-moon", "some description")
160 deleted_groups = Observed()161 self.ec2.describe_security_groups()
161 self.mocker.call(deleted_groups.add)162 self.mocker.result(succeed([secgroup]))
162 self.mocker.count(1)163 self.ec2.delete_security_group(id="sg-0a0a0a")
164 self.mocker.result(succeed(True))
163165
164 self.mocker.replay()166 self.mocker.replay()
165167
@@ -169,9 +171,6 @@
169 self.assertEquals(machine_1.instance_id, "i-canbekilled")171 self.assertEquals(machine_1.instance_id, "i-canbekilled")
170 self.assertTrue(isinstance(machine_2, EC2ProviderMachine))172 self.assertTrue(isinstance(machine_2, EC2ProviderMachine))
171 self.assertEquals(machine_2.instance_id, "i-canbekilledtoo")173 self.assertEquals(machine_2.instance_id, "i-canbekilledtoo")
172 self.assertEquals(
173 deleted_groups.items,
174 set(["juju-moon"]))
175174
176 @inlineCallbacks175 @inlineCallbacks
177 def test_s3_failure(self):176 def test_s3_failure(self):
@@ -189,7 +188,10 @@
189 self.ec2.terminate_instances("i-canbekilled")188 self.ec2.terminate_instances("i-canbekilled")
190 self.mocker.result(succeed([189 self.mocker.result(succeed([
191 ("i-canbekilled", "running", "shutting-down")]))190 ("i-canbekilled", "running", "shutting-down")]))
192 self.ec2.delete_security_group("juju-moon")191 secgroup = SecurityGroup("sg-0a0a0a", "juju-moon", "some description")
192 self.ec2.describe_security_groups()
193 self.mocker.result(succeed([secgroup]))
194 self.ec2.delete_security_group(id="sg-0a0a0a")
193 self.mocker.result(succeed(True))195 self.mocker.result(succeed(True))
194 self.mocker.replay()196 self.mocker.replay()
195197
@@ -208,7 +210,10 @@
208 self.mocker.result(succeed(None))210 self.mocker.result(succeed(None))
209 self.ec2.describe_instances()211 self.ec2.describe_instances()
210 self.mocker.result(succeed([]))212 self.mocker.result(succeed([]))
211 self.ec2.delete_security_group("juju-moon")213 secgroup = SecurityGroup("sg-0a0a0a", "juju-moon", "some description")
214 self.ec2.describe_security_groups()
215 self.mocker.result(succeed([secgroup]))
216 self.ec2.delete_security_group(id="sg-0a0a0a")
212 self.mocker.result(fail(217 self.mocker.result(fail(
213 self.get_ec2_error(218 self.get_ec2_error(
214 "juju-moon",219 "juju-moon",
215220
=== modified file 'juju/providers/ec2/utils.py'
--- juju/providers/ec2/utils.py 2012-07-05 21:49:12 +0000
+++ juju/providers/ec2/utils.py 2012-11-23 21:00:27 +0000
@@ -6,10 +6,10 @@
6import StringIO6import StringIO
77
8from twisted.internet.defer import inlineCallbacks, returnValue8from twisted.internet.defer import inlineCallbacks, returnValue
9from twisted.web.client import getPage
10from twisted.web.error import Error9from twisted.web.error import Error
1110
12from juju.errors import ProviderError11from juju.errors import ProviderError
12from juju.lib.http_client import get_page
1313
14# We don't actually know what's available in any given region14# We don't actually know what's available in any given region
15_PLAUSIBLE_ZONES = ascii_lowercase15_PLAUSIBLE_ZONES = ascii_lowercase
@@ -102,7 +102,7 @@
102 contextFactory = VerifyingContextFactory(_CURRENT_IMAGE_HOST)102 contextFactory = VerifyingContextFactory(_CURRENT_IMAGE_HOST)
103 else:103 else:
104 contextFactory = None104 contextFactory = None
105 d = getPage(uri, contextFactory=contextFactory)105 d = get_page(uri, contextFactory=contextFactory)
106 d.addErrback(handle_404)106 d.addErrback(handle_404)
107 d.addCallback(extract_ami)107 d.addCallback(extract_ami)
108 return d108 return d
109109
=== modified file 'juju/providers/local/files.py'
--- juju/providers/local/files.py 2012-09-28 06:13:47 +0000
+++ juju/providers/local/files.py 2012-11-23 21:00:27 +0000
@@ -3,10 +3,10 @@
33
4from twisted.internet.defer import inlineCallbacks, returnValue4from twisted.internet.defer import inlineCallbacks, returnValue
5from twisted.internet.error import ConnectionRefusedError5from twisted.internet.error import ConnectionRefusedError
6from twisted.web.client import getPage
76
8from juju.errors import ProviderError, FileNotFound7from juju.errors import ProviderError, FileNotFound
9from juju.lib import serializer8from juju.lib import serializer
9from juju.lib.http_client import get_page
10from juju.lib.service import TwistedDaemonService10from juju.lib.service import TwistedDaemonService
11from juju.providers.common.files import FileStorage11from juju.providers.common.files import FileStorage
1212
@@ -55,7 +55,7 @@
55 def is_serving(self):55 def is_serving(self):
56 try:56 try:
57 storage = LocalStorage(self._storage_dir)57 storage = LocalStorage(self._storage_dir)
58 yield getPage((yield storage.get_url(SERVER_URL_KEY)))58 yield get_page((yield storage.get_url(SERVER_URL_KEY)))
59 returnValue(True)59 returnValue(True)
60 except ConnectionRefusedError:60 except ConnectionRefusedError:
61 returnValue(False)61 returnValue(False)
6262
=== modified file 'juju/providers/orchestra/files.py'
--- juju/providers/orchestra/files.py 2011-10-17 07:43:09 +0000
+++ juju/providers/orchestra/files.py 2012-11-23 21:00:27 +0000
@@ -2,10 +2,10 @@
2import urllib2import urllib
3import urlparse3import urlparse
44
5from twisted.web.client import getPage
6from twisted.web.error import Error5from twisted.web.error import Error
76
8from juju.errors import FileNotFound, ProviderError7from juju.errors import FileNotFound, ProviderError
8from juju.lib.http_client import get_page
9from juju.providers.common.utils import convert_unknown_error9from juju.providers.common.utils import convert_unknown_error
10from juju.providers.orchestra.digestauth import (10from juju.providers.orchestra.digestauth import (
11 DigestAuthenticator, get_page_auth)11 DigestAuthenticator, get_page_auth)
@@ -60,7 +60,7 @@
60 :raises: :exc:`juju.errors.FileNotFound` if the file doesn't exist60 :raises: :exc:`juju.errors.FileNotFound` if the file doesn't exist
61 """61 """
62 url = self.get_url(name)62 url = self.get_url(name)
63 d = getPage(url)63 d = get_page(url)
64 d.addCallback(StringIO)64 d.addCallback(StringIO)
65 d.addErrback(_convert_error, "GET", url, {404: FileNotFound(url)})65 d.addErrback(_convert_error, "GET", url, {404: FileNotFound(url)})
66 return d66 return d
6767
=== modified file 'juju/providers/orchestra/tests/data/bootstrap_user_data'
--- juju/providers/orchestra/tests/data/bootstrap_user_data 2012-08-23 16:14:42 +0000
+++ juju/providers/orchestra/tests/data/bootstrap_user_data 2012-11-23 21:00:27 +0000
@@ -3,8 +3,8 @@
3machine-data: {juju-provider-type: orchestra, juju-zookeeper-hosts: 'localhost:2181',3machine-data: {juju-provider-type: orchestra, juju-zookeeper-hosts: 'localhost:2181',
4 machine-id: '0'}4 machine-id: '0'}
5output: {all: '| tee -a /var/log/cloud-init-output.log'}5output: {all: '| tee -a /var/log/cloud-init-output.log'}
6packages: [bzr, byobu, tmux, python-setuptools, python-twisted, python-txaws, python-zookeeper,6packages: [bzr, byobu, tmux, python-setuptools, python-twisted, python-zookeeper,
7 default-jre-headless, zookeeper, zookeeperd, juju]7 default-jre-headless, zookeeper, zookeeperd, juju, python-txaws]
8runcmd: [sudo mkdir -p /var/lib/juju, sudo mkdir -p /var/log/juju, 'juju-admin initialize8runcmd: [sudo mkdir -p /var/lib/juju, sudo mkdir -p /var/log/juju, 'juju-admin initialize
9 --instance-id=winston-uid --admin-identity=admin:qRBXC1ubEEUqRL6wcBhgmc9xkaY=9 --instance-id=winston-uid --admin-identity=admin:qRBXC1ubEEUqRL6wcBhgmc9xkaY=
10 --constraints-data=e29yY2hlc3RyYS1jbGFzc2VzOiAnZm9vLGJhcicsIHByb3ZpZGVyLXR5cGU6IG9yY2hlc3RyYSwgdWJ1bnR1LXNlcmllczogYml6YXJyZX0K10 --constraints-data=e29yY2hlc3RyYS1jbGFzc2VzOiAnZm9vLGJhcicsIHByb3ZpZGVyLXR5cGU6IG9yY2hlc3RyYSwgdWJ1bnR1LXNlcmllczogYml6YXJyZX0K
1111
=== modified file 'juju/providers/orchestra/tests/data/launch_user_data'
--- juju/providers/orchestra/tests/data/launch_user_data 2012-08-23 16:14:42 +0000
+++ juju/providers/orchestra/tests/data/launch_user_data 2012-11-23 21:00:27 +0000
@@ -3,7 +3,7 @@
3machine-data: {juju-provider-type: orchestra, juju-zookeeper-hosts: 'jennifer:2181',3machine-data: {juju-provider-type: orchestra, juju-zookeeper-hosts: 'jennifer:2181',
4 machine-id: '42'}4 machine-id: '42'}
5output: {all: '| tee -a /var/log/cloud-init-output.log'}5output: {all: '| tee -a /var/log/cloud-init-output.log'}
6packages: [bzr, byobu, tmux, python-setuptools, python-twisted, python-txaws, python-zookeeper, juju]6packages: [bzr, byobu, tmux, python-setuptools, python-twisted, python-zookeeper, juju, python-txaws]
7runcmd: [sudo mkdir -p /var/lib/juju, sudo mkdir -p7runcmd: [sudo mkdir -p /var/lib/juju, sudo mkdir -p
8 /var/log/juju, 'cat >> /etc/init/juju-machine-agent.conf <<EOF8 /var/log/juju, 'cat >> /etc/init/juju-machine-agent.conf <<EOF
99
1010
=== modified file 'juju/unit/address.py'
--- juju/unit/address.py 2012-10-05 17:49:27 +0000
+++ juju/unit/address.py 2012-11-23 21:00:27 +0000
@@ -1,5 +1,6 @@
1"""Service units have both a public and private address.1"""Service units have both a public and private address.
2"""2"""
3import os
3import subprocess4import subprocess
45
5from twisted.internet.defer import inlineCallbacks, returnValue, succeed6from twisted.internet.defer import inlineCallbacks, returnValue, succeed
@@ -15,7 +16,9 @@
15 settings = GlobalSettingsStateManager(client)16 settings = GlobalSettingsStateManager(client)
16 provider_type = yield settings.get_provider_type()17 provider_type = yield settings.get_provider_type()
17 if provider_type == "ec2":18 if provider_type == "ec2":
18 returnValue(EC2UnitAddress())19 address = EC2UnitAddress()
20 address.private = os.environ.get("JUJU_PRIVATE") is not None
21 returnValue(address)
19 if provider_type in ("openstack", "openstack_s3"):22 if provider_type in ("openstack", "openstack_s3"):
20 returnValue(OpenStackUnitAddress())23 returnValue(OpenStackUnitAddress())
21 elif provider_type == "local":24 elif provider_type == "local":
@@ -50,6 +53,10 @@
5053
51class EC2UnitAddress(UnitAddress):54class EC2UnitAddress(UnitAddress):
5255
56 def __init__(self, *args, **kwargs):
57 super(EC2UnitAddress, self).__init__(*args, **kwargs)
58 self.private = False
59
53 @inlineCallbacks60 @inlineCallbacks
54 def get_private_address(self):61 def get_private_address(self):
55 content = yield client.getPage(62 content = yield client.getPage(
@@ -58,8 +65,12 @@
5865
59 @inlineCallbacks66 @inlineCallbacks
60 def get_public_address(self):67 def get_public_address(self):
68 if self.private:
69 field = "local-ipv4"
70 else:
71 field = "public-hostname"
61 content = yield client.getPage(72 content = yield client.getPage(
62 "http://169.254.169.254/latest/meta-data/public-hostname")73 "http://169.254.169.254/latest/meta-data/%s" % field)
63 returnValue(content.strip())74 returnValue(content.strip())
6475
6576
6677
=== modified file 'juju/unit/charm.py'
--- juju/unit/charm.py 2012-03-21 12:54:28 +0000
+++ juju/unit/charm.py 2012-11-23 21:00:27 +0000
@@ -3,12 +3,12 @@
3import shutil3import shutil
44
5from twisted.internet.defer import inlineCallbacks, returnValue5from twisted.internet.defer import inlineCallbacks, returnValue
6from twisted.web.client import downloadPage
7from twisted.web.error import Error6from twisted.web.error import Error
87
9from juju.errors import FileNotFound8from juju.errors import FileNotFound
10from juju.charm.bundle import CharmBundle9from juju.charm.bundle import CharmBundle
11from juju.lib import under10from juju.lib import under
11from juju.lib.http_client import download_page
12from juju.state.charm import CharmStateManager12from juju.state.charm import CharmStateManager
1313
1414
@@ -33,7 +33,7 @@
33 shutil.copyfileobj(open(file_path), open(local_charm_path, "w"))33 shutil.copyfileobj(open(file_path), open(local_charm_path, "w"))
34 else:34 else:
35 try:35 try:
36 yield downloadPage(charm_state.bundle_url, local_charm_path)36 yield download_page(charm_state.bundle_url, local_charm_path)
37 except Error:37 except Error:
38 raise FileNotFound(charm_state.bundle_url)38 raise FileNotFound(charm_state.bundle_url)
3939
4040
=== modified file 'juju/unit/deploy.py'
--- juju/unit/deploy.py 2012-04-04 20:21:44 +0000
+++ juju/unit/deploy.py 2012-11-23 21:00:27 +0000
@@ -80,6 +80,11 @@
80 deployment = self.deploy_factory(80 deployment = self.deploy_factory(
81 service_unit_name, self.juju_directory)81 service_unit_name, self.juju_directory)
8282
83 for env in ("http_proxy", "https_proxy", "JUJU_PRIVATE"):
84 value = os.environ.get(env)
85 if value:
86 deployment.set_env(env, value)
87
83 log.debug("Using %r for %s in %s",88 log.debug("Using %r for %s in %s",
84 deployment,89 deployment,
85 service_unit_name,90 service_unit_name,
8691
=== modified file 'juju/unit/tests/test_address.py'
--- juju/unit/tests/test_address.py 2012-10-05 17:49:27 +0000
+++ juju/unit/tests/test_address.py 2012-11-23 21:00:27 +0000
@@ -1,3 +1,4 @@
1import os
1import subprocess2import subprocess
2import zookeeper3import zookeeper
34
@@ -30,6 +31,14 @@
30 def test_get_ec2_address(self):31 def test_get_ec2_address(self):
31 address = yield self.get_address_for("ec2")32 address = yield self.get_address_for("ec2")
32 self.assertTrue(isinstance(address, EC2UnitAddress))33 self.assertTrue(isinstance(address, EC2UnitAddress))
34 self.assertFalse(address.private)
35
36 @inlineCallbacks
37 def test_get_ec2_address_private_mode(self):
38 os.environ.setdefault("JUJU_PRIVATE", "private")
39 address = yield self.get_address_for("ec2")
40 self.assertTrue(address.private)
41 del os.environ["JUJU_PRIVATE"]
3342
34 @inlineCallbacks43 @inlineCallbacks
35 def test_get_openstack_address(self):44 def test_get_openstack_address(self):
@@ -118,6 +127,23 @@
118 self.assertEqual(127 self.assertEqual(
119 (yield self.address.get_public_address()), "foobar")128 (yield self.address.get_public_address()), "foobar")
120129
130 @inlineCallbacks
131 def test_get_address_private_mode(self):
132 urls = [
133 "http://169.254.169.254/latest/meta-data/local-hostname",
134 "http://169.254.169.254/latest/meta-data/local-ipv4"]
135
136 def verify_args(url):
137 self.assertEqual(urls.pop(0), url)
138 return succeed("foobar\n")
139
140 self.address.private = True
141 self.patch(client, "getPage", verify_args)
142 self.assertEqual(
143 (yield self.address.get_private_address()), "foobar")
144 self.assertEqual(
145 (yield self.address.get_public_address()), "foobar")
146 self.address.private = False
121147
122class OpenStackAddressTest(TestCase):148class OpenStackAddressTest(TestCase):
123149

Subscribers

People subscribed via source and target branches

to status/vote changes: