From f9e267fa42f5b8a024edaafd872eeeb9eb9f9b43 Mon Sep 17 00:00:00 2001 From: licanwei Date: Thu, 6 Jun 2019 11:13:34 +0800 Subject: [PATCH] check instance state for instance.update In the process of creating an instance, Nova will emit an instance.update notification with 'building' state. This will cause a KeyError exception because this instance isn't in Watcher datamodel. So we should ignore the notification instance.update with 'building' state. Closes-Bug: #1832154 Change-Id: I950eec50d2cee38bd22c47a70ae6f88bbf049080 --- .../model/notification/nova.py | 5 ++++ .../notification/test_nova_notifications.py | 25 +++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/watcher/decision_engine/model/notification/nova.py b/watcher/decision_engine/model/notification/nova.py index f4dee54ae..77cfb07b0 100644 --- a/watcher/decision_engine/model/notification/nova.py +++ b/watcher/decision_engine/model/notification/nova.py @@ -216,7 +216,12 @@ class VersionedNotification(NovaNotification): def instance_updated(self, payload): instance_data = payload['nova_object.data'] instance_uuid = instance_data['uuid'] + instance_state = instance_data['state'] node_uuid = instance_data.get('host') + # if instance state is building, don't update data model + if instance_state == 'building': + return + instance = self.get_or_create_instance(instance_uuid, node_uuid) self.update_instance(instance, payload) diff --git a/watcher/tests/decision_engine/model/notification/test_nova_notifications.py b/watcher/tests/decision_engine/model/notification/test_nova_notifications.py index 95f793e70..ab7d5fdd4 100644 --- a/watcher/tests/decision_engine/model/notification/test_nova_notifications.py +++ b/watcher/tests/decision_engine/model/notification/test_nova_notifications.py @@ -245,6 +245,31 @@ class TestNovaNotifications(NotificationTestCase): self.assertEqual(element.InstanceState.PAUSED.value, instance0.state) + def test_nova_instance_state_building(self): + compute_model = self.fake_cdmc.generate_scenario_3_with_2_nodes() + self.fake_cdmc.cluster_data_model = compute_model + handler = novanotification.VersionedNotification(self.fake_cdmc) + + instance0_uuid = '73b09e16-35b7-4922-804e-e8f5d9b740fc' + instance0 = compute_model.get_instance_by_uuid(instance0_uuid) + self.assertEqual(element.InstanceState.ACTIVE.value, instance0.state) + + message = self.load_message('instance-update.json') + + message['payload']['nova_object.data']['state'] = 'building' + + handler.info( + ctxt=self.context, + publisher_id=message['publisher_id'], + event_type=message['event_type'], + payload=message['payload'], + metadata=self.FAKE_METADATA, + ) + + # Assert that the instance state in the model is unchanged + # since the 'building' state is ignored. + self.assertEqual(element.InstanceState.ACTIVE.value, instance0.state) + @mock.patch.object(nova_helper, "NovaHelper") def test_nova_instance_update_notfound_still_creates( self, m_nova_helper_cls):