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:
parent
91f36f39d2
commit
793d987a88
2 changed files with 87 additions and 16 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -554,7 +554,7 @@ let
|
|||
capabilities = ["delete"]
|
||||
}
|
||||
|
||||
path "${credentialMountPath}/data/${ciRunnerTokenLeaf}" {
|
||||
path "${credentialMountPath}/data/${ciRunnerTokenLeaf}" {
|
||||
capabilities = ["create", "update"]
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue