Merge "Make reservation checks caseless"

This commit is contained in:
Zuul 2020-03-10 12:07:44 +00:00 committed by Gerrit Code Review
commit 0cfb66fd0f
3 changed files with 18 additions and 4 deletions

View File

@ -999,9 +999,9 @@ class Connection(api.Connection):
nodes = [] nodes = []
with _session_for_write(): with _session_for_write():
query = (model_query(models.Node) query = (model_query(models.Node)
.filter_by(reservation=hostname)) .filter(models.Node.reservation.ilike(hostname)))
nodes = [node['uuid'] for node in query] nodes = [node['uuid'] for node in query]
query.update({'reservation': None}) query.update({'reservation': None}, synchronize_session=False)
if nodes: if nodes:
nodes = ', '.join(nodes) nodes = ', '.join(nodes)
@ -1014,13 +1014,14 @@ class Connection(api.Connection):
nodes = [] nodes = []
with _session_for_write(): with _session_for_write():
query = (model_query(models.Node) query = (model_query(models.Node)
.filter_by(reservation=hostname)) .filter(models.Node.reservation.ilike(hostname)))
query = query.filter(models.Node.target_power_state != sql.null()) query = query.filter(models.Node.target_power_state != sql.null())
nodes = [node['uuid'] for node in query] nodes = [node['uuid'] for node in query]
query.update({'target_power_state': None, query.update({'target_power_state': None,
'last_error': _("Pending power operation was " 'last_error': _("Pending power operation was "
"aborted due to conductor " "aborted due to conductor "
"restart")}) "restart")},
synchronize_session=False)
if nodes: if nodes:
nodes = ', '.join(nodes) nodes = ', '.join(nodes)

View File

@ -179,13 +179,16 @@ class DbConductorTestCase(base.DbTestCase):
node1 = self.dbapi.create_node({'reservation': 'hostname1'}) node1 = self.dbapi.create_node({'reservation': 'hostname1'})
node2 = self.dbapi.create_node({'reservation': 'hostname2'}) node2 = self.dbapi.create_node({'reservation': 'hostname2'})
node3 = self.dbapi.create_node({'reservation': None}) node3 = self.dbapi.create_node({'reservation': None})
node4 = self.dbapi.create_node({'reservation': 'hostName1'})
self.dbapi.clear_node_reservations_for_conductor('hostname1') self.dbapi.clear_node_reservations_for_conductor('hostname1')
node1 = self.dbapi.get_node_by_id(node1.id) node1 = self.dbapi.get_node_by_id(node1.id)
node2 = self.dbapi.get_node_by_id(node2.id) node2 = self.dbapi.get_node_by_id(node2.id)
node3 = self.dbapi.get_node_by_id(node3.id) node3 = self.dbapi.get_node_by_id(node3.id)
node4 = self.dbapi.get_node_by_id(node4.id)
self.assertIsNone(node1.reservation) self.assertIsNone(node1.reservation)
self.assertEqual('hostname2', node2.reservation) self.assertEqual('hostname2', node2.reservation)
self.assertIsNone(node3.reservation) self.assertIsNone(node3.reservation)
self.assertIsNone(node4.reservation)
def test_clear_node_target_power_state(self): def test_clear_node_target_power_state(self):
node1 = self.dbapi.create_node({'reservation': 'hostname1', node1 = self.dbapi.create_node({'reservation': 'hostname1',
@ -194,16 +197,21 @@ class DbConductorTestCase(base.DbTestCase):
'target_power_state': 'power on'}) 'target_power_state': 'power on'})
node3 = self.dbapi.create_node({'reservation': None, node3 = self.dbapi.create_node({'reservation': None,
'target_power_state': 'power on'}) 'target_power_state': 'power on'})
node4 = self.dbapi.create_node({'reservation': 'hostName1',
'target_power_state': 'power on'})
self.dbapi.clear_node_target_power_state('hostname1') self.dbapi.clear_node_target_power_state('hostname1')
node1 = self.dbapi.get_node_by_id(node1.id) node1 = self.dbapi.get_node_by_id(node1.id)
node2 = self.dbapi.get_node_by_id(node2.id) node2 = self.dbapi.get_node_by_id(node2.id)
node3 = self.dbapi.get_node_by_id(node3.id) node3 = self.dbapi.get_node_by_id(node3.id)
node4 = self.dbapi.get_node_by_id(node4.id)
self.assertIsNone(node1.target_power_state) self.assertIsNone(node1.target_power_state)
self.assertIn('power operation was aborted', node1.last_error) self.assertIn('power operation was aborted', node1.last_error)
self.assertEqual('power on', node2.target_power_state) self.assertEqual('power on', node2.target_power_state)
self.assertIsNone(node2.last_error) self.assertIsNone(node2.last_error)
self.assertEqual('power on', node3.target_power_state) self.assertEqual('power on', node3.target_power_state)
self.assertIsNone(node3.last_error) self.assertIsNone(node3.last_error)
self.assertIsNone(node4.target_power_state)
self.assertIn('power operation was aborted', node4.last_error)
@mock.patch.object(timeutils, 'utcnow', autospec=True) @mock.patch.object(timeutils, 'utcnow', autospec=True)
def test_get_active_hardware_type_dict_one_host_no_ht(self, mock_utcnow): def test_get_active_hardware_type_dict_one_host_no_ht(self, mock_utcnow):

View File

@ -0,0 +1,5 @@
---
fixes:
- |
Fixes an issue where a node may be locked from changes if a conductor's
hostname case is changed before restarting the conductor service.