Check min_ram and min_disk when boot from volume

Currently when boot from volume and the volume is created
from a image, the original image's min_ram, min_disk attributes
are ignored, this is not good.

We should extract these properties from the volume and check
it when boot from volume.

Change-Id: I861a78b5c7efa71e4bf7206d388b8d0d8048c78e
Closes-Bug: #1360022
This commit is contained in:
Yunhong Jiang 2014-08-21 17:46:50 -07:00
parent 4f0ce8ac8c
commit acf881a69b
3 changed files with 61 additions and 18 deletions

View File

@ -587,7 +587,6 @@ class API(base.Base):
def _check_requested_image(self, context, image_id, image, instance_type):
if not image:
# Image checks don't apply when building from volume
return
if image['status'] != 'active':
@ -681,9 +680,7 @@ class API(base.Base):
files_to_inject):
self._check_metadata_properties_quota(context, metadata)
self._check_injected_file_quota(context, files_to_inject)
if image_id is not None:
self._check_requested_image(context, image_id,
image, instance_type)
self._check_requested_image(context, image_id, image, instance_type)
def _validate_and_build_base_options(self, context, instance_type,
boot_meta, image_href, image_id,
@ -862,7 +859,7 @@ class API(base.Base):
try:
image_id = bdm['image_id']
image_meta = self.image_api.get(context, image_id)
return image_meta.get('properties', {})
return image_meta
except Exception:
raise exception.InvalidBDMImage(id=image_id)
elif bdm.get('volume_id'):
@ -876,7 +873,18 @@ class API(base.Base):
if not volume.get('bootable', True):
raise exception.InvalidBDMVolumeNotBootable(id=volume_id)
return volume.get('volume_image_metadata', {})
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(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.
image_meta['status'] = 'active'
return image_meta
return {}
@staticmethod
@ -947,10 +955,8 @@ class API(base.Base):
image_id, boot_meta = self._get_image(context, image_href)
else:
image_id = None
boot_meta = {}
boot_meta['properties'] = \
self._get_bdm_image_metadata(context,
block_device_mapping, legacy_bdm)
boot_meta = self._get_bdm_image_metadata(
context, block_device_mapping, legacy_bdm)
self._check_auto_disk_config(image=boot_meta,
auto_disk_config=auto_disk_config)

View File

@ -544,13 +544,19 @@ class ComputeVolumeTestCase(BaseTestCase):
def volume_api_get(*args, **kwargs):
if metadata:
return {
'volume_image_metadata': {'vol_test_key': 'vol_test_value'}
'volume_image_metadata': {'vol_test_key': 'vol_test_value',
'min_ram': 128,
'min_disk': 256,
},
}
else:
return {}
self.stubs.Set(self.compute_api.volume_api, 'get', volume_api_get)
expected_no_metadata = {'min_disk': 0, 'min_ram': 0, 'properties': {},
'size': 0, 'status': 'active'}
block_device_mapping = [{
'id': 1,
'device_name': 'vda',
@ -564,9 +570,12 @@ class ComputeVolumeTestCase(BaseTestCase):
image_meta = self.compute_api._get_bdm_image_metadata(
self.context, block_device_mapping)
if metadata:
self.assertEqual(image_meta['vol_test_key'], 'vol_test_value')
self.assertEqual(image_meta['properties']['vol_test_key'],
'vol_test_value')
self.assertEqual(128, image_meta['min_ram'])
self.assertEqual(256, image_meta['min_disk'])
else:
self.assertEqual(image_meta, {})
self.assertEqual(expected_no_metadata, image_meta)
# Test it with new-style BDMs
block_device_mapping = [{
@ -580,9 +589,12 @@ class ComputeVolumeTestCase(BaseTestCase):
image_meta = self.compute_api._get_bdm_image_metadata(
self.context, block_device_mapping, legacy_bdm=False)
if metadata:
self.assertEqual(image_meta['vol_test_key'], 'vol_test_value')
self.assertEqual(image_meta['properties']['vol_test_key'],
'vol_test_value')
self.assertEqual(128, image_meta['min_ram'])
self.assertEqual(256, image_meta['min_disk'])
else:
self.assertEqual(image_meta, {})
self.assertEqual(expected_no_metadata, image_meta)
def test_boot_volume_no_metadata(self):
self.test_boot_volume_metadata(metadata=False)
@ -610,7 +622,8 @@ class ComputeVolumeTestCase(BaseTestCase):
self.context, block_device_mapping, legacy_bdm=False)
if metadata:
self.assertEqual(image_meta['img_test_key'], 'img_test_value')
self.assertEqual('img_test_value',
image_meta['properties']['img_test_key'])
else:
self.assertEqual(image_meta, {})
@ -11076,7 +11089,7 @@ class CheckRequestedImageTestCase(test.TestCase):
self.instance_type['root_gb'] = 1
def test_no_image_specified(self):
self.compute_api._check_requested_image(self.context, None, {},
self.compute_api._check_requested_image(self.context, None, None,
self.instance_type)
def test_image_status_must_be_active(self):

View File

@ -1811,6 +1811,9 @@ class _ComputeAPIUnitTestMixIn(object):
'delete_on_termination': False,
}]
expected_meta = {'min_disk': 0, 'min_ram': 0, 'properties': {},
'size': 0, 'status': 'active'}
with mock.patch.object(self.compute_api.volume_api, 'get',
side_effect=get_vol_data):
if not is_bootable:
@ -1820,7 +1823,7 @@ class _ComputeAPIUnitTestMixIn(object):
else:
meta = self.compute_api._get_bdm_image_metadata(self.context,
block_device_mapping)
self.assertEqual({}, meta)
self.assertEqual(expected_meta, meta)
def test_boot_volume_non_bootable(self):
self._test_boot_volume_bootable(False)
@ -1828,6 +1831,27 @@ class _ComputeAPIUnitTestMixIn(object):
def test_boot_volume_bootable(self):
self._test_boot_volume_bootable(True)
def test_boot_volume_basic_property(self):
block_device_mapping = [{
'id': 1,
'device_name': 'vda',
'no_device': None,
'virtual_name': None,
'snapshot_id': None,
'volume_id': '1',
'delete_on_termination': False,
}]
fake_volume = {"volume_image_metadata":
{"min_ram": 256, "min_disk": 128, "foo": "bar"}}
with mock.patch.object(self.compute_api.volume_api, 'get',
return_value=fake_volume):
meta = self.compute_api._get_bdm_image_metadata(
self.context, block_device_mapping)
self.assertEqual(256, meta['min_ram'])
self.assertEqual(128, meta['min_disk'])
self.assertEqual('active', meta['status'])
self.assertEqual('bar', meta['properties']['foo'])
def _create_instance_with_disabled_disk_config(self, object=False):
sys_meta = {"image_auto_disk_config": "Disabled"}
params = {"system_metadata": sys_meta}