Only get image location attributes if including locations
Commit 155eeabbfa
added 'direct_url' and
'locations' to the list of attributes to get from an image which makes a
call back to glance if the attributes aren't on the image, and can
result in a 404 if they aren't available, which would be in the glance
v1 API case.
This change simply passes the new include_locations parameter down to
_extract_attributes so we can do the proper filtering.
Change-Id: I903fa5c781fed52183b340dc3d9bc4b6598b21ce
Partial-Bug: #1351333
This commit is contained in:
parent
3619c1914e
commit
ed2aa220aa
|
@ -307,16 +307,14 @@ class GlanceImageService(object):
|
|||
if not _is_image_available(context, image):
|
||||
raise exception.ImageNotFound(image_id=image_id)
|
||||
|
||||
image = _translate_from_glance(image)
|
||||
image = _translate_from_glance(image,
|
||||
include_locations=include_locations)
|
||||
if include_locations:
|
||||
locations = image.get('locations', None) or []
|
||||
du = image.get('direct_url', None)
|
||||
if du:
|
||||
locations.append({'url': du, 'metadata': {}})
|
||||
image['locations'] = locations
|
||||
else:
|
||||
image.pop('locations', None)
|
||||
image.pop('direct_url', None)
|
||||
|
||||
return image
|
||||
|
||||
|
@ -482,8 +480,9 @@ def _translate_to_glance(image_meta):
|
|||
return image_meta
|
||||
|
||||
|
||||
def _translate_from_glance(image):
|
||||
image_meta = _extract_attributes(image)
|
||||
def _translate_from_glance(image, include_locations=False):
|
||||
image_meta = _extract_attributes(image,
|
||||
include_locations=include_locations)
|
||||
image_meta = _convert_timestamps_to_datetimes(image_meta)
|
||||
image_meta = _convert_from_string(image_meta)
|
||||
return image_meta
|
||||
|
@ -532,7 +531,7 @@ def _convert_to_string(metadata):
|
|||
return _convert(_json_dumps, metadata)
|
||||
|
||||
|
||||
def _extract_attributes(image):
|
||||
def _extract_attributes(image, include_locations=False):
|
||||
# NOTE(hdd): If a key is not found, base.Resource.__getattr__() may perform
|
||||
# a get(), resulting in a useless request back to glance. This list is
|
||||
# therefore sorted, with dependent attributes as the end
|
||||
|
@ -547,6 +546,7 @@ def _extract_attributes(image):
|
|||
|
||||
queued = getattr(image, 'status') == 'queued'
|
||||
queued_exclude_attrs = ['disk_format', 'container_format']
|
||||
include_locations_attrs = ['direct_url', 'locations']
|
||||
output = {}
|
||||
|
||||
for attr in IMAGE_ATTRIBUTES:
|
||||
|
@ -560,6 +560,10 @@ def _extract_attributes(image):
|
|||
# NOTE(liusheng): queued image may not have these attributes and 'name'
|
||||
elif queued and attr in queued_exclude_attrs:
|
||||
output[attr] = getattr(image, attr, None)
|
||||
# NOTE(mriedem): Only get location attrs if including locations.
|
||||
elif attr in include_locations_attrs:
|
||||
if include_locations:
|
||||
output[attr] = getattr(image, attr, None)
|
||||
else:
|
||||
# NOTE(xarses): Anything that is caught with the default value
|
||||
# will result in a additional lookup to glance for said attr.
|
||||
|
|
|
@ -454,7 +454,7 @@ class TestGlanceImageService(test.NoDBTestCase):
|
|||
self.assertEqual(same_id, image_id)
|
||||
self.assertEqual(service._client.host, 'something-less-likely')
|
||||
|
||||
def test_extracting_missing_attributes(self):
|
||||
def _test_extracting_missing_attributes(self, include_locations):
|
||||
"""Verify behavior from glance objects that are missing attributes
|
||||
|
||||
This fakes the image class and is missing attribute as the client can
|
||||
|
@ -475,7 +475,8 @@ class TestGlanceImageService(test.NoDBTestCase):
|
|||
'updated_at': self.NOW_DATETIME,
|
||||
}
|
||||
image = MyFakeGlanceImage(metadata)
|
||||
observed = glance._extract_attributes(image)
|
||||
observed = glance._extract_attributes(
|
||||
image, include_locations=include_locations)
|
||||
expected = {
|
||||
'id': 1,
|
||||
'name': None,
|
||||
|
@ -492,12 +493,19 @@ class TestGlanceImageService(test.NoDBTestCase):
|
|||
'deleted': None,
|
||||
'status': None,
|
||||
'properties': {},
|
||||
'owner': None,
|
||||
'locations': None,
|
||||
'direct_url': None
|
||||
'owner': None
|
||||
}
|
||||
if include_locations:
|
||||
expected['locations'] = None
|
||||
expected['direct_url'] = None
|
||||
self.assertEqual(expected, observed)
|
||||
|
||||
def test_extracting_missing_attributes_include_locations(self):
|
||||
self._test_extracting_missing_attributes(include_locations=True)
|
||||
|
||||
def test_extracting_missing_attributes_exclude_locations(self):
|
||||
self._test_extracting_missing_attributes(include_locations=False)
|
||||
|
||||
|
||||
def _create_failing_glance_client(info):
|
||||
class MyGlanceStubClient(glance_stubs.StubGlanceClient):
|
||||
|
@ -652,7 +660,7 @@ class TestShow(test.NoDBTestCase):
|
|||
client.call.assert_called_once_with(ctx, 1, 'get',
|
||||
mock.sentinel.image_id)
|
||||
is_avail_mock.assert_called_once_with(ctx, {})
|
||||
trans_from_mock.assert_called_once_with({})
|
||||
trans_from_mock.assert_called_once_with({}, include_locations=False)
|
||||
self.assertIn('mock', info)
|
||||
self.assertEqual(mock.sentinel.trans_from, info['mock'])
|
||||
|
||||
|
@ -743,7 +751,8 @@ class TestShow(test.NoDBTestCase):
|
|||
|
||||
client.call.assert_called_once_with(ctx, 2, 'get', image_id)
|
||||
avail_mock.assert_called_once_with(ctx, mock.sentinel.image)
|
||||
trans_from_mock.assert_called_once_with(mock.sentinel.image)
|
||||
trans_from_mock.assert_called_once_with(mock.sentinel.image,
|
||||
include_locations=True)
|
||||
self.assertIn('locations', info)
|
||||
self.assertEqual(locations, info['locations'])
|
||||
|
||||
|
|
Loading…
Reference in New Issue