From 521240195e107b87a526d7000674121f785dc4da Mon Sep 17 00:00:00 2001 From: Christopher Dearborn Date: Fri, 9 Feb 2018 11:24:15 -0500 Subject: [PATCH] Added support for PCIe drives This patch adds support for PCIe drives. Change-Id: Ib0a2f0f71d98c9945c1333db2f06584088e4e385 --- dracclient/resources/raid.py | 80 +++++++++++++------ dracclient/resources/uris.py | 3 + dracclient/tests/test_raid.py | 35 +++++++- .../physical_disk_view-enum-ok.xml | 31 ++++++- 4 files changed, 122 insertions(+), 27 deletions(-) diff --git a/dracclient/resources/raid.py b/dracclient/resources/raid.py index 0469eab..56dab55 100644 --- a/dracclient/resources/raid.py +++ b/dracclient/resources/raid.py @@ -66,14 +66,17 @@ PHYSICAL_DISK_BUS_PROTOCOL = { '3': 'fibre', '4': 'usb', '5': 'sata', - '6': 'sas' + '6': 'sas', + '7': 'pcie', + '8': 'nvme' } PhysicalDiskTuple = collections.namedtuple( 'PhysicalDisk', ['id', 'description', 'controller', 'manufacturer', 'model', 'media_type', 'interface_type', 'size_mb', 'free_size_mb', 'serial_number', - 'firmware_version', 'status', 'raid_status', 'sas_address']) + 'firmware_version', 'status', 'raid_status', 'sas_address', + 'device_protocol']) class PhysicalDisk(PhysicalDiskTuple): @@ -232,7 +235,7 @@ class RAIDManagement(object): nullable=True), controller=fqdd.split(':')[-1], raid_level=REVERSE_RAID_LEVELS[drac_raid_level], - size_mb=int(size_b) / 2 ** 20, + size_mb=int(size_b) // 2 ** 20, status=constants.PRIMARY_STATUS[drac_status], raid_status=DISK_RAID_STATUS[drac_raid_status], span_depth=int(self._get_virtual_disk_attr(drac_disk, @@ -268,45 +271,74 @@ class RAIDManagement(object): drac_physical_disks = utils.find_xml(doc, 'DCIM_PhysicalDiskView', uris.DCIM_PhysicalDiskView, find_all=True) + physical_disks = [self._parse_drac_physical_disk(disk) + for disk in drac_physical_disks] - return [self._parse_drac_physical_disk(disk) - for disk in drac_physical_disks] + drac_pcie_disks = utils.find_xml(doc, 'DCIM_PCIeSSDView', + uris.DCIM_PCIeSSDView, + find_all=True) + pcie_disks = [self._parse_drac_physical_disk(disk, + uris.DCIM_PCIeSSDView) for disk in drac_pcie_disks] + + return physical_disks + pcie_disks + + def _parse_drac_physical_disk(self, + drac_disk, + uri=uris.DCIM_PhysicalDiskView): + fqdd = self._get_physical_disk_attr(drac_disk, 'FQDD', uri) + size_b = self._get_physical_disk_attr(drac_disk, 'SizeInBytes', uri) - def _parse_drac_physical_disk(self, drac_disk): - fqdd = self._get_physical_disk_attr(drac_disk, 'FQDD') - size_b = self._get_physical_disk_attr(drac_disk, 'SizeInBytes') free_size_b = self._get_physical_disk_attr(drac_disk, - 'FreeSizeInBytes') - drac_status = self._get_physical_disk_attr(drac_disk, 'PrimaryStatus') + 'FreeSizeInBytes', uri) + if free_size_b is not None: + free_size_mb = int(free_size_b) // 2 ** 20 + else: + free_size_mb = None + + drac_status = self._get_physical_disk_attr(drac_disk, 'PrimaryStatus', + uri) drac_raid_status = self._get_physical_disk_attr(drac_disk, - 'RaidStatus') - drac_media_type = self._get_physical_disk_attr(drac_disk, 'MediaType') + 'RaidStatus', uri) + if drac_raid_status is not None: + raid_status = DISK_RAID_STATUS[drac_raid_status] + else: + raid_status = None + drac_media_type = self._get_physical_disk_attr(drac_disk, 'MediaType', + uri) drac_bus_protocol = self._get_physical_disk_attr(drac_disk, - 'BusProtocol') + 'BusProtocol', uri) return PhysicalDisk( id=fqdd, description=self._get_physical_disk_attr(drac_disk, - 'DeviceDescription'), + 'DeviceDescription', + uri), controller=fqdd.split(':')[-1], manufacturer=self._get_physical_disk_attr(drac_disk, - 'Manufacturer'), - model=self._get_physical_disk_attr(drac_disk, 'Model'), + 'Manufacturer', uri), + model=self._get_physical_disk_attr(drac_disk, 'Model', uri), media_type=PHYSICAL_DISK_MEDIA_TYPE[drac_media_type], interface_type=PHYSICAL_DISK_BUS_PROTOCOL[drac_bus_protocol], - size_mb=int(size_b) / 2 ** 20, - free_size_mb=int(free_size_b) / 2 ** 20, + size_mb=int(size_b) // 2 ** 20, + free_size_mb=free_size_mb, serial_number=self._get_physical_disk_attr(drac_disk, - 'SerialNumber'), + 'SerialNumber', uri), firmware_version=self._get_physical_disk_attr(drac_disk, - 'Revision'), + 'Revision', uri), status=constants.PRIMARY_STATUS[drac_status], - raid_status=DISK_RAID_STATUS[drac_raid_status], - sas_address=self._get_physical_disk_attr(drac_disk, 'SASAddress')) + raid_status=raid_status, + sas_address=self._get_physical_disk_attr(drac_disk, 'SASAddress', + uri, allow_missing=True), + device_protocol=self._get_physical_disk_attr(drac_disk, + 'DeviceProtocol', + uri, + allow_missing=True)) - def _get_physical_disk_attr(self, drac_disk, attr_name): + def _get_physical_disk_attr(self, drac_disk, attr_name, uri, + allow_missing=False): return utils.get_wsman_resource_attr( - drac_disk, uris.DCIM_PhysicalDiskView, attr_name, nullable=True) + drac_disk, uri, attr_name, nullable=True, + allow_missing=allow_missing) def convert_physical_disks(self, physical_disks, raid_enable): """Converts a list of physical disks into or out of RAID mode. diff --git a/dracclient/resources/uris.py b/dracclient/resources/uris.py index ce72087..5f173ca 100644 --- a/dracclient/resources/uris.py +++ b/dracclient/resources/uris.py @@ -73,6 +73,9 @@ DCIM_MemoryView = ('http://schemas.dell.com/wbem/wscim/1/cim-schema/2/' DCIM_NICView = ('http://schemas.dell.com/wbem/wscim/1/cim-schema/2/' 'DCIM_NICView') +DCIM_PCIeSSDView = ('http://schemas.dell.com/wbem/wscim/1/cim-schema/2/' + 'DCIM_PCIeSSDView') + DCIM_PhysicalDiskView = ('http://schemas.dell.com/wbem/wscim/1/cim-schema/2/' 'DCIM_PhysicalDiskView') diff --git a/dracclient/tests/test_raid.py b/dracclient/tests/test_raid.py index 271a4d0..87e599a 100644 --- a/dracclient/tests/test_raid.py +++ b/dracclient/tests/test_raid.py @@ -104,7 +104,8 @@ class ClientRAIDManagementTestCase(base.BaseTest): firmware_version='LS0A', status='ok', raid_status='ready', - sas_address='5000C5007764F409') + sas_address='5000C5007764F409', + device_protocol=None) mock_requests.post( 'https://1.2.3.4:443/wsman', @@ -133,7 +134,37 @@ class ClientRAIDManagementTestCase(base.BaseTest): firmware_version='LS0B', status='ok', raid_status='ready', - sas_address='5000C5007764F409') + sas_address='5000C5007764F409', + device_protocol=None) + + mock_requests.post( + 'https://1.2.3.4:443/wsman', + text=test_utils.RAIDEnumerations[uris.DCIM_PhysicalDiskView]['ok']) + + self.assertIn(expected_physical_disk, + self.drac_client.list_physical_disks()) + + @mock.patch.object(dracclient.client.WSManClient, + 'wait_until_idrac_is_ready', spec_set=True, + autospec=True) + def test_list_physical_disks_nvme(self, mock_requests, + mock_wait_until_idrac_is_ready): + expected_physical_disk = raid.PhysicalDisk( + id='Disk.Bay.20:Enclosure.Internal.0-1:PCIeExtender.Slot.1', + description='PCIe SSD in Slot 20 in Bay 1', + controller='PCIeExtender.Slot.1', + manufacturer='SAMSUNG', + model='Dell Express Flash PM1725a 800GB SFF', + media_type='ssd', + interface_type='pcie', + size_mb=763097, + free_size_mb=None, + serial_number='S39YNX0JB02343', + firmware_version='1.0.4', + status='unknown', + raid_status=None, + sas_address=None, + device_protocol='NVMe-MI1.0') mock_requests.post( 'https://1.2.3.4:443/wsman', diff --git a/dracclient/tests/wsman_mocks/physical_disk_view-enum-ok.xml b/dracclient/tests/wsman_mocks/physical_disk_view-enum-ok.xml index bf3633b..aa9dca1 100644 --- a/dracclient/tests/wsman_mocks/physical_disk_view-enum-ok.xml +++ b/dracclient/tests/wsman_mocks/physical_disk_view-enum-ok.xml @@ -2,7 +2,9 @@ xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsen="http://schemas.xmlsoap.org/ws/2004/09/enumeration" xmlns:wsman="http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd" - xmlns:n1="http://schemas.dell.com/wbem/wscim/1/cim-schema/2/DCIM_PhysicalDiskView"> + xmlns:n1="http://schemas.dell.com/wbem/wscim/1/cim-schema/2/DCIM_PhysicalDiskView" + xmlns:n2="http://schemas.dell.com/wbem/wscim/1/cim-schema/2/DCIM_PCIeSSDView" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous http://schemas.xmlsoap.org/ws/2004/09/enumeration/EnumerateResponse @@ -123,6 +125,33 @@ 0 0 + + 7 + PCIe SSD in Slot 20 in Bay 1 + NVMe-MI1.0 + 2 + Disk.Bay.20:Enclosure.Internal.0-1:PCIeExtender.Slot.1 + NO + + + Disk.Bay.20:Enclosure.Internal.0-1:PCIeExtender.Slot.1 + SAMSUNG + 8 GT/s + 1 + Dell Express Flash PM1725a 800GB SFF + 8 GT/s + x4 + x4 + 0 + a822 + 0 + + 100 + 1.0.4 + S39YNX0JB02343 + 800166076416 + 1 +