Repository: RedHatInsights/insights-core

Issue:
Lspci combiner missing data
There is a problem in the Lspci combiner that causes it to not include data from `lspci -k`.  The following data when parsed will not include all of the `lspci -k` results:

The `lspci -k` data:

```
pcilib: Error reading /sys/bus/pci/devices/0000:00:0c.0/label: Operation not permitted
pcilib: Error reading /sys/bus/pci/devices/0000:00:0e.0/label: Operation not permitted
00:00.0 System peripheral: Intel Corporation Ice Lake Memory Map/VT-d (rev 20)
	Subsystem: Dell Device 0b73
bb:00.0 Processing accelerators: Habana Labs Ltd. Gaudi2 AI Training Accelerator (rev 01)
	Subsystem: Habana Labs Ltd. Gaudi2 AI Training Accelerator
	Kernel driver in use: habanalabs
	Kernel modules: habanalabs
cb:00.0 Processing accelerators: Habana Labs Ltd. Gaudi2 AI Training Accelerator (rev 01)
	Subsystem: Habana Labs Ltd. Gaudi2 AI Training Accelerator
	Kernel driver in use: habanalabs
	Kernel modules: habanalabs
db:00.0 Processing accelerators: Habana Labs Ltd. Gaudi2 AI Training Accelerator (rev 01)
	Subsystem: Habana Labs Ltd. Gaudi2 AI Training Accelerator
	Kernel driver in use: habanalabs
	Kernel modules: habanalabs
```

The `lspi -vmmkn` data:

```
Slot:	00:00.0
Class:	0880
Vendor:	8086
Device:	09a2
SVendor:	1028
SDevice:	0b73
Rev:	20
NUMANode:	0

Slot:	bb:00.0
Class:	1200
Vendor:	1da3
Device:	1020
SVendor:	1da3
SDevice:	1020
Rev:	01
Driver:	habanalabs
Module:	habanalabs
NUMANode:	1

Slot:	cb:00.0
Class:	1200
Vendor:	1da3
Device:	1020
SVendor:	1da3
SDevice:	1020
Rev:	01
Driver:	habanalabs
Module:	habanalabs
NUMANode:	1

Slot:	db:00.0
Class:	1200
Vendor:	1da3
Device:	1020
SVendor:	1da3
SDevice:	1020
Rev:	01
Driver:	habanalabs
Module:	habanalabs
NUMANode:	1
```

The combiner output for the last 3 slots will look like this:

```
Out[8]: 
[{'Slot': 'bb:00.0',
  'Class': '1200',
  'Vendor': '1da3',
  'Device': '1020',
  'SVendor': '1da3',
  'SDevice': '1020',
  'Rev': '01',
  'Driver': 'habanalabs',
  'Module': ['habanalabs'],
  'NUMANode': '1'}]

In [9]: lspci.search(Slot='cb:00.0')
Out[9]: 
[{'Slot': 'cb:00.0',
  'Class': '1200',
  'Vendor': '1da3',
  'Device': '1020',
  'SVendor': '1da3',
  'SDevice': '1020',
  'Rev': '01',
  'Driver': 'habanalabs',
  'Module': ['habanalabs'],
  'NUMANode': '1'}]

In [10]: lspci.search(Slot='db:00.0')
Out[10]: 
[{'Slot': 'db:00.0',
  'Class': '1200',
  'Vendor': '1da3',
  'Device': '1020',
  'SVendor': '1da3',
  'SDevice': '1020',
  'Rev': '01',
  'Driver': 'habanalabs',
  'Module': ['habanalabs'],
  'NUMANode': '1'}]
```

Hints from issue comments:

Solution patch:
diff --git a/insights/combiners/lspci.py b/insights/combiners/lspci.py
index 42d28acc3b..6dc9bb3304 100644
--- a/insights/combiners/lspci.py
+++ b/insights/combiners/lspci.py
@@ -122,8 +122,8 @@ def __init__(self, lspci_k, lspci_vmmkn):
         if lspci_vmmkn:
             for dev in lspci_vmmkn:
                 # use the local copy to prevent from writing back to the parser
-                dev = dev.copy()
-                if lspci_k and dev['Slot'] in lspci_k:
+                dev_t = dev.copy()
+                if lspci_k and (dev['Slot'] in lspci_k.data or '0000:' + dev['Slot'] in lspci_k.data):
                     # use the local copy to prevent from writing back to the parser
                     dev_k = [v for v in lspci_k.data.values() if v['Slot'].endswith(dev['Slot'])][0].copy()
                     # Since the 'lspci -k' is a more common command than the
@@ -133,8 +133,9 @@ def __init__(self, lspci_k, lspci_vmmkn):
                     # dev_k.pop('Slot') if 'Slot' in dev_k else None
                     dev_k.pop('Kernel driver in use') if 'Kernel driver in use' in dev_k else None
                     dev_k.pop('Kernel modules') if 'Kernel modules' in dev_k else None
-                    dev.update(dev_k)
-                self.append(dev)
+                    dev_t.update(dev_k)
+
+                self.append(dev_t)
             self._pci_dev_list = (lspci_k if lspci_k else lspci_vmmkn).pci_dev_list
         else:
             for dev in lspci_k.data.values():


