]> review.fuel-infra Code Review - openstack-build/cinder-build.git/commitdiff
Catch and report errors from copy image to volume.
authorJohn Griffith <john.griffith@solidfire.com>
Mon, 27 May 2013 20:04:56 +0000 (20:04 +0000)
committerAdam Gandelman <adamg@canonical.com>
Wed, 29 May 2013 23:14:48 +0000 (16:14 -0700)
The copy image-to-volume errors weren't being handled
properly and the result was the lvcreate being retried
even though the lvcreate itself succeeded.

The result of this was misleading errors stating that
the volume couldn't be created because it already existed
(which it did, becuase the create itself was succesful).

Fixes bug: 1183283

Change-Id: I23f05fe64475c3efe285e05a258c4625b801375c
(cherry picked from commit b2371aeff9eccbd28952dd0f568da26722dc58f7)

cinder/exception.py
cinder/volume/drivers/xenapi/sm.py
cinder/volume/manager.py

index ccbaad114a6fa103a3c0235d15b62a4856ce6535..be9a984a0b815712433b8a559c047e5168431c52 100644 (file)
@@ -562,7 +562,7 @@ class GlanceMetadataExists(Invalid):
 
 
 class ImageCopyFailure(Invalid):
-    message = _("Failed to copy image to volume")
+    message = _("Failed to copy image to volume: %(reason)s")
 
 
 class BackupNotFound(NotFound):
index c1b64e2c9cf605aae8aec9bb02be1d0056f5c68f..6fedfa300a37d246ea520a2d4fc23dcf98767f1f 100644 (file)
@@ -194,7 +194,8 @@ class XenAPINFSDriver(driver.VolumeDriver):
             FLAGS.xenapi_sr_base_path)
 
         if overwrite_result is False:
-            raise exception.ImageCopyFailure()
+            raise exception.ImageCopyFailure(reason='Overwriting volume '
+                                                    'failed.')
 
         self.nfs_ops.resize_volume(
             FLAGS.xenapi_nfs_server,
index 0e3fcb288b73b22d0ba4db639a25058cb8ebb615..f2be2d64966552b4f137daac9ef5a5c62274d07d 100644 (file)
@@ -183,7 +183,6 @@ class VolumeManager(manager.SchedulerDependentManager):
                 volume_ref = self.db.volume_update(context,
                                                    volume_ref['id'],
                                                    updates)
-
                 self._copy_image_to_volume(context,
                                            volume_ref,
                                            image_service,
@@ -249,6 +248,13 @@ class VolumeManager(manager.SchedulerDependentManager):
                                                            image_service,
                                                            image_id,
                                                            image_location)
+            except exception.ImageCopyFailure as ex:
+                LOG.error(_('Setting volume: %s status to error '
+                            'after failed image copy.'), volume_ref['id'])
+                self.db.volume_update(context,
+                                      volume_ref['id'],
+                                      {'status': 'error'})
+                return
             except Exception:
                 # restore source volume status before reschedule
                 if sourcevol_ref is not None:
@@ -275,7 +281,6 @@ class VolumeManager(manager.SchedulerDependentManager):
             model_update = self.driver.create_export(context, volume_ref)
             if model_update:
                 self.db.volume_update(context, volume_ref['id'], model_update)
-
         except Exception:
             with excutils.save_and_reraise_exception():
                 self.db.volume_update(context,
@@ -591,11 +596,24 @@ class VolumeManager(manager.SchedulerDependentManager):
     def _copy_image_to_volume(self, context, volume, image_service, image_id):
         """Downloads Glance image to the specified volume. """
         volume_id = volume['id']
-        self.driver.copy_image_to_volume(context, volume,
-                                         image_service,
-                                         image_id)
-        LOG.debug(_("Downloaded image %(image_id)s to %(volume_id)s "
-                    "successfully") % locals())
+        try:
+            self.driver.copy_image_to_volume(context, volume,
+                                             image_service,
+                                             image_id)
+        except exception.ProcessExecutionError as ex:
+            LOG.error(_("Failed to copy image to volume: %(volume_id)s, "
+                        "error: %(error)s") % {'volume_id': volume_id,
+                                               'error': ex.stderr})
+            raise exception.ImageCopyFailure(reason=ex.stderr)
+        except exception.ImageUnacceptable as ex:
+            LOG.error(_("Failed to copy image to volume: %(volume_id)s, "
+                        "error: %(error)s") % {'volume_id': volume_id,
+                                               'error': ex})
+            raise exception.ImageCopyFailure(reason=ex)
+
+        LOG.info(_("Downloaded image %(image_id)s to %(volume_id)s "
+                   "successfully.") % {'image_id': image_id,
+                                       'volume_id': volume_id})
 
     def copy_volume_to_image(self, context, volume_id, image_meta):
         """Uploads the specified volume to Glance.