From: Thomas Herve Date: Mon, 6 May 2013 07:02:25 +0000 (+0200) Subject: Support SnapshotId in volume creation. X-Git-Tag: 2014.1~644^2 X-Git-Url: https://review.fuel-infra.org/gitweb?a=commitdiff_plain;h=8dcea9b40c8299fe615a0ceb63960af3177882bd;p=openstack-build%2Fheat-build.git Support SnapshotId in volume creation. This uses cinder backups as snapshot, to be symmetrical to the deletion policy. Change-Id: Ie8f1ff095df7bdad8500c6298d1b7d9fd233693f Implements: blueprint bp/volume-snapshots --- diff --git a/heat/engine/resources/volume.py b/heat/engine/resources/volume.py index 5f367b39..32564531 100644 --- a/heat/engine/resources/volume.py +++ b/heat/engine/resources/volume.py @@ -34,14 +34,23 @@ class Volume(resource.Resource): 'SnapshotId': {'Type': 'String'}, 'Tags': {'Type': 'List'}} - def __init__(self, name, json_snippet, stack): - super(Volume, self).__init__(name, json_snippet, stack) - def handle_create(self): - vol = self.cinder().volumes.create( - self.properties['Size'], - display_name=self.physical_resource_name(), - display_description=self.physical_resource_name()) + backup_id = self.properties.get('SnapshotId') + cinder = self.cinder() + if backup_id is not None: + if volume_backups is None: + raise exception.Error('SnapshotId not supported') + vol_id = cinder.restores.restore(backup_id)['volume_id'] + + vol = cinder.volumes.get(vol_id) + vol.update( + display_name=self.physical_resource_name(), + display_description=self.physical_resource_name()) + else: + vol = cinder.volumes.create( + self.properties['Size'], + display_name=self.physical_resource_name(), + display_description=self.physical_resource_name()) while vol.status == 'creating': eventlet.sleep(1) diff --git a/heat/tests/test_volume.py b/heat/tests/test_volume.py index 9a28907f..4041f1aa 100644 --- a/heat/tests/test_volume.py +++ b/heat/tests/test_volume.py @@ -326,6 +326,34 @@ class VolumeTest(HeatTestCase): self.m.VerifyAll() + def test_create_from_snapshot(self): + stack_name = 'test_volume_stack' + fv = FakeVolume('creating', 'available') + + # create script + clients.OpenStackClients.cinder().MultipleTimes().AndReturn( + self.cinder_fc) + self.m.StubOutWithMock(self.cinder_fc.restores, 'restore') + self.cinder_fc.restores.restore('backup-123').AndReturn( + {'volume_id': 'vol-123'}) + self.cinder_fc.volumes.get('vol-123').AndReturn(fv) + self.m.StubOutWithMock(fv, 'update') + fv.update( + display_description='%s.DataVolume' % stack_name, + display_name='%s.DataVolume' % stack_name) + eventlet.sleep(1).AndReturn(None) + + self.m.ReplayAll() + + t = self.load_template() + t['Resources']['DataVolume']['Properties']['SnapshotId'] = 'backup-123' + stack = self.parse_stack(t, stack_name) + + self.create_volume(t, stack, 'DataVolume') + self.assertEqual(fv.status, 'available') + + self.m.VerifyAll() + class FakeVolume: status = 'attaching' @@ -338,6 +366,9 @@ class FakeVolume: def get(self): self.status = self.final_status + def update(self, **kw): + pass + class FakeBackup(FakeVolume): status = 'creating'