fix(replicas): reach publisher via unix socket or sudo postgres

TCP 127.0.0.1:15432 is often closed; the cluster listens on a unix
socket. Fall back to /var/run/postgresql then runuser -u postgres.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-08-18 12:59:45 +03:30
co-authored by Cursor
parent 1cc5e09b5f
commit 82f63d224e
+85 -5
View File
@@ -81,6 +81,9 @@ resolve_publisher_dsn() {
} }
PUBLISHER="$(resolve_publisher_dsn)" || exit 1 PUBLISHER="$(resolve_publisher_dsn)" || exit 1
PUBLISHER_MODE="dsn"
PUB_PORT=""
PUB_DB="superadmin"
mapfile -t REPLICAS < <( mapfile -t REPLICAS < <(
printf '%s\n' "$REPLICA_DSNS" | tr ',' '\n' | sed 's/^[[:space:]]*//;s/[[:space:]]*$//' | grep -v '^$' printf '%s\n' "$REPLICA_DSNS" | tr ',' '\n' | sed 's/^[[:space:]]*//;s/[[:space:]]*$//' | grep -v '^$'
@@ -107,14 +110,91 @@ label() {
echo "${host:-?}:${port:-5432}/${db:-?}" echo "${host:-?}:${port:-5432}/${db:-?}"
} }
if ! run_psql "$(libpq_dsn "$PUBLISHER")" -v ON_ERROR_STOP=1 -At -c "SELECT 1" >/dev/null 2>&1; then as_postgres() {
echo "Cannot connect to publisher ($(label "$PUBLISHER"))." >&2 if command -v runuser >/dev/null; then
echo "Add PUBLISHER_DSN to deploy/replicas.env — URL-encode @ in passwords as %40." >&2 runuser -u postgres -- "$@"
else
sudo -n -u postgres -- "$@"
fi
}
publisher_port() {
local src="${PUBLISHER:-}${DATABASE_URL:-}"
if [[ "$src" =~ :([0-9]{4,5})/ ]]; then
echo "${BASH_REMATCH[1]}"
return
fi
if [[ "$src" =~ port=([0-9]+) ]]; then
echo "${BASH_REMATCH[1]}"
return
fi
echo "15432"
}
probe_dsn() {
local dsn="$1"
run_psql "$(libpq_dsn "$dsn")" -v ON_ERROR_STOP=1 -At -c "SELECT 1" >/dev/null
}
connect_publisher() {
PUB_PORT="$(publisher_port)"
echo "publisher probe port=$PUB_PORT dsn=$(label "$PUBLISHER")"
if probe_dsn "$PUBLISHER"; then
PUBLISHER_MODE="dsn"
echo "publisher: TCP/DSN ok"
return 0
fi
echo "publisher: TCP/DSN failed (cluster is often unix-socket only on this host)"
local sock="host=/var/run/postgresql port=${PUB_PORT} dbname=${PUB_DB} user=postgres"
if probe_dsn "$sock"; then
PUBLISHER="$sock"
PUBLISHER_MODE="socket"
echo "publisher: unix socket as postgres ok"
return 0
fi
if as_postgres psql -p "$PUB_PORT" -d "$PUB_DB" -v ON_ERROR_STOP=1 -At -c "SELECT 1" </dev/null >/dev/null; then
PUBLISHER_MODE="sudo"
echo "publisher: runuser/sudo -u postgres ok (port $PUB_PORT)"
return 0
fi
echo "Cannot connect to publisher." >&2
echo "Tried: $(label "$PUBLISHER") then unix socket then sudo -u postgres -p $PUB_PORT" >&2
echo "Debug:" >&2
run_psql "$(libpq_dsn "$PUBLISHER")" -c "SELECT 1" || true
as_postgres psql -p "$PUB_PORT" -d "$PUB_DB" -c "SELECT 1" || true
ss -lntp 2>/dev/null | grep -E "$PUB_PORT|postgres" || netstat -lntp 2>/dev/null | grep postgres || true
exit 1 exit 1
fi }
publisher_psql() {
if [[ "$PUBLISHER_MODE" == "sudo" ]]; then
as_postgres psql -p "$PUB_PORT" -d "$PUB_DB" "$@" </dev/null
else
run_psql "$(libpq_dsn "$PUBLISHER")" "$@"
fi
}
publisher_dump() {
if [[ "$PUBLISHER_MODE" == "sudo" ]]; then
as_postgres pg_dump -p "$PUB_PORT" -d "$PUB_DB" "$@"
else
pg_dump "$(libpq_dsn "$PUBLISHER")" "$@"
fi
}
connect_publisher
table_count() { table_count() {
local dsn="$1" table="$2" local dsn="$1" table="$2"
if [[ "$dsn" == "$PUBLISHER" ]]; then
publisher_psql -v ON_ERROR_STOP=1 -At -c \
"SELECT count(*)::bigint FROM public.\"$table\""
return
fi
run_psql "$(libpq_dsn "$dsn")" -v ON_ERROR_STOP=1 -At -c \ run_psql "$(libpq_dsn "$dsn")" -v ON_ERROR_STOP=1 -At -c \
"SELECT count(*)::bigint FROM public.\"$table\"" "SELECT count(*)::bigint FROM public.\"$table\""
} }
@@ -157,7 +237,7 @@ copy_table_from_publisher() {
local replica_dsn="$1" table="$2" local replica_dsn="$1" table="$2"
local dump local dump
dump="$(mktemp)" dump="$(mktemp)"
pg_dump "$(libpq_dsn "$PUBLISHER")" \ publisher_dump \
-t "$table" \ -t "$table" \
--data-only \ --data-only \
--no-owner \ --no-owner \