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 37f3444c32)
(cherry picked from commit 518fdc7a22)
This commit is contained in:
Dan Smith 2018-09-20 07:15:25 -07:00 committed by Mohammed Naser
parent 8157b16a65
commit d01336a332
2 changed files with 14 additions and 1 deletions

View File

@ -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

View File

@ -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