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:
@@ -221,6 +221,15 @@ func (s *Server) restoreOpBlocked() (string, bool) {
|
||||
return "Egy mentési művelet már fut, ezért most nem indítható visszaállítás. Az állapotát " +
|
||||
"ezen az oldalon követheted; amint befejeződik, újra indíthatsz visszaállítást.", true
|
||||
}
|
||||
// The stray-copy fix: a second-drive copy (rsync --delete) runs now, or one a previous controller process lost may
|
||||
// still run — a restore beside it could lose the files it brings back (R-1180's other direction).
|
||||
if app, blocked := s.backupMgr.Tier2CopyBlocksRestore(); blocked {
|
||||
if s.logger != nil {
|
||||
s.logger.Printf("[WARN] [restore] restore refused — a second-drive copy is running or may still run (app=%q)", app)
|
||||
}
|
||||
return "Éppen fut a második meghajtóra készülő mentési másolat, ezért most nem indítható visszaállítás. " +
|
||||
"Néhány perc múlva próbáld újra.", true
|
||||
}
|
||||
return "", false
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
package web
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"gitea.dooplex.hu/admin/felhom-controller/internal/backup"
|
||||
)
|
||||
|
||||
// The stray-copy fix: a restore is refused while a second-drive copy (rsync --delete) runs — every restore entry
|
||||
// point asks restoreOpBlocked first. RED-PROOF (2026-10-22 night): with the Tier2CopyBlocksRestore check removed from
|
||||
// restoreOpBlocked, this fails.
|
||||
func TestStrayCopy_RestoreRefusedWhileACopyRuns(t *testing.T) {
|
||||
s, _, _ := newOffboxWebServer(t)
|
||||
if _, blocked := s.restoreOpBlocked(); blocked {
|
||||
t.Fatal("fixture: nothing runs, a restore must be allowed")
|
||||
}
|
||||
done := backup.MarkTier2CopyForTest("immich")
|
||||
msg, blocked := s.restoreOpBlocked()
|
||||
done()
|
||||
if !blocked || !strings.Contains(msg, "második meghajtóra") {
|
||||
t.Fatalf("during a second-drive copy a restore must be refused with the copy named; got blocked=%v %q", blocked, msg)
|
||||
}
|
||||
if _, blocked := s.restoreOpBlocked(); blocked {
|
||||
t.Fatal("after the copy a restore must be allowed again")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user