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):