From 976e52a49c7b43a5bb9ba86bf7970bf7185ef285 Mon Sep 17 00:00:00 2001 From: Dan Smith Date: Thu, 20 Sep 2018 07:15:25 -0700 Subject: [PATCH] Filter deleted computes from get_all_by_uuids() Fix ComputeNodeList.get_all_by_uuids() to use model_query() so that deleted compute nodes are filtered from the results. Without this, a stale result from placement could cause us to choose a compute node as a scheduling destination that has since been deleted. Change-Id: I811e84af46d678c3fdbf94ee400eabe659fc3d4e Closes-Bug: #1793533 (cherry picked from commit 37f3444c32ccb72076a1a6549c183f40c33fe684) (cherry picked from commit 518fdc7a22dd3dabbc9dd032e816e0aecdd75150) (cherry picked from commit d01336a332a4080f26ac70d131ecf3ed66e129a9) --- nova/objects/compute_node.py | 3 ++- nova/tests/functional/db/test_compute_node.py | 12 ++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/nova/objects/compute_node.py b/nova/objects/compute_node.py index 742c7bdb3cf4..c27cf8c61f76 100644 --- a/nova/objects/compute_node.py +++ b/nova/objects/compute_node.py @@ -19,6 +19,7 @@ from oslo_utils import versionutils import nova.conf from nova import db +from nova.db.sqlalchemy import api as sa_api from nova.db.sqlalchemy import models from nova import exception from nova import objects @@ -441,7 +442,7 @@ class ComputeNodeList(base.ObjectListBase, base.NovaObject): @staticmethod @db.select_db_reader_mode def _db_compute_node_get_all_by_uuids(context, compute_uuids): - db_computes = context.session.query(models.ComputeNode).filter( + db_computes = sa_api.model_query(context, models.ComputeNode).filter( models.ComputeNode.uuid.in_(compute_uuids)).all() return db_computes diff --git a/nova/tests/functional/db/test_compute_node.py b/nova/tests/functional/db/test_compute_node.py index dfa88ab64373..e802be4702d5 100644 --- a/nova/tests/functional/db/test_compute_node.py +++ b/nova/tests/functional/db/test_compute_node.py @@ -85,6 +85,12 @@ class ComputeNodeTestCase(test.TestCase): # Two compute nodes can't have the same tuple (host, node, deleted) cn2.host = _HOSTNAME + '2' cn2.create() + # A deleted compute node + cn3 = fake_compute_obj.obj_clone() + cn3._context = self.context + cn3.host = _HOSTNAME + '3' + cn3.create() + cn3.destroy() cns = objects.ComputeNodeList.get_all_by_uuids(self.context, []) self.assertEqual(0, len(cns)) @@ -107,6 +113,12 @@ class ComputeNodeTestCase(test.TestCase): uuidsentinel.noexists]) self.assertEqual(2, len(cns)) + # Ensure we don't get the deleted one, even if we ask for it + cns = objects.ComputeNodeList.get_all_by_uuids(self.context, + [cn1.uuid, cn2.uuid, + cn3.uuid]) + self.assertEqual(2, len(cns)) + def test_get_by_hypervisor_type(self): cn1 = fake_compute_obj.obj_clone() cn1._context = self.context