Files
felhom-controller/controller/internal/system/mounts_other.go
T
admin d2071430ea v0.55.0: Phase 3 — auto off-drive Tier 2 (rootfs-headroom guard)
Tier 2 rsync-mirrors each HDD app's recovery unit + appdata to a DIFFERENT physical
disk (the only off-drive protection bind-mounted userdata can get; PBS can't reach it).
Auto-enabled, auto-target: prefer another registered drive (different physical disk via
system.SamePhysicalDevice), else the internal SSD for SMALL units only — with a
size-aware headroom guard that REFUSES rather than fill the ~8G guest rootfs, recording
an honest "needs 2nd HDD" status. Status persisted via the surviving CrossDriveBackup;
"2. mentés" UI card now populated. Daily tier2-backup job + POST /api/backup/tier2.

- backup/tier2.go (engine+selection+headroom), tier2_test.go (headroom arithmetic)
- system.SamePhysicalDevice (linux Stat_t.Dev + stub)
- handlers.go Tier2 UI population + tier2DestLabel; backups.html honest no-target reason
- fixed stale TestBackupCopiesOnPath (old felhom-data layout -> in-guest layout)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-13 13:24:49 +02:00

113 lines
2.8 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 }
// SamePhysicalDevice always returns false on non-Linux (dev/testing only — Tier 2 runs on Linux).
func SamePhysicalDevice(_, _ string) bool { return false }
// 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 }