v0.324.0: the database password comes back with the data (R-1106, R-127b, R-926); restic 0.19.1 (R-1107); R-1108, R-1065, R-1017; dashboard hardening (R-983, R-976)
gates / gates (push) Successful in 44s

This commit is contained in:
2026-10-16 22:46:00 +02:00
parent 00a0d91976
commit f75b3aa778
212 changed files with 2414 additions and 398 deletions
@@ -0,0 +1,51 @@
package stacks
import (
"io"
"log"
"os"
"path/filepath"
"strings"
"testing"
"gitea.dooplex.hu/admin/felhom-controller/internal/config"
)
// R-1106 / R-926: the off-site restore over a REINSTALL writes the backup's database password and nothing else of the
// app's settings, and records the reinstall's generated admin login as NOT the app's login (the restored data carries
// the household's own). Through the production writer.
func TestR1106_SetStackSecretValues(t *testing.T) {
dir := t.TempDir()
cfg := &config.Config{}
cfg.Paths.StacksDir = filepath.Join(dir, "stacks")
cfg.Stacks.ComposeCommand = "docker compose"
app := filepath.Join(cfg.Paths.StacksDir, "bookstack")
must(t, os.MkdirAll(app, 0o755))
must(t, os.WriteFile(filepath.Join(app, "docker-compose.yml"), []byte("services:\n web:\n image: x/y:1\n"), 0o644))
must(t, os.WriteFile(filepath.Join(app, ".felhom.yml"), []byte("display_name: X\ndeploy_fields:\n"+
" - env_var: DB_PASSWORD\n label: DB\n type: secret\n"+
" - env_var: ADMIN_PASSWORD\n label: Admin\n type: password\n"), 0o644))
must(t, os.WriteFile(filepath.Join(app, "app.yaml"), []byte("deployed: true\ndeployed_at: \"2026-10-16T19:00:00Z\"\n"+
"pinned_images:\n web: x/y:1\nenv:\n DB_PASSWORD: reinstall-db\n ADMIN_PASSWORD: reinstall-admin\n SUBDOMAIN: books\n"), 0o600))
m, err := NewManager(cfg, log.New(io.Discard, "", 0))
must(t, err)
must(t, m.ScanStacks())
must(t, m.SetStackSecretValues("bookstack", map[string]string{"DB_PASSWORD": "backup-db"}))
got := LoadAppConfig(app)
if got == nil {
t.Fatal("app.yaml unreadable")
}
if got.Env["DB_PASSWORD"] != "backup-db" {
t.Errorf("DB_PASSWORD = %q, want the backup's", got.Env["DB_PASSWORD"])
}
if got.Env["SUBDOMAIN"] != "books" || got.Env["ADMIN_PASSWORD"] != "reinstall-admin" || got.DeployedAt != "2026-10-16T19:00:00Z" {
t.Errorf("other settings changed: %+v", got)
}
if len(got.PinnedImages) == 0 {
t.Error("the pin was dropped — a non-install writer must load, then save (R-697)")
}
if strings.Join(got.RestoredLogins, ",") != "ADMIN_PASSWORD" {
t.Errorf("restored_logins = %v, want the reinstall's admin login recorded as not the app's (R-926)", got.RestoredLogins)
}
}