Files
scripts/restic-maintenance.sh
T
Julien LutranandClaude Fable 5 75760ba303 restic scripts: absolute /usr/local/bin/restic — cron PATH lacks it
First cron run (2026-08-28 05:00) failed with 'restic: command not
found'; interactive shells had /usr/local/bin, cron does not.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-28 12:53:04 +02:00

55 lines
1.8 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/bash
#
# Weekly restic maintenance for both repos (Sunday, offset from the
# nightly backups — prune takes an EXCLUSIVE lock). Per repo:
# - unlock: clear locks left by crashed runs
# - prune: --max-unused 10% (our dead-data rate is ~0.10.4 GiB/day
# vs ~1 T repos, so pruning can skip repacking for months) and
# --max-repack-size 4G (bounds any single Sunday's rewrite to
# ~10-15 min even after a mass deletion; the rest defers)
# - check: structure every week, plus a rotating 1/52 data subset —
# a full verification of every byte once a year
#
# Usage: restic-maintenance.sh [-r <repo>[,<repo>...]]
set -u
REPOS="s3:s3.sbg.io.cloud.ovh.net/restic-data,s3:s3.sbg.io.cloud.ovh.net/restic-incus"
LOCKFILE=/run/lock/restic-maintenance.lock
ENVFILE=/root/.restic-env
RESTIC=/usr/local/bin/restic # cron PATH lacks /usr/local/bin
while getopts r: flag; do
case "${flag}" in
r) REPOS=${OPTARG};;
*) echo "Usage: $0 [-r <repo>[,<repo>...]]" >&2; exit 2;;
esac
done
[ -r "$ENVFILE" ] || { echo "env file $ENVFILE not readable" >&2; exit 2; }
. "$ENVFILE"
exec 9>"$LOCKFILE"
if ! flock -n 9; then
echo "another restic-maintenance run holds $LOCKFILE, aborting" >&2
exit 1
fi
log() { echo "[$(date '+%F %T')] $*"; }
# rotate the read-data subset weekly: full coverage once a year
WEEK=$(( ($(date +%s) / 604800) % 52 + 1 ))
rc=0
for repo in $(printf '%s' "$REPOS" | tr ',' ' '); do
log "maintenance: $repo"
$RESTIC -r "$repo" unlock || rc=1
$RESTIC -r "$repo" prune --max-unused 10% --max-repack-size 4G --pack-size 64 || rc=1
$RESTIC -r "$repo" check || rc=1
log "check --read-data-subset=$WEEK/52"
$RESTIC -r "$repo" check --read-data-subset="$WEEK/52" || rc=1
done
log "done (rc=$rc)"
exit $rc