feat: backup safety — stop-before-dump, streaming restore, health check, per-app restic, infra configs (v0.34.0)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -5,6 +5,7 @@ import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"gitea.dooplex.hu/admin/felhom-controller/internal/backup"
|
||||
@@ -30,11 +31,18 @@ type InfraBackup struct {
|
||||
}
|
||||
|
||||
// InfraStack identifies a deployed app for disaster recovery.
|
||||
// Note: AppYamlB64 contains encrypted secrets (ENC:... values).
|
||||
// The encryption key is also in this backup (EncryptionKeyB64).
|
||||
// This is intentional — the infra backup must be self-contained for DR.
|
||||
// Physical security of the backup media protects both.
|
||||
type InfraStack struct {
|
||||
Name string `json:"name"`
|
||||
DisplayName string `json:"display_name"`
|
||||
HDDPath string `json:"hdd_path,omitempty"`
|
||||
NeedsHDD bool `json:"needs_hdd"`
|
||||
Name string `json:"name"`
|
||||
DisplayName string `json:"display_name"`
|
||||
HDDPath string `json:"hdd_path,omitempty"`
|
||||
NeedsHDD bool `json:"needs_hdd"`
|
||||
DockerComposeB64 string `json:"docker_compose_b64,omitempty"`
|
||||
AppYamlB64 string `json:"app_yaml_b64,omitempty"`
|
||||
FelhomYamlB64 string `json:"felhom_yaml_b64,omitempty"`
|
||||
}
|
||||
|
||||
// BuildInfraBackup collects all infrastructure state for Hub backup.
|
||||
@@ -89,15 +97,28 @@ func BuildInfraBackup(
|
||||
// Collect disk layout from fstab + blkid
|
||||
ib.DiskLayout = collectDiskLayout(systemDataPath)
|
||||
|
||||
// Collect deployed stacks
|
||||
// Collect deployed stacks (including actual config files for DR)
|
||||
deployed := stackProvider.ListDeployedStacks()
|
||||
for _, s := range deployed {
|
||||
ib.DeployedStacks = append(ib.DeployedStacks, InfraStack{
|
||||
is := InfraStack{
|
||||
Name: s.Name,
|
||||
DisplayName: s.DisplayName,
|
||||
HDDPath: stackProvider.GetStackHDDPath(s.Name),
|
||||
NeedsHDD: s.NeedsHDD,
|
||||
})
|
||||
}
|
||||
if composePath, ok := stackProvider.GetStackComposePath(s.Name); ok {
|
||||
stackDir := filepath.Dir(composePath)
|
||||
if data, err := os.ReadFile(filepath.Join(stackDir, "docker-compose.yml")); err == nil {
|
||||
is.DockerComposeB64 = base64.StdEncoding.EncodeToString(data)
|
||||
}
|
||||
if data, err := os.ReadFile(filepath.Join(stackDir, "app.yaml")); err == nil {
|
||||
is.AppYamlB64 = base64.StdEncoding.EncodeToString(data)
|
||||
}
|
||||
if data, err := os.ReadFile(filepath.Join(stackDir, ".felhom.yml")); err == nil {
|
||||
is.FelhomYamlB64 = base64.StdEncoding.EncodeToString(data)
|
||||
}
|
||||
}
|
||||
ib.DeployedStacks = append(ib.DeployedStacks, is)
|
||||
}
|
||||
if ib.DeployedStacks == nil {
|
||||
ib.DeployedStacks = []InfraStack{}
|
||||
|
||||
Reference in New Issue
Block a user