installer 1.25.0: the off-site tier stops asking to prune (R-191)
gates / gates (push) Successful in 8s
gates / gates (push) Successful in 8s
Every weekly off-site run uploaded successfully and then failed the job on a prune the box's token is deliberately refused — R-89 moved off-site pruning server-side to ep0 and box tokens stay write-only. The 2026-07-26 'two weeks' ruling was not reversed; where it is enforced moved, and keep_last: 2 did not follow. Now 0, which the agent's existing guard already reads as 'never prune from the box'. Verified read-only on ep0 before changing it: both namespaces have a prune job at 03:30 keep-last 2 that has run every day since 2026-07-27 — 18 tasks, all OK, the newest keeping exactly two. Without that check this would have traded a weekly false alarm for unbounded growth. A gate asserts the offsite tier carries no client-side prune. The local tier is untouched.
This commit is contained in:
@@ -233,6 +233,32 @@ else:
|
||||
"invisible to the agent, it is never restore-tested, and an empty listing looks exactly "
|
||||
"like a brand-new tier." % (resolutions, grants))
|
||||
|
||||
# ── R-191: the OFFSITE tier must not arm a client-side prune ─────────────────────────────────
|
||||
#
|
||||
# R-89 moved offsite pruning SERVER-SIDE — ep0 runs a per-namespace prune job and box tokens stay
|
||||
# write-only, so the box is REFUSED if it asks. When this default was `keep_last: 2` the effect was a
|
||||
# weekly lie: vzdump uploaded the snapshot, then failed the whole job on the prune, and the operator
|
||||
# was told the offsite backup had failed when it had succeeded.
|
||||
#
|
||||
# The assertion is on the OFFSITE entry only. The local tier's `local_backup_retention` is untouched
|
||||
# and must stay untouched — it prunes correctly and is allowed to.
|
||||
m = re.search(r'"backup_targets":\s*\[(.*?)\]', src, re.S)
|
||||
if not m:
|
||||
fail("cannot find backup_targets in the rendered agent.json defaults — the offsite-retention "
|
||||
"assertion cannot run, and a check that cannot run must never report OK (R-191)")
|
||||
else:
|
||||
targets = m.group(1)
|
||||
kl = re.search(r'"keep_last"\s*:\s*(\d+)', targets)
|
||||
if not kl:
|
||||
fail("the offsite backup_target carries no keep_last at all — expected an explicit 0 "
|
||||
"(R-191: 0 means 'never prune from the box'; absent is not the same statement)")
|
||||
elif kl.group(1) != "0":
|
||||
fail("the offsite backup_target arms a CLIENT-SIDE prune (keep_last=%s). R-89 moved offsite "
|
||||
"pruning server-side to ep0 and box tokens are write-only, so every weekly run will "
|
||||
"upload successfully and then FAIL the job on a refused prune (R-191)." % kl.group(1))
|
||||
else:
|
||||
ok("the offsite tier arms no client-side prune (keep_last=0; retention is ep0's prune jobs)")
|
||||
|
||||
print()
|
||||
if fails:
|
||||
print("hostinstall gates: %d FAILURE(S)" % len(fails))
|
||||
|
||||
Reference in New Issue
Block a user