]> review.fuel-infra Code Review - openstack-build/heat-build.git/commitdiff
Handle errors in Volume creation
authorZane Bitter <zbitter@redhat.com>
Thu, 16 May 2013 11:18:19 +0000 (13:18 +0200)
committerZane Bitter <zbitter@redhat.com>
Thu, 16 May 2013 11:18:19 +0000 (13:18 +0200)
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

heat/engine/resources/volume.py
heat/tests/test_volume.py

index 63aeb6e88e98f4a1610b2eccfeaab4b156aab76f..dc9d89f463ec00515a274fe6f079bf303576b1d9 100644 (file)
@@ -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',
index 3bc19f25cd32234d574a35d625e4ad23619e62a1..df71f976895a4532bea4b69126928156e8df9bca 100644 (file)
@@ -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)