docs: archive rollback volumes after burn-in

This commit is contained in:
2026-06-02 19:55:02 +02:00
parent 8eb367f0b5
commit 9f63e6e3bc
9 changed files with 62 additions and 43 deletions
+38 -15
View File
@@ -3,6 +3,7 @@ set -euo pipefail
MODE="dry-run"
CUTOFF_DATE="2026-06-02"
ARCHIVE_ROOT="/mnt/user/appdata/_archive/pg18-immich-rollback-volumes-20260602"
if [[ "${1:-}" == "--execute" ]]; then
MODE="execute"
@@ -23,10 +24,10 @@ if [[ "$MODE" == "execute" && "$today" < "$CUTOFF_DATE" ]]; then
fi
declare -a CANDIDATES=(
"/mnt/user/appdata/postgresql17|/mnt/user/appdata/postgresql18|shared PostgreSQL 17 rollback"
"/mnt/user/appdata/mealie/postgres|/mnt/user/appdata/mealie/postgres18|Mealie PostgreSQL 17 rollback"
"/mnt/user/appdata/nextcloud/postgres|/mnt/user/appdata/nextcloud/postgres18|Nextcloud PostgreSQL 17 rollback"
"/mnt/user/appdata/immich_postgres|/mnt/user/appdata/immich_postgres_vectorchord|Immich pgvecto.rs rollback"
"/mnt/user/appdata/postgresql17|/mnt/user/appdata/postgresql18|postgresql17|shared PostgreSQL 17 rollback"
"/mnt/user/appdata/mealie/postgres|/mnt/user/appdata/mealie/postgres18|mealie-postgres17|Mealie PostgreSQL 17 rollback"
"/mnt/user/appdata/nextcloud/postgres|/mnt/user/appdata/nextcloud/postgres18|nextcloud-postgres17|Nextcloud PostgreSQL 17 rollback"
"/mnt/user/appdata/immich_postgres|/mnt/user/appdata/immich_postgres_vectorchord|immich-postgres-pgvecto-rs|Immich pgvecto.rs rollback"
)
require_container_healthy() {
@@ -48,9 +49,10 @@ require_container_healthy() {
fi
}
echo "Alt-volume release check"
echo "Alt-volume archive check"
echo "Mode: $MODE"
echo "Date: $today"
echo "Archive: $ARCHIVE_ROOT"
echo
require_container_healthy postgresql17
@@ -68,37 +70,58 @@ if [[ -x /mnt/user/services/homelab-infra/ops/restore-tests/run-restore-checks.s
/mnt/user/services/homelab-infra/ops/restore-tests/run-restore-checks.sh freshness
fi
mapfile -t active_mounts < <(docker inspect $(docker ps -q) --format '{{range .Mounts}}{{println .Source}}{{end}}' 2>/dev/null || true)
mapfile -t active_mounts < <(docker inspect $(docker ps -aq) --format '{{range .Mounts}}{{println .Source}}{{end}}' 2>/dev/null || true)
if [[ "$MODE" == "execute" ]]; then
mkdir -p "$ARCHIVE_ROOT"
fi
for entry in "${CANDIDATES[@]}"; do
IFS='|' read -r old_path active_path label <<< "$entry"
IFS='|' read -r old_path active_path archive_name label <<< "$entry"
archive_path="$ARCHIVE_ROOT/$archive_name"
if [[ ! -d "$active_path" ]]; then
echo "Missing active path for $label: $active_path" >&2
exit 1
fi
if [[ ! -d "$old_path" ]]; then
echo "Already absent: $old_path ($label)"
if printf '%s\n' "${active_mounts[@]}" | grep -Fxq "$old_path"; then
echo "Refusing: old path is still mounted by a container: $old_path" >&2
exit 1
fi
if [[ -d "$old_path" && -d "$archive_path" ]]; then
echo "Refusing: both old path and archive path exist for $label." >&2
echo "Old: $old_path" >&2
echo "Archive: $archive_path" >&2
exit 1
fi
if [[ -d "$archive_path" ]]; then
size="$(du -sh "$archive_path" 2>/dev/null | awk '{print $1}')"
echo "Archived: $archive_path ($label, $size)"
echo
continue
fi
if printf '%s\n' "${active_mounts[@]}" | grep -Fxq "$old_path"; then
echo "Refusing: old path is still mounted by a running container: $old_path" >&2
if [[ ! -d "$old_path" ]]; then
echo "Absent and not archived: $old_path ($label)" >&2
exit 1
fi
size="$(du -sh "$old_path" 2>/dev/null | awk '{print $1}')"
echo "Candidate: $old_path ($label, $size)"
echo "Active: $active_path"
echo "Archive: $archive_path"
if [[ "$MODE" == "execute" ]]; then
rm -rf --one-file-system "$old_path"
echo "Removed: $old_path"
mv "$old_path" "$archive_path"
printf '%s MOVE %s -> %s size=%s\n' "$(date -Is)" "$old_path" "$archive_path" "$size" >> "$ARCHIVE_ROOT/MANIFEST.txt"
echo "Moved: $archive_path"
else
echo "Dry-run: would remove $old_path"
echo "Dry-run: would move $old_path to $archive_path"
fi
echo
done
echo "Alt-volume release check completed."
echo "Alt-volume archive check completed."