atlas-iac/scripts/ops/k3s_datastore_backup.sh

40 lines
1.7 KiB
Bash
Executable File

#!/usr/bin/env bash
# Native external-datastore backup on titan-db. Never print database contents.
set -euo pipefail
umask 077
root=/var/backups/atlas-k3s
[[ $EUID == 0 ]] || exit 77
install -d -m 0700 "$root"
exec 9>/run/lock/atlas-k3s-backup.lock
flock -w 600 9
if [[ ${1:-backup} == export ]]; then
latest=$(readlink -f "$root/latest")
[[ $latest == "$root"/snapshot-* && -f $latest/COMPLETE ]] || exit 1
[[ $(( $(date +%s) - $(stat -c %Y "$latest/COMPLETE") )) -lt 5400 ]] || exit 75
# This is the only command allowed by the replica's restricted SSH key.
cd "$latest"
sha256sum --quiet -c SHA256SUMS
exec tar -cf - k3s.dump globals.sql server-token SHA256SUMS COMPLETE
fi
[[ ${1:-backup} == backup ]] || exit 64
[[ $(df --output=avail -k "$root" | tail -1) -gt 5242880 ]] || exit 73
stage=$(mktemp -d "$root/.pending.XXXXXXXX")
trap 'rm -rf -- "$stage"' EXIT
exec 2>"$root/last-error.txt"
started=$(date -u +%FT%TZ)
timeout 900 runuser -u postgres -- pg_dump --format=custom --dbname=k3s >"$stage/k3s.dump"
timeout 120 runuser -u postgres -- pg_dumpall --globals-only >"$stage/globals.sql"
pg_restore --list "$stage/k3s.dump" >/dev/null
install -m 0600 /etc/atlas-k3s-backup/server-token "$stage/server-token"
(
cd "$stage"
sha256sum k3s.dump globals.sql server-token >SHA256SUMS
printf 'started_utc=%s\ncompleted_utc=%s\n' "$started" "$(date -u +%FT%TZ)" >COMPLETE
)
final="$root/snapshot-$(date -u +%Y%m%dT%H%M%SZ)"
mv "$stage" "$final"
ln -sfn "$(basename "$final")" "$root/.latest"
mv -Tf "$root/.latest" "$root/latest"
find "$root" -mindepth 1 -maxdepth 1 -type d -name 'snapshot-*' -mtime +7 -exec rm -rf -- {} +
printf 'Datastore backup complete: %s bytes\n' "$(stat -c %s "$final/k3s.dump")"