From 26b1f71c5eb373f8ee104139523c49ad010b4601 Mon Sep 17 00:00:00 2001 From: "Daniel P. Berrange" Date: Wed, 10 Jun 2015 18:14:54 +0100 Subject: [PATCH] utils: ignore block device mapping in system metadata The 'mappings' and 'block_device_mappings' fields in the image system metadata can be very large strings, as they are json encodings of the entire disk config. The instance system metadata table values are restricted in length, which results in the mappings & block_device_mappings fields being truncated Change-Id: Ie5d354ba4377343b148acda4679c562fd8ed43d6 --- nova/tests/unit/test_utils.py | 22 ++++++++++++++++++++++ nova/utils.py | 15 +++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/nova/tests/unit/test_utils.py b/nova/tests/unit/test_utils.py index 7a664030f321..23d06f11a416 100644 --- a/nova/tests/unit/test_utils.py +++ b/nova/tests/unit/test_utils.py @@ -831,6 +831,24 @@ class GetSystemMetadataFromImageTestCase(test.NoDBTestCase): sys_key = "%s%s" % (utils.SM_IMAGE_PROP_PREFIX, key) self.assertEqual(sys_meta[sys_key], expected) + def test_skip_image_properties(self): + image = self.get_image() + image["properties"] = { + "foo1": "bar", "foo2": "baz", + "mappings": "wizz", "img_block_device_mapping": "eek", + } + + sys_meta = utils.get_system_metadata_from_image(image) + + # Verify that we inherit all the image properties + for key, expected in six.iteritems(image["properties"]): + sys_key = "%s%s" % (utils.SM_IMAGE_PROP_PREFIX, key) + + if key in utils.SM_SKIP_KEYS: + self.assertNotIn(sys_key, sys_meta) + else: + self.assertEqual(sys_meta[sys_key], expected) + def test_vhd_min_disk_image(self): image = self.get_image() flavor = self.get_flavor() @@ -873,6 +891,8 @@ class GetImageFromSystemMetadataTestCase(test.NoDBTestCase): sys_meta = self.get_system_metadata() sys_meta["%soo1" % utils.SM_IMAGE_PROP_PREFIX] = "bar" sys_meta["%soo2" % utils.SM_IMAGE_PROP_PREFIX] = "baz" + sys_meta["%simg_block_device_mapping" % + utils.SM_IMAGE_PROP_PREFIX] = "eek" image = utils.get_image_from_system_metadata(sys_meta) @@ -888,6 +908,8 @@ class GetImageFromSystemMetadataTestCase(test.NoDBTestCase): sys_key = "%s%s" % (utils.SM_IMAGE_PROP_PREFIX, key) self.assertEqual(image["properties"][key], sys_meta[sys_key]) + self.assertNotIn("img_block_device_mapping", image["properties"]) + def test_dont_inherit_empty_values(self): sys_meta = self.get_system_metadata() diff --git a/nova/utils.py b/nova/utils.py index a57356c24cd3..264b44b2bea6 100644 --- a/nova/utils.py +++ b/nova/utils.py @@ -160,6 +160,15 @@ SM_IMAGE_PROP_PREFIX = "image_" SM_INHERITABLE_KEYS = ( 'min_ram', 'min_disk', 'disk_format', 'container_format', ) +# Keys which hold large structured data that won't fit in the +# size constraints of the system_metadata table, so we avoid +# storing and/or loading them. +SM_SKIP_KEYS = ( + # Legacy names + 'mappings', 'block_device_mapping', + # Modern names + 'img_mappings', 'img_block_device_mapping', +) def vpn_ping(address, port, timeout=0.05, session_id=None): @@ -1103,6 +1112,9 @@ def get_system_metadata_from_image(image_meta, flavor=None): prefix_format = SM_IMAGE_PROP_PREFIX + '%s' for key, value in six.iteritems(image_meta.get('properties', {})): + if key in SM_SKIP_KEYS: + continue + new_value = safe_truncate(six.text_type(value), 255) system_meta[prefix_format % key] = new_value @@ -1139,6 +1151,9 @@ def get_image_from_system_metadata(system_meta): if key.startswith(SM_IMAGE_PROP_PREFIX): key = key[len(SM_IMAGE_PROP_PREFIX):] + if key in SM_SKIP_KEYS: + continue + if key in SM_INHERITABLE_KEYS: image_meta[key] = value else: