#!/usr/bin/env bash set -Eeuo pipefail umask 077 export_root={{ server_backup_export_root | quote }} versions="$export_root/versions" stamp=$(date -u +%Y%m%dT%H%M%SZ) stage='' gitea_stopped=false exec 9>/run/lock/prometheus-backup-export.lock flock -n 9 || { echo 'A Prometheus backup export is already running' >&2; exit 1; } cleanup() { local rc=$? trap - EXIT if (( rc != 0 )) && "$gitea_stopped"; then podman start gitea >/dev/null || rc=1 fi if (( rc != 0 )) && [[ -n "$stage" && -d "$stage" ]]; then rm -rf -- "$stage" fi exit "$rc" } trap cleanup EXIT trap 'exit 129' HUP trap 'exit 130' INT trap 'exit 143' TERM systemctl is-active --quiet podman-compose-server.service || { echo 'Prometheus Compose stack is not active' >&2; exit 1; } if systemctl is-active --quiet prometheus-backup-export.timer; then echo 'Stop the scheduled export timer for the cutover first' >&2 exit 1 fi [[ $(podman inspect --format '{{ '{{.State.Running}}' }}' gitea) == true ]] || { echo 'Source Gitea must be running before the final export' >&2; exit 1; } [[ -d /opt/gitea/data && -d /home/git/.ssh ]] || { echo 'Required source Gitea paths are missing' >&2; exit 1; } [[ ! -e "$versions/$stamp" ]] || { echo 'Final export timestamp already exists' >&2; exit 1; } gitea_stopped=true podman stop --time 30 gitea >/dev/null [[ $(podman inspect --format '{{ '{{.State.Running}}' }}' gitea) == false ]] || { echo 'Source Gitea did not stop' >&2; exit 1; } python3 - <<'PY' import sqlite3 path = '/opt/gitea/data/gitea/gitea.db' with sqlite3.connect(f'file:{path}?mode=ro', uri=True) as database: if database.execute('PRAGMA quick_check').fetchone()[0] != 'ok': raise SystemExit('Source Gitea SQLite quick_check failed') PY stage=$(mktemp -d "$export_root/.staging.XXXXXXXX") tar --acls --xattrs --selinux -C / -cf "$stage/payload.tar" \ opt/gitea/data home/git/.ssh tar -tf "$stage/payload.tar" >/dev/null (cd "$stage" && sha256sum payload.tar >payload.sha256) printf '{"schema":1,"host":"prometheus","purpose":"gitea-cutover","created_utc":"%s"}\n' \ "$stamp" >"$stage/metadata.json" [[ $(podman inspect --format '{{ '{{.State.Running}}' }}' gitea) == false ]] || { echo 'Source Gitea restarted during final export' >&2; exit 1; } chown root:{{ server_backup_username }} "$stage" "$stage/payload.tar" \ "$stage/payload.sha256" "$stage/metadata.json" chmod 0750 "$stage" chmod 0640 "$stage/payload.tar" "$stage/payload.sha256" "$stage/metadata.json" mv -- "$stage" "$versions/$stamp" stage='' ln -s "$stamp" "$versions/.current.new" mv -Tf -- "$versions/.current.new" "$versions/current" echo "Prepared final Gitea export $stamp; source Gitea remains stopped"