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
+27
@@ -4,6 +4,7 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"git.mchus.pro/mchus/logpile/internal/models"
|
||||
"git.mchus.pro/mchus/logpile/internal/parser"
|
||||
)
|
||||
|
||||
@@ -249,3 +250,29 @@ func TestParseBeeAuditSnapshot(t *testing.T) {
|
||||
t.Fatal("expected board FRU fallback to be populated")
|
||||
}
|
||||
}
|
||||
|
||||
func TestNormalizePSUSlots(t *testing.T) {
|
||||
in := []models.PSU{
|
||||
{Slot: "0", Firmware: "B"}, {Slot: "1", Firmware: "B"},
|
||||
{Slot: "2", Firmware: "B"}, {Slot: "3", Firmware: "B"},
|
||||
}
|
||||
out := normalizePSUSlots(in)
|
||||
for i, want := range []string{"1", "2", "3", "4"} {
|
||||
if out[i].Slot != want {
|
||||
t.Errorf("psu[%d].Slot = %q, want %q", i, out[i].Slot, want)
|
||||
}
|
||||
if out[i].Firmware != "" {
|
||||
t.Errorf("psu[%d].Firmware = %q, want empty (bare FRU version leak)", i, out[i].Firmware)
|
||||
}
|
||||
}
|
||||
|
||||
// Already 1-based / non-numeric: leave untouched.
|
||||
keep := []models.PSU{{Slot: "1"}, {Slot: "2"}}
|
||||
if got := normalizePSUSlots(keep); got[0].Slot != "1" || got[1].Slot != "2" {
|
||||
t.Errorf("1-based slots must be untouched, got %q,%q", got[0].Slot, got[1].Slot)
|
||||
}
|
||||
psuA := []models.PSU{{Slot: "PSU0"}}
|
||||
if got := normalizePSUSlots(psuA); got[0].Slot != "PSU0" {
|
||||
t.Errorf("non-numeric slot must be untouched, got %q", got[0].Slot)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user