mirror of
https://github.com/henrygd/beszel.git
synced 2026-09-17 05:24:31 +00:00
fix(agent): warn on critical ATA SMART attributes (#2275)
This commit is contained in:
@@ -931,6 +931,9 @@ func (sm *SmartManager) parseSmartForSata(output []byte, deviceType string) (boo
|
||||
if parsed, ok := smart.ParseSmartRawValueString(attr.Raw.String); ok {
|
||||
rawValue = parsed
|
||||
}
|
||||
if smartData.SmartStatus == "PASSED" && rawValue > 0 && (attr.ID == 5 || attr.ID == 197 || attr.ID == 198) {
|
||||
smartData.SmartStatus = "WARNING"
|
||||
}
|
||||
smartAttr := &smart.SmartAttribute{
|
||||
ID: attr.ID,
|
||||
Name: attr.Name,
|
||||
|
||||
@@ -4,8 +4,10 @@ package agent
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"testing"
|
||||
|
||||
"github.com/henrygd/beszel/internal/entities/smart"
|
||||
@@ -88,6 +90,52 @@ func TestParseSmartForSata(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseSmartForSataWarnsForCriticalAttributes(t *testing.T) {
|
||||
for _, attrID := range []int{5, 197, 198} {
|
||||
t.Run("attribute "+strconv.Itoa(attrID), func(t *testing.T) {
|
||||
jsonPayload := []byte(fmt.Sprintf(`{
|
||||
"smartctl": {"exit_status": 0},
|
||||
"device": {"name": "/dev/sda", "type": "sat"},
|
||||
"model_name": "Example",
|
||||
"serial_number": "WARNING%d",
|
||||
"smart_status": {"passed": true},
|
||||
"temperature": {"current": 30},
|
||||
"ata_smart_attributes": {"table": [{"id": %d, "raw": {"value": 1, "string": "1"}}]}
|
||||
}`, attrID, attrID))
|
||||
|
||||
sm := &SmartManager{SmartDataMap: make(map[string]*smart.SmartData)}
|
||||
hasData, _ := sm.parseSmartForSata(jsonPayload, "")
|
||||
require.True(t, hasData)
|
||||
assert.Equal(t, "WARNING", sm.SmartDataMap[fmt.Sprintf("WARNING%d", attrID)].SmartStatus)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseSmartForSataPreservesFailedAndUnknownStatus(t *testing.T) {
|
||||
for _, test := range []struct {
|
||||
name string
|
||||
temperature int
|
||||
want string
|
||||
}{
|
||||
{name: "failed", temperature: 30, want: "FAILED"},
|
||||
{name: "unknown", want: "UNKNOWN"},
|
||||
} {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
jsonPayload := []byte(fmt.Sprintf(`{
|
||||
"device": {"name": "/dev/sda", "type": "sat"},
|
||||
"serial_number": "PRESERVE%s",
|
||||
"temperature": {"current": %d},
|
||||
"ata_smart_attributes": {"table": [{"id": 197, "raw": {"value": 1, "string": "1"}}]}
|
||||
}`, test.name, test.temperature))
|
||||
|
||||
sm := &SmartManager{SmartDataMap: make(map[string]*smart.SmartData)}
|
||||
hasData, _ := sm.parseSmartForSata(jsonPayload, "")
|
||||
require.True(t, hasData)
|
||||
assert.Equal(t, test.want, sm.SmartDataMap["PRESERVE"+test.name].SmartStatus)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseSmartForSataDeviceStatisticsTemperature(t *testing.T) {
|
||||
jsonPayload := []byte(`{
|
||||
"smartctl": {"exit_status": 0},
|
||||
|
||||
Reference in New Issue
Block a user