v0.204.0 — the restore list is keyed on the store (R-237); the size gate stops refusing in silence (R-238)
gates / gates (push) Successful in 26s
gates / gates (push) Successful in 26s
R-237: /backups/restore listed apps that are CURRENTLY DEPLOYED and CURRENTLY TOGGLED ON for future off-site backups. A rebuilt box has neither, so a household that had just lost everything was shown nothing to restore while the repository held their snapshots — measured live on the R-201 re-walk. To restore an app you had to select it, to select it you had to have installed it, and to know what to install you had to see the backup you could not see. The store is now the source of the list (offsite_restore_list.go), built on the existing R-193 OffsiteInventoryList. Installed-ness became a property OF a row, never a filter on it. Every case is answered rather than hidden: a snapshot for an app that is not installed is offered and says it will reinstall first; an installed app with no snapshot is shown as having nothing; an unreadable store renders as UNKNOWN (R-225's rule, one screen over) AND keeps the action, because "we could not look" is not "there is nothing"; no-target is its own state. The felhom-offbox and _shares marker tags are excluded from the app list. R-238 classified as a HARNESS ARTIFACT: mode=full without confirm=1 is step 1 of a deliberate two-step — it starts no job by design and redirects carrying &full_prep=<app>, which deriveWizardStep requires to reveal the commit. A driver that did not carry it forward landed back on the intent step. The operator's browser run completed the same restore. The wizard's precedence rules were NOT re-keyed: a stale ?full_prep= must never resurrect a commit button mid-restore. The residue WAS real and is fixed: neither branch of that step wrote anything to the log, so a refusal — including by the headroom gate — left no trace on the box. Both branches now log, and so does the concurrent-op refusal. resolveWizardApp is removed: it was dead once the gate moved, and its test pinned the defect's behaviour (an untoggled app refused), which would have read as policy. 28 packages ok, 9/9 gates OK. Three red-proofs, each asserted to have applied.
This commit is contained in:
@@ -160,23 +160,6 @@ func deriveWizardStep(in restoreWizardInput) restoreWizardView {
|
||||
}
|
||||
}
|
||||
|
||||
// resolveWizardApp finds the wizard's app in the offsite-toggled set — the same gating the list page
|
||||
// applies. Pure, so the two refusal rows (unknown app, app present but NOT toggled for offsite) are
|
||||
// table-testable without a live backup manager.
|
||||
//
|
||||
// An app that is not toggled has no offsite snapshot to restore FROM, so its wizard would be a page
|
||||
// of controls that cannot work. Both refusals return nil and the caller redirects — a customer-visible
|
||||
// URL that survives a bookmark, an app rename or a toggle being switched off must never 500.
|
||||
func resolveWizardApp(rows []OffboxAppRow, name string) *OffboxAppRow {
|
||||
for _, a := range rows {
|
||||
if a.Name == name && a.Enabled {
|
||||
cp := a
|
||||
return &cp
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// restoreOpInFlight reports whether a restore op is in flight, FOR DISPLAY.
|
||||
//
|
||||
// **Use this, not `Manager.IsRunning()`.** The Manager carries two different booleans and they are
|
||||
@@ -216,9 +199,19 @@ func (s *Server) backupsRestoreWizardHandler(w http.ResponseWriter, r *http.Requ
|
||||
return
|
||||
}
|
||||
|
||||
row := resolveWizardApp(s.buildOffboxApps(), app)
|
||||
// R-237: the gate is "is it in the store", NOT "is it toggled on for future backups". The old
|
||||
// resolver required the toggle, which locked a rebuilt box out of its own snapshots — measured
|
||||
// live on the R-201 re-walk. A refusal here still never 500s.
|
||||
rows, storeState := s.offsiteRestoreRows(r.Context())
|
||||
row := resolveOffsiteRestoreApp(rows, app)
|
||||
if row == nil {
|
||||
offboxRedirectTo(w, r, "/backups/restore", "Ez az alkalmazás nincs távoli mentésre kijelölve.", true)
|
||||
msg := "Ehhez az alkalmazáshoz nincs mentés a távoli tárolóban."
|
||||
if storeState != offsiteStoreKnown {
|
||||
// Never say "there is nothing" when we could not look — R-225's rule, one screen over.
|
||||
msg = "Nem tudjuk elolvasni a távoli tárolót, ezért nem tudjuk, van-e benne mentés ehhez az alkalmazáshoz."
|
||||
}
|
||||
s.logger.Printf("[INFO] [web] restore wizard refused for %q: not restorable (store=%s)", app, storeState)
|
||||
offboxRedirectTo(w, r, "/backups/restore", msg, true)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user