Review fixes for 0.340.0: C5 a catch-up releases the whole-guest backup when its backup legs end (red-proved); C3 the R-1187 c refusal text fits an unhealthy app; C6 two comments; C8 README backup.volumes wording; unreleased
gates / gates (push) Successful in 1m40s
gates / gates (push) Successful in 1m40s
This commit is contained in:
1 parent
912e59210d
commit
943c517550
7 files changed
+57
-11
No files matched your search
@@ -362,11 +362,13 @@ func (e *Exporter) executeImport(req ImportRequest, job *Job) {
|
||||
// NOT running used to „overwrite config in place" — its volumes were never removed, and `docker cp` only adds and
|
||||
// overwrites, so the result was the old data MERGED with the bundle's (a stale SQLite -wal beside the bundle's .db
|
||||
// is a corruption shape), reported as success. Only a running app's volumes are removed first. So this import is
|
||||
// refused here, before anything is written; the household starts the app (or removes it) and imports again.
|
||||
// refused here, before anything is written; the household starts the app (or removes it) and imports again. „Not
|
||||
// running" is IsStackRunning's view: running or degraded only, so an unhealthy or restarting app is refused too —
|
||||
// the text says so and names removal (review 2026-10-22 night, C3; the import path for those states is R-1187).
|
||||
// Pinned by TestR1187c_AStoppedAppIsNotImportedOver.
|
||||
if isDeployed && !isRunning {
|
||||
e.logger.Printf("[WARN] Import: refused — %s is installed but not running; importing over it would merge the old data with the bundle's (R-1187 c)", manifest.AppName)
|
||||
e.failJob(job, step, "Az alkalmazás telepítve van, de nem fut, ezért a csomagot nem töltjük vissza: a régi adatai összekeveredhetnének a csomagéval. Az alkalmazás érintetlen. Indítsd el (vagy távolítsd el), és próbáld újra.")
|
||||
e.failJob(job, step, "Az alkalmazás telepítve van, de nem fut rendben (leállt, vagy hibásan indul), ezért a csomagot nem töltjük vissza: a régi adatai összekeveredhetnének a csomagéval. Az alkalmazás érintetlen. Ha leállt, indítsd el; ha hibásan fut, távolítsd el. Utána próbáld újra.")
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -340,6 +340,13 @@ func (c *CatchUp) run(ctx context.Context, why string) {
|
||||
names = append(names, string(leg))
|
||||
}
|
||||
c.Ledger.markCatchUp(c.now())
|
||||
// The backup legs are done: the whole-guest backup no longer waits for this catch-up (review 2026-10-22 night, C5).
|
||||
// The checks below read only the off-site store, and on a big store they take long — held, they could push that
|
||||
// day's whole-guest backup out of its window. `pending` stays set until run() returns (no second catch-up).
|
||||
// Pinned by TestC5_TheWholeGuestBackupDoesNotWaitForTheChecks.
|
||||
c.mu.Lock()
|
||||
c.running = false
|
||||
c.mu.Unlock()
|
||||
if c.After != nil {
|
||||
c.Logger.Printf("[INFO] [catch-up] running the after-catch-up checks (the off-site proof and the due-gated integrity check, R-1189 d)")
|
||||
c.After(ctx)
|
||||
|
||||
@@ -43,3 +43,29 @@ func TestR1189d_TheChecksRunAfterTheCatchUpLegs(t *testing.T) {
|
||||
t.Fatal("no catch-up ran, so the after-catch-up checks must not run")
|
||||
}
|
||||
}
|
||||
|
||||
// C5 (review 2026-10-22 night): while the after-catch-up checks run, the catch-up no longer reports Running() — the
|
||||
// scheduled whole-guest backup (quiesce.go, R-871) waits only for the backup legs, not for the off-site proof and the
|
||||
// integrity check, which take long on a big store. RED-PROOF: with the `c.running = false` before After removed,
|
||||
// this fails — seen failing 2026-10-22 night.
|
||||
func TestC5_TheWholeGuestBackupDoesNotWaitForTheChecks(t *testing.T) {
|
||||
h := newHarness(t, at(1, 12, 0), at(5, 9, 0))
|
||||
h.l.MarkEnded(LegDBDump, at(4, 2, 31))
|
||||
h.l.MarkEnded(LegTier2, at(4, 3, 31))
|
||||
h.l.MarkEnded(LegOffsite, at(4, 4, 20))
|
||||
var mu sync.Mutex
|
||||
runningDuringAfter := []bool{}
|
||||
h.c.After = func(context.Context) {
|
||||
r := h.c.Running()
|
||||
mu.Lock()
|
||||
runningDuringAfter = append(runningDuringAfter, r)
|
||||
mu.Unlock()
|
||||
}
|
||||
h.c.Evaluate(context.Background(), "start")
|
||||
h.wait(t)
|
||||
mu.Lock()
|
||||
defer mu.Unlock()
|
||||
if len(runningDuringAfter) != 1 || runningDuringAfter[0] {
|
||||
t.Fatalf("Running() during the after-catch-up checks = %v, want [false]", runningDuringAfter)
|
||||
}
|
||||
}
|
||||
@@ -597,7 +597,7 @@ func (m *Manager) ClassifiedBinds(name string) ([]appbackup.ClassifiedBind, bool
|
||||
return appbackup.ClassifyBinds(meta.Backup, binds)
|
||||
}
|
||||
|
||||
// ExcludedDockerVolumes returns the Docker names of the stack's named volumes its template excludes from every backup
|
||||
// ExcludedDockerVolumes returns the Docker names of the stack's named volumes its template excludes from every app-data backup
|
||||
// (R-49, D21 = B; appbackup.ExcludedDockerVolumes), and a sentence per template entry that was ignored.
|
||||
func (m *Manager) ExcludedDockerVolumes(name string) ([]string, []string) {
|
||||
stack, ok := m.GetStack(name)
|
||||
|
||||
Reference in new issue
Block a user