Fix image metadata returned for volumes
When creating a volume from a glance image, cinder stores the original image metadata in volume_glance_metadata. This is a key/value store, and all the values are strings. When Nova boots an instance from a volume, it passes the image metadata returned by cinder, which is all strings. If a driver expects these values to be ints, as they are when booting from an image, it will get a type error. This change also pulls size from the volume directly rather than taking the value from the stored image metadata. This is because the volume will have been created in 1Gb increments, and is unlikely to be the same size as the original image. It may also have been subsequently extended. Change-Id: I7928f6be1ca99f1502941b9df2b443f2ca63a37b Closes-Bug: #1367540
This commit is contained in:
parent
803eba994a
commit
688be19e8a
|
@ -29,6 +29,7 @@ from oslo.config import cfg
|
|||
from oslo.utils import excutils
|
||||
from oslo.utils import strutils
|
||||
from oslo.utils import timeutils
|
||||
from oslo.utils import units
|
||||
import six
|
||||
|
||||
from nova import availability_zones
|
||||
|
@ -956,9 +957,18 @@ class API(base.Base):
|
|||
properties = volume.get('volume_image_metadata', {})
|
||||
image_meta = {'properties': properties}
|
||||
# NOTE(yjiang5): restore the basic attributes
|
||||
image_meta['min_ram'] = properties.get('min_ram', 0)
|
||||
image_meta['min_disk'] = properties.get('min_disk', 0)
|
||||
image_meta['size'] = properties.get('size', 0)
|
||||
# NOTE(mdbooth): These values come from volume_glance_metadata
|
||||
# in cinder. This is a simple key/value table, and all values
|
||||
# are strings. We need to convert them to ints to avoid
|
||||
# unexpected type errors.
|
||||
image_meta['min_ram'] = int(properties.get('min_ram', 0))
|
||||
image_meta['min_disk'] = int(properties.get('min_disk', 0))
|
||||
# Volume size is no longer related to the original image size,
|
||||
# so we take it from the volume directly. Cinder creates
|
||||
# volumes in Gb increments, and stores size in Gb, whereas
|
||||
# glance reports size in bytes. As we're returning glance
|
||||
# metadata here, we need to convert it.
|
||||
image_meta['size'] = volume.get('size', 0) * units.Gi
|
||||
# NOTE(yjiang5): Always set the image status as 'active'
|
||||
# and depends on followed volume_api.check_attach() to
|
||||
# verify it. This hack should be harmless with that check.
|
||||
|
|
|
@ -33,6 +33,7 @@ from oslo.config import cfg
|
|||
from oslo import messaging
|
||||
from oslo.utils import importutils
|
||||
from oslo.utils import timeutils
|
||||
from oslo.utils import units
|
||||
import six
|
||||
import testtools
|
||||
from testtools import matchers as testtools_matchers
|
||||
|
@ -579,9 +580,11 @@ class ComputeVolumeTestCase(BaseTestCase):
|
|||
def volume_api_get(*args, **kwargs):
|
||||
if metadata:
|
||||
return {
|
||||
'size': 1,
|
||||
'volume_image_metadata': {'vol_test_key': 'vol_test_value',
|
||||
'min_ram': 128,
|
||||
'min_disk': 256,
|
||||
'min_ram': u'128',
|
||||
'min_disk': u'256',
|
||||
'size': u'536870912'
|
||||
},
|
||||
}
|
||||
else:
|
||||
|
@ -609,6 +612,7 @@ class ComputeVolumeTestCase(BaseTestCase):
|
|||
'vol_test_value')
|
||||
self.assertEqual(128, image_meta['min_ram'])
|
||||
self.assertEqual(256, image_meta['min_disk'])
|
||||
self.assertEqual(units.Gi, image_meta['size'])
|
||||
else:
|
||||
self.assertEqual(expected_no_metadata, image_meta)
|
||||
|
||||
|
@ -628,6 +632,7 @@ class ComputeVolumeTestCase(BaseTestCase):
|
|||
'vol_test_value')
|
||||
self.assertEqual(128, image_meta['min_ram'])
|
||||
self.assertEqual(256, image_meta['min_disk'])
|
||||
self.assertEqual(units.Gi, image_meta['size'])
|
||||
else:
|
||||
self.assertEqual(expected_no_metadata, image_meta)
|
||||
|
||||
|
|
Loading…
Reference in New Issue