Add better dbapi support for querying reservation

This commit adds support for querying reservation of
a node by a list of desired conductor names.  It adds
a new filter 'reserved_by_any_of' which is expected to
be a list of conductors.

Change-Id: I149eae115fd3267e9b9efdb99aca445e7b18ba03
Closes-Bug: 1472212
This commit is contained in:
Ramakrishnan G 2015-08-07 10:46:27 +00:00
parent ff451bc310
commit 1669d4d75f
4 changed files with 24 additions and 8 deletions

View File

@ -1202,14 +1202,12 @@ class ConductorManager(periodic_task.PeriodicTasks):
node_iter = self.iter_nodes(
fields=['id', 'reservation'],
filters={'provision_state': states.DEPLOYING,
'maintenance': False})
'maintenance': False,
'reserved_by_any_of': offline_conductors})
if not node_iter:
return
for node_uuid, driver, node_id, conductor_hostname in node_iter:
if conductor_hostname not in offline_conductors:
continue
# NOTE(lucasagomes): Although very rare, this may lead to a
# race condition. By the time we release the lock the conductor
# that was previously managing the node could be back online.

View File

@ -56,6 +56,7 @@ class Connection(object):
:associated: True | False
:reserved: True | False
:reserved_by_any_of: [conductor1, conductor2]
:maintenance: True | False
:chassis_uuid: uuid of chassis
:driver: driver's name

View File

@ -168,6 +168,9 @@ class Connection(api.Connection):
query = query.filter(models.Node.reservation != sql.null())
else:
query = query.filter(models.Node.reservation == sql.null())
if 'reserved_by_any_of' in filters:
query = query.filter(models.Node.reservation.in_(
filters['reserved_by_any_of']))
if 'maintenance' in filters:
query = query.filter_by(maintenance=filters['maintenance'])
if 'driver' in filters:

View File

@ -113,9 +113,14 @@ class DbNodeTestCase(base.DbTestCase):
driver='driver-two',
uuid=uuidutils.generate_uuid(),
maintenance=True)
node3 = utils.create_test_node(
driver='driver-one',
uuid=uuidutils.generate_uuid(),
reservation='another-fake-host')
res = self.dbapi.get_nodeinfo_list(filters={'driver': 'driver-one'})
self.assertEqual([node1.id], [r[0] for r in res])
self.assertEqual(sorted([node1.id, node3.id]),
sorted([r[0] for r in res]))
res = self.dbapi.get_nodeinfo_list(filters={'driver': 'bad-driver'})
self.assertEqual([], [r[0] for r in res])
@ -124,10 +129,12 @@ class DbNodeTestCase(base.DbTestCase):
self.assertEqual([node1.id], [r[0] for r in res])
res = self.dbapi.get_nodeinfo_list(filters={'associated': False})
self.assertEqual([node2.id], [r[0] for r in res])
self.assertEqual(sorted([node2.id, node3.id]),
sorted([r[0] for r in res]))
res = self.dbapi.get_nodeinfo_list(filters={'reserved': True})
self.assertEqual([node1.id], [r[0] for r in res])
self.assertEqual(sorted([node1.id, node3.id]),
sorted([r[0] for r in res]))
res = self.dbapi.get_nodeinfo_list(filters={'reserved': False})
self.assertEqual([node2.id], [r[0] for r in res])
@ -136,7 +143,14 @@ class DbNodeTestCase(base.DbTestCase):
self.assertEqual([node2.id], [r.id for r in res])
res = self.dbapi.get_node_list(filters={'maintenance': False})
self.assertEqual([node1.id], [r.id for r in res])
self.assertEqual(sorted([node1.id, node3.id]),
sorted([r.id for r in res]))
res = self.dbapi.get_node_list(
filters={'reserved_by_any_of': ['fake-host',
'another-fake-host']})
self.assertEqual(sorted([node1.id, node3.id]),
sorted([r.id for r in res]))
@mock.patch.object(timeutils, 'utcnow', autospec=True)
def test_get_nodeinfo_list_provision(self, mock_utcnow):