From 5ee7b313480c34c2461af0b0d4dd0191191c4eb3 Mon Sep 17 00:00:00 2001 From: Nguyen Hung Phuong Date: Fri, 18 May 2018 17:02:35 +0700 Subject: [PATCH] Add CUSTOM_CPU_FPGA Traits value to ironic inspection iRMC driver inspects hardware to get qualitative resources. During node inspection, the iRMC driver will automatically update the node.traits field with CUSTOM_CPU_FPGA value based on information provided by the node. Co-Authored-By: Tran Ha Tuyen Change-Id: I685c87561e74e0c7153e8fb948b819a783fad41f Story: #2001999 Task: #19633 --- ironic/conf/irmc.py | 9 + ironic/drivers/modules/irmc/inspect.py | 48 +++- .../unit/drivers/modules/irmc/test_inspect.py | 205 +++++++++++++++--- ..._for_irmc_inspection-2b63941b064f7936.yaml | 6 + 4 files changed, 224 insertions(+), 44 deletions(-) create mode 100644 releasenotes/notes/add_cpu_fpga_trait_for_irmc_inspection-2b63941b064f7936.yaml diff --git a/ironic/conf/irmc.py b/ironic/conf/irmc.py index 8a4e000159..5351d48c8a 100644 --- a/ironic/conf/irmc.py +++ b/ironic/conf/irmc.py @@ -89,6 +89,15 @@ opts = [ 'this option is not defined, then leave out ' 'pci_gpu_devices in capabilities property. ' 'Sample gpu_ids value: 0x1000/0x0079,0x2100/0x0080')), + cfg.ListOpt('fpga_ids', + default=[], + help=_('List of vendor IDs and device IDs for CPU FPGA to ' + 'inspect. List items are in format vendorID/deviceID ' + 'and separated by commas. CPU inspection will use this ' + 'value to find existence of CPU FPGA in a node. If ' + 'this option is not defined, then leave out ' + 'CUSTOM_CPU_FPGA in node traits. ' + 'Sample fpga_ids value: 0x1000/0x0079,0x2100/0x0080')), cfg.IntOpt('query_raid_config_fgi_status_interval', min=1, default=300, diff --git a/ironic/drivers/modules/irmc/inspect.py b/ironic/drivers/modules/irmc/inspect.py index 012fac5e8c..5d438a6c81 100644 --- a/ironic/drivers/modules/irmc/inspect.py +++ b/ironic/drivers/modules/irmc/inspect.py @@ -92,7 +92,7 @@ sc2UnitNodeMacAddress OBJECT-TYPE MAC_ADDRESS_OID = '1.3.6.1.4.1.231.2.10.2.2.10.3.1.1.9.1' CAPABILITIES_PROPERTIES = {'trusted_boot', 'irmc_firmware_version', 'rom_firmware_version', 'server_model', - 'pci_gpu_devices'} + 'pci_gpu_devices', 'cpu_fpga'} def _get_mac_addresses(node): @@ -117,10 +117,11 @@ def _get_mac_addresses(node): if c == NODE_CLASS_OID_VALUE['primary']] -def _inspect_hardware(node, **kwargs): +def _inspect_hardware(node, existing_traits=None, **kwargs): """Inspect the node and get hardware information. :param node: node object. + :param existing_traits: existing traits list. :param kwargs: the dictionary of additional parameters. :raises: HardwareInspectionFailure, if unable to get essential hardware properties. @@ -129,6 +130,7 @@ def _inspect_hardware(node, **kwargs): values, the list contains mac addresses. """ capabilities_props = set(CAPABILITIES_PROPERTIES) + new_traits = list(existing_traits) if existing_traits else [] # Remove all capabilities item which will be inspected in the existing # capabilities of node @@ -140,13 +142,18 @@ def _inspect_hardware(node, **kwargs): existing_cap.remove(prop) node.properties['capabilities'] = ",".join(existing_cap) - # get gpu_ids in ironic configuration - values = [gpu_id.lower() for gpu_id in CONF.irmc.gpu_ids] + # get gpu_ids, fpga_ids in ironic configuration + gpu_ids = [gpu_id.lower() for gpu_id in CONF.irmc.gpu_ids] + fpga_ids = [fpga_id.lower() for fpga_id in CONF.irmc.fpga_ids] # if gpu_ids = [], pci_gpu_devices will not be inspected - if len(values) == 0: + if len(gpu_ids) == 0: capabilities_props.remove('pci_gpu_devices') + # if fpga_ids = [], cpu_fpga will not be inspected + if len(fpga_ids) == 0: + capabilities_props.remove('cpu_fpga') + try: report = irmc_common.get_irmc_report(node) props = scci.get_essential_properties( @@ -155,17 +162,26 @@ def _inspect_hardware(node, **kwargs): capabilities = scci.get_capabilities_properties( d_info, capabilities_props, - values, + gpu_ids, + fpga_ids=fpga_ids, **kwargs) if capabilities: if capabilities.get('pci_gpu_devices') == 0: capabilities.pop('pci_gpu_devices') + + cpu_fpga = capabilities.pop('cpu_fpga', 0) + if cpu_fpga == 0 and 'CUSTOM_CPU_FPGA' in new_traits: + new_traits.remove('CUSTOM_CPU_FPGA') + elif cpu_fpga != 0 and 'CUSTOM_CPU_FPGA' not in new_traits: + new_traits.append('CUSTOM_CPU_FPGA') + if capabilities.get('trusted_boot') is False: capabilities.pop('trusted_boot') capabilities = utils.get_updated_capabilities( node.properties.get('capabilities'), capabilities) if capabilities: props['capabilities'] = capabilities + macs = _get_mac_addresses(node) except (scci.SCCIInvalidInputError, scci.SCCIClientError, @@ -175,7 +191,7 @@ def _inspect_hardware(node, **kwargs): {'node_id': node.uuid, 'error': e}) raise exception.HardwareInspectionFailure(error=error) - return (props, macs) + return props, macs, new_traits class IRMCInspect(base.InspectInterface): @@ -184,14 +200,19 @@ class IRMCInspect(base.InspectInterface): def __init__(self): """Validate the driver-specific inspection information. - This action will validate gpu_ids value along with starting - ironic-conductor service. + This action will validate gpu_ids and fpga_ids value along with + starting ironic-conductor service. """ for gpu_id in CONF.irmc.gpu_ids: if not re.match('^0x[0-9a-f]{4}/0x[0-9a-f]{4}$', gpu_id.lower()): raise exception.InvalidParameterValue(_( "Invalid [irmc]/gpu_ids configuration option.")) + for fpga_id in CONF.irmc.fpga_ids: + if not re.match('^0x[0-9a-f]{4}/0x[0-9a-f]{4}$', fpga_id.lower()): + raise exception.InvalidParameterValue(_( + "Invalid [irmc]/fpga_ids configuration option.")) + super(IRMCInspect, self).__init__() def get_properties(self): @@ -239,9 +260,14 @@ class IRMCInspect(base.InspectInterface): {'node_uuid': task.node.uuid}) kwargs['sleep_flag'] = True - - (props, macs) = _inspect_hardware(node, **kwargs) + traits_obj = objects.TraitList.get_by_node_id(task.context, node.id) + existing_traits = traits_obj.get_trait_names() + props, macs, new_traits = _inspect_hardware(node, + existing_traits, + **kwargs) node.properties = dict(node.properties, **props) + if existing_traits != new_traits: + objects.TraitList.create(task.context, node.id, new_traits) node.save() for mac in macs: diff --git a/ironic/tests/unit/drivers/modules/irmc/test_inspect.py b/ironic/tests/unit/drivers/modules/irmc/test_inspect.py index 8b4499217d..30a1818dc9 100644 --- a/ironic/tests/unit/drivers/modules/irmc/test_inspect.py +++ b/ironic/tests/unit/drivers/modules/irmc/test_inspect.py @@ -59,8 +59,9 @@ class IRMCInspectInternalMethodsTestCase(test_common.BaseIRMCTest): self, get_irmc_report_mock, scci_mock, _get_mac_addresses_mock): # Set config flags gpu_ids = ['0x1000/0x0079', '0x2100/0x0080'] - + cpu_fpgas = ['0x1000/0x0179', '0x2100/0x0180'] self.config(gpu_ids=gpu_ids, group='irmc') + self.config(fpga_ids=cpu_fpgas, group='irmc') kwargs = {'sleep_flag': False} inspected_props = { @@ -73,7 +74,10 @@ class IRMCInspectInternalMethodsTestCase(test_common.BaseIRMCTest): 'irmc_firmware_version': 'iRMC S4-7.82F', 'server_model': 'TX2540M1F5', 'rom_firmware_version': 'V4.6.5.4 R1.15.0 for D3099-B1x', - 'pci_gpu_devices': 1} + 'pci_gpu_devices': 1, + 'cpu_fpga': 1} + new_traits = ['CUSTOM_CPU_FPGA'] + existing_traits = [] inspected_macs = ['aa:aa:aa:aa:aa:aa', 'bb:bb:bb:bb:bb:bb'] report = 'fake_report' @@ -84,18 +88,22 @@ class IRMCInspectInternalMethodsTestCase(test_common.BaseIRMCTest): _get_mac_addresses_mock.return_value = inspected_macs with task_manager.acquire(self.context, self.node.uuid, shared=True) as task: - result = irmc_inspect._inspect_hardware(task.node, **kwargs) + result = irmc_inspect._inspect_hardware(task.node, + existing_traits, + **kwargs) get_irmc_report_mock.assert_called_once_with(task.node) scci_mock.get_essential_properties.assert_called_once_with( report, irmc_inspect.IRMCInspect.ESSENTIAL_PROPERTIES) scci_mock.get_capabilities_properties.assert_called_once_with( mock.ANY, irmc_inspect.CAPABILITIES_PROPERTIES, - gpu_ids, **kwargs) + gpu_ids, fpga_ids=cpu_fpgas, **kwargs) + expected_props = dict(inspected_props) inspected_capabilities = utils.get_updated_capabilities( '', inspected_capabilities) expected_props['capabilities'] = inspected_capabilities - self.assertEqual((expected_props, inspected_macs), result) + self.assertEqual((expected_props, inspected_macs, new_traits), + result) @mock.patch.object(irmc_inspect, '_get_mac_addresses', spec_set=True, autospec=True) @@ -151,12 +159,18 @@ class IRMCInspectTestCase(test_common.BaseIRMCTest): task.driver.inspect.validate, task) - def test__init_fail_invalid_input(self): + def test__init_fail_invalid_gpu_ids_input(self): # Set config flags self.config(gpu_ids='100/x079,0x20/', group='irmc') self.assertRaises(exception.InvalidParameterValue, irmc_inspect.IRMCInspect) + def test__init_fail_invalid_fpga_ids_input(self): + # Set config flags + self.config(fpga_ids='100/x079,0x20/', group='irmc') + self.assertRaises(exception.InvalidParameterValue, + irmc_inspect.IRMCInspect) + @mock.patch.object(irmc_inspect.LOG, 'info', spec_set=True, autospec=True) @mock.patch('ironic.drivers.modules.irmc.inspect.objects.Port', spec_set=True, autospec=True) @@ -172,9 +186,12 @@ class IRMCInspectTestCase(test_common.BaseIRMCTest): 'cpus': 2, 'cpu_arch': 'x86_64'} inspected_macs = ['aa:aa:aa:aa:aa:aa', 'bb:bb:bb:bb:bb:bb'] + new_traits = ['CUSTOM_CPU_FPGA'] + existing_traits = [] power_state_mock.return_value = states.POWER_ON _inspect_hardware_mock.return_value = (inspected_props, - inspected_macs) + inspected_macs, + new_traits) new_port_mock1 = mock.MagicMock(spec=objects.Port) new_port_mock2 = mock.MagicMock(spec=objects.Port) @@ -185,7 +202,8 @@ class IRMCInspectTestCase(test_common.BaseIRMCTest): result = task.driver.inspect.inspect_hardware(task) node_id = task.node.id - _inspect_hardware_mock.assert_called_once_with(task.node) + _inspect_hardware_mock.assert_called_once_with(task.node, + existing_traits) # note (naohirot): # as of mock 1.2, assert_has_calls has a bug which returns @@ -240,9 +258,12 @@ class IRMCInspectTestCase(test_common.BaseIRMCTest): 'cpus': 2, 'cpu_arch': 'x86_64'} inspected_macs = ['aa:aa:aa:aa:aa:aa', 'bb:bb:bb:bb:bb:bb'] + new_traits = ['CUSTOM_CPU_FPGA'] + existing_traits = [] power_state_mock.return_value = states.POWER_OFF _inspect_hardware_mock.return_value = (inspected_props, - inspected_macs) + inspected_macs, + new_traits) new_port_mock1 = mock.MagicMock(spec=objects.Port) new_port_mock2 = mock.MagicMock(spec=objects.Port) @@ -254,6 +275,7 @@ class IRMCInspectTestCase(test_common.BaseIRMCTest): node_id = task.node.id _inspect_hardware_mock.assert_called_once_with(task.node, + existing_traits, sleep_flag=True) port_mock.assert_has_calls([ @@ -290,6 +312,10 @@ class IRMCInspectTestCase(test_common.BaseIRMCTest): task) self.assertFalse(port_mock.called) + @mock.patch.object(objects.trait.TraitList, + 'get_trait_names', + spec_set=True, + autospec=True) @mock.patch.object(irmc_inspect.LOG, 'warn', spec_set=True, autospec=True) @mock.patch('ironic.objects.Port', spec_set=True, autospec=True) @mock.patch.object(irmc_inspect, '_inspect_hardware', spec_set=True, @@ -298,30 +324,37 @@ class IRMCInspectTestCase(test_common.BaseIRMCTest): autospec=True) def test_inspect_hardware_mac_already_exist( self, power_state_mock, _inspect_hardware_mock, - port_mock, warn_mock): + port_mock, warn_mock, trait_mock): inspected_props = { 'memory_mb': '1024', 'local_gb': 10, 'cpus': 2, 'cpu_arch': 'x86_64'} inspected_macs = ['aa:aa:aa:aa:aa:aa', 'bb:bb:bb:bb:bb:bb'] + existing_traits = ['CUSTOM_CPU_FPGA'] + new_traits = list(existing_traits) _inspect_hardware_mock.return_value = (inspected_props, - inspected_macs) + inspected_macs, + new_traits) power_state_mock.return_value = states.POWER_ON side_effect = exception.MACAlreadyExists("fake exception") new_port_mock = port_mock.return_value new_port_mock.create.side_effect = side_effect + trait_mock.return_value = existing_traits with task_manager.acquire(self.context, self.node.uuid, shared=False) as task: result = task.driver.inspect.inspect_hardware(task) - _inspect_hardware_mock.assert_called_once_with(task.node) + _inspect_hardware_mock.assert_called_once_with(task.node, + existing_traits) self.assertTrue(port_mock.call_count, 2) task.node.refresh() self.assertEqual(inspected_props, task.node.properties) self.assertEqual(states.MANAGEABLE, result) + @mock.patch.object(objects.trait.TraitList, 'get_trait_names', + spec_set=True, autospec=True) @mock.patch.object(irmc_inspect, '_get_mac_addresses', spec_set=True, autospec=True) @mock.patch.object(irmc_inspect, 'scci', @@ -329,19 +362,28 @@ class IRMCInspectTestCase(test_common.BaseIRMCTest): @mock.patch.object(irmc_common, 'get_irmc_report', spec_set=True, autospec=True) def _test_inspect_hardware_props(self, gpu_ids, + fpga_ids, existed_capabilities, inspected_capabilities, expected_capabilities, + existed_traits, + expected_traits, get_irmc_report_mock, scci_mock, - _get_mac_addresses_mock): + _get_mac_addresses_mock, + trait_mock): capabilities_props = set(irmc_inspect.CAPABILITIES_PROPERTIES) # if gpu_ids = [], pci_gpu_devices will not be inspected if len(gpu_ids) == 0: capabilities_props.remove('pci_gpu_devices') + # if fpga_ids = [], cpu_fpga will not be inspected + if fpga_ids is None or len(fpga_ids) == 0: + capabilities_props.remove('cpu_fpga') + self.config(gpu_ids=gpu_ids, group='irmc') + self.config(fpga_ids=fpga_ids, group='irmc') kwargs = {'sleep_flag': False} inspected_props = { @@ -352,60 +394,77 @@ class IRMCInspectTestCase(test_common.BaseIRMCTest): inspected_macs = ['aa:aa:aa:aa:aa:aa', 'bb:bb:bb:bb:bb:bb'] report = 'fake_report' + get_irmc_report_mock.return_value = report scci_mock.get_essential_properties.return_value = inspected_props scci_mock.get_capabilities_properties.return_value = \ inspected_capabilities _get_mac_addresses_mock.return_value = inspected_macs + trait_mock.return_value = existed_traits + with task_manager.acquire(self.context, self.node.uuid, shared=True) as task: task.node.properties[u'capabilities'] =\ ",".join('%(k)s:%(v)s' % {'k': k, 'v': v} for k, v in existed_capabilities.items()) - result = irmc_inspect._inspect_hardware(task.node, **kwargs) + result = irmc_inspect._inspect_hardware(task.node, + existed_traits, + **kwargs) get_irmc_report_mock.assert_called_once_with(task.node) scci_mock.get_essential_properties.assert_called_once_with( report, irmc_inspect.IRMCInspect.ESSENTIAL_PROPERTIES) scci_mock.get_capabilities_properties.assert_called_once_with( mock.ANY, capabilities_props, - gpu_ids, **kwargs) + gpu_ids, fpga_ids=fpga_ids, **kwargs) expected_capabilities = utils.get_updated_capabilities( '', expected_capabilities) set1 = set(expected_capabilities.split(',')) set2 = set(result[0]['capabilities'].split(',')) self.assertEqual(set1, set2) + self.assertEqual(expected_traits, result[2]) def test_inspect_hardware_existing_cap_in_props(self): # Set config flags gpu_ids = ['0x1000/0x0079', '0x2100/0x0080'] + cpu_fpgas = ['0x1000/0x0179', '0x2100/0x0180'] existed_capabilities = { 'trusted_boot': True, 'irmc_firmware_version': 'iRMC S4-7.82F', 'server_model': 'TX2540M1F5', 'rom_firmware_version': 'V4.6.5.4 R1.15.0 for D3099-B1x', - 'pci_gpu_devices': 1} + 'pci_gpu_devices': 1 + } inspected_capabilities = { 'trusted_boot': True, 'irmc_firmware_version': 'iRMC S4-7.82F', 'server_model': 'TX2540M1F5', 'rom_firmware_version': 'V4.6.5.4 R1.15.0 for D3099-B1x', - 'pci_gpu_devices': 1} + 'pci_gpu_devices': 1, + 'cpu_fpga': 1 + } expected_capabilities = { 'trusted_boot': True, 'irmc_firmware_version': 'iRMC S4-7.82F', 'server_model': 'TX2540M1F5', 'rom_firmware_version': 'V4.6.5.4 R1.15.0 for D3099-B1x', - 'pci_gpu_devices': 1} + 'pci_gpu_devices': 1 + } + existed_traits = [] + expected_traits = ['CUSTOM_CPU_FPGA'] self._test_inspect_hardware_props(gpu_ids, + cpu_fpgas, existed_capabilities, inspected_capabilities, - expected_capabilities) + expected_capabilities, + existed_traits, + expected_traits) - def test_inspect_hardware_props_empty_gpu_ids(self): + def test_inspect_hardware_props_empty_gpu_ids_fpga_ids(self): # Set config flags gpu_ids = [] + cpu_fpgas = [] existed_capabilities = {} inspected_capabilities = { 'trusted_boot': True, @@ -417,37 +476,52 @@ class IRMCInspectTestCase(test_common.BaseIRMCTest): 'irmc_firmware_version': 'iRMC S4-7.82F', 'server_model': 'TX2540M1F5', 'rom_firmware_version': 'V4.6.5.4 R1.15.0 for D3099-B1x'} + existed_traits = [] + expected_traits = [] self._test_inspect_hardware_props(gpu_ids, + cpu_fpgas, existed_capabilities, inspected_capabilities, - expected_capabilities) + expected_capabilities, + existed_traits, + expected_traits) def test_inspect_hardware_props_pci_gpu_devices_return_zero(self): # Set config flags gpu_ids = ['0x1000/0x0079', '0x2100/0x0080'] - + cpu_fpgas = ['0x1000/0x0179', '0x2100/0x0180'] existed_capabilities = {} inspected_capabilities = { 'trusted_boot': True, 'irmc_firmware_version': 'iRMC S4-7.82F', 'server_model': 'TX2540M1F5', 'rom_firmware_version': 'V4.6.5.4 R1.15.0 for D3099-B1x', - 'pci_gpu_devices': 0} + 'pci_gpu_devices': 0, + 'cpu_fpga': 0 + } expected_capabilities = { 'trusted_boot': True, 'irmc_firmware_version': 'iRMC S4-7.82F', 'server_model': 'TX2540M1F5', 'rom_firmware_version': 'V4.6.5.4 R1.15.0 for D3099-B1x'} + existed_traits = [] + expected_traits = [] + self._test_inspect_hardware_props(gpu_ids, + cpu_fpgas, existed_capabilities, inspected_capabilities, - expected_capabilities) + expected_capabilities, + existed_traits, + expected_traits) - def test_inspect_hardware_props_empty_gpu_ids_and_existing_cap(self): + def test_inspect_hardware_props_empty_gpu_ids_fpga_id_sand_existing_cap( + self): # Set config flags gpu_ids = [] + cpu_fpgas = [] existed_capabilities = { 'trusted_boot': True, 'irmc_firmware_version': 'iRMC S4-7.82F', @@ -465,15 +539,22 @@ class IRMCInspectTestCase(test_common.BaseIRMCTest): 'server_model': 'TX2540M1F5', 'rom_firmware_version': 'V4.6.5.4 R1.15.0 for D3099-B1x'} + existed_traits = [] + expected_traits = [] + self._test_inspect_hardware_props(gpu_ids, + cpu_fpgas, existed_capabilities, inspected_capabilities, - expected_capabilities) + expected_capabilities, + existed_traits, + expected_traits) - def test_inspect_hardware_props_pci_gpu_devices_zero_and_existing_cap( + def test_inspect_hardware_props_gpu_cpu_fpgas_zero_and_existing_cap( self): # Set config flags gpu_ids = ['0x1000/0x0079', '0x2100/0x0080'] + cpu_fpgas = ['0x1000/0x0179', '0x2100/0x0180'] existed_capabilities = { 'trusted_boot': True, 'irmc_firmware_version': 'iRMC S4-7.82F', @@ -485,43 +566,59 @@ class IRMCInspectTestCase(test_common.BaseIRMCTest): 'irmc_firmware_version': 'iRMC S4-7.82F', 'server_model': 'TX2540M1F5', 'rom_firmware_version': 'V4.6.5.4 R1.15.0 for D3099-B1x', - 'pci_gpu_devices': 0} + 'pci_gpu_devices': 0, + 'cpu_fpga': 0} expected_capabilities = { 'trusted_boot': True, 'irmc_firmware_version': 'iRMC S4-7.82F', 'server_model': 'TX2540M1F5', 'rom_firmware_version': 'V4.6.5.4 R1.15.0 for D3099-B1x'} + existed_traits = ['CUSTOM_CPU_FPGA'] + expected_traits = [] + self._test_inspect_hardware_props(gpu_ids, + cpu_fpgas, existed_capabilities, inspected_capabilities, - expected_capabilities) + expected_capabilities, + existed_traits, + expected_traits) def test_inspect_hardware_props_trusted_boot_is_false(self): # Set config flags gpu_ids = ['0x1000/0x0079', '0x2100/0x0080'] + cpu_fpgas = ['0x1000/0x0179', '0x2100/0x0180'] existed_capabilities = {} inspected_capabilities = { 'trusted_boot': False, 'irmc_firmware_version': 'iRMC S4-7.82F', 'server_model': 'TX2540M1F5', 'rom_firmware_version': 'V4.6.5.4 R1.15.0 for D3099-B1x', - 'pci_gpu_devices': 1} + 'pci_gpu_devices': 1, + 'cpu_fpga': 1} expected_capabilities = { 'irmc_firmware_version': 'iRMC S4-7.82F', 'server_model': 'TX2540M1F5', 'rom_firmware_version': 'V4.6.5.4 R1.15.0 for D3099-B1x', 'pci_gpu_devices': 1} + existed_traits = [] + expected_traits = ['CUSTOM_CPU_FPGA'] + self._test_inspect_hardware_props(gpu_ids, + cpu_fpgas, existed_capabilities, inspected_capabilities, - expected_capabilities) + expected_capabilities, + existed_traits, + expected_traits) def test_inspect_hardware_props_trusted_boot_is_false_and_existing_cap( self): # Set config flags gpu_ids = ['0x1000/0x0079', '0x2100/0x0080'] + cpu_fpgas = ['0x1000/0x0179', '0x2100/0x0180'] existed_capabilities = { 'trusted_boot': True, 'irmc_firmware_version': 'iRMC S4-7.82F', @@ -533,13 +630,55 @@ class IRMCInspectTestCase(test_common.BaseIRMCTest): 'irmc_firmware_version': 'iRMC S4-7.82F', 'server_model': 'TX2540M1F5', 'rom_firmware_version': 'V4.6.5.4 R1.15.0 for D3099-B1x', - 'pci_gpu_devices': 1} + 'pci_gpu_devices': 1, + 'cpu_fpga': 1} expected_capabilities = { 'irmc_firmware_version': 'iRMC S4-7.82F', 'server_model': 'TX2540M1F5', 'rom_firmware_version': 'V4.6.5.4 R1.15.0 for D3099-B1x', 'pci_gpu_devices': 1} + + existed_traits = ['CUSTOM_CPU_FPGA'] + expected_traits = ['CUSTOM_CPU_FPGA'] + self._test_inspect_hardware_props(gpu_ids, + cpu_fpgas, existed_capabilities, inspected_capabilities, - expected_capabilities) + expected_capabilities, + existed_traits, + expected_traits) + + def test_inspect_hardware_props_gpu_and_cpu_fpgas_results_are_different( + self): + # Set config flags + gpu_ids = ['0x1000/0x0079', '0x2100/0x0080'] + cpu_fpgas = ['0x1000/0x0179', '0x2100/0x0180'] + existed_capabilities = { + 'trusted_boot': True, + 'irmc_firmware_version': 'iRMC S4-7.82F', + 'server_model': 'TX2540M1F5', + 'rom_firmware_version': 'V4.6.5.4 R1.15.0 for D3099-B1x', + 'pci_gpu_devices': 1} + inspected_capabilities = { + 'trusted_boot': False, + 'irmc_firmware_version': 'iRMC S4-7.82F', + 'server_model': 'TX2540M1F5', + 'rom_firmware_version': 'V4.6.5.4 R1.15.0 for D3099-B1x', + 'pci_gpu_devices': 0, + 'cpu_fpga': 1} + expected_capabilities = { + 'irmc_firmware_version': 'iRMC S4-7.82F', + 'server_model': 'TX2540M1F5', + 'rom_firmware_version': 'V4.6.5.4 R1.15.0 for D3099-B1x'} + + existed_traits = [] + expected_traits = ['CUSTOM_CPU_FPGA'] + + self._test_inspect_hardware_props(gpu_ids, + cpu_fpgas, + existed_capabilities, + inspected_capabilities, + expected_capabilities, + existed_traits, + expected_traits) diff --git a/releasenotes/notes/add_cpu_fpga_trait_for_irmc_inspection-2b63941b064f7936.yaml b/releasenotes/notes/add_cpu_fpga_trait_for_irmc_inspection-2b63941b064f7936.yaml new file mode 100644 index 0000000000..a686bcb98c --- /dev/null +++ b/releasenotes/notes/add_cpu_fpga_trait_for_irmc_inspection-2b63941b064f7936.yaml @@ -0,0 +1,6 @@ +--- +features: + - | + The iRMC driver can now automatically update the + node.traits field with CUSTOM_CPU_FPGA value based on + information provided by the node during node inspection.