bliss/switch-bliss-data.sh
2026-08-02 23:00:26 -04:00

94 lines
2.5 KiB
Bash
Executable file

#!/usr/bin/env bash
set -Eeuo pipefail
usage() {
echo "Usage: $0 BACKUP.tar.gz" >&2
}
if [[ "$#" -ne 1 ]]; then
usage
exit 2
fi
ROOT_DIR="$(cd "$(dirname "$0")" && pwd)"
INPUT="$1"
if [[ "$INPUT" != /* ]]; then
INPUT="$(cd "$(dirname "$INPUT")" && pwd)/$(basename "$INPUT")"
fi
test -f "$INPUT" || { echo "Archive not found: $INPUT" >&2; exit 1; }
gzip -t "$INPUT"
STAGE="$(mktemp -d "$ROOT_DIR/.data-switch.XXXXXX")"
OLD="$(mktemp -d "$ROOT_DIR/.data-previous.XXXXXX")"
COMMITTED=false
cleanup() {
rm -rf "$STAGE"
if [[ "$COMMITTED" == false ]]; then
if [[ -d "$OLD/public" ]]; then
rm -rf "$ROOT_DIR/public"
mv "$OLD/public" "$ROOT_DIR/public"
fi
if [[ -d "$OLD/dbs" ]]; then
rm -rf "$ROOT_DIR/dbs"
mv "$OLD/dbs" "$ROOT_DIR/dbs"
fi
fi
rm -rf "$OLD"
}
trap cleanup EXIT
tar -C "$STAGE" -xzf "$INPUT"
test -d "$STAGE/public" || { echo "Archive has no public/ directory" >&2; exit 1; }
test -d "$STAGE/dbs" || { echo "Archive has no dbs/ directory" >&2; exit 1; }
mapfile -t DATABASES < <(find "$STAGE/dbs" -maxdepth 1 -type f -name '*.sqlite' -print)
if [[ "${#DATABASES[@]}" -eq 0 ]]; then
echo "Archive contains no SQLite databases" >&2
exit 1
fi
for database in "${DATABASES[@]}"; do
DB_FILE="$database" node <<'NODE'
const Database = require("better-sqlite3");
const db = new Database(process.env.DB_FILE, { readonly: true });
const result = db.pragma("quick_check", { simple: true });
db.close();
if (result !== "ok") {
console.error(`${process.env.DB_FILE}: quick_check returned ${result}`);
process.exit(1);
}
NODE
done
for process_dir in /proc/[0-9]*; do
PROCESS_CWD="$(readlink "$process_dir/cwd" 2>/dev/null || true)"
PROCESS_CMD="$(tr '\0' ' ' < "$process_dir/cmdline" 2>/dev/null || true)"
if [[ "$PROCESS_CWD" == "$ROOT_DIR" ]] &&
[[ "$PROCESS_CMD" =~ (^|[[:space:]])(\./)?index\.js([[:space:]]|$) ]]; then
echo "Refusing to switch data while the local Bliss server is running." >&2
echo "Stop it first, then rerun this command." >&2
exit 1
fi
done
STAMP="$(date +%Y%m%d-%H%M%S)"
PREVIOUS="$ROOT_DIR/backups/bliss-local-before-$STAMP.tar.gz"
mkdir -p "$ROOT_DIR/backups"
echo "Saving current local data to $PREVIOUS"
tar -C "$ROOT_DIR" -czf "$PREVIOUS" public dbs
gzip -t "$PREVIOUS"
mv "$ROOT_DIR/public" "$OLD/public"
mv "$ROOT_DIR/dbs" "$OLD/dbs"
mv "$STAGE/public" "$ROOT_DIR/public"
mv "$STAGE/dbs" "$ROOT_DIR/dbs"
COMMITTED=true
echo "Activated data from: $INPUT"
echo "Previous local data: $PREVIOUS"
echo "To switch back:"
printf ' %q %q\n' "$0" "$PREVIOUS"