From 37f3444c32ccb72076a1a6549c183f40c33fe684 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 --- 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 de0af8431025..702081cfc82b 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.db import api as 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 a1ccf9ed12aa..68abbbb95e51 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