Fix root volume to show up in other EC2 volume API calls. Closes 470

This commit is contained in:
Steve Pulec 2015-11-28 09:19:45 -05:00
parent fe946588b2
commit 44f0377cc4
5 changed files with 37 additions and 13 deletions

7
CHANGELOG.md Normal file
View File

@ -0,0 +1,7 @@
Moto Changelog
===================
Latest
------
* Fix root instance volume to show up in other EBS volume calls

View File

@ -319,12 +319,6 @@ class Instance(BotoInstance, TaggedEC2Resource):
# If we are in EC2-Classic, autoassign a public IP
associate_public_ip = True
self.block_device_mapping = BlockDeviceMapping()
# Default have an instance with root volume should you not wish to override with attach volume cmd.
# However this is a ghost volume and wont show up in get_all_volumes or snapshot-able.
self.block_device_mapping['/dev/sda1'] = BlockDeviceType(volume_id=random_volume_id(), status='attached',
attach_time=utc_date_and_time())
amis = self.ec2_backend.describe_images(filters={'image-id': image_id})
ami = amis[0] if amis else None
@ -345,11 +339,23 @@ class Instance(BotoInstance, TaggedEC2Resource):
subnet = ec2_backend.get_subnet(self.subnet_id)
self.vpc_id = subnet.vpc_id
self.block_device_mapping = BlockDeviceMapping()
self.prep_nics(kwargs.get("nics", {}),
subnet_id=self.subnet_id,
private_ip=kwargs.get("private_ip"),
associate_public_ip=associate_public_ip)
def setup_defaults(self):
# Default have an instance with root volume should you not wish to override with attach volume cmd.
volume = self.ec2_backend.create_volume(8, 'us-east-1a')
self.ec2_backend.attach_volume(volume.id, self.id, '/dev/sda1')
def teardown_defaults(self):
volume_id = self.block_device_mapping['/dev/sda1'].volume_id
self.ec2_backend.detach_volume(volume_id, self.id, '/dev/sda1')
self.ec2_backend.delete_volume(volume_id)
@property
def get_block_device_mapping(self):
return self.block_device_mapping.items()
@ -420,6 +426,8 @@ class Instance(BotoInstance, TaggedEC2Resource):
for nic in self.nics.values():
nic.stop()
self.teardown_defaults()
self._state.name = "terminated"
self._state.code = 48
@ -546,6 +554,7 @@ class InstanceBackend(object):
for name in security_group_names]
security_groups.extend(self.get_security_group_from_id(sg_id)
for sg_id in kwargs.pop("security_group_ids", []))
self.reservations[new_reservation.id] = new_reservation
for index in range(count):
new_instance = Instance(
self,
@ -555,7 +564,7 @@ class InstanceBackend(object):
**kwargs
)
new_reservation.instances.append(new_instance)
self.reservations[new_reservation.id] = new_reservation
new_instance.setup_defaults()
return new_reservation
def start_instances(self, instance_ids):

View File

@ -737,14 +737,16 @@ def test_single_instance_with_ebs_volume():
reservation = ec2_conn.get_all_instances()[0]
ec2_instance = reservation.instances[0]
volume = ec2_conn.get_all_volumes()[0]
volumes = ec2_conn.get_all_volumes()
# Grab the mounted drive
volume = [volume for volume in volumes if volume.attach_data.device == '/dev/sdh'][0]
volume.volume_state().should.equal('in-use')
volume.attach_data.instance_id.should.equal(ec2_instance.id)
stack = conn.describe_stacks()[0]
resources = stack.describe_resources()
ebs_volume = [resource for resource in resources if resource.resource_type == 'AWS::EC2::Volume'][0]
ebs_volume.physical_resource_id.should.equal(volume.id)
ebs_volumes = [resource for resource in resources if resource.resource_type == 'AWS::EC2::Volume']
ebs_volumes[0].physical_resource_id.should.equal(volume.id)
@mock_cloudformation()

View File

@ -28,6 +28,7 @@ def test_ami_create_and_delete():
image.architecture.should.equal(instance.architecture)
image.kernel_id.should.equal(instance.kernel)
image.platform.should.equal(instance.platform)
instance.terminate()
# Validate auto-created volume and snapshot
volumes = conn.get_all_volumes()
@ -61,6 +62,7 @@ def test_ami_copy():
instance = reservation.instances[0]
source_image_id = conn.create_image(instance.id, "test-ami", "this is a test ami")
instance.terminate()
source_image = conn.get_all_images(image_ids=[source_image_id])[0]
# Boto returns a 'CopyImage' object with an image_id attribute here. Use the image_id to fetch the full info.
@ -481,4 +483,3 @@ def test_ami_attribute_error_cases():
cm.exception.code.should.equal('InvalidAMIID.NotFound')
cm.exception.status.should.equal(400)
cm.exception.request_id.should_not.be.none

View File

@ -57,8 +57,13 @@ def test_instance_launch_and_terminate():
instances[0].vpc_id.should.equal(None)
root_device_name = instances[0].root_device_name
instances[0].block_device_mapping[root_device_name].status.should.equal('attached')
instances[0].block_device_mapping[root_device_name].volume_id.should.match(r'vol-\w+')
instances[0].block_device_mapping[root_device_name].status.should.equal('in-use')
volume_id = instances[0].block_device_mapping[root_device_name].volume_id
volume_id.should.match(r'vol-\w+')
volume = conn.get_all_volumes(volume_ids=[volume_id])[0]
volume.attach_data.instance_id.should.equal(instance.id)
volume.status.should.equal('in-use')
conn.terminate_instances([instances[0].id])