From: Zane Bitter Date: Thu, 16 May 2013 11:18:19 +0000 (+0200) Subject: Handle errors in Volume creation X-Git-Tag: 2014.1~603^2 X-Git-Url: https://review.fuel-infra.org/gitweb?a=commitdiff_plain;h=114372ca3d584a32bd46b9328dc7033211591457;p=openstack-build%2Fheat-build.git Handle errors in Volume creation Set the resource_id as soon as it is know, since we need to be able to delete the volume later, even if it is in an error state. Avoid attempting to perform a snapshot if the volume was never created successfully. Change-Id: I33dd842d3d249bafe1037c1b97abf1979f605712 --- diff --git a/heat/engine/resources/volume.py b/heat/engine/resources/volume.py index 63aeb6e8..dc9d89f4 100644 --- a/heat/engine/resources/volume.py +++ b/heat/engine/resources/volume.py @@ -66,35 +66,34 @@ class Volume(resource.Resource): display_name=self._display_name(), display_description=self._display_description(), **self._create_arguments()) + self.resource_id_set(vol.id) while vol.status == 'creating': eventlet.sleep(1) vol.get() - if vol.status == 'available': - self.resource_id_set(vol.id) - else: + if vol.status != 'available': raise exception.Error(vol.status) def handle_update(self, json_snippet): return self.UPDATE_REPLACE - if volume_backups is not None: - def handle_snapshot_delete(self, state): - if self.resource_id is not None: - # We use backups as snapshots are not independent of volumes - backup = self.cinder().backups.create(self.resource_id) - while backup.status == 'creating': - eventlet.sleep(1) - backup.get() - if backup.status != 'available': - raise exception.Error(backup.status) - self.handle_delete() + def _backup(self): + backup = self.cinder().backups.create(self.resource_id) + while backup.status == 'creating': + eventlet.sleep(1) + backup.get() + if backup.status != 'available': + raise exception.Error(backup.status) - def handle_delete(self): + def _delete(self, backup=False): if self.resource_id is not None: try: vol = self.cinder().volumes.get(self.resource_id) + if backup: + self._backup() + vol.get() + if vol.status == 'in-use': logger.warn('cant delete volume when in-use') raise exception.Error("Volume in use") @@ -103,6 +102,15 @@ class Volume(resource.Resource): except clients.cinder_exceptions.NotFound: pass + if volume_backups is not None: + def handle_snapshot_delete(self, state): + backup = state not in (self.CREATE_FAILED, + self.UPDATE_FAILED) + return self._delete(backup=backup) + + def handle_delete(self): + return self._delete() + class VolumeAttachment(resource.Resource): properties_schema = {'InstanceId': {'Type': 'String', diff --git a/heat/tests/test_volume.py b/heat/tests/test_volume.py index 3bc19f25..df71f976 100644 --- a/heat/tests/test_volume.py +++ b/heat/tests/test_volume.py @@ -307,6 +307,7 @@ class VolumeTest(HeatTestCase): eventlet.sleep(1).AndReturn(None) # snapshot script + self.cinder_fc.volumes.get('vol-123').AndReturn(fv) self.m.StubOutWithMock(self.cinder_fc.backups, 'create') self.cinder_fc.backups.create('vol-123').AndReturn(fb) eventlet.sleep(1).AndReturn(None) @@ -336,6 +337,9 @@ class VolumeTest(HeatTestCase): display_name='%s.DataVolume' % stack_name).AndReturn(fv) eventlet.sleep(1).AndReturn(None) + self.cinder_fc.volumes.get('vol-123').AndReturn(fv) + self.cinder_fc.volumes.delete('vol-123').AndReturn(None) + self.m.ReplayAll() t = template_format.parse(volume_template)