USB device discovery
The idea is to retreive USB devices informations via 'lshw' and return the list to ironic in order to be able to create introspection rules based on USB devices. Change-Id: I39d60cb467614fca7a7f701dbe576154213580a5
This commit is contained in:
parent
beccfe8c92
commit
3fd68c0848
@ -152,6 +152,12 @@ collectors are:
|
||||
* ``lldp_raw`` - mapping of interface names to lists of raw
|
||||
type-length-value (TLV) records.
|
||||
|
||||
``usb-devices``
|
||||
Collects USB devices information. Adds one key:
|
||||
|
||||
* ``usb_devices`` - list of objects with keys ``product``, ``vendor`` and
|
||||
``handle``
|
||||
|
||||
.. _hardware: https://pypi.org/project/hardware/
|
||||
.. _NUMA: https://en.wikipedia.org/wiki/Non-uniform_memory_access
|
||||
.. _LLDP: https://en.wikipedia.org/wiki/Link_Layer_Discovery_Protocol
|
||||
|
@ -848,6 +848,15 @@ class SystemVendorInfo(encoding.SerializableComparable):
|
||||
self.firmware = firmware
|
||||
|
||||
|
||||
class USBInfo(encoding.SerializableComparable):
|
||||
serializable_fields = ('product', 'vendor', 'handle')
|
||||
|
||||
def __init__(self, product, vendor, handle):
|
||||
self.product = product
|
||||
self.vendor = vendor
|
||||
self.handle = handle
|
||||
|
||||
|
||||
class BootInfo(encoding.SerializableComparable):
|
||||
serializable_fields = ('current_boot_mode', 'pxe_interface')
|
||||
|
||||
@ -925,6 +934,15 @@ class HardwareManager(object, metaclass=abc.ABCMeta):
|
||||
def generate_tls_certificate(self, ip_address):
|
||||
raise errors.IncompatibleHardwareMethodError()
|
||||
|
||||
def get_usb_devices(self):
|
||||
"""Collect USB devices
|
||||
|
||||
List all USB final devices, based on lshw information
|
||||
|
||||
:return: a dict, containing product, vendor, and handle information
|
||||
"""
|
||||
raise errors.IncompatibleHardwareMethodError()
|
||||
|
||||
def erase_block_device(self, node, block_device):
|
||||
"""Attempt to erase a block device.
|
||||
|
||||
@ -1615,6 +1633,23 @@ class GenericHardwareManager(HardwareManager):
|
||||
'node': cached_node['uuid'] if cached_node else None})
|
||||
return dev_name
|
||||
|
||||
def get_usb_devices(self):
|
||||
sys_dict = self._get_system_lshw_dict()
|
||||
try:
|
||||
usb_dict = utils.find_in_lshw(sys_dict, by_id='usb',
|
||||
by_class='generic', recursive=True)
|
||||
|
||||
except StopIteration:
|
||||
LOG.warning('Cannot find detailed information about USB')
|
||||
return None
|
||||
devices = []
|
||||
for dev in usb_dict:
|
||||
usb_info = USBInfo(product=dev.get('product', ''),
|
||||
vendor=dev.get('vendor', ''),
|
||||
handle=dev.get('handle', ''))
|
||||
devices.append(usb_info)
|
||||
return devices
|
||||
|
||||
def get_system_vendor_info(self):
|
||||
try:
|
||||
sys_dict = self._get_system_lshw_dict()
|
||||
|
@ -387,3 +387,12 @@ def collect_lldp(data, failures):
|
||||
:param failures: AccumulatedFailures object
|
||||
"""
|
||||
data['lldp_raw'] = hardware.dispatch_to_managers('collect_lldp_data')
|
||||
|
||||
|
||||
def collect_usb_devices(data, failures):
|
||||
"""Collect USB information for connected devices.
|
||||
|
||||
:param data: mutable data that we'll send to inspector
|
||||
:param failures: AccumulatedFailures object
|
||||
"""
|
||||
data['usb_devices'] = hardware.dispatch_to_managers('get_usb_devices')
|
||||
|
@ -447,6 +447,28 @@ LSHW_JSON_OUTPUT_V1 = ("""
|
||||
"ethernet": true,
|
||||
"physical": "Physical interface"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "usb",
|
||||
"class": "bus",
|
||||
"children": [
|
||||
{
|
||||
"id": "usbhost:0",
|
||||
"class": "bus",
|
||||
"children": [
|
||||
{
|
||||
"id": "usb",
|
||||
"class": "generic",
|
||||
"handle": "USB:1:2",
|
||||
"description": "Generic USB device",
|
||||
"product": "MyProduct",
|
||||
"vendor": "MyVendor",
|
||||
"physid": "1",
|
||||
"businfo": "usb@1:1"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -4897,6 +4897,16 @@ class TestGenericHardwareManager(base.IronicAgentTest):
|
||||
self.assertEqual('', vendor_info.firmware.build_date)
|
||||
self.assertEqual('', vendor_info.firmware.version)
|
||||
|
||||
@mock.patch.object(il_utils, 'execute', autospec=True)
|
||||
def test_get_usb_devices(self, mocked_execute):
|
||||
|
||||
device = hardware.USBInfo('MyProduct', 'MyVendor', 'USB:1:2')
|
||||
|
||||
mocked_execute.return_value = hws.LSHW_JSON_OUTPUT_V1
|
||||
detected_usb_devices = self.hardware.get_usb_devices()
|
||||
|
||||
self.assertEqual([device], detected_usb_devices)
|
||||
|
||||
@mock.patch.object(utils, 'get_agent_params',
|
||||
lambda: {'BOOTIF': 'boot:if'})
|
||||
@mock.patch.object(os.path, 'isdir', autospec=True)
|
||||
|
@ -0,0 +1,5 @@
|
||||
---
|
||||
features:
|
||||
- Add attached USB device auto discovery. The information is
|
||||
retrieived from `lshw` tool and store in introspection data result.
|
||||
|
@ -58,6 +58,7 @@ ironic_python_agent.inspector.collectors =
|
||||
numa-topology = ironic_python_agent.numa_inspector:collect_numa_topology_info
|
||||
dmi-decode = ironic_python_agent.dmi_inspector:collect_dmidecode_info
|
||||
lldp = ironic_python_agent.inspector:collect_lldp
|
||||
usb-devices = ironic_python_agent.inspector:collect_usb_devices
|
||||
|
||||
[pbr]
|
||||
autodoc_index_modules = True
|
||||
|
Loading…
x
Reference in New Issue
Block a user