fix(hub): remove stale smart_devices records when a drive is no longer reported (#2178)

* Fix duplicate /dev/sdg-style entries

* only prune devices after complete refreshes

---------

Co-authored-by: henrygd <hank@henrygd.me>
This commit is contained in:
Sven van Ginkel
2026-08-15 19:40:30 +02:00
committed by GitHub
parent 3337dff64b
commit eb5dd230cf
11 changed files with 273 additions and 34 deletions

View File

@@ -88,15 +88,23 @@ func unmarshalLegacyResponse(resp common.AgentResponse, action common.WebSocketA
*d = *resp.String
return nil
case common.GetSmartData:
d, ok := dest.(*map[string]smart.SmartData)
if !ok {
switch d := dest.(type) {
case *map[string]smart.SmartData:
if resp.SmartData == nil {
return errors.New("no SMART data in response")
}
*d = resp.SmartData
return nil
case *smart.SmartDataResponse:
if resp.SmartData == nil {
return errors.New("no SMART data in response")
}
d.Data = resp.SmartData
d.Complete = resp.SmartComplete
return nil
default:
return fmt.Errorf("unexpected dest type for GetSmartData: %T", dest)
}
if resp.SmartData == nil {
return errors.New("no SMART data in response")
}
*d = resp.SmartData
return nil
case common.GetSystemdInfo:
d, ok := dest.(*systemd.ServiceDetails)
if !ok {

View File

@@ -0,0 +1,33 @@
package transport
import (
"testing"
"github.com/henrygd/beszel/internal/common"
"github.com/henrygd/beszel/internal/entities/smart"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestUnmarshalSmartDataResponse(t *testing.T) {
for _, test := range []struct {
name string
complete bool
}{
{name: "complete response", complete: true},
{name: "older agent defaults to incomplete", complete: false},
} {
t.Run(test.name, func(t *testing.T) {
response := common.AgentResponse{
SmartData: map[string]smart.SmartData{
"AAA": {SerialNumber: "AAA"},
},
SmartComplete: test.complete,
}
var result smart.SmartDataResponse
require.NoError(t, UnmarshalResponse(response, common.GetSmartData, &result))
assert.Equal(t, test.complete, result.Complete)
assert.Equal(t, "AAA", result.Data["AAA"].SerialNumber)
})
}
}