Inspur/Kaytus onekeylog dumps only exposed the mechanical carrier FRU serial
(component/fru.txt Board Product) as board identity. That serial doesn't
change when the actual NVIDIA HGX baseboard (SXM+NVSwitch "delta board") is
swapped, causing false "board unchanged" conclusions. Parse the real HGX
tray/baseboard Model/PartNumber/SerialNumber triples from
HGX_HWInfo_FWVersion.log into a new HardwareConfig.HGX field, and normalize
Redfish's NA/N-A placeholders to empty across HGX identity parsing.
Closes#21
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Fixes#20. This onekeylog variant has no devicefrusdr.log at all: FRU/sensors
come from raw ipmitool text output, PCIe/GPU presence has a dedicated
structural snapshot, SEL lives at a different path, and BMC component
failures are logged separately from SEL/IDL.
- Fall back to component/fru.txt (same FRU block format as devicefrusdr.log)
and component/sensor.txt / sdr.txt (ipmitool sensor list / sdr elist)
when devicefrusdr.log is absent.
- Parse log/bmc/diagnose/OtrdDiagnoseComponent.json's PCIe Device Info array
for GPU/PCIe presence and link state, independent of SEL/IDL alarm
history; flag devices running below their negotiated max link
speed/width as degraded with a Warning event.
- Fall back to log/sel.csv (same format as selelist.csv) when selelist.csv
is absent.
- Parse log/bmc/commer-comp/{commerslot,commerhmc,commerswvr,commerswcpld}
logs (including rotated *.tar.gz.N parts) into failure events, filtering
known-noisy lines.
- Collapse SEL events duplicated across sources by
(timestamp, event_type, description).
- Surface a CollectionError when FRU/sensors are still empty after all
fallbacks, instead of silently returning an empty inventory.
- Fix ParseFRU: a later placeholder "Product Serial : 0" / "Product Part
Number : NULL" line in the same FRU block (e.g. SCM_FRU) was overwriting
an already-parsed real Board Serial/Part Number.
Verified against dump_23DB01633_20260727-1359.tar.gz (HGX B200, KR9288-X3):
fru 0→21, sensors 0→303, 8 GPUs present at Gen5 x16 in slots 100-107.
Deferred (not covered by this change): BIOS-change-settings context and
BIOS POST codes from the same layout — see bible-local/10-decisions.md
ADL-048.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Some onekeylog BMC firmware variants split the combined component.log
into per-file D-Bus GetAll transcripts under component/ (e.g.
PowerSupplyInfo.txt, FanInfo.txt), which the inspur parser did not
read, leaving PSU and fan data empty. Add a GETALL block parser and
wire it as a fallback for PSU and fan telemetry when component.log is
absent; document the layout and known gaps in bible-local.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Adds a PDF button to the report header. Clicking it opens
/chart/current?print=true in a new tab, which auto-triggers
window.print() so the user can save to PDF via the browser dialog.
- chart submodule bumped: PrintMode support (no filter JS, auto-print,
@media print CSS)
- handlers.go: passes PrintMode=true when ?print=true query param is set
- index.html: PDF button alongside Raw Data / Reanimator
- app.js: printReport() helper; button shown/hidden with other exports
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Parse inventory_volume.log: Intel VROC (VMD) RAID volumes including
RAID level, capacity (GiB/TiB support added), status and member drives.
Add Drives []string to StorageVolume model.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Remove power-on and power-off functionality from the Redfish collector;
keep host power-state detection and show a warning in the UI when the
host is powered off before collection starts.
Add a "Пропустить зависшие" (skip hung) button that lets the user abort
stuck Redfish collection phases without losing already-collected data.
Introduces a two-level context model in Collect(): the outer job context
covers the full lifecycle including replay; an inner collectCtx covers
snapshot, prefetch, and plan-B phases only. Closing the skipCh cancels
collectCtx immediately — aborts all in-flight HTTP requests and exits
plan-B loops — then replay runs on whatever rawTree was collected.
Signal path: UI → POST /api/collect/{id}/skip → JobManager.SkipJob()
→ close(skipCh) → goroutine in Collect() → cancelCollect().
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add HPE iLO Redfish profile (priority 20): matches on manufacturer/OEM/iLO signals,
adds SmartStorage/SmartStorageConfig to critical paths, sets realistic ETA baseline
and rate policy for iLO's known slowness
- Fix post-probe hang on HPE iLO: skip numeric probing of collections where
Members@odata.count == len(Members); add 4s postProbeClient timeout as safety net
- Exclude /WorkloadPerformanceAdvisor from crawl paths
- Fix replay parser: skip absent CPU sockets, absent DIMM slots, absent drive bays
- Filter N/A version entries from firmware inventory
- Remove drive firmware from general firmware list (already in Storage[].Firmware)
- Add HPE AHS (.ahs) archive parser with hybrid SMBIOS/Redfish extraction
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Collect hardware event logs (last 7 days) from Systems and Managers/SEL LogServices
- Parse AMI raw IPMI dump messages into readable descriptions (Sensor_Type: Event_Type)
- Filter out audit/journal/non-hardware log services; only SEL from Managers
- MSI ghost GPU filter: exclude processor GPU entries with temperature=0 when host is powered on
- Reanimator collected_at uses InventoryData/Status.LastModifiedTime (30-day fallback)
- Invalidate Redfish inventory CRC groups before host power-on
- Log inventory LastModifiedTime age in collection logs
- Drop SecureBoot collection (SecureBootMode, SecureBootDatabases) — not hardware inventory
- Add build version to UI footer via template
- Add MSI Redfish API reference doc to bible-local/docs/
ADL-032–ADL-035
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Implement the full architectural plan: unified ingest.Service entry point
for archive and Redfish payloads, modular redfishprofile package with
composable profiles (generic, ami-family, msi, supermicro, dell,
hgx-topology), score-based profile matching with fallback expansion mode,
and profile-driven acquisition/analysis plans.
Vendor-specific logic moved out of common executors and into profile hooks.
GPU chassis lookup strategies and known storage recovery collections
(IntelVROC/HA-RAID/MRVL) now live in ResolvedAnalysisPlan, populated by
profiles at analysis time. Replay helpers read from the plan; no hardcoded
path lists remain in generic code.
Also splits redfish_replay.go into domain modules (gpu, storage, inventory,
fru, profiles) and adds full fixture/matcher/directive test coverage
including Dell, AMI, unknown-vendor fallback, and deterministic ordering.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Root cause analysis for device-bound firmware leaking into hardware.firmware
on Supermicro Redfish (SYS-A21GE-NBRT HGX B200):
- collectFirmwareInventory (6c19a58) had no coverage for Supermicro naming.
isDeviceBoundFirmwareName checked "gpu " / "nic " (space-terminated) while
Supermicro uses "GPU1 System Slot0" / "NIC1 System Slot0 ..." (digit suffix).
- 9c5512d added _fw_gpu_ / _fw_nvswitch_ / _inforom_gpu_ patterns to fix HGX,
but checked DeviceName which contains "Software Inventory" (from Redfish Name),
not the firmware Id. Dead code from day one.
09-testing.md: add firmware filter worked example and rule #4 — verify the
filter checks the field that the collector actually populates.
10-decisions.md: ADL-019 — isDeviceBoundFirmwareName must be extended per
vendor with a test case per vendor format before shipping.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
On Supermicro HGX systems (SYS-A21GE-NBRT) ~35 sub-chassis (GPU, NVSwitch,
PCIeRetimer, ERoT/IRoT, BMC, FPGA) all carry ChassisType=Module/Component/Zone
and expose empty /Drives collections. shouldAdaptiveNVMeProbe returned true for
all of them, triggering 35 × 384 = 13 440 HTTP requests → ~22 min wasted per
collection (more than half of total 35 min collection time).
Fix: chassisTypeCanHaveNVMe returns false for Module, Component, Zone. The
candidate selection loop in collectRawRedfishTree now checks the parent chassis
doc before adding a /Drives path to the probe list. Enclosure (NVMe backplane),
RackMount, and unknown types are unaffected.
Tests:
- TestChassisTypeCanHaveNVMe: table-driven, covers excluded and storage-capable types
- TestNVMePostProbeSkipsNonStorageChassis: topology integration, GPU chassis +
backplane with empty /Drives → exactly 1 candidate selected (backplane only)
Docs:
- ADL-018 in bible-local/10-decisions.md
- Candidate-selection test matrix in bible-local/09-testing.md
- SYS-A21GE-NBRT baseline row in docs/test_server_collection_memory.md
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Three bugs, all related to GPU dedup in the Redfish replay pipeline:
1. collectGPUsFromProcessors (redfish_replay.go): GPU-type Processor entries
(Systems/HGX_Baseboard_0/Processors/GPU_SXM_N) were not deduplicated against
existing PCIeDevice GPUs on Supermicro HGX. The chassis-ID lookup keyed on
processor Id ("GPU_SXM_1") but the chassis is named "HGX_GPU_SXM_1" — lookup
returned nothing, serial stayed empty, UUID was unseen → 8 duplicate GPU rows.
Fix: read SerialNumber directly from the Processor doc first; chassis lookup
is now a fallback override (as it was designed for MSI).
2. looksLikeGPU (redfish.go): NVSwitch PCIe devices (Model="NVSwitch",
Manufacturer="NVIDIA") were classified as GPUs because "nvidia" matched the
GPU hint list. Fix: early return false when Model contains "nvswitch".
3. gpuDocDedupKey (redfish.go): commit 9df29b1 changed the dedup key to prefer
slot|model before path, which collapsed two distinct GPUs with identical model
names in GraphicsControllers into one entry. Fix: only serial and BDF are used
as cross-path stable dedup keys; fall back to Redfish path when neither is
present. This also restores TestReplayCollectGPUs_DedupUsesRedfishPathBeforeHeuristics
which had been broken on main since 9df29b1.
Added tests:
- TestCollectGPUsFromProcessors_SupermicroHGX: Processor GPU dedup when
chassis-ID naming convention does not match processor Id
- TestReplayCollectGPUs_DedupCrossChassisSerial: same GPU via two Chassis
PCIeDevice trees with matching serials → collapsed to one
- TestLooksLikeGPU_NVSwitchExcluded: NVSwitch is not a GPU
Added rule to bible-local/09-testing.md: dedup/filter/classify functions must
cover true-positive, true-negative, and the vendor counter-case axes.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Parser / archive:
- Add .sds extension as tar-format alias (archive.go)
- Add tests for multipart upload size limits (multipart_limits_test.go)
- Remove supermicro crashdump parser (ADL-015)
Dell parser:
- Remove GPU duplicates from PCIeDevices (DCIM_VideoView vs DCIM_PCIDeviceView
both list the same GPU; VideoView record is authoritative)
Server:
- Add LOGPILE_CONVERT_MAX_MB env var for independent convert batch size limit
- Improve "file too large" error message with current limit value
Web:
- Add CONVERT_MAX_FILES_PER_BATCH = 1000 cap
- Minor UI copy and CSS fixes
Bible:
- bible-local/06-parsers.md: add pci.ids enrichment rule (enrich model from
pciids when name is empty but vendor_id+device_id are present)
- Sync bible submodule and local overview/architecture docs
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Dell NICView: strip " - XX:XX:XX:XX:XX:XX" suffix from ProductName
(Dell TSR embeds MAC in this field for every NIC port)
- Dell SoftwareIdentity: same strip applied to ElementName; store FQDD
in FirmwareInfo.Description so exporter can filter device-bound entries
- Exporter: add isDeviceBoundFirmwareFQDD() to filter firmware entries
whose Description matches NIC./PSU./Disk./RAID.Backplane./GPU. FQDD
prefixes (prevents device firmware from appearing in hardware.firmware)
- Exporter: extend isDeviceBoundFirmwareName() to filter HGX GPU/NVSwitch
firmware inventory IDs (_fw_gpu_, _fw_nvswitch_, _inforom_gpu_)
- Inspur: remove HDD firmware from Hardware.Firmware — already present
in Storage.Firmware, duplicating it violates ADL-016
- bible-local/06-parsers.md: document firmware and MAC stripping rules
- bible-local/10-decisions.md: add ADL-016 (device-bound firmware) and
ADL-017 (vendor-embedded MAC in model name fields)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add bible.git as submodule at bible/
- Move docs/bible/ → bible-local/ (project-specific architecture)
- Update CLAUDE.md to reference both bible/ and bible-local/
- Add AGENTS.md for Codex with same structure
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>