From 864c074ff15db601c896dadc2842ae703861c0dd Mon Sep 17 00:00:00 2001 From: Francois Deppierraz Date: Mon, 22 Oct 2018 15:33:25 +0200 Subject: [PATCH] cinder-volume: Stop masking IOError different than ENOSPC When glanceclient raises an IOError with a different errno than ENOSPC, cinder-volume silently masked it and continued its volume creation process. The result was volumes with invalid content being successfuly created. With the patch, an ImageDownloadFailed exception is raised in this case, which makes the volume creation process fail and gives enough information to operators for troubleshooting. Change-Id: Ic011fe30b4840e5098db1a594ea276ec98768bff Closes-Bug: #1799221 --- cinder/image/image_utils.py | 6 ++++++ cinder/tests/unit/test_image_utils.py | 20 +++++++++++++++++++ ...ase-of-glance-errors-6cae19218249c3cf.yaml | 6 ++++++ 3 files changed, 32 insertions(+) create mode 100644 releasenotes/notes/bug-1799221-fix-truncated-volumes-in-case-of-glance-errors-6cae19218249c3cf.yaml diff --git a/cinder/image/image_utils.py b/cinder/image/image_utils.py index 3c9c3c29888..72dd25ea6e9 100644 --- a/cinder/image/image_utils.py +++ b/cinder/image/image_utils.py @@ -402,6 +402,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 diff --git a/cinder/tests/unit/test_image_utils.py b/cinder/tests/unit/test_image_utils.py index 4f1af3d5e54..b336694cb29 100644 --- a/cinder/tests/unit/test_image_utils.py +++ b/cinder/tests/unit/test_image_utils.py @@ -383,6 +383,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 MockVerifier(object): def update(self, data): diff --git a/releasenotes/notes/bug-1799221-fix-truncated-volumes-in-case-of-glance-errors-6cae19218249c3cf.yaml b/releasenotes/notes/bug-1799221-fix-truncated-volumes-in-case-of-glance-errors-6cae19218249c3cf.yaml new file mode 100644 index 00000000000..d38a4cc8966 --- /dev/null +++ b/releasenotes/notes/bug-1799221-fix-truncated-volumes-in-case-of-glance-errors-6cae19218249c3cf.yaml @@ -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 `_).