v0.168.0: customer-configurable backup window (Mentési időablak)
ONE setting (window start W) drives every nightly leg at fixed, never-stored offsets: DB dump at W, tier-2 at W+60m, off-box at W+105m (wrap-safe). Precedence settings > controller.yaml db_dump_schedule > 02:30. - scheduler.UpdateDaily: retime a daily job at runtime (no restart) via a per-job buffered resched chan + a select case in runDailyJob. - new pure package internal/backupwindow (LegTimes/GateWindow/EffectiveWindow). - quiesce disk-tier window gate: scheduled cycles run only inside [W+2h,W+6h) with a safety valve (age>cadence+24h runs regardless); manual TriggerNow never gated. Backend.Due now also returns the backup age (from the agent's own /backup/due). - backup page: Mentési időablak card (time input + derived leg/gate rows); POST /backups/window validates -> saves -> UpdateDaily x3 -> flash. Tests: 5 groups, all red-proofed. Agent/cadence//backup/due untouched.
This commit is contained in:
@@ -1,5 +1,41 @@
|
||||
## Changelog
|
||||
|
||||
### v0.168.0 — Customer-configurable backup window ("Mentési időablak") (2026-07-24)
|
||||
|
||||
No agent coupling; MinAgent unchanged (the disk-tier gate is controller-side; the agent's cadence-based
|
||||
`/backup/due` is untouched). New pure package `internal/backupwindow`; touches scheduler, settings,
|
||||
quiesce, the backup page, and main.go wiring.
|
||||
|
||||
**One setting drives every nightly leg.** A single customer control — **"Mentési időablak kezdete"**
|
||||
(default = the effective DB-dump time, historically "02:30") — from which every leg derives at FIXED,
|
||||
never-stored offsets, so misordering is impossible: DB dump at **W**, tier-2 mirror at **W+60m**,
|
||||
off-box at **W+105m** (wrap-safe across midnight). Precedence: settings > controller.yaml
|
||||
`db_dump_schedule` > "02:30".
|
||||
|
||||
- **Scheduler seam `UpdateDaily(name, timeStr) bool`** (+ a per-daily-job buffered `resched` channel and
|
||||
a new select case in `runDailyJob`): a saved window fans out to all three legs and takes effect at the
|
||||
next scheduling pass **without a restart**. Unknown/non-daily name or invalid time → WARN + false, job
|
||||
untouched.
|
||||
- **Disk-tier (whole-guest PBS/vzdump) window gate.** The quiesce loop's scheduled cycles now run only
|
||||
inside **[W+2h, W+6h)** (wrap-safe, Europe/Budapest wall-clock), with a **safety valve**: if the newest
|
||||
successful backup is older than cadence+24h (or none exists), the cycle runs regardless of the window —
|
||||
a box powered on only outside its window never starves. Gate denials log at DEBUG with the window.
|
||||
**Manual triggers ("Mentés most" / `TriggerNow`) are NEVER gated** (they bypass `runOnce`). The
|
||||
`Backend.Due` seam now also returns the backup age (from the agent's own `/backup/due` answer) for the
|
||||
valve; the agent, its cadence, and `/backup/due` semantics are unchanged.
|
||||
- **Backup page (Áttekintés):** a compact "Mentési időablak" card — time input (value = effective
|
||||
window) + "Mentés" button, and the derived rows (adatbázis-mentés / helyi másolat / távoli mentés
|
||||
times, and the "teljes rendszermentés kb. W+2h–W+6h között" line). POST `/backups/window` validates →
|
||||
saves → `UpdateDaily`×3 → PRG redirect with a Hungarian flash. Behind RequireAuth + CsrfProtect like
|
||||
its siblings.
|
||||
- Derived leg/gate times are **computed, never persisted**; no per-leg settings; the offsets are not
|
||||
exposed in the UI.
|
||||
|
||||
Tests (5 groups, all red-proofed): `LegTimes`/`GateWindow` incl. midnight wrap + invalid-rejected;
|
||||
`EffectiveWindow` precedence table; `UpdateDaily` mutate+signal + unknown/invalid + goroutine consumes
|
||||
the reschedule; `scheduledRunAllowed` truth table (inside/outside/valve/wrap/nil-age) + Loop integration
|
||||
(defer outside / run inside / valve runs / manual never gated); handler valid-save + invalid-rejected.
|
||||
|
||||
### v0.167.1 — Center the sidebar logo (2026-07-24)
|
||||
|
||||
CSS one-liner + test. `.sidebar-logo` gains `margin: 0 auto` so the 140px logo is horizontally
|
||||
|
||||
Reference in New Issue
Block a user