Skip to content

Commit f9ef21f

Browse files
author
Gabriel Monroy
committed
Merge pull request #159 from opdemand/124-ami-in-flavors
Fixed #124 -- fill in explicit values for Flavor params. Ultimately we want to move this into the provider modules themselves, but for now this is the easiest way to accomplish the stated goal. When we implement the next provider we'll tackle how we seed flavors in a pluggable way.
2 parents 8ea96e2 + dc7ae67 commit f9ef21f

6 files changed

Lines changed: 78 additions & 43 deletions

File tree

api/models.py

Lines changed: 47 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,8 @@ def __str__(self):
124124
class FlavorManager(models.Manager):
125125
"""Manage database interactions for :class:`Flavor`."""
126126

127-
def load_cloud_config_base(self):
127+
@staticmethod
128+
def load_cloud_config_base():
128129
"""Read the base configuration file and return YAML data."""
129130
# load cloud-config-base yaml_
130131
_cloud_config_path = os.path.abspath(
@@ -137,30 +138,38 @@ def seed(self, user, **kwargs):
137138
"""Seed the database with default Flavors for each cloud region."""
138139
# TODO: add optimized AMIs to default flavors
139140
flavors = (
140-
{'id': 'ec2-us-east-1',
141-
'provider': 'ec2',
142-
'params': json.dumps({'region': 'us-east-1'})},
143-
{'id': 'ec2-us-west-1',
144-
'provider': 'ec2',
145-
'params': json.dumps({'region': 'us-west-1'})},
146-
{'id': 'ec2-us-west-2',
147-
'provider': 'ec2',
148-
'params': json.dumps({'region': 'us-west-2'})},
149-
{'id': 'ec2-eu-west-1',
150-
'provider': 'ec2',
151-
'params': json.dumps({'region': 'eu-west-1'})},
152-
{'id': 'ec2-ap-northeast-1',
153-
'provider': 'ec2',
154-
'params': json.dumps({'region': 'ap-northeast-1'})},
155-
{'id': 'ec2-ap-southeast-1',
156-
'provider': 'ec2',
157-
'params': json.dumps({'region': 'ap-southeast-1'})},
158-
{'id': 'ec2-ap-southeast-2',
159-
'provider': 'ec2',
160-
'params': json.dumps({'region': 'ap-southeast-2'})},
161-
{'id': 'ec2-sa-east-1',
162-
'provider': 'ec2',
163-
'params': json.dumps({'region': 'sa-east-1'})},
141+
{'id': 'ec2-us-east-1', 'provider': 'ec2',
142+
'params': json.dumps({
143+
'region': 'us-east-1', 'image': Flavor.IMAGE_MAP['us-east-1'],
144+
'zone': 'any', 'size': 'm1.medium'})},
145+
{'id': 'ec2-us-west-1', 'provider': 'ec2',
146+
'params': json.dumps({
147+
'region': 'us-west-1', 'image': Flavor.IMAGE_MAP['us-west-1'],
148+
'zone': 'any', 'size': 'm1.medium'})},
149+
{'id': 'ec2-us-west-2', 'provider': 'ec2',
150+
'params': json.dumps({
151+
'region': 'us-west-2', 'image': Flavor.IMAGE_MAP['us-west-2'],
152+
'zone': 'any', 'size': 'm1.medium'})},
153+
{'id': 'ec2-eu-west-1', 'provider': 'ec2',
154+
'params': json.dumps({
155+
'region': 'eu-west-1', 'image': Flavor.IMAGE_MAP['eu-west-1'],
156+
'zone': 'any', 'size': 'm1.medium'})},
157+
{'id': 'ec2-ap-northeast-1', 'provider': 'ec2',
158+
'params': json.dumps({
159+
'region': 'ap-northeast-1', 'image': Flavor.IMAGE_MAP['ap-northeast-1'],
160+
'zone': 'any', 'size': 'm1.medium'})},
161+
{'id': 'ec2-ap-southeast-1', 'provider': 'ec2',
162+
'params': json.dumps({
163+
'region': 'ap-southeast-1', 'image': Flavor.IMAGE_MAP['ap-southeast-1'],
164+
'zone': 'any', 'size': 'm1.medium'})},
165+
{'id': 'ec2-ap-southeast-2', 'provider': 'ec2',
166+
'params': json.dumps({
167+
'region': 'ap-southeast-2', 'image': Flavor.IMAGE_MAP['ap-southeast-2'],
168+
'zone': 'any', 'size': 'm1.medium'})},
169+
{'id': 'ec2-sa-east-1', 'provider': 'ec2',
170+
'params': json.dumps({
171+
'region': 'sa-east-1', 'image': Flavor.IMAGE_MAP['sa-east-1'],
172+
'zone': 'any', 'size': 'm1.medium'})},
164173
)
165174
cloud_config = self.load_cloud_config_base()
166175
for flavor in flavors:
@@ -184,6 +193,19 @@ class Flavor(UuidAuditedModel):
184193
params = fields.ParamsField()
185194
init = fields.CloudInitField()
186195

196+
# Deis-optimized EC2 amis -- with 3.8 kernel, chef 11 deps,
197+
# and large docker images (e.g. buildstep) pre-installed
198+
IMAGE_MAP = {
199+
'ap-northeast-1': 'ami-a57aeca4',
200+
'ap-southeast-1': 'ami-e03a72b2',
201+
'ap-southeast-2': 'ami-bd801287',
202+
'eu-west-1': 'ami-d9d3cdad',
203+
'sa-east-1': 'ami-a7df7bba',
204+
'us-east-1': 'ami-e85a2081',
205+
'us-west-1': 'ami-ac6942e9',
206+
'us-west-2': 'ami-b55ac885',
207+
}
208+
187209
class Meta:
188210
unique_together = (('owner', 'id'),)
189211

api/tests/build.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ def setUp(self):
3232
body = {
3333
'id': 'autotest',
3434
'provider': 'autotest',
35-
'params': json.dumps({'region': 'us-west-2', 'instance_size': 'm1.medium'}),
35+
'params': json.dumps({'region': 'us-west-2'}),
3636
}
3737
response = self.client.post(url, json.dumps(body), content_type='application/json')
3838
self.assertEqual(response.status_code, 201)

api/tests/config.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ def setUp(self):
2727
self.assertEqual(response.status_code, 201)
2828
url = '/api/flavors'
2929
body = {'id': 'autotest', 'provider': 'autotest',
30-
'params': json.dumps({'region': 'us-west-2', 'instance_size': 'm1.medium'})}
30+
'params': json.dumps({'region': 'us-west-2'})}
3131
response = self.client.post(url, json.dumps(body), content_type='application/json')
3232
self.assertEqual(response.status_code, 201)
3333

