summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Lindsley <daniel@toastdriven.com>2013-09-13 15:37:29 -0700
committerDaniel Lindsley <daniel@toastdriven.com>2013-09-13 15:37:29 -0700
commitd7edafccda9fb1c1169e4b0a22a0afbaf853dcc3 (patch)
tree1557b3976a470f58a0e86f91f463d6d4601f75d1
parent9049f05190134296d2aa11206a5900c358c3dd7f (diff)
downloadboto-d7edafccda9fb1c1169e4b0a22a0afbaf853dcc3.tar.gz
Fixes #1723 - A prior commit broke ``run_instances`` with block device mappings on EC2. This makes both EC2 & Autoscaling work with block device mappings.
-rw-r--r--boto/ec2/autoscale/__init__.py2
-rw-r--r--boto/ec2/blockdevicemapping.py12
-rw-r--r--boto/ec2/connection.py6
-rw-r--r--tests/unit/ec2/test_blockdevicemapping.py54
4 files changed, 68 insertions, 6 deletions
diff --git a/boto/ec2/autoscale/__init__.py b/boto/ec2/autoscale/__init__.py
index f82ce9ec..9a8270db 100644
--- a/boto/ec2/autoscale/__init__.py
+++ b/boto/ec2/autoscale/__init__.py
@@ -225,7 +225,7 @@ class AutoScaleConnection(AWSQueryConnection):
if launch_config.ramdisk_id:
params['RamdiskId'] = launch_config.ramdisk_id
if launch_config.block_device_mappings:
- [x.build_list_params(params) for x in launch_config.block_device_mappings]
+ [x.autoscale_build_list_params(params) for x in launch_config.block_device_mappings]
if launch_config.security_groups:
self.build_list_params(params, launch_config.security_groups,
'SecurityGroups')
diff --git a/boto/ec2/blockdevicemapping.py b/boto/ec2/blockdevicemapping.py
index df774ae9..78f7e61d 100644
--- a/boto/ec2/blockdevicemapping.py
+++ b/boto/ec2/blockdevicemapping.py
@@ -115,10 +115,18 @@ class BlockDeviceMapping(dict):
elif name == 'item':
self[self.current_name] = self.current_value
- def build_list_params(self, params, prefix=''):
+ def ec2_build_list_params(self, params, prefix=''):
+ pre = '%sBlockDeviceMapping' % prefix
+ return self._build_list_params(params, prefix=pre)
+
+ def autoscale_build_list_params(self, params, prefix=''):
+ pre = '%sBlockDeviceMappings.member' % prefix
+ return self._build_list_params(params, prefix=pre)
+
+ def _build_list_params(self, params, prefix=''):
i = 1
for dev_name in self:
- pre = '%sBlockDeviceMapping.%d' % (prefix, i)
+ pre = '%s.%d' % (prefix, i)
params['%s.DeviceName' % pre] = dev_name
block_dev = self[dev_name]
if block_dev.ephemeral_name:
diff --git a/boto/ec2/connection.py b/boto/ec2/connection.py
index be0286df..71da5f0b 100644
--- a/boto/ec2/connection.py
+++ b/boto/ec2/connection.py
@@ -312,7 +312,7 @@ class EC2Connection(AWSQueryConnection):
if root_device_name:
params['RootDeviceName'] = root_device_name
if block_device_map:
- block_device_map.build_list_params(params)
+ block_device_map.ec2_build_list_params(params)
if dry_run:
params['DryRun'] = 'true'
rs = self.get_object('RegisterImage', params, ResultSet, verb='POST')
@@ -843,7 +843,7 @@ class EC2Connection(AWSQueryConnection):
if private_ip_address:
params['PrivateIpAddress'] = private_ip_address
if block_device_map:
- block_device_map.build_list_params(params)
+ block_device_map.ec2_build_list_params(params)
if disable_api_termination:
params['DisableApiTermination'] = 'true'
if instance_initiated_shutdown_behavior:
@@ -1466,7 +1466,7 @@ class EC2Connection(AWSQueryConnection):
if placement_group:
params['%s.Placement.GroupName' % ls] = placement_group
if block_device_map:
- block_device_map.build_list_params(params, '%s.' % ls)
+ block_device_map.ec2_build_list_params(params, '%s.' % ls)
if instance_profile_name:
params['%s.IamInstanceProfile.Name' % ls] = instance_profile_name
if instance_profile_arn:
diff --git a/tests/unit/ec2/test_blockdevicemapping.py b/tests/unit/ec2/test_blockdevicemapping.py
index 02ecf582..78539744 100644
--- a/tests/unit/ec2/test_blockdevicemapping.py
+++ b/tests/unit/ec2/test_blockdevicemapping.py
@@ -1,8 +1,12 @@
import mock
import unittest
+from boto.ec2.connection import EC2Connection
from boto.ec2.blockdevicemapping import BlockDeviceType, BlockDeviceMapping
+from tests.unit import AWSMockServiceTestCase
+
+
class BlockDeviceTypeTests(unittest.TestCase):
def setUp(self):
self.block_device_type = BlockDeviceType()
@@ -75,5 +79,55 @@ class BlockDeviceMappingTests(unittest.TestCase):
self.block_device_mapping.endElement("item", "some item", None)
self.assertEqual(self.block_device_mapping["some name"], "some value")
+
+class TestLaunchConfiguration(AWSMockServiceTestCase):
+ connection_class = EC2Connection
+
+ def default_body(self):
+ # This is a dummy response
+ return """
+ <DescribeLaunchConfigurationsResponse>
+ </DescribeLaunchConfigurationsResponse>
+ """
+
+ def test_run_instances_block_device_mapping(self):
+ # Same as the test in ``unit/ec2/autoscale/test_group.py:TestLaunchConfiguration``,
+ # but with modified request parameters (due to a mismatch between EC2 &
+ # Autoscaling).
+ self.set_http_response(status_code=200)
+ dev_sdf = BlockDeviceType(snapshot_id='snap-12345')
+ dev_sdg = BlockDeviceType(snapshot_id='snap-12346')
+
+ bdm = BlockDeviceMapping()
+ bdm['/dev/sdf'] = dev_sdf
+ bdm['/dev/sdg'] = dev_sdg
+
+ response = self.service_connection.run_instances(
+ image_id='123456',
+ instance_type='m1.large',
+ security_groups=['group1', 'group2'],
+ block_device_map=bdm
+ )
+
+ self.assert_request_parameters({
+ 'Action': 'RunInstances',
+ 'BlockDeviceMapping.1.DeviceName': '/dev/sdf',
+ 'BlockDeviceMapping.1.Ebs.DeleteOnTermination': 'false',
+ 'BlockDeviceMapping.1.Ebs.SnapshotId': 'snap-12345',
+ 'BlockDeviceMapping.2.DeviceName': '/dev/sdg',
+ 'BlockDeviceMapping.2.Ebs.DeleteOnTermination': 'false',
+ 'BlockDeviceMapping.2.Ebs.SnapshotId': 'snap-12346',
+ 'ImageId': '123456',
+ 'InstanceType': 'm1.large',
+ 'MaxCount': 1,
+ 'MinCount': 1,
+ 'SecurityGroup.1': 'group1',
+ 'SecurityGroup.2': 'group2',
+ }, ignore_params_values=[
+ 'Version', 'AWSAccessKeyId', 'SignatureMethod', 'SignatureVersion',
+ 'Timestamp'
+ ])
+
+
if __name__ == "__main__":
unittest.main()