Files
deploy-felhom-compose/controller/internal/web/funcmap.go
T
admin d32d9fb44b v0.4.0: monitoring & backup — scheduler, CPU/temp metrics, healthchecks, restic backups
Phase 2 (Monitoring & Health):
- Central job scheduler replacing ad-hoc goroutines (internal/scheduler)
- CPU usage collector via /proc/stat background sampling (internal/system/cpu_linux.go)
- Temperature reading from /sys/class/thermal + /host/sys (Docker mount)
- Load average from /proc/loadavg
- Healthchecks.io-compatible HTTP pinger (internal/monitor/pinger.go)
- System health checks: disk, memory, CPU, temp, Docker, protected containers (internal/monitor/healthcheck.go)

Phase 3 (Backups):
- Database auto-discovery via docker ps + docker inspect (internal/backup/dbdump.go)
- Database dumping via docker exec (pg_dump / mariadb-dump) with atomic writes
- Restic backup integration with auto-password generation (internal/backup/restic.go)
- Backup orchestrator: DB dumps + restic snapshots + weekly prune (internal/backup/backup.go)
- Manual backup trigger via dashboard button and POST /api/backup/run

Dashboard UI:
- CPU usage bar with load average display
- Temperature with colored indicator dot
- Backup status card with last run time, DB count, repo stats
- "Mentés most" button for manual backup trigger

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 11:17:10 +01:00

149 lines
3.5 KiB
Go

package web
import (
"fmt"
"html/template"
"gitea.dooplex.hu/admin/felhom-controller/internal/stacks"
)
// templateFuncMap returns the FuncMap used by all HTML templates.
func (s *Server) templateFuncMap() template.FuncMap {
return template.FuncMap{
"stateColor": func(state stacks.ContainerState) string {
switch state {
case stacks.StateRunning:
return "green"
case stacks.StateStarting:
return "orange"
case stacks.StateUnhealthy:
return "yellow"
case stacks.StateStopped, stacks.StateExited:
return "red"
case stacks.StateRestarting:
return "yellow"
default:
return "gray"
}
},
"stateLabel": func(state stacks.ContainerState) string {
switch state {
case stacks.StateRunning:
return "Fut"
case stacks.StateStarting:
return "Indulás..."
case stacks.StateUnhealthy:
return "Nem egészséges"
case stacks.StateStopped, stacks.StateExited:
return "Leállítva"
case stacks.StateRestarting:
return "Újraindítás..."
case stacks.StateNotDeployed:
return "Nincs telepítve"
case stacks.StatePaused:
return "Szüneteltetve"
default:
return "Ismeretlen"
}
},
"stateIcon": func(state stacks.ContainerState) string {
switch state {
case stacks.StateRunning:
return "●"
case stacks.StateStarting:
return "◐"
case stacks.StateUnhealthy:
return "◑"
case stacks.StateStopped, stacks.StateExited:
return "○"
case stacks.StateRestarting:
return "◐"
default:
return "◌"
}
},
"stateStr": func(state stacks.ContainerState) string {
return string(state)
},
// isOperational returns true for any state where the stack has containers
// and is not stopped/exited — used by templates for showing action buttons
"isOperational": func(state stacks.ContainerState) bool {
switch state {
case stacks.StateRunning, stacks.StateStarting, stacks.StateUnhealthy, stacks.StateRestarting:
return true
default:
return false
}
},
"logoURL": func(slug string) string {
return s.cfg.AppLogoURL(slug)
},
"logoPNGURL": func(slug string) string {
return s.cfg.AppLogoPNGURL(slug)
},
"appPageURL": func(slug string) string {
return s.cfg.AppPageURL(slug)
},
"usageColor": func(percent float64) string {
if percent >= 85 {
return "red"
}
if percent >= 70 {
return "yellow"
}
return "green"
},
"fmtMB": func(mb uint64) string {
if mb >= 1024 {
gb := float64(mb) / 1024.0
if gb >= 10 {
return fmt.Sprintf("%.0f GB", gb)
}
return fmt.Sprintf("%.1f GB", gb)
}
return fmt.Sprintf("%d MB", mb)
},
"fmtGB": func(gb float64) string {
if gb >= 100 {
return fmt.Sprintf("%.0f GB", gb)
}
if gb >= 10 {
return fmt.Sprintf("%.1f GB", gb)
}
return fmt.Sprintf("%.2f GB", gb)
},
"subtract": func(a, b int) int {
r := a - b
if r < 0 {
return 0
}
return r
},
"screenshotURL": func(slug string, index int) string {
return s.cfg.AppScreenshotURL(slug, index)
},
"seq": func(n int) []int {
result := make([]int, n)
for i := range result {
result[i] = i + 1
}
return result
},
"tempColor": func(celsius float64) string {
if celsius > 75 {
return "red"
}
if celsius >= 60 {
return "yellow"
}
return "green"
},
"fmtTemp": func(celsius float64) string {
return fmt.Sprintf("%.0f°C", celsius)
},
"fmtLoad": func(load float64) string {
return fmt.Sprintf("%.2f", load)
},
}
}