From 6d60c74191f271c1fcea2ff1556a1f00baaa3f58 Mon Sep 17 00:00:00 2001 From: Balazs Gibizer Date: Fri, 8 Jun 2018 17:57:07 +0200 Subject: [PATCH] Fix unbound local when saving an unchanged RequestSpec RequestSpec._get_update_primitives() tried to return the unitialized db_updates field when the object has no changes. This patch initalizes that local to None and handles that None in create() and save() where the RequestSpec._get_update_primitives() is called. Change-Id: Iad256079945bf8b5745ebdcc393c55115dbcab75 Closes-Bug: #1775863 (cherry picked from commit 08fb09e878dcaedbb446e18502a6172fa4d43121) (cherry picked from commit a31ebd87ba9a9c0ab0013fe59b6d5056c1193f4c) --- nova/objects/request_spec.py | 13 +++++++++---- nova/tests/unit/objects/test_request_spec.py | 10 ++++++++++ 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/nova/objects/request_spec.py b/nova/objects/request_spec.py index c6521b1b3053..f37b491a9efb 100644 --- a/nova/objects/request_spec.py +++ b/nova/objects/request_spec.py @@ -497,6 +497,7 @@ class RequestSpec(base.NovaObject): it was originally scheduled with. """ updates = self.obj_get_changes() + db_updates = None # NOTE(alaski): The db schema is the full serialized object in a # 'spec' column. If anything has changed we rewrite the full thing. if updates: @@ -522,7 +523,9 @@ class RequestSpec(base.NovaObject): reason='already created') updates = self._get_update_primitives() - + if not updates: + raise exception.ObjectActionError(action='create', + reason='no fields are set') db_spec = self._create_in_db(self._context, updates) self._from_db_object(self._context, self, db_spec) @@ -540,9 +543,11 @@ class RequestSpec(base.NovaObject): @base.remotable def save(self): updates = self._get_update_primitives() - db_spec = self._save_in_db(self._context, self.instance_uuid, updates) - self._from_db_object(self._context, self, db_spec) - self.obj_reset_changes() + if updates: + db_spec = self._save_in_db(self._context, self.instance_uuid, + updates) + self._from_db_object(self._context, self, db_spec) + self.obj_reset_changes() @staticmethod @db.api_context_manager.writer diff --git a/nova/tests/unit/objects/test_request_spec.py b/nova/tests/unit/objects/test_request_spec.py index 52734fbd5b6a..d8802ac614e9 100644 --- a/nova/tests/unit/objects/test_request_spec.py +++ b/nova/tests/unit/objects/test_request_spec.py @@ -622,6 +622,16 @@ class _TestRequestSpecObject(object): objects.SecurityGroupList) self.assertIn('security_groups', req_obj) + def test_create_raises_on_unchanged_object(self): + ctxt = context.RequestContext(uuids.user_id, uuids.project_id) + req_obj = request_spec.RequestSpec(context=ctxt) + self.assertRaises(exception.ObjectActionError, req_obj.create) + + def test_save_can_be_called_on_unchanged_object(self): + req_obj = fake_request_spec.fake_spec_obj(remove_id=True) + req_obj.create() + req_obj.save() + class TestRequestSpecObject(test_objects._LocalTest, _TestRequestSpecObject):