diff --git a/nova/objects/base.py b/nova/objects/base.py index 1466e2327085..7b4d3d8d62f9 100644 --- a/nova/objects/base.py +++ b/nova/objects/base.py @@ -632,7 +632,7 @@ class NovaObjectSerializer(messaging.NoOpSerializer): def _process_object(self, context, objprim): try: objinst = NovaObject.obj_from_primitive(objprim, context=context) - except exception.IncompatibleObjectVersion as e: + except exception.IncompatibleObjectVersion: objver = objprim['nova_object.version'] if objver.count('.') == 2: # NOTE(danms): For our purposes, the .z part of the version @@ -640,8 +640,13 @@ class NovaObjectSerializer(messaging.NoOpSerializer): objprim['nova_object.version'] = \ '.'.join(objver.split('.')[:2]) return self._process_object(context, objprim) - objinst = self.conductor.object_backport(context, objprim, - e.kwargs['supported']) + objname = objprim['nova_object.name'] + supported = NovaObjectRegistry.obj_classes().get(objname, []) + if supported: + objinst = self.conductor.object_backport(context, objprim, + supported[0].VERSION) + else: + raise return objinst def _process_iterable(self, context, action_fn, values): diff --git a/nova/tests/unit/objects/test_objects.py b/nova/tests/unit/objects/test_objects.py index 8bc0c4d28792..2280697cee76 100644 --- a/nova/tests/unit/objects/test_objects.py +++ b/nova/tests/unit/objects/test_objects.py @@ -986,6 +986,36 @@ class TestObjectSerializer(_BaseTestCase): # .0 of the object. self.assertEqual('1.6', obj.VERSION) + def test_nested_backport(self): + @base.NovaObjectRegistry.register + class Parent(base.NovaObject): + VERSION = '1.0' + + fields = { + 'child': fields.ObjectField('MyObj'), + } + + @base.NovaObjectRegistry.register # noqa + class Parent(base.NovaObject): + VERSION = '1.1' + + fields = { + 'child': fields.ObjectField('MyObj'), + } + + child = MyObj(foo=1) + parent = Parent(child=child) + prim = parent.obj_to_primitive() + child_prim = prim['nova_object.data']['child'] + child_prim['nova_object.version'] = '1.10' + ser = base.NovaObjectSerializer() + with mock.patch.object(ser.conductor, 'object_backport') as backport: + ser.deserialize_entity(self.context, prim) + # NOTE(danms): This should be the version of the parent object, + # not the child. If wrong, this will be '1.6', which is the max + # child version in our registry. + backport.assert_called_once_with(self.context, prim, '1.1') + def test_object_serialization(self): ser = base.NovaObjectSerializer() obj = MyObj()