From 7de29bd26f5e514e95d5d261c08f3029337eecb3 Mon Sep 17 00:00:00 2001 From: Oliver Charles Date: Sun, 6 Apr 2014 11:56:43 +0100 Subject: [PATCH 1/2] Create the 'postgres' superuser Old PostgreSQL installations were created using the 'root' database user. In this case, we need to create a new 'postgres' account, as we now assume that this is the superuser account. Unfortunately, these machines will be left with a 'root' user as well (which will have ownership of some databases). While PostgreSQL does let you rename superuser accounts, you can only do that when you are connected as a *different* database user. Thus we'd have to create a special superuser account to do the renaming. As we default to using ident authentication, we would have to create a system level user to do this. This all feels rather complex, so I'm currently opting to keep the 'root' user on these old machines. --- nixos/modules/services/databases/postgresql.nix | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/nixos/modules/services/databases/postgresql.nix b/nixos/modules/services/databases/postgresql.nix index 33ee7244e3f4..08a9cdd9f5da 100644 --- a/nixos/modules/services/databases/postgresql.nix +++ b/nixos/modules/services/databases/postgresql.nix @@ -197,6 +197,7 @@ in fi rm -f ${cfg.dataDir}/*.conf touch "${cfg.dataDir}/.first_startup" + touch "${cfg.dataDir}/postgresql-user-created" fi ln -sfn "${configFile}" "${cfg.dataDir}/postgresql.conf" @@ -230,6 +231,11 @@ in sleep 0.1 done + if ! [ -e ${cfg.dataDir}/postgresql-user-created ]; then + createuser --superuser postgres + touch ${cfg.dataDir}/postgresql-user-created + fi + if test -e "${cfg.dataDir}/.first_startup"; then ${optionalString (cfg.initialScript != null) '' cat "${cfg.initialScript}" | su -s ${pkgs.stdenv.shell} postgres -c 'psql postgres' From e2066841106a6b89093ab685368742efa4e3c2c1 Mon Sep 17 00:00:00 2001 From: Oliver Charles Date: Sun, 6 Apr 2014 12:00:02 +0100 Subject: [PATCH 2/2] Use PostgreSQL 9.3's `pg_isready` to wait for connectivity The postgresql module has a postStart section that waits for a database to accept connections before continuing. However, this assumes various properties about the database - specifically the database user and (implicitly) the database name. This means that for old installations, this command fails because there is no 'postgres' user, and the service never starts. While 7deff39 does create the 'postgres' user, a better solution is to use `pg_isready`, who's sole purpose is to check if the database is accepting connections. This has no dependency on users, so should be more robust. --- nixos/modules/services/databases/postgresql.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nixos/modules/services/databases/postgresql.nix b/nixos/modules/services/databases/postgresql.nix index 08a9cdd9f5da..ed66c15e304d 100644 --- a/nixos/modules/services/databases/postgresql.nix +++ b/nixos/modules/services/databases/postgresql.nix @@ -226,7 +226,7 @@ in # Wait for PostgreSQL to be ready to accept connections. postStart = '' - while ! su -s ${pkgs.stdenv.shell} postgres -c 'psql postgres -c ""' 2> /dev/null; do + while ! ${pkgs.postgresql93}/bin/pg_isready > /dev/null; do if ! kill -0 "$MAINPID"; then exit 1; fi sleep 0.1 done