Files
deploy-felhom-compose/controller/internal/system/mounts_other.go
T
admin bdbe170a54 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>
2026-02-19 19:42:26 +01:00

110 lines
2.6 KiB
Go

//go:build !linux
package system
import (
"os"
"path/filepath"
"strings"
)
// IsMountPoint always returns true on non-Linux (assume OK for dev/testing).
func IsMountPoint(_ string) bool { return true }
// IsWritable checks if the given path is writable by attempting to create+remove a temp file.
func IsWritable(path string) bool {
testFile := filepath.Join(path, ".felhom-write-test")
f, err := os.Create(testFile)
if err != nil {
return false
}
f.Close()
os.Remove(testFile)
return true
}
// PathsOverlap returns true if one path is a parent or child of the other.
func PathsOverlap(a, b string) bool {
a = filepath.Clean(a)
b = filepath.Clean(b)
if a == b {
return true
}
aSep := a + string(os.PathSeparator)
bSep := b + string(os.PathSeparator)
return strings.HasPrefix(aSep, bSep) || strings.HasPrefix(bSep, aSep)
}
// DiskUsageInfo holds disk usage statistics for a path.
type DiskUsageInfo struct {
TotalGB float64
UsedGB float64
AvailGB float64
UsedPercent float64
TotalHuman string
UsedHuman string
}
// GetDiskUsage returns nil on non-Linux.
func GetDiskUsage(_ string) *DiskUsageInfo { return nil }
// FSInfo holds filesystem type, device, and disk model info.
type FSInfo struct {
FSType string
Device string
Model string
}
// GetFSInfo returns nil on non-Linux.
func GetFSInfo(_ string) *FSInfo { return nil }
// DestinationHealth holds the result of a tiered backup destination check.
type DestinationHealth struct {
Exists bool
Writable bool
MountPoint bool
SystemDrive bool
UsedPercent float64
FreeGB float64
Warning string
Blocked bool
Severity string
}
// CheckBackupDestination always returns ok on non-Linux (assume healthy for dev/testing).
func CheckBackupDestination(path string) DestinationHealth {
return DestinationHealth{
Exists: true,
Writable: true,
MountPoint: true,
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 }