From c080c780bada37787289a505a31282d0e8b1914d Mon Sep 17 00:00:00 2001 From: Julien Lutran Date: Mon, 24 Aug 2026 17:08:27 +0200 Subject: [PATCH] Add plakar-incus-backup.sh: leg-4 driver (incus integration -> S3) Thin wrapper chained after incus-copy in the same cron entry: backs up the incus source (quiesced backup-project replicas via the plakar incus integration) into @s3incus, prune + maintenance. Co-Authored-By: Claude Fable 5 --- plakar-incus-backup.sh | 64 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100755 plakar-incus-backup.sh diff --git a/plakar-incus-backup.sh b/plakar-incus-backup.sh new file mode 100755 index 0000000..af0c29b --- /dev/null +++ b/plakar-incus-backup.sh @@ -0,0 +1,64 @@ +#!/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 ] [-s ] [-r ] +# +# 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 ] [-s ] [-r ]" >&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 + +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