v0.314.0: a restore puts the setup gate back as it was (R-1057); a test build moves with the floor (R-1053); Prowlarr links itself (R-1058); the box claims Plex by address (R-1060)
gates / gates (push) Successful in 47s
gates / gates (push) Successful in 47s
MinAgent 0.155.0 (unchanged). Tests red-proved by mutation (A: 10, B: 7, C: 1, C2: 2). Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
This commit is contained in:
@@ -27,6 +27,7 @@ type AppBackupInfo = appbackup.AppBackupInfo
|
||||
type AppDataPath = appbackup.AppDataPath
|
||||
type AppDockerVolume = appbackup.AppDockerVolume
|
||||
type RecoveryInfo = appbackup.RecoveryInfo
|
||||
type GateState = appbackup.GateState
|
||||
type ClassifiedBind = appbackup.ClassifiedBind
|
||||
|
||||
// --- type aliases (dbdump) ---
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
package backup
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"gitea.dooplex.hu/admin/felhom-controller/internal/stacks"
|
||||
)
|
||||
|
||||
// R-1057 (v0.314.0): the unit's app.yaml carries the setup gate as it stood at the backup, in the keys the restore
|
||||
// reads (stacks.ReadGateAtBackup); an app with no gate gets byte-identical bytes to before (the checksum-skip guard).
|
||||
// COMPANION RED-PROOF: drop `SetupGate: info.SetupGate` from buildUnitAppYaml → the read-back says „not known".
|
||||
func TestR1057_TheUnitCarriesTheGateAndTheRestoreReadsIt(t *testing.T) {
|
||||
base := RecoveryInfo{NonSecretEnv: map[string]string{"DOMAIN": "example.hu"}}
|
||||
plain := buildUnitAppYaml(base)
|
||||
if bytes.Contains(plain, []byte("setup_gate")) {
|
||||
t.Fatalf("an app with no gate must not carry a gate record:\n%s", plain)
|
||||
}
|
||||
withNil := base
|
||||
withNil.SetupGate = nil
|
||||
if !bytes.Equal(plain, buildUnitAppYaml(withNil)) {
|
||||
t.Fatal("an ungated app's unit bytes changed")
|
||||
}
|
||||
closed := base
|
||||
closed.SetupGate = &GateState{State: stacks.SetupGateClosed}
|
||||
p := filepath.Join(t.TempDir(), "app.yaml")
|
||||
if err := os.WriteFile(p, buildUnitAppYaml(closed), 0o600); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if got := stacks.ReadGateAtBackup(p); !got.Known || !got.Closed {
|
||||
t.Fatalf("the restore must read the closed gate back from the unit, got %+v", got)
|
||||
}
|
||||
}
|
||||
@@ -503,6 +503,9 @@ func (m *Manager) versionLocked() string {
|
||||
type strippedAppYaml struct {
|
||||
Deployed bool `yaml:"deployed"`
|
||||
Env map[string]string `yaml:"env"`
|
||||
// SetupGate (v0.314.0, R-1057): the gate at this backup; absent for an app with no gate, so an ungated app's
|
||||
// unit bytes are unchanged (the checksum-skip guard).
|
||||
SetupGate *GateState `yaml:"setup_gate,omitempty"`
|
||||
}
|
||||
|
||||
// buildUnitAppYaml renders the unit's app.yaml as bytes: the non-secret env PLUS the portable secret
|
||||
@@ -521,7 +524,7 @@ func buildUnitAppYaml(info RecoveryInfo) []byte {
|
||||
for k, v := range info.PortableSecrets {
|
||||
env[k] = v
|
||||
}
|
||||
body, err := yaml.Marshal(strippedAppYaml{Deployed: true, Env: env})
|
||||
body, err := yaml.Marshal(strippedAppYaml{Deployed: true, Env: env, SetupGate: info.SetupGate})
|
||||
if err != nil {
|
||||
body = []byte("deployed: true\nenv: {}\n")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user