diff --git a/scciclient/irmc/ipmi.py b/scciclient/irmc/ipmi.py index f5cc686..f7ef852 100755 --- a/scciclient/irmc/ipmi.py +++ b/scciclient/irmc/ipmi.py @@ -18,8 +18,8 @@ import itertools from pyghmi import exceptions as ipmi_exception from pyghmi.ipmi import command as ipmi_command -# F1 1A - Get the number of GPU devices on PCI and the number of CPUs with FPGA -GET_GPU = '0x2E 0xF1 0x80 0x28 0x00 0x1A %s 0x00' +# F1 1A - Get the number of specific PCI devices on baremetal +GET_PCI = '0x2E 0xF1 0x80 0x28 0x00 0x1A %s 0x00' # F5 81 - GET TPM STATUS GET_TPM_STATUS = '0x2E 0xF5 0x80 0x28 0x00 0x81 0xC0' @@ -118,29 +118,27 @@ def _pci_seq(ipmicmd): """ for i in range(1, 0xff + 1): try: - res = _send_raw_command(ipmicmd, GET_GPU % hex(i)) + res = _send_raw_command(ipmicmd, GET_PCI % hex(i)) yield i, res except ipmi_exception.IpmiException as e: raise IPMIFailure( "IPMI operation '%(operation)s' failed: %(error)s" % - {'operation': "GET GPU device quantity", 'error': e}) + {'operation': "GET PCI device quantity", 'error': e}) -def get_gpu(d_info, pci_device_ids): - """Get quantity of GPU devices on PCI and quantity of CPUs with FPGA. +def get_pci_device(d_info, pci_device_ids): + """Get quantity of PCI devices. - Get quantity of GPU devices on PCI and quantity of CPUs with FPGA of the - node. + Get quantity of PCI devices of the node. :param d_info: the list of ipmitool parameters for accessing a node. :param pci_device_ids: the list contains pairs of / for - GPU on PCI. - :returns: a tuple of the number of GPU devices on PCI and the number of - CPUs with FPGA. + PCI devices. + :returns: the number of PCI devices. """ # note: - # Get quantity of GPU devices on PCI and quantity of CPUs with FPGA: + # Get quantity of PCI devices: # ipmi cmd '0xF1' # # $ ipmitool raw 0x2E 0xF1 0x80 0x28 0x00 0x1A 0x01 0x00 @@ -167,6 +165,6 @@ def get_gpu(d_info, pci_device_ids): out[7], out[6], out[9], out[8]) return accm + 1 if pci_id in pci_device_ids else accm - gpu_count = functools.reduce(_pci_count, response, 0) + device_count = functools.reduce(_pci_count, response, 0) - return gpu_count + return device_count diff --git a/scciclient/irmc/scci.py b/scciclient/irmc/scci.py index be4e92a..c5986e2 100755 --- a/scciclient/irmc/scci.py +++ b/scciclient/irmc/scci.py @@ -492,7 +492,8 @@ def get_essential_properties(report, prop_keys): def get_capabilities_properties(d_info, capa_keys, - pci_device_ids, + gpu_ids, + fpga_ids=None, **kwargs): """get capabilities properties @@ -502,8 +503,10 @@ def get_capabilities_properties(d_info, :param d_info: the dictionary of ipmitool parameters for accessing a node. :param capa_keys: a list of keys for additional capabilities properties. - :param pci_device_ids: the list of string contains / + :param gpu_ids: the list of string contains / for GPU. + :param fpga_ids: the list of string contains / + for CPU FPGA. :param kwargs: additional arguments passed to scciclient. :returns: a dictionary which contains keys and their values. """ @@ -529,11 +532,15 @@ def get_capabilities_properties(d_info, # Sometime the server started but PCI device list building is # still in progress so system will response error. We have to wait # for some more seconds. - if kwargs.get('sleep_flag', False) and 'pci_gpu_devices' in capa_keys: + if kwargs.get('sleep_flag', False) and \ + any(k in capa_keys for k in ('pci_gpu_devices', 'cpu_fpga')): time.sleep(5) if 'pci_gpu_devices' in capa_keys: - v['pci_gpu_devices'] = ipmi.get_gpu(d_info, pci_device_ids) + v['pci_gpu_devices'] = ipmi.get_pci_device(d_info, gpu_ids) + + if fpga_ids is not None and 'cpu_fpga' in capa_keys: + v['cpu_fpga'] = ipmi.get_pci_device(d_info, fpga_ids) if 'trusted_boot' in capa_keys: v['trusted_boot'] = ipmi.get_tpm_status(d_info) diff --git a/scciclient/tests/irmc/test_ipmi.py b/scciclient/tests/irmc/test_ipmi.py index 556d029..8685e6a 100644 --- a/scciclient/tests/irmc/test_ipmi.py +++ b/scciclient/tests/irmc/test_ipmi.py @@ -78,8 +78,8 @@ class IpmiTestCase(testtools.TestCase): exec_mock.assert_called_once_with(mock.ANY, cmd) @mock.patch.object(ipmi, '_send_raw_command') - def test_get_gpu(self, exec_mock): - gpu_ids = ['0x1000/0x0079', '0x2100/0x0080'] + def test_get_pci(self, exec_mock): + pci_device_ids = ['0x1000/0x0079', '0x2100/0x0080'] exec_mock.side_effect = ({'command': 0xF1, 'code': 0x00, 'netfn': 0x2F, 'data': [0x80, 0x28, 0x00, 0x00, 0x00, 0x05, @@ -91,22 +91,22 @@ class IpmiTestCase(testtools.TestCase): cmd1 = "0x2E 0xF1 0x80 0x28 0x00 0x1A 0x1 0x00" cmd2 = "0x2E 0xF1 0x80 0x28 0x00 0x1A 0x2 0x00" - actual_out = ipmi.get_gpu(self.info, gpu_ids) + actual_out = ipmi.get_pci_device(self.info, pci_device_ids) self.assertEqual(1, actual_out) exec_mock.assert_has_calls([mock.call(mock.ANY, cmd1), mock.call(mock.ANY, cmd2)]) @mock.patch.object(ipmi, '_send_raw_command') - def test_get_gpu_blank(self, exec_mock): - gpu_ids = [] + def test_get_pci_blank(self, exec_mock): + pci_device_ids = [] - actual_out = ipmi.get_gpu(self.info, gpu_ids) + actual_out = ipmi.get_pci_device(self.info, pci_device_ids) self.assertEqual(0, actual_out) self.assertTrue(exec_mock.called) @mock.patch.object(ipmi, '_send_raw_command') - def test_get_gpu_not_found(self, exec_mock): - gpu_ids = ['0x1111/0x1179', '0x2100/0x0080'] + def test_get_pci_not_found(self, exec_mock): + pci_device_ids = ['0x1111/0x1179', '0x2100/0x0080'] exec_mock.side_effect = ({'command': 0xF1, 'code': 0x00, 'netfn': 0x2F, 'data': [0x80, 0x28, 0x00, 0x00, 0x00, 0x05, @@ -117,23 +117,23 @@ class IpmiTestCase(testtools.TestCase): 'data': [0x80, 0x28, 0x00]}) cmd1 = "0x2E 0xF1 0x80 0x28 0x00 0x1A 0x1 0x00" cmd2 = "0x2E 0xF1 0x80 0x28 0x00 0x1A 0x2 0x00" - actual_out = ipmi.get_gpu(self.info, gpu_ids) + actual_out = ipmi.get_pci_device(self.info, pci_device_ids) self.assertEqual(0, actual_out) exec_mock.assert_has_calls([mock.call(mock.ANY, cmd1), mock.call(mock.ANY, cmd2)]) @mock.patch.object(ipmi, '_send_raw_command') - def test_get_gpu_exception(self, exec_mock): - gpu_ids = ['0x1111/0x1179', '0x2100/0x0080'] + def test_get_pci_exception(self, exec_mock): + pci_device_ids = ['0x1111/0x1179', '0x2100/0x0080'] exec_mock.side_effect = ipmi_exception.IpmiException('Error') cmd = "0x2E 0xF1 0x80 0x28 0x00 0x1A 0x1 0x00" e = self.assertRaises(ipmi.IPMIFailure, - ipmi.get_gpu, + ipmi.get_pci_device, self.info, - gpu_ids) + pci_device_ids) exec_mock.assert_called_once_with(mock.ANY, cmd) - self.assertEqual('IPMI operation \'GET GPU device quantity\' ' + self.assertEqual('IPMI operation \'GET PCI device quantity\' ' 'failed: Error', str(e)) diff --git a/scciclient/tests/irmc/test_scci.py b/scciclient/tests/irmc/test_scci.py index 024e1e7..8c6bc8a 100644 --- a/scciclient/tests/irmc/test_scci.py +++ b/scciclient/tests/irmc/test_scci.py @@ -704,7 +704,7 @@ class SCCITestCase(testtools.TestCase): self.assertEqual(expected, result) - @mock.patch.object(ipmi, 'get_gpu') + @mock.patch.object(ipmi, 'get_pci_device') @mock.patch.object(snmp, 'get_server_model') @mock.patch.object(snmp, 'get_irmc_firmware_version') @mock.patch.object(snmp, 'get_bios_firmware_version') @@ -714,7 +714,7 @@ class SCCITestCase(testtools.TestCase): bios_mock, irmc_mock, server_mock, - gpu_mock): + pci_device_mock): capabilities_properties = {'trusted_boot', 'irmc_firmware_version', 'rom_firmware_version', 'server_model', 'pci_gpu_devices'} @@ -726,7 +726,7 @@ class SCCITestCase(testtools.TestCase): bios_mock.return_value = 'V4.6.5.4 R1.15.0 for D3099-B1x' irmc_mock.return_value = 'iRMC S4-7.82F' server_mock.return_value = 'TX2540M1F5' - gpu_mock.return_value = 1 + pci_device_mock.side_effect = [1] expected = {'irmc_firmware_version': 'iRMC S4-7.82F', 'pci_gpu_devices': 1, @@ -745,10 +745,57 @@ class SCCITestCase(testtools.TestCase): bios_mock.assert_called_once_with(mock.ANY) irmc_mock.assert_called_once_with(mock.ANY) server_mock.assert_called_once_with(mock.ANY) - gpu_mock.assert_called_once_with(self.irmc_info, - gpu_ids) + pci_device_mock.assert_called_once_with(self.irmc_info, gpu_ids) - @mock.patch.object(ipmi, 'get_gpu') + @mock.patch.object(ipmi, 'get_pci_device') + @mock.patch.object(snmp, 'get_server_model') + @mock.patch.object(snmp, 'get_irmc_firmware_version') + @mock.patch.object(snmp, 'get_bios_firmware_version') + @mock.patch.object(ipmi, 'get_tpm_status') + def test_get_capabilities_properties_with_cpu_fpga(self, + tpm_mock, + bios_mock, + irmc_mock, + server_mock, + pci_device_mock): + capabilities_properties = {'trusted_boot', 'irmc_firmware_version', + 'rom_firmware_version', 'server_model', + 'pci_gpu_devices', 'cpu_fpga'} + gpu_ids = ['0x1000/0x0079', '0x2100/0x0080'] + cpu_fpgas = ['0x1000/0x0179', '0x2100/0x0180'] + kwargs = {} + kwargs['sleep_flag'] = True + + tpm_mock.return_value = False + bios_mock.return_value = 'V4.6.5.4 R1.15.0 for D3099-B1x' + irmc_mock.return_value = 'iRMC S4-7.82F' + server_mock.return_value = 'TX2540M1F5' + pci_device_mock.side_effect = [1, 1] + + expected = {'irmc_firmware_version': 'iRMC S4-7.82F', + 'pci_gpu_devices': 1, + 'cpu_fpga': 1, + 'rom_firmware_version': 'V4.6.5.4 R1.15.0 for D3099-B1x', + 'server_model': 'TX2540M1F5', + 'trusted_boot': False} + + result = scci.get_capabilities_properties( + self.irmc_info, + capabilities_properties, + gpu_ids, + cpu_fpgas, + **kwargs) + + self.assertEqual(expected, result) + tpm_mock.assert_called_once_with(self.irmc_info) + bios_mock.assert_called_once_with(mock.ANY) + irmc_mock.assert_called_once_with(mock.ANY) + server_mock.assert_called_once_with(mock.ANY) + pci_device_mock.assert_has_calls([ + mock.call(self.irmc_info, gpu_ids), + mock.call(self.irmc_info, cpu_fpgas)]) + + @mock.patch.object(ipmi, 'get_pci_device') @mock.patch.object(snmp, 'get_server_model') @mock.patch.object(snmp, 'get_irmc_firmware_version') @mock.patch.object(snmp, 'get_bios_firmware_version') @@ -758,10 +805,11 @@ class SCCITestCase(testtools.TestCase): bios_mock, irmc_mock, server_mock, - gpu_mock): + pci_device_mock): capabilities_properties = {} gpu_ids = ['0x1000/0x0079', '0x2100/0x0080'] + cpu_fpgas = ['0x1000/0x0179', '0x2100/0x0180'] kwargs = {} kwargs['sleep_flag'] = True @@ -769,7 +817,7 @@ class SCCITestCase(testtools.TestCase): bios_mock.return_value = 'V4.6.5.4 R1.15.0 for D3099-B1x' irmc_mock.return_value = 'iRMC S4-7.82F' server_mock.return_value = 'TX2540M1F5' - gpu_mock.return_value = 1 + pci_device_mock.side_effect = [1, 1] expected = {} @@ -777,6 +825,7 @@ class SCCITestCase(testtools.TestCase): self.irmc_info, capabilities_properties, gpu_ids, + cpu_fpgas, **kwargs) self.assertEqual(expected, result) @@ -788,8 +837,9 @@ class SCCITestCase(testtools.TestCase): ipmiraw_mock): capabilities_properties = {'trusted_boot', 'irmc_firmware_version', 'rom_firmware_version', 'server_model', - 'pci_gpu_devices'} + 'pci_gpu_devices', 'cpu_fpga'} gpu_ids = ['0x1000/0x0079', '0x2100/0x0080'] + cpu_fpgas = ['0x1000/0x0179', '0x2100/0x0180'] kwargs = {} kwargs['sleep_flag'] = True @@ -801,19 +851,21 @@ class SCCITestCase(testtools.TestCase): self.irmc_info, capabilities_properties, gpu_ids, + cpu_fpgas, **kwargs) self.assertEqual('Capabilities inspection failed: SNMP operation \'' 'GET BIOS FIRMWARE VERSION\' failed: error', str(e)) - @mock.patch.object(ipmi, 'get_gpu') + @mock.patch.object(ipmi, 'get_pci_device') @mock.patch.object(snmp.SNMPClient, 'get') def test_get_capabilities_properties_scci_client_error_ipmi(self, snmp_mock, ipmi_mock): capabilities_properties = {'trusted_boot', 'irmc_firmware_version', 'rom_firmware_version', 'server_model', - 'pci_gpu_devices'} + 'pci_gpu_devices', 'cpu_fpga'} gpu_ids = ['0x1000/0x0079', '0x2100/0x0080'] + cpu_fpgas = ['0x1000/0x0179', '0x2100/0x0180'] kwargs = {} kwargs['sleep_flag'] = True @@ -825,6 +877,7 @@ class SCCITestCase(testtools.TestCase): self.irmc_info, capabilities_properties, gpu_ids, + cpu_fpgas, **kwargs) self.assertEqual('Capabilities inspection failed: IPMI error', str(e))