docs(vector): add local backup restore and parity gate
This commit is contained in:
Executable
+78
@@ -0,0 +1,78 @@
|
||||
#!/bin/sh
|
||||
set -eu
|
||||
|
||||
root=$(CDPATH= cd -- "$(dirname "$0")/.." && pwd)
|
||||
. "$root/deploy/vector/secret-policy.sh"
|
||||
|
||||
usage() {
|
||||
echo "usage: $0 --active-host HOST --active-database DB --active-user USER --active-password-file FILE --target-host HOST --target-database DB --target-user USER --target-password-file FILE --input FILE [--active-port PORT] [--target-port PORT] [--force-nonempty]" >&2
|
||||
exit 2
|
||||
}
|
||||
|
||||
active_host= active_database= active_user= active_password_file= active_port=5432
|
||||
target_host= target_database= target_user= target_password_file= target_port=5432
|
||||
input= force=0
|
||||
while [ "$#" -gt 0 ]; do
|
||||
case "$1" in
|
||||
--active-host) active_host=${2-}; shift 2 ;;
|
||||
--active-port) active_port=${2-}; shift 2 ;;
|
||||
--active-database) active_database=${2-}; shift 2 ;;
|
||||
--active-user) active_user=${2-}; shift 2 ;;
|
||||
--active-password-file) active_password_file=${2-}; shift 2 ;;
|
||||
--target-host) target_host=${2-}; shift 2 ;;
|
||||
--target-port) target_port=${2-}; shift 2 ;;
|
||||
--target-database) target_database=${2-}; shift 2 ;;
|
||||
--target-user) target_user=${2-}; shift 2 ;;
|
||||
--target-password-file) target_password_file=${2-}; shift 2 ;;
|
||||
--input) input=${2-}; shift 2 ;;
|
||||
--force-nonempty) force=1; shift ;;
|
||||
*) usage ;;
|
||||
esac
|
||||
done
|
||||
for value in "$active_host" "$active_database" "$active_user" "$active_password_file" \
|
||||
"$target_host" "$target_database" "$target_user" "$target_password_file" "$input"; do
|
||||
[ -n "$value" ] || usage
|
||||
done
|
||||
[ -r "$input" ] || { echo "backup input is not readable" >&2; exit 2; }
|
||||
validate_secret_file "$active_password_file" "active source password file"
|
||||
validate_secret_file "$target_password_file" "target password file"
|
||||
|
||||
umask 077
|
||||
active_pass=$(mktemp "${TMPDIR:-/tmp}/thoth-vector-active-pgpass.XXXXXX")
|
||||
target_pass=$(mktemp "${TMPDIR:-/tmp}/thoth-vector-target-pgpass.XXXXXX")
|
||||
cleanup() { rm -f "$active_pass" "$target_pass"; }
|
||||
trap cleanup EXIT HUP INT TERM
|
||||
make_passfile() {
|
||||
secret=$(read_secret_file "$5" "database password file")
|
||||
escaped=$(printf '%s' "$secret" | sed 's/\\/\\\\/g; s/:/\\:/g')
|
||||
printf '%s:%s:%s:%s:%s\n' "$1" "$2" "$3" "$4" "$escaped" >"$6"
|
||||
chmod 0600 "$6"
|
||||
}
|
||||
make_passfile "$active_host" "$active_port" "$active_database" "$active_user" \
|
||||
"$active_password_file" "$active_pass"
|
||||
make_passfile "$target_host" "$target_port" "$target_database" "$target_user" \
|
||||
"$target_password_file" "$target_pass"
|
||||
|
||||
identity_sql="SELECT system_identifier::text || ':' || d.oid::text FROM pg_control_system(), pg_database d WHERE d.datname = current_database()"
|
||||
active_identity=$(PGPASSFILE=$active_pass psql -XAt --host="$active_host" --port="$active_port" \
|
||||
--username="$active_user" --dbname="$active_database" --command="$identity_sql")
|
||||
target_identity=$(PGPASSFILE=$target_pass psql -XAt --host="$target_host" --port="$target_port" \
|
||||
--username="$target_user" --dbname="$target_database" --command="$identity_sql")
|
||||
[ "$active_identity" != "$target_identity" ] || {
|
||||
echo "refusing restore: active source and target are the same database" >&2; exit 2;
|
||||
}
|
||||
|
||||
object_count=$(PGPASSFILE=$target_pass psql -XAt --host="$target_host" --port="$target_port" \
|
||||
--username="$target_user" --dbname="$target_database" --command="
|
||||
SELECT count(*) FROM pg_class c JOIN pg_namespace n ON n.oid=c.relnamespace
|
||||
WHERE (n.nspname='vectors' OR (n.nspname='public' AND c.relname='tht_vector_migrations'))
|
||||
AND c.relkind IN ('r','p','S','v','m');")
|
||||
if [ "$object_count" != 0 ] && [ "$force" != 1 ]; then
|
||||
echo "refusing restore into non-empty target; use --force-nonempty explicitly" >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
PGPASSFILE=$target_pass pg_restore --exit-on-error --clean --if-exists --no-owner \
|
||||
--host="$target_host" --port="$target_port" --username="$target_user" \
|
||||
--dbname="$target_database" "$input"
|
||||
echo "Vector restore completed into explicit target $target_host:$target_port/$target_database"
|
||||
Reference in New Issue
Block a user