import pyudev from leapp.libraries.stdlib import api from leapp.models import Interface, PCIAddress udev_context = pyudev.Context() def physical_interfaces(): """ Returns a list of pyudev.Device objects for all physical network interfaces """ enumerator = pyudev.Enumerator(udev_context).match_subsystem('net') return [d for d in enumerator if not d.device_path.startswith('/devices/virtual/')] def pci_info(path): """ Returns PCI topology info from string which is expected to be a value of ID_PATH udev device property """ pci = {} # TODO(msekleta): check that path argument actually has ID_PATH format if path.startswith('pci-'): components = path[4:16].split(':') pci['domain'] = components[0] pci['bus'] = components[1] pci['device'] = components[2].split('.')[0] pci['function'] = components[2].split('.')[1] return pci def interfaces(): """ Generator which produces an Interface objects containing assorted interface properties relevant for network naming """ for dev in physical_interfaces(): attrs = {} try: attrs['name'] = dev.sys_name attrs['devpath'] = dev.device_path attrs['driver'] = dev['ID_NET_DRIVER'] attrs['vendor'] = dev['ID_VENDOR_ID'] attrs['pci_info'] = PCIAddress(**pci_info(dev['ID_PATH'])) attrs['mac'] = dev.attributes.get('address') if isinstance(attrs['mac'], bytes): attrs['mac'] = attrs['mac'].decode() except Exception as e: # pylint: disable=broad-except # FIXME(msekleta): We should probably handle errors more granularly # Maybe we should inhibit upgrade process at this point api.current_logger().warning('Failed to gather information about network interface: ' + str(e)) continue yield Interface(**attrs)