ironic: Get correct inventory for deployed node
_node_resources_unavailable() is supposed to be called after _node_resources_used() returns False. Because get_inventory() doesn't satisfy this condition, this method returns an empty inventory for a deployed bare metal node. It causes the resource tracker to try removing an allocated inventory from placement. This removal results in periodic unexpected errors. This patch calls _node_resources_used() prior to _node_resources_unanvailable() for getting a proper inventory. Change-Id: I6717ce19f6005c8ebb7af75437a72876c5a53f34 Closes-Bug: 1751472 (cherry picked from commitac20fc22ad
) (cherry picked from commit525ea3cfac
)
This commit is contained in:
parent
56350b977e
commit
15aed7e0e0
|
@ -733,11 +733,14 @@ class IronicDriverTestCase(test.NoDBTestCase):
|
|||
expected_uuids = [n['uuid'] for n in node_dicts if n['expected']]
|
||||
self.assertEqual(sorted(expected_uuids), sorted(available_nodes))
|
||||
|
||||
@mock.patch.object(ironic_driver.IronicDriver,
|
||||
'_node_resources_used', return_value=False)
|
||||
@mock.patch.object(ironic_driver.IronicDriver,
|
||||
'_node_resources_unavailable', return_value=False)
|
||||
@mock.patch.object(ironic_driver.IronicDriver, '_node_resource')
|
||||
@mock.patch.object(ironic_driver.IronicDriver, '_node_from_cache')
|
||||
def test_get_inventory_no_rc(self, mock_nfc, mock_nr, mock_res_unavail):
|
||||
def test_get_inventory_no_rc(self, mock_nfc, mock_nr, mock_res_unavail,
|
||||
mock_res_used):
|
||||
"""Ensure that when node.resource_class is missing, that we return the
|
||||
legacy VCPU, MEMORY_MB and DISK_GB resources for inventory.
|
||||
"""
|
||||
|
@ -781,14 +784,18 @@ class IronicDriverTestCase(test.NoDBTestCase):
|
|||
}
|
||||
mock_nfc.assert_called_once_with(mock.sentinel.nodename)
|
||||
mock_nr.assert_called_once_with(mock_nfc.return_value)
|
||||
mock_res_used.assert_called_once_with(mock_nfc.return_value)
|
||||
mock_res_unavail.assert_called_once_with(mock_nfc.return_value)
|
||||
self.assertEqual(expected, result)
|
||||
|
||||
@mock.patch.object(ironic_driver.IronicDriver,
|
||||
'_node_resources_used', return_value=False)
|
||||
@mock.patch.object(ironic_driver.IronicDriver,
|
||||
'_node_resources_unavailable', return_value=False)
|
||||
@mock.patch.object(ironic_driver.IronicDriver, '_node_resource')
|
||||
@mock.patch.object(ironic_driver.IronicDriver, '_node_from_cache')
|
||||
def test_get_inventory_with_rc(self, mock_nfc, mock_nr, mock_res_unavail):
|
||||
def test_get_inventory_with_rc(self, mock_nfc, mock_nr, mock_res_unavail,
|
||||
mock_res_used):
|
||||
"""Ensure that when node.resource_class is present, that we return the
|
||||
legacy VCPU, MEMORY_MB and DISK_GB resources for inventory in addition
|
||||
to the custom resource class inventory record.
|
||||
|
@ -841,14 +848,18 @@ class IronicDriverTestCase(test.NoDBTestCase):
|
|||
}
|
||||
mock_nfc.assert_called_once_with(mock.sentinel.nodename)
|
||||
mock_nr.assert_called_once_with(mock_nfc.return_value)
|
||||
mock_res_used.assert_called_once_with(mock_nfc.return_value)
|
||||
mock_res_unavail.assert_called_once_with(mock_nfc.return_value)
|
||||
self.assertEqual(expected, result)
|
||||
|
||||
@mock.patch.object(ironic_driver.IronicDriver,
|
||||
'_node_resources_used', return_value=False)
|
||||
@mock.patch.object(ironic_driver.IronicDriver,
|
||||
'_node_resources_unavailable', return_value=False)
|
||||
@mock.patch.object(ironic_driver.IronicDriver, '_node_resource')
|
||||
@mock.patch.object(ironic_driver.IronicDriver, '_node_from_cache')
|
||||
def test_get_inventory_only_rc(self, mock_nfc, mock_nr, mock_res_unavail):
|
||||
def test_get_inventory_only_rc(self, mock_nfc, mock_nr, mock_res_unavail,
|
||||
mock_res_used):
|
||||
"""Ensure that when node.resource_class is present, that we return the
|
||||
legacy VCPU, MEMORY_MB and DISK_GB resources for inventory in addition
|
||||
to the custom resource class inventory record.
|
||||
|
@ -877,15 +888,18 @@ class IronicDriverTestCase(test.NoDBTestCase):
|
|||
}
|
||||
mock_nfc.assert_called_once_with(mock.sentinel.nodename)
|
||||
mock_nr.assert_called_once_with(mock_nfc.return_value)
|
||||
mock_res_used.assert_called_once_with(mock_nfc.return_value)
|
||||
mock_res_unavail.assert_called_once_with(mock_nfc.return_value)
|
||||
self.assertEqual(expected, result)
|
||||
|
||||
@mock.patch.object(ironic_driver.IronicDriver,
|
||||
'_node_resources_used', return_value=True)
|
||||
@mock.patch.object(ironic_driver.IronicDriver,
|
||||
'_node_resources_unavailable', return_value=False)
|
||||
@mock.patch.object(ironic_driver.IronicDriver, '_node_resource')
|
||||
@mock.patch.object(ironic_driver.IronicDriver, '_node_from_cache')
|
||||
def test_get_inventory_with_rc_occupied(self, mock_nfc, mock_nr,
|
||||
mock_res_unavail):
|
||||
mock_res_unavail, mock_res_used):
|
||||
"""Ensure that when a node is used, we report the inventory matching
|
||||
the consumed resources.
|
||||
"""
|
||||
|
@ -937,18 +951,23 @@ class IronicDriverTestCase(test.NoDBTestCase):
|
|||
}
|
||||
mock_nfc.assert_called_once_with(mock.sentinel.nodename)
|
||||
mock_nr.assert_called_once_with(mock_nfc.return_value)
|
||||
mock_res_unavail.assert_called_once_with(mock_nfc.return_value)
|
||||
mock_res_used.assert_called_once_with(mock_nfc.return_value)
|
||||
self.assertFalse(mock_res_unavail.called)
|
||||
self.assertEqual(expected, result)
|
||||
|
||||
@mock.patch.object(ironic_driver.IronicDriver,
|
||||
'_node_resources_used', return_value=False)
|
||||
@mock.patch.object(ironic_driver.IronicDriver,
|
||||
'_node_resources_unavailable', return_value=True)
|
||||
@mock.patch.object(ironic_driver.IronicDriver, '_node_from_cache')
|
||||
def test_get_inventory_disabled_node(self, mock_nfc, mock_res_unavail):
|
||||
def test_get_inventory_disabled_node(self, mock_nfc, mock_res_unavail,
|
||||
mock_res_used):
|
||||
"""Ensure that when a node is disabled, that get_inventory() returns
|
||||
an empty dict.
|
||||
"""
|
||||
result = self.driver.get_inventory(mock.sentinel.nodename)
|
||||
mock_nfc.assert_called_once_with(mock.sentinel.nodename)
|
||||
mock_res_used.assert_called_once_with(mock_nfc.return_value)
|
||||
mock_res_unavail.assert_called_once_with(mock_nfc.return_value)
|
||||
self.assertEqual({}, result)
|
||||
|
||||
|
|
|
@ -757,7 +757,8 @@ class IronicDriver(virt_driver.ComputeDriver):
|
|||
# and DISK_GB resource classes in early Queens when Ironic nodes will
|
||||
# *always* return the custom resource class that represents the
|
||||
# baremetal node class in an atomic, singular unit.
|
||||
if self._node_resources_unavailable(node):
|
||||
if (not self._node_resources_used(node) and
|
||||
self._node_resources_unavailable(node)):
|
||||
# TODO(dtantsur): report resources as reserved instead of reporting
|
||||
# an empty inventory
|
||||
LOG.debug('Node %(node)s is not ready for a deployment, '
|
||||
|
|
Loading…
Reference in New Issue