Find the PostgreSQL a machine has, rather than assume its names

server init --postgres failed on Rocky with postgresql-setup not found.
The PostgreSQL project's packages (PGDG) provide "postgresql-server",
so dnf can satisfy that name with postgresql16-server — whose unit is
postgresql-16.service, whose tools are in /usr/pgsql-16/bin and whose
setup script is postgresql-16-setup. The code assumed the distribution's
names for all three.

The server unit is now picked from systemd's postgresql* unit files, its
data directory read from the unit's own PGDATA, and initdb run directly
as postgres when that directory is empty, with password logins over TCP.
psql, initdb and the restart use what was found. The unit names and
PGDATA values in the tests are the ones Rocky's and PGDG's packages ship.

Not yet handled: a server initialised with ident for TCP logins, one on a
port other than 5432, and several PGDG versions where the highest is not
the one on 5432.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Ilker ManapandClaude Opus 5.5 committed 2026-09-28 14:47:55 +02:00
1 parent 2e0465f10a
commit a764cfacbc
3 files changed
+214 -49

No files matched your search

+35
View File
@@ -166,3 +166,38 @@ func TestInitWillNotMoveOnePostgresIntoAnother(t *testing.T) {
t.Fatalf("expected a refusal, got %v\n%s", err, out)
}
}
// The lists below are what `systemctl list-unit-files --type=service
// --no-legend --plain 'postgresql*'` prints on each kind of machine.
func TestPickPostgresUnit(t *testing.T) {
for _, c := range []struct{ name, list, want string }{
{"rocky, distribution package",
"postgresql.service disabled disabled\npostgresql@.service disabled disabled\n", "postgresql.service"},
{"rocky, PGDG package",
"postgresql-16.service disabled disabled\n", "postgresql-16.service"},
{"two PGDG versions",
"postgresql-13.service enabled disabled\npostgresql-16.service disabled disabled\n", "postgresql-16.service"},
{"debian",
"postgresql.service enabled enabled\npostgresql@.service indirect enabled\n", "postgresql.service"},
{"only the template", "postgresql@.service indirect enabled\n", ""},
{"none", "", ""},
} {
if got := pickPostgresUnit(c.list); got != c.want {
t.Errorf("%s: got %q, want %q", c.name, got, c.want)
}
}
}
// What `systemctl show -p Environment --value` prints for each unit, from
// the unit files the packages ship.
func TestPGDATAFromTheUnit(t *testing.T) {
for env, want := range map[string]string{
"PG_OOM_ADJUST_FILE=/proc/self/oom_score_adj PG_OOM_ADJUST_VALUE=0 PGDATA=/var/lib/pgsql/data": "/var/lib/pgsql/data",
"PGDATA=/var/lib/pgsql/16/data/ PG_OOM_ADJUST_FILE=/proc/self/oom_score_adj": "/var/lib/pgsql/16/data/",
"": "",
} {
if got := pgdataFrom(env); got != want {
t.Errorf("%q: got %q, want %q", env, got, want)
}
}
}