3
from yaml import dump, load
5
6
from twisted.internet.defer import succeed
7
8
from txaws.ec2.model import SecurityGroup
9
from ensemble.lib.mocker import MATCH
10
from ensemble.lib.testing import TestCase
11
from ensemble.providers.common.launch import (
12
BOOTSTRAP_PACKAGES, DEFAULT_REPOSITORIES, DEFAULT_PACKAGES)
13
from ensemble.providers.ec2.machine import EC2ProviderMachine
14
from ensemble.state.auth import make_identity
16
from .common import EC2TestMixin, EC2MachineLaunchMixin, MATCH_AMI
10
from juju.lib.mocker import MATCH
11
from juju.lib.testing import TestCase
12
from juju.providers.ec2.machine import EC2ProviderMachine
14
from .common import EC2TestMixin, EC2MachineLaunchMixin
17
DATA_DIR = os.path.join(os.path.abspath(os.path.dirname(__file__)), "data")
19
20
class EC2BootstrapTest(EC2TestMixin, EC2MachineLaunchMixin, TestCase):
34
35
MATCH(match_string))
35
36
self.mocker.result(succeed(True))
37
def _mock_launch(self, machine_id):
38
def _mock_launch(self):
38
39
"""Mock launching a bootstrap machine on ec2."""
39
credentials = "admin:%s" % self.get_config()["admin-secret"]
40
admin_identity = make_identity(credentials)
42
40
def verify_user_data(data):
44
lines = data.split("\n")
45
self.assertEqual(lines.pop(0), "#cloud-config")
46
config = load("\n".join(lines))
47
repos = [dict(source=r) for r in DEFAULT_REPOSITORIES]
48
self.assertEqual(config["apt_sources"], repos)
51
list(DEFAULT_PACKAGES) + BOOTSTRAP_PACKAGES)
52
self.failUnlessIn("admin-identity", config["runcmd"][-3])
55
'ensemble-admin initialize --instance-id=%s'
56
' --admin-identity="%s"') % (
57
"$(curl http://169.254.169.254/1.0/meta-data/instance-id)",
60
self.assertEqual(config["runcmd"][-3], script)
63
"ENSEMBLE_MACHINE_ID=0 ENSEMBLE_ZOOKEEPER=localhost:2181 "
64
"python -m ensemble.agents.machine -n "
65
"--logfile=/var/log/ensemble/machine-agent.log "
66
"--pidfile=/var/run/ensemble/machine-agent.pid")
68
self.assertEqual(config["runcmd"][-2], script)
70
provision_agent_script = (
71
"ENSEMBLE_ZOOKEEPER=localhost:2181 "
72
"python -m ensemble.agents.provision -n "
73
"--logfile=/var/log/ensemble/provision-agent.log "
74
"--pidfile=/var/run/ensemble/provision-agent.pid")
75
self.assertEqual(config["runcmd"][-1], provision_agent_script)
41
expect_path = os.path.join(DATA_DIR, "bootstrap_cloud_init")
42
with open(expect_path) as f:
43
expect_cloud_init = yaml.load(f.read())
44
self.assertEquals(yaml.load(data), expect_cloud_init)
78
47
self.ec2.run_instances(
48
image_id="ami-default",
80
49
instance_type="m1.small",
84
"%s-%s" % ("ensemble", self.env_name),
85
"%s-%s-%s" % ("ensemble", self.env_name, machine_id)],
52
security_groups=["juju-moon", "juju-moon-0"],
86
53
user_data=MATCH(verify_user_data))
88
55
def test_launch_bootstrap(self):
89
56
"""The provider bootstrap can launch a bootstrap/zookeeper machine."""
91
log = self.capture_logging("ensemble.common", level=logging.DEBUG)
58
log = self.capture_logging("juju.common", level=logging.DEBUG)
93
60
self.s3.get_object(self.env_name, "provider-state")
94
61
self.mocker.result(succeed(""))
119
86
When launching a bootstrap instance the provider will use an existing
120
87
provider instance group.
122
self.capture_logging("ensemble.ec2")
89
self.capture_logging("juju.ec2")
123
90
self.s3.get_object(self.env_name, "provider-state")
124
91
self.mocker.result(succeed(""))
125
92
self._mock_verify()
126
93
self.ec2.describe_security_groups()
127
94
self.mocker.result(succeed([
128
SecurityGroup("ensemble-%s" % self.env_name, "")]))
95
SecurityGroup("juju-%s" % self.env_name, "")]))
129
96
self._mock_create_machine_group(0)
130
97
self._mock_launch_utils(region="us-east-1")
132
99
self.mocker.result(succeed([]))
133
100
self._mock_save()
134
101
self.mocker.replay()
141
108
If the provider bootstrap is run when there is already a running
142
109
bootstrap instance, it will just return the existing machine.
144
state = dump({"zookeeper-instances": ["i-foobar"]})
111
state = yaml.dump({"zookeeper-instances": ["i-foobar"]})
145
112
self.s3.get_object(self.env_name, "provider-state")
146
113
self.mocker.result(succeed(state))
147
114
self.ec2.describe_instances("i-foobar")
148
115
self.mocker.result(succeed([self.get_instance("i-foobar")]))
149
116
self.mocker.replay()
151
log = self.capture_logging("ensemble.common")
118
log = self.capture_logging("juju.common")
153
120
def validate_result(result):
154
121
self.assertTrue(result)
174
141
self._mock_verify()
175
142
self.ec2.describe_security_groups()
176
143
self.mocker.result(succeed([
177
SecurityGroup("ensemble-%s" % self.env_name, "")]))
144
SecurityGroup("juju-%s" % self.env_name, "")]))
178
145
self._mock_create_machine_group(0)
179
146
self._mock_launch_utils(region="us-east-1")
181
148
self.mocker.result(succeed([self.get_instance("i-foobar")]))
182
149
self._mock_save()
183
150
self.mocker.replay()