Handle case when a glance image contains no data
In my experience, it happens when Swift storage backing Glance was purged, but it can probably also happen if an image never had data at all. This patch raises a correct exception instead of TypeError. Switch relevant unit tests to Glance V2, as V1 is long deprecated. Change-Id: I75e5ae7f46ce3a1506ed6108ff05df3083fd5084 Closes-Bug: #1741223
This commit is contained in:
parent
bf8cb05aa4
commit
70039cbe60
@ -217,6 +217,14 @@ class BaseImageService(object):
|
|||||||
return
|
return
|
||||||
|
|
||||||
image_chunks = self.call(method, image_id)
|
image_chunks = self.call(method, image_id)
|
||||||
|
# NOTE(dtantsur): when using Glance V2, image_chunks is a wrapper
|
||||||
|
# around real data, so we have to check the wrapped data for None.
|
||||||
|
# Glance V1 returns HTTP 404 in this case, so no need to fix it.
|
||||||
|
# TODO(dtantsur): remove the hasattr check when we no longer support
|
||||||
|
# Glance V1.
|
||||||
|
if hasattr(image_chunks, 'wrapped') and image_chunks.wrapped is None:
|
||||||
|
raise exception.ImageDownloadFailed(
|
||||||
|
image_href=image_href, reason=_('image contains no data.'))
|
||||||
|
|
||||||
if data is None:
|
if data is None:
|
||||||
return image_chunks
|
return image_chunks
|
||||||
|
@ -92,11 +92,11 @@ class TestGlanceImageService(base.TestCase):
|
|||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(TestGlanceImageService, self).setUp()
|
super(TestGlanceImageService, self).setUp()
|
||||||
client = stubs.StubGlanceClient()
|
self.client = stubs.StubGlanceClient()
|
||||||
self.context = context.RequestContext(auth_token=True)
|
self.context = context.RequestContext(auth_token=True)
|
||||||
self.context.user_id = 'fake'
|
self.context.user_id = 'fake'
|
||||||
self.context.project_id = 'fake'
|
self.context.project_id = 'fake'
|
||||||
self.service = service.GlanceImageService(client, 1, self.context)
|
self.service = service.GlanceImageService(self.client, 2, self.context)
|
||||||
|
|
||||||
self.config(glance_api_servers=['http://localhost'], group='glance')
|
self.config(glance_api_servers=['http://localhost'], group='glance')
|
||||||
self.config(auth_strategy='keystone', group='glance')
|
self.config(auth_strategy='keystone', group='glance')
|
||||||
@ -203,6 +203,17 @@ class TestGlanceImageService(base.TestCase):
|
|||||||
stub_service.download(image_id, writer)
|
stub_service.download(image_id, writer)
|
||||||
self.assertTrue(mock_sleep.called)
|
self.assertTrue(mock_sleep.called)
|
||||||
|
|
||||||
|
def test_download_no_data(self):
|
||||||
|
self.client.fake_wrapped = None
|
||||||
|
image_id = uuidutils.generate_uuid()
|
||||||
|
|
||||||
|
image = self._make_datetime_fixture()
|
||||||
|
with mock.patch.object(self.client, 'get', return_value=image,
|
||||||
|
autospec=True):
|
||||||
|
self.assertRaisesRegex(exception.ImageDownloadFailed,
|
||||||
|
'image contains no data',
|
||||||
|
self.service.download, image_id)
|
||||||
|
|
||||||
@mock.patch('sendfile.sendfile', autospec=True)
|
@mock.patch('sendfile.sendfile', autospec=True)
|
||||||
@mock.patch('os.path.getsize', autospec=True)
|
@mock.patch('os.path.getsize', autospec=True)
|
||||||
@mock.patch('%s.open' % __name__, new=mock.mock_open(), create=True)
|
@mock.patch('%s.open' % __name__, new=mock.mock_open(), create=True)
|
||||||
|
@ -18,8 +18,18 @@ from glanceclient import exc as glance_exc
|
|||||||
NOW_GLANCE_FORMAT = "2010-10-11T10:30:22"
|
NOW_GLANCE_FORMAT = "2010-10-11T10:30:22"
|
||||||
|
|
||||||
|
|
||||||
|
class _GlanceWrapper(object):
|
||||||
|
def __init__(self, wrapped):
|
||||||
|
self.wrapped = wrapped
|
||||||
|
|
||||||
|
def __iter__(self):
|
||||||
|
return iter(())
|
||||||
|
|
||||||
|
|
||||||
class StubGlanceClient(object):
|
class StubGlanceClient(object):
|
||||||
|
|
||||||
|
fake_wrapped = object()
|
||||||
|
|
||||||
def __init__(self, images=None):
|
def __init__(self, images=None):
|
||||||
self._images = []
|
self._images = []
|
||||||
_images = images or []
|
_images = images or []
|
||||||
@ -38,7 +48,7 @@ class StubGlanceClient(object):
|
|||||||
|
|
||||||
def data(self, image_id):
|
def data(self, image_id):
|
||||||
self.get(image_id)
|
self.get(image_id)
|
||||||
return []
|
return _GlanceWrapper(self.fake_wrapped)
|
||||||
|
|
||||||
|
|
||||||
class FakeImage(object):
|
class FakeImage(object):
|
||||||
|
6
releasenotes/notes/image-no-data-c281f638d3dedfb2.yaml
Normal file
6
releasenotes/notes/image-no-data-c281f638d3dedfb2.yaml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
fixes:
|
||||||
|
- |
|
||||||
|
Fails deployment with the correct error message in a node's ``last_error``
|
||||||
|
field if an image from the Image service doesn't contain any data.
|
||||||
|
See `bug 1741223 <https://bugs.launchpad.net/bugs/1741223>`_ for details.
|
Loading…
Reference in New Issue
Block a user