fix(parser,exporter): reconcile BMC-dump and live-CD exports of the same server
The audit tool that ingests Reanimator exports treats any per-component field
change between imports as a component replacement. Importing an xFusion BMC dump
and an easy_bee BEE-SP bundle for one server produced large spurious diffs.
xfusion:
- parseMemInfo tolerates a stray 0x0A inside the binary SPD "bom number" column
(it was splitting a DIMM record in two and emitting a phantom "slot s" module)
- DIMM slot from the "dimm name" column ("DIMM071"), mainboard "location" dropped
- GPU slot = BDF (Reanimator contract)
- NIC emitted per PCI function from netcard_info.txt (BDF + per-port MAC, shared
card serial) instead of one card-level adapter with the wrong BDF, which had
been colliding with a GPU and vanishing in dedup
- NIC manufacturer left blank when it is the system OEM so the exporter resolves
the silicon vendor from pci.ids
- "(U6216)" chip designator stripped from firmware versions
easy_bee:
- PSU bay numbers rebased 0-indexed -> 1-indexed; bare single-letter PSU
"firmware" (a leaked FRU version) cleared
- board.part_number taken from the bundle's ipmitool-fru.txt chassis
"Product Part Number" to match the BMC value
exporter (cross-vendor):
- canonicalMemorySlot: drop dmidecode "(J)" channel tag, Memory111 -> DIMM111
- canonicalGPUModel: NVIDIA DC GPUs reduce to the bare chip token
- canonicalStorageMediaAndInterface: NVMe is a bus not a medium
- manufacturerFromStorageModel: fill blank drive vendor from the model prefix
- isRemovableUSBStorageDevice: drop live-CD boot sticks
- isOnboardControllerPCIeDevice: drop SATA/NVMe/MegaRAID/PCIe-switch controller
functions that only an lspci scan reports (keep add-in cards with an identity)
For the reference server every physical component now appears in both exports
keyed identically; residual diffs are one-sided enrichment only.
Refs ADL-061, ADL-062.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VFy4m7cVv4cqp25jJh2gSB
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
5b65c99b0e
commit
9b2c654182
@@ -1667,3 +1667,71 @@ no slot label keep the previous serial/part fallback dedupe.
|
||||
reflects the latest observed population. Historical swaps are no longer surfaced as
|
||||
extra modules (if a per-slot history is wanted later it must be built explicitly,
|
||||
not inferred from dedupe residue). Regression test `TestDedupeMemorySlotSwap`.
|
||||
|
||||
---
|
||||
|
||||
## ADL-061 — xFusion mem_info rows survive an embedded newline in the SPD BOM field
|
||||
|
||||
**Date:** 2026-08-31
|
||||
**Context:** The iBMC `AppDump/CpuMem/mem_info` file copies the raw SPD "bom number"
|
||||
(col 14) verbatim, and it contains arbitrary binary bytes. On a G5500 V7 dump
|
||||
(S/N 210619KUGGXGS2000017) one DIMM's BOM field held a `0x0A`, splitting that
|
||||
record across two physical lines. `parseMemInfo` split the file on `"\n"` and
|
||||
treated each line as a record, so the head line lost every field after the BOM
|
||||
column (type, speed, part number) and the tail fragment
|
||||
`s, M321R8GA0EB2-CWMXH, ..., OK` passed the `len(parts) >= 9` guard and became a
|
||||
phantom 33rd "DIMM" with slot `s`, manufacturer `N/A`, serial `OK`. The BEE-SP
|
||||
export of the same host (dmidecode-based) correctly showed 32 healthy DIMMs.
|
||||
**Decision:** `parseMemInfo` now feeds `reassembleMemInfoRows`, which folds any
|
||||
line not starting with `Memory<digit>` (or the `slot(col 1)` header) back into the
|
||||
previous logical row before comma-splitting. `looksLikeMemInfoRowStart` gates this.
|
||||
**Consequences:** The phantom DIMM is gone and the split record is fully recovered.
|
||||
Both collectors now yield the same 32-module inventory for this host — identical
|
||||
serial/size/type/speed/part/status per module; only slot labels (`Memory140` vs
|
||||
`DIMM140(E)`), the `location` field, and `status_checked_at` still differ, which is
|
||||
inherent to the two sources. Regression test `TestParseMemInfo_EmbeddedNewlineInBOM`.
|
||||
|
||||
---
|
||||
|
||||
## ADL-062 — BMC-dump and live-CD exports of the same server must agree component-for-component
|
||||
|
||||
**Date:** 2026-08-31
|
||||
**Context:** The audit tool that ingests Reanimator exports treats any per-component
|
||||
field change between imports as a component replacement. Importing a BMC dump
|
||||
(`xfusion`) and a BEE-SP live-CD bundle (`easy_bee`) for the *same* server produced
|
||||
large spurious diffs: a device present in one bundle and absent in the other, and
|
||||
the same physical part carrying different slot labels / model strings / vendor
|
||||
names depending on the collector.
|
||||
**Decision:** Normalize toward a single cross-collector representation, splitting
|
||||
the work between the two vendor parsers and the shared exporter:
|
||||
- **Exporter (`reanimator_converter.go`)** — cross-vendor rules that any two
|
||||
collectors must converge on: `canonicalMemorySlot` (drop dmidecode channel tag
|
||||
`(J)`, rewrite BMC `Memory111`→`DIMM111`); `canonicalGPUModel` (NVIDIA
|
||||
data-center GPUs reduce to the bare chip token, "NVIDIA H200 NVL"→"H200");
|
||||
`canonicalStorageMediaAndInterface` ("NVMe" is a bus not a medium → type SSD /
|
||||
interface NVMe; bare PCIe drive → NVMe); `manufacturerFromStorageModel`;
|
||||
`isRemovableUSBStorageDevice` (a live-CD boot stick is not inventory);
|
||||
`isOnboardControllerPCIeDevice` (SATA/NVMe/MegaRAID/PCIe-switch controller
|
||||
functions that only an lspci scan ever reports — an add-in HBA/RAID card with
|
||||
its own serial or part number is kept).
|
||||
- **xfusion** — DIMM slot from the `mem_info` "dimm name" column, `location`
|
||||
dropped; GPU `slot` = BDF (Reanimator contract); NIC emitted **per PCI function**
|
||||
from `netcard_info.txt` (BDF + per-port MAC, shared card serial), replacing the
|
||||
single card-level adapter, so it matches an lspci view and no longer collides
|
||||
with a GPU on a wrong BDF; NIC manufacturer left blank when it is the system OEM
|
||||
so the exporter resolves the silicon vendor from pci.ids; `(U6216)` chip
|
||||
designator stripped from firmware versions.
|
||||
- **easy_bee** — PSU bay numbers rebased 0→1 (`normalizePSUSlots`), bare
|
||||
single-letter PSU "firmware" (a leaked FRU version) cleared, `board.part_number`
|
||||
taken from the bundle's `ipmitool-fru.txt` chassis "Product Part Number" to match
|
||||
the BMC value.
|
||||
**Consequences:** For the reference server every physical component now appears in
|
||||
both exports keyed identically (serial, or BDF for PCIe). Residual diffs are
|
||||
one-sided *enrichment* only — PCIe link speed/width, NVMe block sizes, drive
|
||||
`size_gb`, CPU clocks, PSU firmware/wattage, `board.uuid`, and the extra firmware
|
||||
components (CPLD/U-Boot/SDK/…) — where one collector's source simply has data the
|
||||
other's does not; none is a value that *conflicts*. Whether the audit treats a
|
||||
null→value transition on an unchanged component as a change is a config question
|
||||
on the audit side. Tests: `TestCanonicalMemorySlot`, `TestCanonicalGPUModel`,
|
||||
`TestCanonicalStorageMediaAndInterface`, `TestIsOnboardControllerPCIeDevice`,
|
||||
`TestNormalizePSUSlots`, updated `TestParse_ServerFileExport_NetworkAdaptersAndFirmware`.
|
||||
|
||||
Reference in New Issue
Block a user