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
gates / gates (push) Successful in 1m53s
This commit is contained in:
@@ -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")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user