Default image.size to 0 when extracting v1 image attributes

When we snapshot a non-volume-backed instance, we create an
image in nova.compute.api.API._create_image and set some
values from the instance but 'size' isn't one of them.

Later in the virt driver's snapshot method, at least for
libvirt, it gets the snapshot image from the image API (glance)
and when using glance v1 (use_glance_v1=True) the _extract_attributes
method in nova.image.glance pulls the attributes out of the v1 image
response to the form that nova expects. This code assumes that
the 'size' attribute is set on the image, which for a snapshot image
it might not be (yet anyway). This results in an AttributeError.

This change defaults the size attribute value to 0 if it's not set.
If it is set, but to None, we still use 0 as before.

Conflicts:
	nova/tests/unit/image/test_glance.py

Original patch added test-case to TestExtractAttributes class,
but stable/mitaka doesn't have that class.
And that class used configurable value "use_glance_v1" that is
not contained in stable/mitaka.
So I added a test-case that tests fixed points to other existing
class.

Change-Id: I14b0e44a7268231c2b19f013b563f0b8f09c2e88
Closes-Bug: #1606707
(cherry picked from commit 7a16c754fb)
This commit is contained in:
Matt Riedemann 2016-07-26 18:27:48 -04:00 committed by Rikimaru Honjo
parent 7cc81c0e1d
commit 056ab125c5
2 changed files with 13 additions and 2 deletions

View File

@ -653,7 +653,9 @@ def _extract_attributes(image, include_locations=False):
output[attr] = getattr(image, attr, None)
# NOTE(mdorman): 'size' attribute must not be 'None', so use 0 instead
elif attr == 'size':
output[attr] = getattr(image, attr) or 0
# NOTE(mriedem): A snapshot image may not have the size attribute
# set so default to 0.
output[attr] = getattr(image, attr, 0) or 0
else:
# NOTE(xarses): Anything that is caught with the default value
# will result in an additional lookup to glance for said attr.

View File

@ -57,7 +57,8 @@ class TestConversions(test.NoDBTestCase):
self.assertEqual(result['updated_at'], NOW_DATETIME)
self.assertEqual(result['deleted_at'], NOW_DATETIME)
def _test_extracting_missing_attributes(self, include_locations):
def _test_extracting_missing_attributes(self, include_locations,
size_attr=True):
# Verify behavior from glance objects that are missing attributes
# TODO(jaypipes): Find a better way of testing this crappy
# glanceclient magic object stuff.
@ -66,6 +67,8 @@ class TestConversions(test.NoDBTestCase):
IMAGE_ATTRIBUTES = ['size', 'owner', 'id', 'created_at',
'updated_at', 'status', 'min_disk',
'min_ram', 'is_public']
if not size_attr:
IMAGE_ATTRIBUTES.pop(0)
raw = dict.fromkeys(IMAGE_ATTRIBUTES)
raw.update(metadata)
self.__dict__['raw'] = raw
@ -119,6 +122,12 @@ class TestConversions(test.NoDBTestCase):
def test_extracting_missing_attributes_exclude_locations(self):
self._test_extracting_missing_attributes(include_locations=False)
def test_extracting_missing_attributes_exclude_size(self):
# If image status is 'queued', 'size' attribute will be excluded
# by glance v1 API.
self._test_extracting_missing_attributes(include_locations=False,
size_attr=False)
class TestExceptionTranslations(test.NoDBTestCase):