plakar's pkg backend deletes an installed ptar when its cache re-extraction fails (observed 2026-08-24: orphaned .incus-* temps, final ptar unlinked, 'unsupported importer protocol'). Reinstall from the kept ptar before backing up instead of failing the night. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
77 lines
2.4 KiB
Bash
Executable File
77 lines
2.4 KiB
Bash
Executable File
#!/bin/bash
|
|
#
|
|
# Nightly plakar backup of the incus instances (leg 4): backs up the
|
|
# configured incus source (the plakar incus integration walking the
|
|
# quiesced replicas of the `backup` project) into the target kloset,
|
|
# then applies retention. Runs CHAINED after incus-copy.sh in the same
|
|
# cron entry — the snapshot is only as fresh as the last completed
|
|
# local replica refresh:
|
|
#
|
|
# 0 1 * * * incus-copy.sh -p backup -s backup >> /var/log/incus-copy.log 2>&1 ; plakar-incus-backup.sh >> /var/log/plakar-incus.log 2>&1
|
|
#
|
|
# Usage: plakar-incus-backup.sh [-k <kloset>] [-s <source>] [-r <retention-days>]
|
|
#
|
|
# The kloset passphrase comes from $PLAKAR_PASSPHRASE or, failing
|
|
# that, /root/.plakar-passphrase (mode 600).
|
|
|
|
set -u
|
|
|
|
KLOSET=@s3incus
|
|
SOURCE=ks4-incus
|
|
RETENTION=30
|
|
LOCKFILE=/run/lock/plakar-incus-backup.lock
|
|
PASSFILE=/root/.plakar-passphrase
|
|
|
|
usage() {
|
|
echo "Usage: $0 [-k <kloset>] [-s <source>] [-r <retention-days>]" >&2
|
|
exit 2
|
|
}
|
|
|
|
while getopts k:s:r: flag; do
|
|
case "${flag}" in
|
|
k) KLOSET=${OPTARG};;
|
|
s) SOURCE=${OPTARG};;
|
|
r) RETENTION=${OPTARG};;
|
|
*) usage;;
|
|
esac
|
|
done
|
|
|
|
exec 9>"$LOCKFILE"
|
|
if ! flock -n 9; then
|
|
echo "another plakar-incus-backup run holds $LOCKFILE, aborting" >&2
|
|
exit 1
|
|
fi
|
|
|
|
log() { echo "[$(date '+%F %T')] $*"; }
|
|
|
|
if [ -z "${PLAKAR_PASSPHRASE:-}" ]; then
|
|
[ -r "$PASSFILE" ] || { echo "no PLAKAR_PASSPHRASE in env and $PASSFILE not readable" >&2; exit 1; }
|
|
PLAKAR_PASSPHRASE=$(cat "$PASSFILE")
|
|
fi
|
|
export PLAKAR_PASSPHRASE
|
|
|
|
rc=0
|
|
|
|
# The plakar pkg backend has been observed to silently expel an
|
|
# installed plugin (its reload path deletes the ptar when the cache
|
|
# re-extraction fails — seen 2026-08-24). Self-heal from the kept
|
|
# ptar instead of failing the nightly run with
|
|
# "unsupported importer protocol".
|
|
if ! plakar pkg list 2>/dev/null | grep -q "^incus@"; then
|
|
PTAR=$(ls -t /root/incus-plugin/incus_v*.ptar 2>/dev/null | head -1)
|
|
echo "incus plugin missing — reinstalling ${PTAR:-<no ptar found>}" >&2
|
|
[ -n "$PTAR" ] && plakar pkg add "$PTAR" \
|
|
|| { echo "incus plugin reinstall failed" >&2; exit 1; }
|
|
fi
|
|
|
|
log "backup @$SOURCE -> $KLOSET"
|
|
plakar -quiet at "$KLOSET" backup -tag "$SOURCE" "@$SOURCE" \
|
|
|| { echo "backup @$SOURCE failed" >&2; rc=1; }
|
|
|
|
log "prune: keep the last $RETENTION days of snapshots"
|
|
plakar at "$KLOSET" prune -days "$RETENTION" -apply || rc=1
|
|
plakar at "$KLOSET" maintenance || rc=1
|
|
|
|
log "done (rc=$rc)"
|
|
exit $rc
|