Add ability to create EBS volumes from snapshots. Closes #447.
This commit is contained in:
parent
d3e4c2c4b5
commit
cddf139bbc
@ -1388,12 +1388,13 @@ class VolumeAttachment(object):
|
|||||||
|
|
||||||
|
|
||||||
class Volume(TaggedEC2Resource):
|
class Volume(TaggedEC2Resource):
|
||||||
def __init__(self, ec2_backend, volume_id, size, zone):
|
def __init__(self, ec2_backend, volume_id, size, zone, snapshot_id=None):
|
||||||
self.id = volume_id
|
self.id = volume_id
|
||||||
self.size = size
|
self.size = size
|
||||||
self.zone = zone
|
self.zone = zone
|
||||||
self.create_time = utc_date_and_time()
|
self.create_time = utc_date_and_time()
|
||||||
self.attachment = None
|
self.attachment = None
|
||||||
|
self.snapshot_id = snapshot_id
|
||||||
self.ec2_backend = ec2_backend
|
self.ec2_backend = ec2_backend
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@ -1436,10 +1437,14 @@ class EBSBackend(object):
|
|||||||
self.snapshots = {}
|
self.snapshots = {}
|
||||||
super(EBSBackend, self).__init__()
|
super(EBSBackend, self).__init__()
|
||||||
|
|
||||||
def create_volume(self, size, zone_name):
|
def create_volume(self, size, zone_name, snapshot_id=None):
|
||||||
volume_id = random_volume_id()
|
volume_id = random_volume_id()
|
||||||
zone = self.get_zone_by_name(zone_name)
|
zone = self.get_zone_by_name(zone_name)
|
||||||
volume = Volume(self, volume_id, size, zone)
|
if snapshot_id:
|
||||||
|
snapshot = self.get_snapshot(snapshot_id)
|
||||||
|
if size is None:
|
||||||
|
size = snapshot.volume.size
|
||||||
|
volume = Volume(self, volume_id, size, zone, snapshot_id)
|
||||||
self.volumes[volume_id] = volume
|
self.volumes[volume_id] = volume
|
||||||
return volume
|
return volume
|
||||||
|
|
||||||
|
@ -25,9 +25,10 @@ class ElasticBlockStore(BaseResponse):
|
|||||||
return template.render(snapshot=snapshot)
|
return template.render(snapshot=snapshot)
|
||||||
|
|
||||||
def create_volume(self):
|
def create_volume(self):
|
||||||
size = self.querystring.get('Size')[0]
|
size = self._get_param('Size')
|
||||||
zone = self.querystring.get('AvailabilityZone')[0]
|
zone = self._get_param('AvailabilityZone')
|
||||||
volume = self.ec2_backend.create_volume(size, zone)
|
snapshot_id = self._get_param('SnapshotId')
|
||||||
|
volume = self.ec2_backend.create_volume(size, zone, snapshot_id)
|
||||||
template = self.response_template(CREATE_VOLUME_RESPONSE)
|
template = self.response_template(CREATE_VOLUME_RESPONSE)
|
||||||
return template.render(volume=volume)
|
return template.render(volume=volume)
|
||||||
|
|
||||||
@ -110,7 +111,11 @@ CREATE_VOLUME_RESPONSE = """<CreateVolumeResponse xmlns="http://ec2.amazonaws.co
|
|||||||
<requestId>59dbff89-35bd-4eac-99ed-be587EXAMPLE</requestId>
|
<requestId>59dbff89-35bd-4eac-99ed-be587EXAMPLE</requestId>
|
||||||
<volumeId>{{ volume.id }}</volumeId>
|
<volumeId>{{ volume.id }}</volumeId>
|
||||||
<size>{{ volume.size }}</size>
|
<size>{{ volume.size }}</size>
|
||||||
<snapshotId/>
|
{% if volume.snapshot_id %}
|
||||||
|
<snapshotId>{{ volume.snapshot_id }}</snapshotId>
|
||||||
|
{% else %}
|
||||||
|
<snapshotId/>
|
||||||
|
{% endif %}
|
||||||
<availabilityZone>{{ volume.zone.name }}</availabilityZone>
|
<availabilityZone>{{ volume.zone.name }}</availabilityZone>
|
||||||
<status>creating</status>
|
<status>creating</status>
|
||||||
<createTime>{{ volume.create_time}}</createTime>
|
<createTime>{{ volume.create_time}}</createTime>
|
||||||
@ -124,7 +129,11 @@ DESCRIBE_VOLUMES_RESPONSE = """<DescribeVolumesResponse xmlns="http://ec2.amazon
|
|||||||
<item>
|
<item>
|
||||||
<volumeId>{{ volume.id }}</volumeId>
|
<volumeId>{{ volume.id }}</volumeId>
|
||||||
<size>{{ volume.size }}</size>
|
<size>{{ volume.size }}</size>
|
||||||
<snapshotId/>
|
{% if volume.snapshot_id %}
|
||||||
|
<snapshotId>{{ volume.snapshot_id }}</snapshotId>
|
||||||
|
{% else %}
|
||||||
|
<snapshotId/>
|
||||||
|
{% endif %}
|
||||||
<availabilityZone>{{ volume.zone.name }}</availabilityZone>
|
<availabilityZone>{{ volume.zone.name }}</availabilityZone>
|
||||||
<status>{{ volume.status }}</status>
|
<status>{{ volume.status }}</status>
|
||||||
<createTime>{{ volume.create_time}}</createTime>
|
<createTime>{{ volume.create_time}}</createTime>
|
||||||
|
@ -33,6 +33,7 @@ def test_create_and_delete_volume():
|
|||||||
cm.exception.status.should.equal(400)
|
cm.exception.status.should.equal(400)
|
||||||
cm.exception.request_id.should_not.be.none
|
cm.exception.request_id.should_not.be.none
|
||||||
|
|
||||||
|
|
||||||
@mock_ec2
|
@mock_ec2
|
||||||
def test_filter_volume_by_id():
|
def test_filter_volume_by_id():
|
||||||
conn = boto.connect_ec2('the_key', 'the_secret')
|
conn = boto.connect_ec2('the_key', 'the_secret')
|
||||||
@ -116,6 +117,7 @@ def test_create_snapshot():
|
|||||||
cm.exception.status.should.equal(400)
|
cm.exception.status.should.equal(400)
|
||||||
cm.exception.request_id.should_not.be.none
|
cm.exception.request_id.should_not.be.none
|
||||||
|
|
||||||
|
|
||||||
@mock_ec2
|
@mock_ec2
|
||||||
def test_filter_snapshot_by_id():
|
def test_filter_snapshot_by_id():
|
||||||
conn = boto.connect_ec2('the_key', 'the_secret')
|
conn = boto.connect_ec2('the_key', 'the_secret')
|
||||||
@ -136,6 +138,7 @@ def test_filter_snapshot_by_id():
|
|||||||
s.volume_id.should.be.within([volume2.id, volume3.id])
|
s.volume_id.should.be.within([volume2.id, volume3.id])
|
||||||
s.region.name.should.equal(conn.region.name)
|
s.region.name.should.equal(conn.region.name)
|
||||||
|
|
||||||
|
|
||||||
@mock_ec2
|
@mock_ec2
|
||||||
def test_snapshot_attribute():
|
def test_snapshot_attribute():
|
||||||
conn = boto.connect_ec2('the_key', 'the_secret')
|
conn = boto.connect_ec2('the_key', 'the_secret')
|
||||||
@ -217,6 +220,20 @@ def test_snapshot_attribute():
|
|||||||
user_ids=['user']).should.throw(NotImplementedError)
|
user_ids=['user']).should.throw(NotImplementedError)
|
||||||
|
|
||||||
|
|
||||||
|
@mock_ec2
|
||||||
|
def test_create_volume_from_snapshot():
|
||||||
|
conn = boto.connect_ec2('the_key', 'the_secret')
|
||||||
|
volume = conn.create_volume(80, "us-east-1a")
|
||||||
|
|
||||||
|
snapshot = volume.create_snapshot('a test snapshot')
|
||||||
|
snapshot.update()
|
||||||
|
snapshot.status.should.equal('completed')
|
||||||
|
|
||||||
|
new_volume = snapshot.create_volume('us-east-1a')
|
||||||
|
new_volume.size.should.equal(80)
|
||||||
|
new_volume.snapshot_id.should.equal(snapshot.id)
|
||||||
|
|
||||||
|
|
||||||
@mock_ec2
|
@mock_ec2
|
||||||
def test_modify_attribute_blockDeviceMapping():
|
def test_modify_attribute_blockDeviceMapping():
|
||||||
"""
|
"""
|
||||||
|
Loading…
x
Reference in New Issue
Block a user