Fix BDM legacy usage with objects

When we're doing an upgrade against Havana, our backleveled
compute RPC version will cause us to run block_device.legacy_mapping(),
which attempts to convert a BlockDeviceMapping object into an old-
style dict. This trips over a common problem with objects where
things expecting a list or a dict decide the object is a dict and
try to iterate it as such.

This makes the small tweak necessary and adds a test that verifies
that it works.

Change-Id: I98fe496720ad1c4fce44c0c7fea8bfa1c2721812
This commit is contained in:
Dan Smith 2014-03-06 12:46:11 -08:00
parent bb0445fa92
commit 31a4ffc49c
2 changed files with 14 additions and 1 deletions

View File

@ -86,7 +86,7 @@ class BlockDeviceDict(dict):
self.update( self.update(
dict((field, None) dict((field, None)
for field in self._fields - do_not_default)) for field in self._fields - do_not_default))
self.update(bdm_dict) self.update(list(bdm_dict.iteritems()))
def _validate(self, bdm_dict): def _validate(self, bdm_dict):
"""Basic data format validations.""" """Basic data format validations."""

View File

@ -423,6 +423,19 @@ class TestBlockDeviceDict(test.NoDBTestCase):
for legacy, expected in zip(got_legacy, self.legacy_mapping): for legacy, expected in zip(got_legacy, self.legacy_mapping):
self.assertThat(expected, matchers.IsSubDictOf(legacy)) self.assertThat(expected, matchers.IsSubDictOf(legacy))
def test_legacy_mapping_from_object_list(self):
bdm1 = block_device_obj.BlockDeviceMapping()
bdm1 = block_device_obj.BlockDeviceMapping._from_db_object(
None, bdm1, fake_block_device.FakeDbBlockDeviceDict(
self.new_mapping[0]))
bdm2 = block_device_obj.BlockDeviceMapping()
bdm2 = block_device_obj.BlockDeviceMapping._from_db_object(
None, bdm2, fake_block_device.FakeDbBlockDeviceDict(
self.new_mapping[1]))
bdmlist = block_device_obj.BlockDeviceMappingList()
bdmlist.objects = [bdm1, bdm2]
block_device.legacy_mapping(bdmlist)
def test_image_mapping(self): def test_image_mapping(self):
removed_fields = ['id', 'instance_uuid', 'connection_info', removed_fields = ['id', 'instance_uuid', 'connection_info',
'device_name', 'created_at', 'updated_at', 'device_name', 'created_at', 'updated_at',