Test patch:
diff --git a/insights/tests/combiners/test_lspci.py b/insights/tests/combiners/test_lspci.py
index 7bc5feace9..32e2c4a413 100644
--- a/insights/tests/combiners/test_lspci.py
+++ b/insights/tests/combiners/test_lspci.py
@@ -166,6 +166,69 @@
 NUMANode:       0
 """
 
+LSPCI_K_3 = """
+pcilib: Error reading /sys/bus/pci/devices/0000:00:0c.0/label: Operation not permitted
+pcilib: Error reading /sys/bus/pci/devices/0000:00:0e.0/label: Operation not permitted
+00:00.0 System peripheral: Intel Corporation Ice Lake Memory Map/VT-d (rev 20)
+	Subsystem: Dell Device 0b73
+bb:00.0 Processing accelerators: Habana Labs Ltd. Gaudi2 AI Training Accelerator (rev 01)
+	Subsystem: Habana Labs Ltd. Gaudi2 AI Training Accelerator
+	Kernel driver in use: habanalabs
+	Kernel modules: habanalabs
+cb:00.0 Processing accelerators: Habana Labs Ltd. Gaudi2 AI Training Accelerator (rev 01)
+	Subsystem: Habana Labs Ltd. Gaudi2 AI Training Accelerator
+	Kernel driver in use: habanalabs
+	Kernel modules: habanalabs
+db:00.0 Processing accelerators: Habana Labs Ltd. Gaudi2 AI Training Accelerator (rev 01)
+	Subsystem: Habana Labs Ltd. Gaudi2 AI Training Accelerator
+	Kernel driver in use: habanalabs
+	Kernel modules: habanalabs
+""".strip()  # noqa
+
+LSPCI_V_3 = """
+Slot:	00:00.0
+Class:	0880
+Vendor:	8086
+Device:	09a2
+SVendor:	1028
+SDevice:	0b73
+Rev:	20
+NUMANode:	0
+
+Slot:	bb:00.0
+Class:	1200
+Vendor:	1da3
+Device:	1020
+SVendor:	1da3
+SDevice:	1020
+Rev:	01
+Driver:	habanalabs
+Module:	habanalabs
+NUMANode:	1
+
+Slot:	cb:00.0
+Class:	1200
+Vendor:	1da3
+Device:	1020
+SVendor:	1da3
+SDevice:	1020
+Rev:	01
+Driver:	habanalabs
+Module:	habanalabs
+NUMANode:	1
+
+Slot:	db:00.0
+Class:	1200
+Vendor:	1da3
+Device:	1020
+SVendor:	1da3
+SDevice:	1020
+Rev:	01
+Driver:	habanalabs
+Module:	habanalabs
+NUMANode:	1
+""".strip()  # noqa
+
 
 def test_lspci_k():
     lspci_k = LsPciParser(context_wrap(LSPCI_K))
@@ -271,6 +334,55 @@ def test_lspci_both_long_slot():
             'PhySlot', 'NUMANode'])
 
 
+def test_lspci_both_2():
+    lspci_vmmkn = LsPciVmmkn(context_wrap(LSPCI_V_3))
+    lspci_k = LsPciParser(context_wrap(LSPCI_K_3))
+    lspci = LsPci(lspci_k, lspci_vmmkn)
+    assert sorted(lspci.pci_dev_list) == ['00:00.0', 'bb:00.0', 'cb:00.0', 'db:00.0']
+    assert lspci.search(Slot='bb:00.0') == [{
+        'Slot': 'bb:00.0',
+        'Module': ['habanalabs', ],
+        'Driver': 'habanalabs',
+        'Class': '1200',
+        'Vendor': '1da3',
+        'Device': '1020',
+        'Rev': '01',
+        'Dev_Details': 'Processing accelerators: Habana Labs Ltd. Gaudi2 AI Training Accelerator (rev 01)',
+        'SVendor': '1da3',
+        'SDevice': '1020',
+        'Subsystem': 'Habana Labs Ltd. Gaudi2 AI Training Accelerator',
+        'NUMANode': '1',
+    }, ]
+    assert lspci.search(Slot='cb:00.0') == [{
+        'Slot': 'cb:00.0',
+        'Module': ['habanalabs', ],
+        'Driver': 'habanalabs',
+        'Class': '1200',
+        'Vendor': '1da3',
+        'Device': '1020',
+        'Rev': '01',
+        'Dev_Details': 'Processing accelerators: Habana Labs Ltd. Gaudi2 AI Training Accelerator (rev 01)',
+        'SVendor': '1da3',
+        'SDevice': '1020',
+        'Subsystem': 'Habana Labs Ltd. Gaudi2 AI Training Accelerator',
+        'NUMANode': '1',
+    }, ]
+    assert lspci.search(Slot='db:00.0') == [{
+        'Slot': 'db:00.0',
+        'Module': ['habanalabs', ],
+        'Driver': 'habanalabs',
+        'Class': '1200',
+        'Vendor': '1da3',
+        'Device': '1020',
+        'Rev': '01',
+        'Dev_Details': 'Processing accelerators: Habana Labs Ltd. Gaudi2 AI Training Accelerator (rev 01)',
+        'SVendor': '1da3',
+        'SDevice': '1020',
+        'Subsystem': 'Habana Labs Ltd. Gaudi2 AI Training Accelerator',
+        'NUMANode': '1',
+    }, ]
+
+
 def test_doc_examples():
     lspci_vmmkn = LsPciVmmkn(context_wrap(LSPCI_VMMKN))
     lspci_k = LsPciParser(context_wrap(LSPCI_K))