Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
63ed8a384e |
2
bible
2
bible
Submodule bible updated: 52444350c1...d2600f1279
Submodule internal/chart updated: 2fb01d30a6...2a15bc87f1
@@ -159,6 +159,16 @@ func buildDevicesFromLegacy(hw *models.HardwareConfig) []models.HardwareDevice {
|
|||||||
}
|
}
|
||||||
for _, stor := range hw.Storage {
|
for _, stor := range hw.Storage {
|
||||||
present := stor.Present
|
present := stor.Present
|
||||||
|
storDetails := mergeDetailMaps(nil, stor.Details)
|
||||||
|
if stor.LogicalBlockSizeBytes != 0 {
|
||||||
|
storDetails = mergeDetailMaps(storDetails, map[string]any{"logical_block_size_bytes": stor.LogicalBlockSizeBytes})
|
||||||
|
}
|
||||||
|
if stor.PhysicalBlockSizeBytes != 0 {
|
||||||
|
storDetails = mergeDetailMaps(storDetails, map[string]any{"physical_block_size_bytes": stor.PhysicalBlockSizeBytes})
|
||||||
|
}
|
||||||
|
if stor.MetadataBytesPerBlock != 0 {
|
||||||
|
storDetails = mergeDetailMaps(storDetails, map[string]any{"metadata_bytes_per_block": stor.MetadataBytesPerBlock})
|
||||||
|
}
|
||||||
appendDevice(models.HardwareDevice{
|
appendDevice(models.HardwareDevice{
|
||||||
Kind: models.DeviceKindStorage,
|
Kind: models.DeviceKindStorage,
|
||||||
Slot: stor.Slot,
|
Slot: stor.Slot,
|
||||||
@@ -177,27 +187,38 @@ func buildDevicesFromLegacy(hw *models.HardwareConfig) []models.HardwareDevice {
|
|||||||
StatusAtCollect: stor.StatusAtCollect,
|
StatusAtCollect: stor.StatusAtCollect,
|
||||||
StatusHistory: stor.StatusHistory,
|
StatusHistory: stor.StatusHistory,
|
||||||
ErrorDescription: stor.ErrorDescription,
|
ErrorDescription: stor.ErrorDescription,
|
||||||
Details: mergeDetailMaps(nil, stor.Details),
|
Details: storDetails,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
for _, pcie := range hw.PCIeDevices {
|
for _, pcie := range hw.PCIeDevices {
|
||||||
// Use PartNumber as model when available; fall back to chip description.
|
// Priority: PartNumber (vendor P/N) > Model (product name) > Description (chip label).
|
||||||
// Description contains the chip/product name (e.g. "BCM57414 NetXtreme-E …")
|
pcieModel := firstNonEmptyString(pcie.PartNumber, pcie.Model, pcie.Description)
|
||||||
// while PartNumber is a part/product code. Prefer PartNumber when set.
|
|
||||||
pcieModel := pcie.PartNumber
|
|
||||||
if pcieModel == "" {
|
|
||||||
pcieModel = pcie.Description
|
|
||||||
}
|
|
||||||
details := mergeDetailMaps(nil, pcie.Details)
|
details := mergeDetailMaps(nil, pcie.Details)
|
||||||
pcieFirmware := stringFromDetailMap(details, "firmware")
|
// Firmware: prefer direct field, fall back to details, then NVSwitch lookup.
|
||||||
|
pcieFirmware := firstNonEmptyString(pcie.Firmware, stringFromDetailMap(details, "firmware"))
|
||||||
if pcieFirmware == "" && isNVSwitchPCIeDevice(pcie) {
|
if pcieFirmware == "" && isNVSwitchPCIeDevice(pcie) {
|
||||||
pcieFirmware = nvswitchFirmwareBySlot[normalizeNVSwitchSlotForLookup(pcie.Slot)]
|
pcieFirmware = nvswitchFirmwareBySlot[normalizeNVSwitchSlotForLookup(pcie.Slot)]
|
||||||
if pcieFirmware != "" {
|
|
||||||
details = mergeDetailMaps(details, map[string]any{
|
|
||||||
"firmware": pcieFirmware,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if pcieFirmware != "" {
|
||||||
|
details = mergeDetailMaps(details, map[string]any{"firmware": pcieFirmware})
|
||||||
|
}
|
||||||
|
// Telemetry fields: put into details so convertPCIeFromDevices can pick them up.
|
||||||
|
if pcie.TemperatureC != nil {
|
||||||
|
details = mergeDetailMaps(details, map[string]any{"temperature_c": *pcie.TemperatureC})
|
||||||
|
}
|
||||||
|
if pcie.PowerW != nil {
|
||||||
|
details = mergeDetailMaps(details, map[string]any{"power_w": *pcie.PowerW})
|
||||||
|
}
|
||||||
|
if pcie.ECCCorrectedTotal != nil {
|
||||||
|
details = mergeDetailMaps(details, map[string]any{"ecc_corrected_total": *pcie.ECCCorrectedTotal})
|
||||||
|
}
|
||||||
|
if pcie.ECCUncorrectedTotal != nil {
|
||||||
|
details = mergeDetailMaps(details, map[string]any{"ecc_uncorrected_total": *pcie.ECCUncorrectedTotal})
|
||||||
|
}
|
||||||
|
if pcie.HWSlowdown != nil {
|
||||||
|
details = mergeDetailMaps(details, map[string]any{"hw_slowdown": *pcie.HWSlowdown})
|
||||||
|
}
|
||||||
|
present := pcie.Present
|
||||||
appendDevice(models.HardwareDevice{
|
appendDevice(models.HardwareDevice{
|
||||||
Kind: models.DeviceKindPCIe,
|
Kind: models.DeviceKindPCIe,
|
||||||
Slot: pcie.Slot,
|
Slot: pcie.Slot,
|
||||||
@@ -209,11 +230,13 @@ func buildDevicesFromLegacy(hw *models.HardwareConfig) []models.HardwareDevice {
|
|||||||
PartNumber: pcie.PartNumber,
|
PartNumber: pcie.PartNumber,
|
||||||
Manufacturer: pcie.Manufacturer,
|
Manufacturer: pcie.Manufacturer,
|
||||||
SerialNumber: pcie.SerialNumber,
|
SerialNumber: pcie.SerialNumber,
|
||||||
|
MACAddresses: append([]string(nil), pcie.MACAddresses...),
|
||||||
LinkWidth: pcie.LinkWidth,
|
LinkWidth: pcie.LinkWidth,
|
||||||
LinkSpeed: pcie.LinkSpeed,
|
LinkSpeed: pcie.LinkSpeed,
|
||||||
MaxLinkWidth: pcie.MaxLinkWidth,
|
MaxLinkWidth: pcie.MaxLinkWidth,
|
||||||
MaxLinkSpeed: pcie.MaxLinkSpeed,
|
MaxLinkSpeed: pcie.MaxLinkSpeed,
|
||||||
NUMANode: pcie.NUMANode,
|
NUMANode: pcie.NUMANode,
|
||||||
|
Present: present,
|
||||||
Status: pcie.Status,
|
Status: pcie.Status,
|
||||||
StatusCheckedAt: pcie.StatusCheckedAt,
|
StatusCheckedAt: pcie.StatusCheckedAt,
|
||||||
StatusChangedAt: pcie.StatusChangedAt,
|
StatusChangedAt: pcie.StatusChangedAt,
|
||||||
@@ -738,36 +761,39 @@ func convertStorageFromDevices(devices []models.HardwareDevice, collectedAt stri
|
|||||||
meta := buildStatusMeta(status, d.StatusCheckedAt, d.StatusChangedAt, d.StatusHistory, d.ErrorDescription, collectedAt)
|
meta := buildStatusMeta(status, d.StatusCheckedAt, d.StatusChangedAt, d.StatusHistory, d.ErrorDescription, collectedAt)
|
||||||
presentValue := present
|
presentValue := present
|
||||||
result = append(result, ReanimatorStorage{
|
result = append(result, ReanimatorStorage{
|
||||||
Slot: d.Slot,
|
Slot: d.Slot,
|
||||||
Type: d.Type,
|
Type: d.Type,
|
||||||
Model: d.Model,
|
Model: d.Model,
|
||||||
SizeGB: d.SizeGB,
|
SizeGB: d.SizeGB,
|
||||||
SerialNumber: d.SerialNumber,
|
SerialNumber: d.SerialNumber,
|
||||||
Manufacturer: d.Manufacturer,
|
Manufacturer: d.Manufacturer,
|
||||||
Firmware: d.Firmware,
|
Firmware: d.Firmware,
|
||||||
Interface: d.Interface,
|
Interface: d.Interface,
|
||||||
Present: &presentValue,
|
Present: &presentValue,
|
||||||
TemperatureC: floatFromDetailMap(d.Details, "temperature_c"),
|
LogicalBlockSizeBytes: int64FromDetailMap(d.Details, "logical_block_size_bytes"),
|
||||||
PowerOnHours: int64FromDetailMap(d.Details, "power_on_hours"),
|
PhysicalBlockSizeBytes: int64FromDetailMap(d.Details, "physical_block_size_bytes"),
|
||||||
PowerCycles: int64FromDetailMap(d.Details, "power_cycles"),
|
MetadataBytesPerBlock: int64FromDetailMap(d.Details, "metadata_bytes_per_block"),
|
||||||
UnsafeShutdowns: int64FromDetailMap(d.Details, "unsafe_shutdowns"),
|
TemperatureC: floatFromDetailMap(d.Details, "temperature_c"),
|
||||||
MediaErrors: int64FromDetailMap(d.Details, "media_errors"),
|
PowerOnHours: int64FromDetailMap(d.Details, "power_on_hours"),
|
||||||
ErrorLogEntries: int64FromDetailMap(d.Details, "error_log_entries"),
|
PowerCycles: int64FromDetailMap(d.Details, "power_cycles"),
|
||||||
WrittenBytes: int64FromDetailMap(d.Details, "written_bytes"),
|
UnsafeShutdowns: int64FromDetailMap(d.Details, "unsafe_shutdowns"),
|
||||||
ReadBytes: int64FromDetailMap(d.Details, "read_bytes"),
|
MediaErrors: int64FromDetailMap(d.Details, "media_errors"),
|
||||||
LifeUsedPct: floatFromDetailMap(d.Details, "life_used_pct"),
|
ErrorLogEntries: int64FromDetailMap(d.Details, "error_log_entries"),
|
||||||
RemainingEndurancePct: d.RemainingEndurancePct,
|
WrittenBytes: int64FromDetailMap(d.Details, "written_bytes"),
|
||||||
LifeRemainingPct: floatFromDetailMap(d.Details, "life_remaining_pct"),
|
ReadBytes: int64FromDetailMap(d.Details, "read_bytes"),
|
||||||
AvailableSparePct: floatFromDetailMap(d.Details, "available_spare_pct"),
|
LifeUsedPct: floatFromDetailMap(d.Details, "life_used_pct"),
|
||||||
ReallocatedSectors: int64FromDetailMap(d.Details, "reallocated_sectors"),
|
RemainingEndurancePct: d.RemainingEndurancePct,
|
||||||
CurrentPendingSectors: int64FromDetailMap(d.Details, "current_pending_sectors"),
|
LifeRemainingPct: floatFromDetailMap(d.Details, "life_remaining_pct"),
|
||||||
OfflineUncorrectable: int64FromDetailMap(d.Details, "offline_uncorrectable"),
|
AvailableSparePct: floatFromDetailMap(d.Details, "available_spare_pct"),
|
||||||
Status: status,
|
ReallocatedSectors: int64FromDetailMap(d.Details, "reallocated_sectors"),
|
||||||
StatusCheckedAt: meta.StatusCheckedAt,
|
CurrentPendingSectors: int64FromDetailMap(d.Details, "current_pending_sectors"),
|
||||||
StatusChangedAt: meta.StatusChangedAt,
|
OfflineUncorrectable: int64FromDetailMap(d.Details, "offline_uncorrectable"),
|
||||||
ManufacturedYearWeek: manufacturedYearWeekFromDetails(d.Details),
|
Status: status,
|
||||||
StatusHistory: meta.StatusHistory,
|
StatusCheckedAt: meta.StatusCheckedAt,
|
||||||
ErrorDescription: meta.ErrorDescription,
|
StatusChangedAt: meta.StatusChangedAt,
|
||||||
|
ManufacturedYearWeek: manufacturedYearWeekFromDetails(d.Details),
|
||||||
|
StatusHistory: meta.StatusHistory,
|
||||||
|
ErrorDescription: meta.ErrorDescription,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
|
|||||||
@@ -12,15 +12,16 @@ type ReanimatorExport struct {
|
|||||||
|
|
||||||
// ReanimatorHardware contains all hardware components
|
// ReanimatorHardware contains all hardware components
|
||||||
type ReanimatorHardware struct {
|
type ReanimatorHardware struct {
|
||||||
Board ReanimatorBoard `json:"board"`
|
Board ReanimatorBoard `json:"board"`
|
||||||
Firmware []ReanimatorFirmware `json:"firmware,omitempty"`
|
Firmware []ReanimatorFirmware `json:"firmware,omitempty"`
|
||||||
CPUs []ReanimatorCPU `json:"cpus,omitempty"`
|
CPUs []ReanimatorCPU `json:"cpus,omitempty"`
|
||||||
Memory []ReanimatorMemory `json:"memory,omitempty"`
|
Memory []ReanimatorMemory `json:"memory,omitempty"`
|
||||||
Storage []ReanimatorStorage `json:"storage,omitempty"`
|
Storage []ReanimatorStorage `json:"storage,omitempty"`
|
||||||
PCIeDevices []ReanimatorPCIe `json:"pcie_devices,omitempty"`
|
PCIeDevices []ReanimatorPCIe `json:"pcie_devices,omitempty"`
|
||||||
PowerSupplies []ReanimatorPSU `json:"power_supplies,omitempty"`
|
PowerSupplies []ReanimatorPSU `json:"power_supplies,omitempty"`
|
||||||
Sensors *ReanimatorSensors `json:"sensors,omitempty"`
|
Sensors *ReanimatorSensors `json:"sensors,omitempty"`
|
||||||
EventLogs []ReanimatorEventLog `json:"event_logs,omitempty"`
|
EventLogs []ReanimatorEventLog `json:"event_logs,omitempty"`
|
||||||
|
PlatformConfig map[string]any `json:"platform_config,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReanimatorBoard represents motherboard/server information
|
// ReanimatorBoard represents motherboard/server information
|
||||||
@@ -101,17 +102,20 @@ type ReanimatorMemory struct {
|
|||||||
|
|
||||||
// ReanimatorStorage represents a storage device
|
// ReanimatorStorage represents a storage device
|
||||||
type ReanimatorStorage struct {
|
type ReanimatorStorage struct {
|
||||||
Slot string `json:"slot"`
|
Slot string `json:"slot"`
|
||||||
Type string `json:"type,omitempty"`
|
Type string `json:"type,omitempty"`
|
||||||
Model string `json:"model"`
|
Model string `json:"model"`
|
||||||
SizeGB int `json:"size_gb,omitempty"`
|
SizeGB int `json:"size_gb,omitempty"`
|
||||||
SerialNumber string `json:"serial_number"`
|
SerialNumber string `json:"serial_number"`
|
||||||
Manufacturer string `json:"manufacturer,omitempty"`
|
Manufacturer string `json:"manufacturer,omitempty"`
|
||||||
Firmware string `json:"firmware,omitempty"`
|
Firmware string `json:"firmware,omitempty"`
|
||||||
Interface string `json:"interface,omitempty"`
|
Interface string `json:"interface,omitempty"`
|
||||||
Present *bool `json:"present,omitempty"`
|
Present *bool `json:"present,omitempty"`
|
||||||
TemperatureC float64 `json:"temperature_c,omitempty"`
|
LogicalBlockSizeBytes int64 `json:"logical_block_size_bytes,omitempty"`
|
||||||
PowerOnHours int64 `json:"power_on_hours,omitempty"`
|
PhysicalBlockSizeBytes int64 `json:"physical_block_size_bytes,omitempty"`
|
||||||
|
MetadataBytesPerBlock int64 `json:"metadata_bytes_per_block,omitempty"`
|
||||||
|
TemperatureC float64 `json:"temperature_c,omitempty"`
|
||||||
|
PowerOnHours int64 `json:"power_on_hours,omitempty"`
|
||||||
PowerCycles int64 `json:"power_cycles,omitempty"`
|
PowerCycles int64 `json:"power_cycles,omitempty"`
|
||||||
UnsafeShutdowns int64 `json:"unsafe_shutdowns,omitempty"`
|
UnsafeShutdowns int64 `json:"unsafe_shutdowns,omitempty"`
|
||||||
MediaErrors int64 `json:"media_errors,omitempty"`
|
MediaErrors int64 `json:"media_errors,omitempty"`
|
||||||
|
|||||||
@@ -245,6 +245,9 @@ type Storage struct {
|
|||||||
Location string `json:"location,omitempty"` // Front/Rear
|
Location string `json:"location,omitempty"` // Front/Rear
|
||||||
BackplaneID int `json:"backplane_id,omitempty"`
|
BackplaneID int `json:"backplane_id,omitempty"`
|
||||||
RemainingEndurancePct *int `json:"remaining_endurance_pct,omitempty"` // 0-100 %; nil = not reported
|
RemainingEndurancePct *int `json:"remaining_endurance_pct,omitempty"` // 0-100 %; nil = not reported
|
||||||
|
LogicalBlockSizeBytes int64 `json:"logical_block_size_bytes,omitempty"`
|
||||||
|
PhysicalBlockSizeBytes int64 `json:"physical_block_size_bytes,omitempty"`
|
||||||
|
MetadataBytesPerBlock int64 `json:"metadata_bytes_per_block,omitempty"`
|
||||||
Status string `json:"status,omitempty"`
|
Status string `json:"status,omitempty"`
|
||||||
Details map[string]any `json:"details,omitempty"`
|
Details map[string]any `json:"details,omitempty"`
|
||||||
|
|
||||||
@@ -277,6 +280,8 @@ type PCIeDevice struct {
|
|||||||
BDF string `json:"bdf"`
|
BDF string `json:"bdf"`
|
||||||
DeviceClass string `json:"device_class"`
|
DeviceClass string `json:"device_class"`
|
||||||
Manufacturer string `json:"manufacturer,omitempty"`
|
Manufacturer string `json:"manufacturer,omitempty"`
|
||||||
|
Model string `json:"model,omitempty"`
|
||||||
|
Firmware string `json:"firmware,omitempty"`
|
||||||
LinkWidth int `json:"link_width"`
|
LinkWidth int `json:"link_width"`
|
||||||
LinkSpeed string `json:"link_speed"`
|
LinkSpeed string `json:"link_speed"`
|
||||||
MaxLinkWidth int `json:"max_link_width"`
|
MaxLinkWidth int `json:"max_link_width"`
|
||||||
@@ -285,8 +290,17 @@ type PCIeDevice struct {
|
|||||||
SerialNumber string `json:"serial_number,omitempty"`
|
SerialNumber string `json:"serial_number,omitempty"`
|
||||||
MACAddresses []string `json:"mac_addresses,omitempty"`
|
MACAddresses []string `json:"mac_addresses,omitempty"`
|
||||||
NUMANode int `json:"numa_node,omitempty"` // 0 = not reported/N/A
|
NUMANode int `json:"numa_node,omitempty"` // 0 = not reported/N/A
|
||||||
|
Present *bool `json:"present,omitempty"`
|
||||||
|
IOMMUGroup *int `json:"iommu_group,omitempty"`
|
||||||
Status string `json:"status,omitempty"`
|
Status string `json:"status,omitempty"`
|
||||||
|
|
||||||
|
// GPU telemetry fields (populated by bee audit for GPU devices)
|
||||||
|
TemperatureC *float64 `json:"temperature_c,omitempty"`
|
||||||
|
PowerW *float64 `json:"power_w,omitempty"`
|
||||||
|
ECCCorrectedTotal *int64 `json:"ecc_corrected_total,omitempty"`
|
||||||
|
ECCUncorrectedTotal *int64 `json:"ecc_uncorrected_total,omitempty"`
|
||||||
|
HWSlowdown *bool `json:"hw_slowdown,omitempty"`
|
||||||
|
|
||||||
StatusCheckedAt *time.Time `json:"status_checked_at,omitempty"`
|
StatusCheckedAt *time.Time `json:"status_checked_at,omitempty"`
|
||||||
StatusChangedAt *time.Time `json:"status_changed_at,omitempty"`
|
StatusChangedAt *time.Time `json:"status_changed_at,omitempty"`
|
||||||
StatusAtCollect *StatusAtCollection `json:"status_at_collection,omitempty"`
|
StatusAtCollect *StatusAtCollection `json:"status_at_collection,omitempty"`
|
||||||
|
|||||||
Reference in New Issue
Block a user