install the psql client, matching the server it talks to
there was no psql on this machine. the server runs in a container, so nothing ever put a client on the host, and `docker exec officer-postgres psql` is the owner's tool — a member has their own Postgres role and no access to the owner's Docker socket. the version is derived from PG_IMAGE rather than typed again, because the pairing is load-bearing: pg_dump refuses a server newer than itself, and Ubuntu 24.04 ships client 16 against this 18 server. so the archive package is not merely old, it is unusable for dumps. that is also why this sits beside the server definition instead of in machine-setup's package list — one constant, one place to bump. PGDG added the same way docker.sh adds Docker's: key in its own file, one sources.list.d entry, no add-apt-repository. non-fatal, and the exit status is not the gate — apt can succeed while holding an older client back, so the check is that psql is present AND is the major we asked for. installed by hand on this host already: psql/pg_dump 18.6, verified as green connecting with their own role. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -446,6 +446,11 @@ if ! skip; then
|
||||
echo " network: ${OFFICER_NETWORK} (already there)"
|
||||
fi
|
||||
|
||||
# The client goes on the HOST, before any of the container work, because it is the half
|
||||
# that is not in the container. A member has their own Postgres role and no access to the
|
||||
# owner's Docker socket, so `docker exec … psql` is the owner's tool, not theirs.
|
||||
install_pg_client || ERRORS+=("psql: client not installed — members have no Postgres CLI")
|
||||
|
||||
echo " compose file: $(pg_compose_exists && echo "$(pg_compose_file)" || echo 'not written yet')"
|
||||
echo " container: $(pg_container_running && echo "${PG_CONTAINER} running" || echo 'not running')"
|
||||
echo " port ${PG_PORT}: $(pg_port_in_use && echo 'something is listening' || echo 'free')"
|
||||
|
||||
@@ -39,6 +39,73 @@ PG_DATABASE="${PG_DATABASE:-officer}"
|
||||
PG_CONTAINER="${PG_CONTAINER:-officer-postgres}"
|
||||
PG_PORT="${PG_PORT:-5432}"
|
||||
|
||||
# ── The CLIENT, on the host, matching the server in the container ──
|
||||
#
|
||||
# `psql` was on no install. The server runs in Docker, so nothing ever put a client on the
|
||||
# host, and `docker exec officer-postgres psql` is not a substitute for a member: they have
|
||||
# their own Postgres role (`provisionPostgresRole` for Developers) and no access to the
|
||||
# owner's Docker socket.
|
||||
#
|
||||
# The version is derived from PG_IMAGE rather than typed again, because the pairing is not
|
||||
# cosmetic: **pg_dump refuses a server newer than itself** ("server version 18.6, pg_dump
|
||||
# version 16.x — aborting"). Ubuntu 24.04 ships client 16 against this 18 server, so the
|
||||
# archive package is not merely old, it is unusable for dumps. That is also why this lives
|
||||
# beside the server definition rather than in machine-setup's package list — one constant,
|
||||
# one place to bump.
|
||||
pg_client_major() { sed -E 's/^postgres:([0-9]+).*/\1/' <<<"$PG_IMAGE"; }
|
||||
|
||||
pg_client_installed() {
|
||||
command -v psql >/dev/null 2>&1 && [[ "$(psql --version | grep -oE '[0-9]+' | head -1)" == "$(pg_client_major)" ]]
|
||||
}
|
||||
|
||||
# PGDG, added the same way docker.sh adds Docker's: key to its own file, one sources.list.d
|
||||
# entry, no add-apt-repository. Non-fatal — an install without psql is a working platform,
|
||||
# just a more annoying one to operate.
|
||||
install_pg_client() {
|
||||
local major codename
|
||||
major="$(pg_client_major)"
|
||||
[[ -n "$major" ]] || {
|
||||
warn "could not read a major version out of PG_IMAGE=${PG_IMAGE} — skipping the client"
|
||||
return 1
|
||||
}
|
||||
|
||||
if pg_client_installed; then
|
||||
ok "psql ${major} already installed"
|
||||
return 0
|
||||
fi
|
||||
|
||||
codename="$(. /etc/os-release && echo "${VERSION_CODENAME:-}")"
|
||||
[[ -n "$codename" ]] || {
|
||||
warn "could not work out this release's codename — cannot add the PostgreSQL repository"
|
||||
return 1
|
||||
}
|
||||
|
||||
install -d -m 0755 /usr/share/postgresql-common/pgdg
|
||||
curl -fsSL https://www.postgresql.org/media/keys/ACCC4CF8.asc \
|
||||
-o /usr/share/postgresql-common/pgdg/apt.postgresql.org.asc || {
|
||||
warn "could not fetch the PostgreSQL signing key"
|
||||
return 1
|
||||
}
|
||||
chmod a+r /usr/share/postgresql-common/pgdg/apt.postgresql.org.asc
|
||||
echo "deb [signed-by=/usr/share/postgresql-common/pgdg/apt.postgresql.org.asc] https://apt.postgresql.org/pub/repos/apt ${codename}-pgdg main" \
|
||||
>/etc/apt/sources.list.d/pgdg.list
|
||||
|
||||
DEBIAN_FRONTEND=noninteractive NEEDRESTART_MODE=a apt-get update -qq || true
|
||||
DEBIAN_FRONTEND=noninteractive NEEDRESTART_MODE=a apt-get install -y -qq "postgresql-client-${major}" || {
|
||||
warn "postgresql-client-${major} did not install"
|
||||
return 1
|
||||
}
|
||||
|
||||
# The exit status is not the gate — same lesson as rootless Docker and the claude CLI: what
|
||||
# matters is whether the binary is there AND is the version we asked for, because apt can
|
||||
# succeed while holding an older client back.
|
||||
pg_client_installed || {
|
||||
warn "psql is not version ${major} after installing — check: apt-cache policy postgresql-client-${major}"
|
||||
return 1
|
||||
}
|
||||
ok "psql $(psql --version | grep -oE '[0-9]+\.[0-9]+' | head -1) installed for every account on this machine"
|
||||
}
|
||||
|
||||
docker_network_exists() { docker network inspect "$OFFICER_NETWORK" &>/dev/null; }
|
||||
ensure_docker_network() {
|
||||
docker_network_exists && return 1
|
||||
|
||||
Reference in New Issue
Block a user