Files
homelab-infra/ops/restore-tests/paperless-restore-test.sh
T

114 lines
3.7 KiB
Bash
Executable File

#!/bin/bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
. "$SCRIPT_DIR/common.sh"
WHATIF=0
KEEP_DATA=0
for arg in "$@"; do
case "$arg" in
--what-if) WHATIF=1 ;;
--keep-data) KEEP_DATA=1 ;;
*) echo "Unknown argument: $arg" >&2; exit 1 ;;
esac
done
RESTORE_ROOT="/mnt/user/backups/restore-lab/paperless"
REPORT_ROOT="/mnt/user/backups/restore-reports"
EXTRACT_DIR="$BORG_RESTORE_HOST_ROOT/paperless-extract"
COMPOSE_FILE="$SCRIPT_DIR/paperless-compose.test.yml"
REPORT_FILE="$REPORT_ROOT/paperless-$(date +%F).md"
if [ "$WHATIF" -eq 1 ]; then
cat <<EOF
Paperless restore test
Mode: WhatIf
RestoreRoot: $RESTORE_ROOT
ReportRoot: $REPORT_ROOT
Expected Borg source paths:
- local/appdata/paperless-ngx/data
- local/paperless/media
- local/paperless/export
- local/paperless/consume
- local/borg-dumps/latest/postgresql17-paperless.dump
EOF
exit 0
fi
require_cmd docker
require_cmd curl
require_path "$BORG_PASSPHRASE_FILE_DEFAULT"
require_path "$COMPOSE_FILE"
cleanup() {
cleanup_compose "$COMPOSE_FILE"
if [ "$KEEP_DATA" -ne 1 ]; then
rm -rf "$RESTORE_ROOT"
fi
rm -rf "$EXTRACT_DIR"
}
trap cleanup EXIT
rm -rf "$EXTRACT_DIR" "$RESTORE_ROOT"
mkdir -p "$RESTORE_ROOT/postgres" "$RESTORE_ROOT/dumps/latest"
archive="$(latest_archive_name)"
repo="$(borg_repo_url)"
borg_extract "/restore/paperless-extract" \
"local/appdata/paperless-ngx/data" \
"local/paperless/media" \
"local/paperless/export" \
"local/paperless/consume" \
"local/borg-dumps/latest/postgresql17-paperless.dump"
mv "$EXTRACT_DIR/local/appdata/paperless-ngx/data" "$RESTORE_ROOT/data"
mv "$EXTRACT_DIR/local/paperless/media" "$RESTORE_ROOT/media"
mv "$EXTRACT_DIR/local/paperless/export" "$RESTORE_ROOT/export"
mv "$EXTRACT_DIR/local/paperless/consume" "$RESTORE_ROOT/consume"
mv "$EXTRACT_DIR/local/borg-dumps/latest/postgresql17-paperless.dump" "$RESTORE_ROOT/dumps/latest/postgresql17-paperless.dump"
docker compose -f "$COMPOSE_FILE" up -d restoretest-paperless-postgres restoretest-paperless-redis >/dev/null
until docker exec restoretest-paperless-postgres pg_isready -U paperless -d paperless >/dev/null 2>&1; do sleep 2; done
cat "$RESTORE_ROOT/dumps/latest/postgresql17-paperless.dump" | docker exec -i restoretest-paperless-postgres pg_restore -U paperless -d paperless --clean --if-exists --no-owner --no-privileges
docker compose -f "$COMPOSE_FILE" up -d restoretest-paperless >/dev/null
sleep 12
status="$(curl -s -o /tmp/paperless-body.html -w '%{http_code}' -L http://127.0.0.1:18120)"
grep -qi "Paperless-ngx sign in" /tmp/paperless-body.html
doc_count="$(docker exec restoretest-paperless-postgres psql -U paperless -d paperless -tAc "select count(*) from documents_document;" | tr -d '[:space:]')"
doc_sample="$(find "$RESTORE_ROOT/media/documents/originals" -type f | sed -n '1p')"
write_report "$REPORT_FILE" <<EOF
# Paperless Restore Test Report - $(date +%F)
- Service: \`paperless-ngx\`
- Source repo: \`$repo\`
- Archive: \`$archive\`
- Restore root: \`$RESTORE_ROOT\`
- Test containers:
- \`restoretest-paperless\`
- \`restoretest-paperless-postgres\`
- \`restoretest-paperless-redis\`
- Test endpoint: \`http://127.0.0.1:18120\`
- Result: \`SUCCESS\`
## Checks
- Borg extract of file data: \`ok\`
- Borg extract of dump: \`ok\`
- Dump import into isolated Postgres: \`ok\`
- HTTP status after redirect: \`$status\`
- Login page content: \`Paperless-ngx sign in\`
- Document count in test DB: \`$doc_count\`
- Document sample in media path: \`$doc_sample\`
## Notes
- Test ran without Traefik and without the productive domain.
- Test used isolated Postgres and Redis containers.
- Test data was cleaned after success: \`$([ "$KEEP_DATA" -eq 1 ] && echo no || echo yes)\`
EOF
echo "Paperless restore test ok -> $REPORT_FILE"