v0.9.0: Storage paths registry, per-app HDD_PATH resolution, storage management UI
- Fix backup toggles not appearing (read each app's own HDD_PATH from app.yaml) - Storage paths registry in settings.json with auto-discovery from deployed apps - Settings page "Adattárolók" section with disk usage, add/remove/default/schedulable - Deploy page path field as dropdown of registered storage paths - Health check storage monitoring (mount point, disk usage alerts) - Mount-point validation utilities (Linux syscall + cross-platform stubs) - Controller docker-compose mount changed to /mnt:/mnt:rw for multi-storage Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -2,11 +2,13 @@ package monitor
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"gitea.dooplex.hu/admin/felhom-controller/internal/config"
|
||||
"gitea.dooplex.hu/admin/felhom-controller/internal/settings"
|
||||
"gitea.dooplex.hu/admin/felhom-controller/internal/system"
|
||||
)
|
||||
|
||||
@@ -20,13 +22,17 @@ type HealthReport struct {
|
||||
}
|
||||
|
||||
// RunHealthCheck runs system checks and returns a diagnostic report.
|
||||
func RunHealthCheck(cfg *config.Config, cpuCollector *system.CPUCollector) *HealthReport {
|
||||
func RunHealthCheck(cfg *config.Config, cpuCollector *system.CPUCollector, storagePaths []settings.StoragePath) *HealthReport {
|
||||
report := &HealthReport{
|
||||
Status: "ok",
|
||||
Timestamp: time.Now(),
|
||||
}
|
||||
|
||||
sysInfo := system.GetInfo(cfg.Paths.HDDPath, cpuCollector)
|
||||
hddPath := cfg.Paths.HDDPath
|
||||
if len(storagePaths) > 0 {
|
||||
hddPath = storagePaths[0].Path
|
||||
}
|
||||
sysInfo := system.GetInfo(hddPath, cpuCollector)
|
||||
|
||||
// 1. Disk usage (SSD)
|
||||
if sysInfo.DiskPercent > 0 {
|
||||
@@ -88,6 +94,11 @@ func RunHealthCheck(cfg *config.Config, cpuCollector *system.CPUCollector) *Heal
|
||||
report.Issues = append(report.Issues, fmt.Sprintf("Protected container not running: %s", name))
|
||||
}
|
||||
|
||||
// 7. Storage paths
|
||||
storageIssues, storageWarnings := checkStoragePaths(storagePaths)
|
||||
report.Issues = append(report.Issues, storageIssues...)
|
||||
report.Warnings = append(report.Warnings, storageWarnings...)
|
||||
|
||||
// Determine status
|
||||
if len(report.Issues) > 0 {
|
||||
report.Status = "fail"
|
||||
@@ -158,3 +169,28 @@ func checkProtectedContainers(protected []string) []string {
|
||||
}
|
||||
return missing
|
||||
}
|
||||
|
||||
func checkStoragePaths(paths []settings.StoragePath) (issues, warnings []string) {
|
||||
for _, sp := range paths {
|
||||
// Path accessible?
|
||||
if _, err := os.Stat(sp.Path); err != nil {
|
||||
warnings = append(warnings, fmt.Sprintf("Storage path not accessible: %s", sp.Path))
|
||||
continue
|
||||
}
|
||||
|
||||
// Mount point check
|
||||
if !system.IsMountPoint(sp.Path) {
|
||||
issues = append(issues, fmt.Sprintf("Storage path %s is NOT a mount point — data writes to SSD!", sp.Path))
|
||||
}
|
||||
|
||||
// Disk usage
|
||||
if di := system.GetDiskUsage(sp.Path); di != nil {
|
||||
if di.UsedPercent >= 95 {
|
||||
issues = append(issues, fmt.Sprintf("Storage %s nearly full: %.0f%%", sp.Path, di.UsedPercent))
|
||||
} else if di.UsedPercent >= 90 {
|
||||
warnings = append(warnings, fmt.Sprintf("Storage %s usage high: %.0f%%", sp.Path, di.UsedPercent))
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user