mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-09-10 18:45:53 +00:00
Normalize typed SMART device labels for temp merge
This commit is contained in:
@@ -104,6 +104,26 @@ func TestMergeNVMeTempsIntoDisks(t *testing.T) {
|
||||
{Node: "node1", DevPath: "/dev/sdc", Temperature: 35},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "SMART temperature matched by typed device label",
|
||||
disks: []models.PhysicalDisk{
|
||||
{Node: "node1", DevPath: "/dev/sdd", Temperature: 0},
|
||||
},
|
||||
nodes: []models.Node{
|
||||
{
|
||||
Name: "node1",
|
||||
Temperature: &models.Temperature{
|
||||
Available: true,
|
||||
SMART: []models.DiskTemp{
|
||||
{Device: "sdd [scsi]", Temperature: 39},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: []models.PhysicalDisk{
|
||||
{Node: "node1", DevPath: "/dev/sdd", Temperature: 39},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "NVMe legacy fallback when no SMART match",
|
||||
disks: []models.PhysicalDisk{
|
||||
@@ -331,3 +351,34 @@ func TestMergeNVMeTempsIntoDisks_OriginalSliceUnchanged(t *testing.T) {
|
||||
t.Errorf("original disk temperature was modified: got %d, want 0", original[0].Temperature)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMergeHostAgentSMARTIntoDisks_MatchesTypedDeviceLabel(t *testing.T) {
|
||||
disks := []models.PhysicalDisk{{
|
||||
Node: "node1",
|
||||
Instance: "inst",
|
||||
DevPath: "/dev/sda",
|
||||
Temperature: 0,
|
||||
}}
|
||||
nodes := []models.Node{{
|
||||
Name: "node1",
|
||||
Instance: "inst",
|
||||
LinkedHostAgentID: "host-1",
|
||||
}}
|
||||
hosts := []models.Host{{
|
||||
ID: "host-1",
|
||||
Sensors: models.HostSensorSummary{
|
||||
SMART: []models.HostDiskSMART{{
|
||||
Device: "/dev/sda [scsi]",
|
||||
Temperature: 41,
|
||||
}},
|
||||
},
|
||||
}}
|
||||
|
||||
merged := mergeHostAgentSMARTIntoDisks(disks, nodes, hosts)
|
||||
if len(merged) != 1 {
|
||||
t.Fatalf("expected 1 merged disk, got %#v", merged)
|
||||
}
|
||||
if merged[0].Temperature != 41 {
|
||||
t.Fatalf("expected SMART temperature 41, got %#v", merged[0])
|
||||
}
|
||||
}
|
||||
|
||||
@@ -162,6 +162,20 @@ func (m *Monitor) getInstanceConfig(instanceName string) *config.PVEInstance {
|
||||
return nil
|
||||
}
|
||||
|
||||
func normalizeSMARTDeviceIdentifier(device string) string {
|
||||
normalized := strings.TrimSpace(device)
|
||||
if normalized == "" {
|
||||
return ""
|
||||
}
|
||||
|
||||
if base, suffix, found := strings.Cut(normalized, " ["); found && strings.HasSuffix(suffix, "]") {
|
||||
normalized = base
|
||||
}
|
||||
|
||||
normalized = strings.TrimSpace(normalized)
|
||||
return strings.TrimPrefix(normalized, "/dev/")
|
||||
}
|
||||
|
||||
func mergeNVMeTempsIntoDisks(disks []models.PhysicalDisk, nodes []models.Node) []models.PhysicalDisk {
|
||||
if len(disks) == 0 || len(nodes) == 0 {
|
||||
return disks
|
||||
@@ -275,10 +289,10 @@ func mergeNVMeTempsIntoDisks(disks []models.PhysicalDisk, nodes []models.Node) [
|
||||
|
||||
// Last resort: match by device path (normalized)
|
||||
if updated[i].Temperature == 0 {
|
||||
normalizedDevPath := strings.TrimPrefix(updated[i].DevPath, "/dev/")
|
||||
normalizedDevPath := normalizeSMARTDeviceIdentifier(updated[i].DevPath)
|
||||
for _, temp := range smartTemps {
|
||||
normalizedTempDev := strings.TrimPrefix(temp.Device, "/dev/")
|
||||
if normalizedTempDev == normalizedDevPath {
|
||||
normalizedTempDev := normalizeSMARTDeviceIdentifier(temp.Device)
|
||||
if normalizedTempDev != "" && normalizedTempDev == normalizedDevPath {
|
||||
if temp.Temperature > 0 && !temp.StandbySkipped {
|
||||
updated[i].Temperature = temp.Temperature
|
||||
log.Debug().
|
||||
@@ -401,10 +415,10 @@ func mergeHostAgentSMARTIntoDisks(disks []models.PhysicalDisk, nodes []models.No
|
||||
|
||||
// Last resort: match by device path
|
||||
if matched == nil {
|
||||
normalizedDevPath := strings.TrimPrefix(updated[i].DevPath, "/dev/")
|
||||
normalizedDevPath := normalizeSMARTDeviceIdentifier(updated[i].DevPath)
|
||||
for j := range smartData {
|
||||
normalizedDiskDev := strings.TrimPrefix(smartData[j].Device, "/dev/")
|
||||
if normalizedDiskDev == normalizedDevPath {
|
||||
normalizedDiskDev := normalizeSMARTDeviceIdentifier(smartData[j].Device)
|
||||
if normalizedDiskDev != "" && normalizedDiskDev == normalizedDevPath {
|
||||
matched = &smartData[j]
|
||||
break
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user