fix(inspur): read RESTful FRU info and float fans_power from component.log

Diffing an NF5280M6 BMC dump against its BEE-SP live-CD bundle found two
blind spots in the combined-component.log onekeylog layout (no
devicefrusdr.log / asset.json):

- board manufacturer/product/part/uuid empty and stats.fru 0: the
  "RESTful FRU info:" JSON block was never parsed. New component_fru.go
  (ParseComponentLogFRU) flattens it to []models.FRUInfo, prefers the
  product-area system serial over the board PCB serial, and sets
  BoardInfo.UUID from system_uuid. Wired as a fallback only when
  result.FRU is still empty.
- zero fan sensors: FanRESTInfo.FansPower was int but this firmware
  writes "fans_power": 12.000000, so json.Unmarshal of the whole fan
  block failed. Changed to float64.

Also included: SOL smartd SCSI/SAS device-line parsing and diagnose.go
gofmt from concurrent work on the same live-CD-diff task. See ADL-064.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011LffAvostt3uMkiUbVUiyM
This commit is contained in:
Mikhail Chusavitin
2026-09-01 11:58:55 +03:00
co-authored by Claude Sonnet 5
parent ab8636da04
commit 2fa0f78f94
9 changed files with 780 additions and 99 deletions
+69
View File
@@ -1767,3 +1767,72 @@ on every source switch. Fixed by emitting the xFusion NIC as per-port entries
components. Net: after this work the only fields that still differ between the two
bundles are ones reanimator does not track, so alternating collection methods for
one server produces no spurious install/remove/firmware events.
---
## ADL-063 — xFusion disk_info "Capacity" is binary-unit; normalize to decimal GB
**Date:** 2026-09-01
**Context:** Diffing a BMC dump (`xfusion`) against the BEE-SP live-CD bundle
(`easy_bee`) for the same G5500 V7 (S/N 210619KUGGXGS2000017) showed every storage
device in the BMC export with `size_gb` absent while the live-CD export had real
sizes (KIOXIA 7681, INTEL 3840). Root cause: `parseDiskInfo`
(`internal/parser/vendors/xfusion/hardware.go`) read capacity with
`fmt.Sscanf(fields["Capacity"], "%f GB", &capFloat)`. The iBMC file writes
`Capacity : 6.986 TB` / `3.492 TB` for NVMe drives, so the literal ` GB` never
matched and `sizeGB` stayed 0. Even for the `446.625 GB` boot-SSD case the old
code truncated the binary GiB value (446) instead of the vendor's decimal spec.
**Decision:** Added `parseDiskCapacityGB`: parse `<number> <unit>` (TB/GB/MB,
case-insensitive), treat the number as binary (iBMC reports GiB/TiB mislabeled as
GB/TB), convert to decimal GB (`round(value * 2^n / 1e9)`). This matches both the
drive's marketed decimal capacity and the BEE-SP live-CD `size_gb`. A few GB of
rounding slack vs the live-CD's exact byte count is accepted (`size_gb` is
display-only and not persisted by Reanimator).
**Consequences:**
- BMC-dump storage now carries `size_gb` matching the live-CD export
component-for-component (7681/7681, 3839/3840).
- `Drive Temperature`, byte-swapped system `GUID` in `OptPme/pram/per_power_off.ini`,
and PCIe link speed/width remain unparsed for xFusion: temperature has no
`models.Storage` field yet, the GUID is fragile wire-order, and card_info carries
no link fields (that data only exists in the live-CD's lspci view, not the dump).
- Regression test `TestParseDiskInfo_CapacityUnits`.
---
## ADL-064 — Inspur combined component.log: parse `RESTful FRU info:` and float `fans_power`
**Date:** 2026-09-01
**Context:** Diffing a BMC dump (`inspur`) against the BEE-SP live-CD bundle
(`easy_bee`) for the same NF5280M6 (S/N 24C319579) surfaced two blind spots in the
combined-`component.log` onekeylog layout (classic `onekeylog/` root, has
`component/component.log`, but no `devicefrusdr.log` and no `asset.json`):
1. Board `manufacturer` / `product_name` / `part_number` / `uuid` all empty and
`stats.fru: 0` (with a "still missing: FRU" collection error). `component.log`
carries a `RESTful FRU info:` JSON array (BMC_FRU + PSU/backplane/riser FRUs
with `device.system_uuid`, `board`, `product` areas) that no parser read.
2. Zero fan sensors (live-CD had 8). `FanRESTInfo.FansPower` was typed `int` but
this firmware writes `"fans_power": 12.000000`; `json.Unmarshal` of the whole
fan block failed, so `parseFanSensors` / `parseFanEvents` returned nil.
**Decision:**
- `internal/parser/vendors/inspur/component_fru.go` (`ParseComponentLogFRU`)
parses the `RESTful FRU info:` array into `[]models.FRUInfo`, preferring the
product area (operator-facing system serial / asset tag) over the board area
(PCB serial) for identity, and sets `hw.BoardInfo.UUID` from `system_uuid`
directly. Placeholder area values (`0`, `NULL`, `N/A`, blank) are skipped.
Wired in `parser.go` as a fallback only when `result.FRU` is still empty after
the devicefrusdr.log path, so dumps that already have real FRU data are
untouched.
- `FanRESTInfo.FansPower` changed to `float64`.
**Consequences:**
- This dump class now yields full board identity + UUID matching the live-CD
export, 8 fan sensors, `stats.fru: 7`, and no collection error.
- Real motherboard `part_number` (`YZMB-01642-102`) is exported where the live-CD
had only the `"0"` product-area placeholder - a deliberate improvement, not a
regression (Reanimator treats `"0"`/`"NULL"` board part as absent).
- Remaining live-CD-vs-BMC diffs for this host are not parser gaps: the combined
`component.log` carries no full IPMI SDR (so ~16 sensors vs 72), the live-CD
`0000:00:1f.2` PCH power-management function is lspci-only noise, and the
live-CD actually *missed* one DIMM (`CPU1_C1D0`) that the BMC dump reports.
- Tests: `TestParseComponentLogFRU_BoardIdentityAndUUID`,
`TestParseComponentLogFRU_AbsentSection`,
`TestParseComponentLogSensors_FloatFansPower`.