Merge "cinder-volume: Stop masking IOError different than ENOSPC" into stable/pike
This commit is contained in:
commit
0e623cc427
|
@ -716,6 +716,10 @@ class GlanceMetadataNotFound(NotFound):
|
|||
message = _("Glance metadata for volume/snapshot %(id)s cannot be found.")
|
||||
|
||||
|
||||
class ImageDownloadFailed(CinderException):
|
||||
message = _("Failed to download image %(image_href)s, reason: %(reason)s")
|
||||
|
||||
|
||||
class ExportFailure(Invalid):
|
||||
message = _("Failed to export for volume: %(reason)s")
|
||||
|
||||
|
|
|
@ -335,6 +335,10 @@ class GlanceImageService(object):
|
|||
except Exception:
|
||||
_reraise_translated_image_exception(image_id)
|
||||
|
||||
if image_chunks is None:
|
||||
raise exception.ImageDownloadFailed(
|
||||
image_href=image_id, reason=_('image contains no data.'))
|
||||
|
||||
if not data:
|
||||
return image_chunks
|
||||
else:
|
||||
|
|
|
@ -232,6 +232,12 @@ def fetch(context, image_service, image_id, path, _user_id, _project_id):
|
|||
raise exception.ImageTooBig(image_id=image_id,
|
||||
reason=reason)
|
||||
|
||||
reason = ("IOError: %(errno)s %(strerror)s" %
|
||||
{'errno': e.errno, 'strerror': e.strerror})
|
||||
LOG.error(reason)
|
||||
raise exception.ImageDownloadFailed(image_href=image_id,
|
||||
reason=reason)
|
||||
|
||||
duration = timeutils.delta_seconds(start_time, timeutils.utcnow())
|
||||
|
||||
# NOTE(jdg): use a default of 1, mostly for unit test, but in
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
import datetime
|
||||
import itertools
|
||||
import six
|
||||
|
||||
import ddt
|
||||
import glanceclient.exc
|
||||
|
@ -556,6 +557,20 @@ class TestGlanceImageService(test.TestCase):
|
|||
self.flags(glance_num_retries=1)
|
||||
service.download(self.context, image_id, writer)
|
||||
|
||||
def test_download_no_data(self):
|
||||
class MyGlanceStubClient(glance_stubs.StubGlanceClient):
|
||||
"""Returns None instead of an iterator."""
|
||||
def data(self, image_id):
|
||||
return None
|
||||
|
||||
client = MyGlanceStubClient()
|
||||
service = self._create_image_service(client)
|
||||
image_id = 'fake-image-uuid'
|
||||
e = self.assertRaises(exception.ImageDownloadFailed, service.download,
|
||||
self.context, image_id)
|
||||
self.assertIn('image contains no data', six.text_type(e))
|
||||
self.assertIn(image_id, six.text_type(e))
|
||||
|
||||
def test_client_forbidden_converts_to_imagenotauthed(self):
|
||||
class MyGlanceStubClient(glance_stubs.StubGlanceClient):
|
||||
"""A client that raises a Forbidden exception."""
|
||||
|
|
|
@ -315,6 +315,26 @@ class TestFetch(test.TestCase):
|
|||
context, image_service, image_id, path,
|
||||
_user_id, _project_id)
|
||||
|
||||
def test_fetch_ioerror(self):
|
||||
context = mock.sentinel.context
|
||||
image_service = mock.Mock()
|
||||
image_id = mock.sentinel.image_id
|
||||
e = IOError()
|
||||
e.errno = errno.ECONNRESET
|
||||
e.strerror = 'Some descriptive message'
|
||||
image_service.download.side_effect = e
|
||||
path = '/test_path'
|
||||
_user_id = mock.sentinel._user_id
|
||||
_project_id = mock.sentinel._project_id
|
||||
|
||||
with mock.patch('cinder.image.image_utils.open',
|
||||
new=mock.mock_open(), create=True):
|
||||
self.assertRaisesRegex(exception.ImageDownloadFailed,
|
||||
e.strerror,
|
||||
image_utils.fetch,
|
||||
context, image_service, image_id, path,
|
||||
_user_id, _project_id)
|
||||
|
||||
|
||||
class TestVerifyImage(test.TestCase):
|
||||
@mock.patch('cinder.image.image_utils.qemu_img_info')
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
fixes:
|
||||
- |
|
||||
Fixed a bug which could create volumes with invalid content in case of
|
||||
unhandled errors from glance client
|
||||
(Bug `#1799221 <https://bugs.launchpad.net/cinder/+bug/1799221>`_).
|
Loading…
Reference in New Issue