Watch
0
0
Fork
You've already forked hyperhive
0

swarm-archive: forget future-dated snapshots before each prune; fix the grants case

A client chooses a snapshot's time, so snapshots dated ahead could fill
--keep-last and push the real ones out of a prune. The prune now forgets
snapshots dated more than an hour after now first, and logs their ids. The
VM test forges one and checks the real snapshot stays. The bao-grants case
that read a + path as a glob now names the literal path, and two cases that
pinned 'nothing else' list the archive grants. The ciRunner stanza is back
at its original indent.
This commit is contained in:
atlas 2026-11-10 08:32:54 +01:00
commit 793d987a88

View file

@ -33,6 +33,9 @@ let
resticPrefix = "secret/swarm/services/archive/restic";
readyPath = "secret/swarm/services/archive/ready";
# Slack for the clocks of the hives that stamp snapshots.
futureSkewSeconds = 3600;
keepFlags = lib.concatStringsSep " " (
[ "--keep-last ${toString retention.keepLast}" ]
++ lib.optional (
@ -130,10 +133,37 @@ in
# `restic forget --prune` on every repository, with its password read from
# the store at run time. The server refuses deletes from clients, so this is
# the only place history is dropped.
#
# restic ranks snapshots by their time, which the client chooses (`restic
# backup --time`). Snapshots dated years ahead would fill `--keep-last` and
# push the real ones out, so each prune first forgets the snapshots dated more
# than `futureSkewSeconds` after now. restic has no rule relative to the
# clock for `--keep-last`.
pruneScript = ''
set -euo pipefail
${storeSeededSecret}
# Forgets the snapshots of $repo dated after the limit, naming them in the
# log; returns non-zero when it cannot read the list or a time.
forget_future() {
local repo="$1" agent="$2" snaps id time at future="" limit
limit=$(( $(date +%s) + ${toString futureSkewSeconds} ))
snaps="$(${restic}/bin/restic -r "$repo" --retry-lock 10m snapshots --json \
| jq -r '.[] | "\(.id) \(.time)"')" || return 1
while read -r id time; do
[ -n "$id" ] || continue
at="$(date -d "$time" +%s)" || return 1
if [ "$at" -gt "$limit" ]; then
future+=" $id"
fi
done <<<"$snaps"
if [ -n "$future" ]; then
echo "archive prune warning: $agent has snapshots dated after now, forgetting them:$future" >&2
# shellcheck disable=SC2086
${restic}/bin/restic -r "$repo" --retry-lock 10m forget $future || return 1
fi
}
store_init
store_login
if [ "$STORE_UP" != 1 ]; then
@ -151,7 +181,8 @@ in
continue
fi
export RESTIC_PASSWORD_COMMAND="bao kv get -field=password ${resticPrefix}/$agent"
if ${restic}/bin/restic -r "$repo" --retry-lock 10m forget --group-by host ${keepFlags} --prune; then
if forget_future "$repo" "$agent" \
&& ${restic}/bin/restic -r "$repo" --retry-lock 10m forget --group-by host ${keepFlags} --prune; then
echo "pruned $agent"
else
echo "archive prune failed: $agent" >&2