api/tests/flavor.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,3 +50,22 @@ def test_flavor(self):
5050
self.assertEqual(yaml.safe_load(response.data['init']), new_init)
5151
response = self.client.delete(url)
5252
self.assertEqual(response.status_code, 204)
53+
54+
def test_flavor_contents(self):
55+
"""Tests that flavors explicitly contain AMI ID, instance size, region, and zone."""
56+
url = '/api/flavors'
57+
body = {'id': 'autotest', 'provider': 'autotest', 'params': json.dumps({})}
58+
response = self.client.post(url, json.dumps(body), content_type='application/json')
59+
self.assertEqual(response.status_code, 201)
60+
flavor_id = response.data['id']
61+
response = self.client.get('/api/flavors')
62+
self.assertEqual(response.status_code, 200)
63+
self.assertEqual(len(response.data['results']), 1)
64+
url = "/api/flavors/{flavor_id}".format(**locals())
65+
response = self.client.get(url)
66+
self.assertEqual(response.status_code, 200)
67+
params = json.loads(response.data['params'])
68+
self.assertEqual(params['region'], 'us-east-1')
69+
self.assertEqual(params['zone'], 'any')
70+
self.assertEqual(params['size'], 'm1.medium')
71+
self.assertTrue(params['image'])

api/views.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,8 +137,14 @@ def create(self, request, **kwargs):
137137
request._data = request.DATA.copy()
138138
# set default cloud-init configuration
139139
if not 'init' in request.DATA:
140-
request.DATA['init'] = models.FlavorManager().load_cloud_config_base()
141-
return viewsets.ModelViewSet.create(self, request, **kwargs)
140+
request.DATA['init'] = models.FlavorManager.load_cloud_config_base()
141+
params = json.loads(request.DATA['params'])
142+
params.setdefault('region', 'us-east-1')
143+
params.setdefault('image', models.Flavor.IMAGE_MAP[params['region']])
144+
params.setdefault('size', 'm1.medium')
145+
params.setdefault('zone', 'any')
146+
request.DATA['params'] = json.dumps(params)
147+
return super(FlavorViewSet, self).create(request, **kwargs)
142148

143149

144150
class FormationViewSet(OwnerViewSet):

celerytasks/ec2.py

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,23 +9,11 @@
99
import yaml
1010

1111
from . import util
12+
from api.models import Flavor
1213
from api.models import Node
1314
from deis import settings
1415
from celerytasks.chef import ChefAPI
1516

16-
# deis optimized amis -- with 3.8 kernel, chef 11 deps,
17-
# and large docker images (e.g. buildstep) pre-installed
18-
EC2_IMAGE_MAP = {
19-
'ap-northeast-1': 'ami-a57aeca4',
20-
'ap-southeast-1': 'ami-e03a72b2',
21-
'ap-southeast-2': 'ami-bd801287',
22-
'eu-west-1': 'ami-d9d3cdad',
23-
'sa-east-1': 'ami-a7df7bba',
24-
'us-east-1': 'ami-e85a2081',
25-
'us-west-1': 'ami-ac6942e9',
26-
'us-west-2': 'ami-b55ac885',
27-
}
28-
2917

3018
@task(name='ec2.build_layer')
3119
def build_layer(layer, creds, params):
@@ -74,7 +62,7 @@ def launch_node(node_id, creds, params, init, ssh_username, ssh_private_key):
7462
params.setdefault('security_groups', []).append(sg.name)
7563
# retrieve the ami for launching this node
7664
image_id = params.get(
77-
'image', getattr(settings, 'EC2_IMAGE_MAP', EC2_IMAGE_MAP)[region])
65+
'image', getattr(settings, 'IMAGE_MAP', Flavor.IMAGE_MAP)[region])
7866
images = conn.get_all_images([image_id])
7967
if len(images) != 1:
8068
raise LookupError('Could not find AMI: %s' % image_id)

0 commit comments

Comments
 (0)