Stray-copy fix: the capped second-drive copy container never outlives the copy — fixed name + label, removed by name on any error (the timeout included), every leftover removed at start before the scheduler and web server; a restore is refused while a copy runs or may still run; --mount (refuses a path the daemon does not see) and the image ID with --pull never (review); red-proved; unreleased
gates / gates (push) Successful in 1m53s

This commit is contained in:
2026-10-22 20:20:35 +02:00
parent df78b6caae
commit 66a69d4954
9 changed files with 552 additions and 8 deletions
+6
View File
@@ -576,6 +576,12 @@ func main() {
}
if cfg.Backup.Enabled {
backupMgr = backup.NewManager(cfg, sett, logger)
// The stray-copy fix: a second-drive copy container a previous controller process lost (restart, self-update)
// still runs `rsync --delete`. Remove every one BEFORE the scheduler or the web server can start a backup or a
// restore; until that succeeds, restores are refused. Pinned by TestStrayCopy_ClearIsWiredBeforeTheScheduler.
if err := backup.ClearLeftoverTier2Copies(ctx); err != nil {
logger.Printf("[ERROR] [backup] leftover second-drive copy check: %v", err)
}
// R-550: load the persisted restore record BEFORE any page can ask for it.
var putBack []string
if appStopRecovery != nil {
@@ -0,0 +1,27 @@
package main
import (
"os"
"strings"
"testing"
)
// The stray-copy fix: main.go removes every leftover second-drive copy container BEFORE the scheduler and the web
// server start (either could begin a backup or a restore beside a lost copy). RED-PROOF (2026-10-22 night): the call
// removed, or moved below sched.Start, → this fails.
func TestStrayCopy_ClearIsWiredBeforeTheScheduler(t *testing.T) {
src, err := os.ReadFile("main.go")
if err != nil {
t.Fatal(err)
}
s := string(src)
c := strings.Index(s, "backup.ClearLeftoverTier2Copies(ctx)")
st := strings.Index(s, "sched.Start(ctx)")
ws := strings.Index(s, "web.NewServer(")
if c < 0 || st < 0 || ws < 0 {
t.Fatalf("missing: clear=%d sched.Start=%d web.NewServer=%d", c, st, ws)
}
if c > st || c > ws {
t.Fatal("the leftover-copy removal must run before the scheduler and the web server start")
}
}