Files
vps/ansible/roles/matrix_backup/templates/matrix-backup.sh.j2
T

60 lines
2.5 KiB
Django/Jinja
Raw Normal View History

2026-08-03 12:26:42 +08:00
#!/usr/bin/env bash
set -euo pipefail
umask 077
backup_root='{{ matrix_backup_path }}'
namespace='{{ matrix_namespace }}'
warn_percent='{{ matrix_backup_warn_percent }}'
stop_percent='{{ matrix_backup_stop_percent }}'
retention_days='{{ matrix_backup_retention_days }}'
postgres_selector='{{ matrix_backup_postgres_pod_selector }}'
media_selector='{{ matrix_backup_media_pod_selector }}'
bootstrap_dir='{{ matrix_backup_bootstrap_dir }}'
usage=$(df -P / | awk 'NR == 2 {gsub(/%/, "", $5); print $5}')
if (( usage >= stop_percent )); then
printf 'Refusing Matrix backup: root filesystem usage is %s%% (stop threshold %s%%).\n' "$usage" "$stop_percent" >&2
exit 2
fi
stamp=$(date -u +%Y%m%dT%H%M%SZ)
stage="$backup_root/.staging-$stamp"
final="$backup_root/$stamp"
mkdir -p "$stage" "$backup_root"
trap 'rm -rf "$stage"' EXIT
if ! command -v k3s >/dev/null 2>&1; then
printf 'K3s is unavailable; refusing Matrix backup.\n' >&2
exit 3
fi
postgres_pod=$(k3s kubectl -n "$namespace" get pod -l "$postgres_selector" -o jsonpath='{.items[0].metadata.name}')
media_pod=$(k3s kubectl -n "$namespace" get pod -l "$media_selector" -o jsonpath='{.items[0].metadata.name}')
if [[ -z "$postgres_pod" || -z "$media_pod" ]]; then
printf 'Required Matrix PostgreSQL or media pod is unavailable.\n' >&2
exit 3
fi
for database in synapse mas; do
k3s kubectl -n "$namespace" exec "$postgres_pod" -- \
pg_dump --username=postgres --format=custom --file="/tmp/$database-$stamp.dump" "$database"
k3s kubectl -n "$namespace" cp \
"$namespace/$postgres_pod:/tmp/$database-$stamp.dump" "$stage/$database.dump"
k3s kubectl -n "$namespace" exec "$postgres_pod" -- rm -f "/tmp/$database-$stamp.dump"
done
k3s kubectl -n "$namespace" exec "$media_pod" -- \
tar --create --gzip --file="/tmp/media-$stamp.tar.gz" --directory=/data media_store
k3s kubectl -n "$namespace" cp \
"$namespace/$media_pod:/tmp/media-$stamp.tar.gz" "$stage/media.tar.gz"
k3s kubectl -n "$namespace" exec "$media_pod" -- rm -f "/tmp/media-$stamp.tar.gz"
tar --create --gzip --file="$stage/bootstrap.tar.gz" --directory="$(dirname "$bootstrap_dir")" "$(basename "$bootstrap_dir")"
sha256sum "$stage"/* > "$stage/SHA256SUMS"
printf '{"created_at":"%s","root_usage_percent":%s,"warning_threshold_percent":%s}\n' \
"$stamp" "$usage" "$warn_percent" > "$stage/manifest.json"
mv "$stage" "$final"
trap - EXIT
find "$backup_root" -mindepth 1 -maxdepth 1 -type d -name '20*Z' -mtime +"$retention_days" -exec rm -rf {} +
printf 'Matrix backup created: %s\n' "$final"