feat: storage watchdog — USB disconnect detection, auto-stop, safe eject, auto-reconnect (v0.17.0)

New storage watchdog monitors registered storage paths every 5s. On disconnect
(3 consecutive probe failures), auto-stops affected apps, lazy-unmounts stale
VFS entries, fires alerts/notifications/hub report. On reconnect (UUID detected),
auto-remounts via fstab, cleans stale restic locks, offers app restart.

Safe disconnect UI for USB drives: confirmation dialog, stop apps, sync, unmount.
Disconnected state visible across all pages (dashboard, settings, backups, monitoring)
with hatched red bars and badges. Backup guards skip disconnected drives.

22 files changed (1 new: monitor/watchdog.go), ~1500 lines added.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-19 19:42:26 +01:00
parent 276be5a88e
commit bdbe170a54
22 changed files with 1537 additions and 57 deletions
@@ -80,3 +80,30 @@ func CheckBackupDestination(path string) DestinationHealth {
Severity: "ok",
}
}
// ProbeStatus represents the result of a storage path probe.
type ProbeStatus int
const (
ProbeConnected ProbeStatus = iota
ProbeDisconnected
ProbeTimeout
)
// ProbeResult holds the outcome of a storage path probe.
type ProbeResult struct {
Status ProbeStatus
Err error
}
// ProbeStoragePath always returns connected on non-Linux.
func ProbeStoragePath(_ string) ProbeResult { return ProbeResult{Status: ProbeConnected} }
// IsUSBDevice always returns false on non-Linux.
func IsUSBDevice(_ string) bool { return false }
// ParseFstabUUID always returns empty on non-Linux.
func ParseFstabUUID(_, _ string) string { return "" }
// HasFelhomRawMount always returns false on non-Linux.
func HasFelhomRawMount(_, _ string) (string, bool) { return "", false }