From e360dc2adcf18cfdc2b39cbea708bb27bf741e2d Mon Sep 17 00:00:00 2001 From: Andrew Laski Date: Thu, 24 Oct 2013 13:48:24 -0400 Subject: [PATCH] Pull system_metadata for notifications on instance.save() When saving changes on an instance object a notification is sent out. An attempt is made to pull flavor information from the instance but if system_metadata is not joined then an exception is raised and the notification fails. This ensures that system_metadata is available for those notifications. Conflicts: nova/objects/base.py The conflict is from change Icd2944f17b6100d51007dbc48da90e4e992bbd48 Change-Id: Ifd317f847c3839cd6019038bb3dc856b9f107000 Closes-bug: 1244311 (cherry picked from commit e03963b1e42ca2900b108201e77edf2386c5c46a) --- nova/objects/base.py | 1 + nova/objects/instance.py | 5 +++++ nova/tests/compute/test_compute.py | 8 ++++---- nova/tests/objects/test_instance.py | 6 ++++-- 4 files changed, 14 insertions(+), 6 deletions(-) diff --git a/nova/objects/base.py b/nova/objects/base.py index de59b69faece..f9a0c9944128 100644 --- a/nova/objects/base.py +++ b/nova/objects/base.py @@ -140,6 +140,7 @@ def remotable(fn): for key, value in updates.iteritems(): if key in self.fields: self[key] = self._attr_from_primitive(key, value) + self.obj_reset_changes() self._changed_fields = set(updates.get('obj_what_changed', [])) return result else: diff --git a/nova/objects/instance.py b/nova/objects/instance.py index 7ea1fb4df6c2..9d77bc74958c 100644 --- a/nova/objects/instance.py +++ b/nova/objects/instance.py @@ -443,6 +443,11 @@ class Instance(base.NovaPersistentObject, base.NovaObject): expected_attrs = [attr for attr in _INSTANCE_OPTIONAL_JOINED_FIELDS if self.obj_attr_is_set(attr)] + # NOTE(alaski): We need to pull system_metadata for the + # notification.send_update() below. If we don't there's a KeyError + # when it tries to extract the flavor. + if 'system_metadata' not in expected_attrs: + expected_attrs.append('system_metadata') old_ref, inst_ref = db.instance_update_and_get_original( context, self.uuid, updates, update_cells=False, columns_to_join=_expected_cols(expected_attrs)) diff --git a/nova/tests/compute/test_compute.py b/nova/tests/compute/test_compute.py index 12a232f6dd1d..60470d330141 100644 --- a/nova/tests/compute/test_compute.py +++ b/nova/tests/compute/test_compute.py @@ -2071,7 +2071,7 @@ class ComputeTestCase(BaseTestCase): db.instance_update_and_get_original(econtext, instance['uuid'], {'power_state': fake_power_state1}, update_cells=False, - columns_to_join=[], + columns_to_join=['system_metadata'] ).AndReturn((None, updated_dbinstance1)) @@ -2117,7 +2117,7 @@ class ComputeTestCase(BaseTestCase): 'task_state': None, 'vm_state': vm_states.ACTIVE}, update_cells=False, - columns_to_join=[], + columns_to_join=['system_metadata'], ).AndRaise(exception.InstanceNotFound( instance_id=instance['uuid'])) self.compute._notify_about_instance_usage( @@ -2129,7 +2129,7 @@ class ComputeTestCase(BaseTestCase): econtext, updated_dbinstance1['uuid'], {'vm_state': vm_states.ERROR}, update_cells=False, - columns_to_join=[], + columns_to_join=['system_metadata'], ).AndRaise(exception.InstanceNotFound( instance_id=instance['uuid'])) else: @@ -2139,7 +2139,7 @@ class ComputeTestCase(BaseTestCase): 'task_state': None, 'vm_state': vm_states.ACTIVE}, update_cells=False, - columns_to_join=[], + columns_to_join=['system_metadata'], ).AndReturn((None, updated_dbinstance2)) self.compute._notify_about_instance_usage( econtext, diff --git a/nova/tests/objects/test_instance.py b/nova/tests/objects/test_instance.py index 5aa08ba39137..b0b85673adf5 100644 --- a/nova/tests/objects/test_instance.py +++ b/nova/tests/objects/test_instance.py @@ -254,7 +254,8 @@ class _TestInstanceObject(object): db.instance_update_and_get_original( self.context, fake_uuid, expected_updates, update_cells=False, - columns_to_join=['info_cache', 'security_groups'] + columns_to_join=['info_cache', 'security_groups', + 'system_metadata'] ).AndReturn((old_ref, new_ref)) if cell_type == 'api': cells_rpcapi.CellsAPI().AndReturn(cells_api_mock) @@ -324,7 +325,8 @@ class _TestInstanceObject(object): ).AndReturn(old_ref) db.instance_update_and_get_original( self.context, fake_uuid, expected_updates, update_cells=False, - columns_to_join=['info_cache', 'security_groups'] + columns_to_join=['info_cache', 'security_groups', + 'system_metadata'] ).AndReturn((old_ref, new_ref)) notifications.send_update(self.context, mox.IgnoreArg(), mox.IgnoreArg())