postgres: fix the port override properly — a twin variable, not a raw substitution

The first commit on this branch embedded ${seat:mesh-store:5432} directly
inside MESH_PROVISION_POSTGRES's URL. That placeholder resolves to an empty
string whenever mesh-store is on its own default port (novox/hq
internal/catalogue/seat_into.go: 'the mesh raised on the catalogue's own
ports never gives them a setting at all') -- which produces a malformed
connection string (host:/postgres) on exactly the common case, a fresh,
non-adopted mesh. It only worked here because novox's mesh-store happens to
be adopted at a non-default port.

mesh-controller's own manifest already has the right shape for this --
internal/envfile/port.go's NAME / NAME_PORT twin, composed by
mesh-controller's Placed(): the base value keeps its own port; a separate
_PORT variable carries the override, spliced in only when it says
something, and left alone -- not a fault -- when it's an unfilled
placeholder (a manifest ahead of the running controller).

Reverted the manifest to its original base value, added
MESH_PROVISION_POSTGRES_PORT as the twin, and taught client.ts (the only
consumer -- both tools/ and provisioner/ import it) the same precedence
envfile.Placed uses. Checked: no other file in the module reads
MESH_PROVISION_POSTGRES directly.
This commit is contained in:
2026-09-24 15:27:16 +02:00
parent 088022d63b
commit 135101ce6e
2 changed files with 12 additions and 2 deletions
+10 -1
View File
@@ -39,7 +39,16 @@ export class PostgresClient {
static fromEnv(env: NodeJS.ProcessEnv = process.env): PostgresClient {
const url = env.MESH_PROVISION_POSTGRES ? safeUrl(env.MESH_PROVISION_POSTGRES) : undefined;
const host = env.MESH_POSTGRES_HOST ?? url?.hostname;
const port = Number(env.MESH_POSTGRES_PORT ?? url?.port ?? "5432") || 5432;
// MESH_PROVISION_POSTGRES_PORT is the seat's twin (mesh-controller's own
// internal/envfile.Placed pattern): which port this machine actually put mesh-store at, when
// that differs from what the connection string above already says — e.g. adopted in place at
// a predecessor's port. Empty means the mesh has nothing to add and the string's own port
// stands; a placeholder the mesh never filled (a manifest ahead of the running controller)
// is treated the same way, not as a fault.
const seatPort = (env.MESH_PROVISION_POSTGRES_PORT ?? "").trim();
const filledSeatPort = seatPort && !/^\$\{[^}]*\}$/.test(seatPort) ? seatPort : undefined;
const portSource = env.MESH_POSTGRES_PORT ?? filledSeatPort ?? url?.port ?? "5432";
const port = Number(portSource) || 5432;
const user = env.MESH_POSTGRES_USER ?? url?.username ?? "postgres";
const password = env.MESH_POSTGRES_PASSWORD ?? readSecretFile(env.MESH_PROVISION_PASSWORD_FILE);
if (!host || !password) {
+2 -1
View File
@@ -97,7 +97,8 @@
"/var/lib/postgres/superuser.secret:/run/secrets/superuser:ro"
],
"env": {
"MESH_PROVISION_POSTGRES": "postgres://postgres@127.0.0.1:${seat:mesh-store:5432}/postgres?sslmode=disable",
"MESH_PROVISION_POSTGRES": "postgres://postgres@127.0.0.1:5432/postgres?sslmode=disable",
"MESH_PROVISION_POSTGRES_PORT": "${seat:mesh-store:5432}",
"MESH_PROVISION_PASSWORD_FILE": "/run/secrets/superuser",
"MESH_BROKER_FILE": "/run/secrets/broker",
"MESH_RECEIVES": "/var/lib/postgres/grants/mesh.json"