feat: improve inspur parsing and pci.ids integration

This commit is contained in:
2026-02-17 18:09:36 +03:00
parent b33cca5fcc
commit 758fa66282
26 changed files with 43567 additions and 247 deletions

View File

@@ -309,6 +309,23 @@ func (s *Server) handleGetSerials(w http.ResponseWriter, r *http.Request) {
}
var serials []SerialEntry
seenByLocationSerial := make(map[string]bool)
markSeen := func(location, serial string) {
loc := strings.ToLower(strings.TrimSpace(location))
sn := strings.ToLower(strings.TrimSpace(serial))
if loc == "" || sn == "" {
return
}
seenByLocationSerial[loc+"|"+sn] = true
}
alreadySeen := func(location, serial string) bool {
loc := strings.ToLower(strings.TrimSpace(location))
sn := strings.ToLower(strings.TrimSpace(serial))
if loc == "" || sn == "" {
return false
}
return seenByLocationSerial[loc+"|"+sn]
}
// From FRU
for _, fru := range result.FRU {
@@ -403,6 +420,7 @@ func (s *Server) handleGetSerials(w http.ResponseWriter, r *http.Request) {
Manufacturer: gpu.Manufacturer,
Category: "GPU",
})
markSeen(gpu.Slot, gpu.SerialNumber)
}
// PCIe devices
@@ -410,7 +428,10 @@ func (s *Server) handleGetSerials(w http.ResponseWriter, r *http.Request) {
if !hasUsableSerial(pcie.SerialNumber) {
continue
}
component := pcie.DeviceClass
if alreadySeen(pcie.Slot, pcie.SerialNumber) {
continue
}
component := normalizePCIeSerialComponentName(pcie)
if strings.EqualFold(strings.TrimSpace(pcie.DeviceClass), "NVSwitch") && strings.TrimSpace(pcie.PartNumber) != "" {
component = strings.TrimSpace(pcie.PartNumber)
}
@@ -422,6 +443,7 @@ func (s *Server) handleGetSerials(w http.ResponseWriter, r *http.Request) {
PartNumber: pcie.PartNumber,
Category: "PCIe",
})
markSeen(pcie.Slot, pcie.SerialNumber)
}
// Network cards
@@ -431,9 +453,11 @@ func (s *Server) handleGetSerials(w http.ResponseWriter, r *http.Request) {
}
serials = append(serials, SerialEntry{
Component: nic.Model,
Location: nic.Name,
SerialNumber: strings.TrimSpace(nic.SerialNumber),
Category: "Network",
})
markSeen(nic.Name, nic.SerialNumber)
}
// Power supplies
@@ -454,6 +478,28 @@ func (s *Server) handleGetSerials(w http.ResponseWriter, r *http.Request) {
jsonResponse(w, serials)
}
func normalizePCIeSerialComponentName(p models.PCIeDevice) string {
className := strings.TrimSpace(p.DeviceClass)
part := strings.TrimSpace(p.PartNumber)
if part != "" && !strings.EqualFold(part, className) {
return part
}
lowerClass := strings.ToLower(className)
switch lowerClass {
case "display", "display controller", "3d controller", "vga", "network", "network controller", "pcie device", "other", "unknown", "":
if part != "" {
return part
}
}
if className != "" {
return className
}
if part != "" {
return part
}
return "PCIe device"
}
func hasUsableSerial(serial string) bool {
s := strings.TrimSpace(serial)
if s == "" {
@@ -474,33 +520,70 @@ func (s *Server) handleGetFirmware(w http.ResponseWriter, r *http.Request) {
return
}
jsonResponse(w, buildFirmwareEntries(result.Hardware))
}
type firmwareEntry struct {
Component string `json:"component"`
Model string `json:"model"`
Version string `json:"version"`
}
func buildFirmwareEntries(hw *models.HardwareConfig) []firmwareEntry {
if hw == nil {
return nil
}
// Deduplicate firmware by extracting model name and version
// E.g., "PSU0 (AP-CR3000F12BY)" and "PSU1 (AP-CR3000F12BY)" with same version -> one entry
type FirmwareEntry struct {
Component string `json:"component"`
Model string `json:"model"`
Version string `json:"version"`
}
seen := make(map[string]bool)
var deduplicated []FirmwareEntry
var deduplicated []firmwareEntry
for _, fw := range result.Hardware.Firmware {
// Extract component type and model from device name
component, model := extractFirmwareComponentAndModel(fw.DeviceName)
key := component + "|" + model + "|" + fw.Version
if !seen[key] {
seen[key] = true
deduplicated = append(deduplicated, FirmwareEntry{
Component: component,
Model: model,
Version: fw.Version,
})
appendEntry := func(component, model, version string) {
component = strings.TrimSpace(component)
model = strings.TrimSpace(model)
version = strings.TrimSpace(version)
if component == "" || version == "" {
return
}
if model == "" {
model = "-"
}
key := component + "|" + model + "|" + version
if seen[key] {
return
}
seen[key] = true
deduplicated = append(deduplicated, firmwareEntry{
Component: component,
Model: model,
Version: version,
})
}
jsonResponse(w, deduplicated)
for _, fw := range hw.Firmware {
component, model := extractFirmwareComponentAndModel(fw.DeviceName)
appendEntry(component, model, fw.Version)
}
// Fallback for parsers that fill GPU firmware on device inventory only
// (e.g. runtime enrichment from redis/HGX) without explicit Hardware.Firmware entries.
for _, gpu := range hw.GPUs {
version := strings.TrimSpace(gpu.Firmware)
if version == "" {
continue
}
model := strings.TrimSpace(gpu.PartNumber)
if model == "" {
model = strings.TrimSpace(gpu.Model)
}
if model == "" {
model = strings.TrimSpace(gpu.Slot)
}
appendEntry("GPU", model, version)
}
return deduplicated
}
// extractFirmwareComponentAndModel extracts the component type and model from firmware device name

View File

@@ -1,6 +1,10 @@
package server
import "testing"
import (
"testing"
"git.mchus.pro/mchus/logpile/internal/models"
)
func TestExtractFirmwareComponentAndModel_GPUUsesPartNumberFromParentheses(t *testing.T) {
component, model := extractFirmwareComponentAndModel("GPU GPUSXM3 (692-2G520-0280-501)")
@@ -21,3 +25,40 @@ func TestExtractFirmwareComponentAndModel_GPUFallbackWithoutParentheses(t *testi
t.Fatalf("expected GPU model 692-2G520-0280-501, got %q", model)
}
}
func TestBuildFirmwareEntries_IncludesGPUFirmwareFallback(t *testing.T) {
hw := &models.HardwareConfig{
Firmware: []models.FirmwareInfo{
{DeviceName: "BIOS", Version: "1.0.0"},
},
GPUs: []models.GPU{
{
Slot: "#CPU0_PCIE2",
Model: "GH100 [H200 NVL]",
PartNumber: "699-2G530-0200-501",
Firmware: "96.00.B7.00.02",
},
{
Slot: "#CPU0_PCIE1",
Model: "GH100 [H200 NVL]",
PartNumber: "699-2G530-0200-501",
Firmware: "96.00.B7.00.02",
},
},
}
entries := buildFirmwareEntries(hw)
if len(entries) != 2 {
t.Fatalf("expected 2 deduplicated firmware entries, got %d", len(entries))
}
var hasGPU bool
for _, e := range entries {
if e.Component == "GPU" && e.Version == "96.00.B7.00.02" {
hasGPU = true
}
}
if !hasGPU {
t.Fatalf("expected GPU firmware entry from hardware.gpus fallback")
}
}

View File

@@ -0,0 +1,20 @@
package server
import (
"testing"
"git.mchus.pro/mchus/logpile/internal/models"
)
func TestNormalizePCIeSerialComponentName_PrefersPartOverGenericClass(t *testing.T) {
got := normalizePCIeSerialComponentName(models.PCIeDevice{DeviceClass:"Display Controller", PartNumber:"GH100 [H200 NVL]"})
if got != "GH100 [H200 NVL]" {
t.Fatalf("expected part number, got %q", got)
}
}
func TestNormalizePCIeSerialComponentName_UsesClassWhenSpecific(t *testing.T) {
got := normalizePCIeSerialComponentName(models.PCIeDevice{DeviceClass:"I350 Gigabit Network Connection", PartNumber:"I350T4V2"})
if got != "I350T4V2" {
t.Fatalf("expected part number for readability, got %q", got)
}
}