Merge pull request #95294 from aanderse/postgresql-rootless
nixos/postgresql: run ExecStartPost as an unprivileged user
This commit is contained in:
commit
b87b6abd17
2 changed files with 43 additions and 39 deletions
|
@ -676,11 +676,19 @@ services.dokuwiki."mywiki" = {
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
The <xref linkend="opt-services.postgresql.dataDir"/> option is now set to <literal>"/var/lib/postgresql/${cfg.package.psqlSchema}"</literal> regardless of your
|
The <xref linkend="opt-services.postgresql.dataDir"/> option is now set to <literal>"/var/lib/postgresql/${cfg.package.psqlSchema}"</literal> regardless of your
|
||||||
<xref linkend="opt-system.stateVersion"/>. Users with an existing postgresql install that have a <xref linkend="opt-system.stateVersion"/> of <literal>17.09</literal> or below
|
<xref linkend="opt-system.stateVersion"/>. Users with an existing postgresql install that have a <xref linkend="opt-system.stateVersion"/> of <literal>17.03</literal> or below
|
||||||
should double check what the value of their <xref linkend="opt-services.postgresql.dataDir"/> option is (<literal>/var/db/postgresql</literal>) and then explicitly
|
should double check what the value of their <xref linkend="opt-services.postgresql.dataDir"/> option is (<literal>/var/db/postgresql</literal>) and then explicitly
|
||||||
set this value to maintain compatibility:
|
set this value to maintain compatibility:
|
||||||
<programlisting>
|
<programlisting>
|
||||||
services.postgresql.dataDir = "/var/db/postgresql";
|
services.postgresql.dataDir = "/var/db/postgresql";
|
||||||
|
</programlisting>
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
The postgresql module now expects there to be a database super user account called <literal>postgres</literal> regardless of your <xref linkend="opt-system.stateVersion"/>. Users
|
||||||
|
with an existing postgresql install that have a <xref linkend="opt-system.stateVersion"/> of <literal>17.03</literal> or below should run the following SQL statements as a
|
||||||
|
database super admin user before upgrading:
|
||||||
|
<programlisting>
|
||||||
|
CREATE ROLE postgres LOGIN SUPERUSER;
|
||||||
</programlisting>
|
</programlisting>
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
|
|
@ -225,14 +225,15 @@ in
|
||||||
Contents of the <filename>recovery.conf</filename> file.
|
Contents of the <filename>recovery.conf</filename> file.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
superUser = mkOption {
|
superUser = mkOption {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
default= if versionAtLeast config.system.stateVersion "17.09" then "postgres" else "root";
|
default = "postgres";
|
||||||
internal = true;
|
internal = true;
|
||||||
|
readOnly = true;
|
||||||
description = ''
|
description = ''
|
||||||
NixOS traditionally used 'root' as superuser, most other distros use 'postgres'.
|
PostgreSQL superuser account to use for various operations. Internal since changing
|
||||||
From 17.09 we also try to follow this standard. Internal since changing this value
|
this value would lead to breakage while setting up databases.
|
||||||
would lead to breakage while setting up databases.
|
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -310,6 +311,35 @@ in
|
||||||
''}
|
''}
|
||||||
'';
|
'';
|
||||||
|
|
||||||
|
# Wait for PostgreSQL to be ready to accept connections.
|
||||||
|
postStart =
|
||||||
|
''
|
||||||
|
PSQL="psql --port=${toString cfg.port}"
|
||||||
|
|
||||||
|
while ! $PSQL -d postgres -c "" 2> /dev/null; do
|
||||||
|
if ! kill -0 "$MAINPID"; then exit 1; fi
|
||||||
|
sleep 0.1
|
||||||
|
done
|
||||||
|
|
||||||
|
if test -e "${cfg.dataDir}/.first_startup"; then
|
||||||
|
${optionalString (cfg.initialScript != null) ''
|
||||||
|
$PSQL -f "${cfg.initialScript}" -d postgres
|
||||||
|
''}
|
||||||
|
rm -f "${cfg.dataDir}/.first_startup"
|
||||||
|
fi
|
||||||
|
'' + optionalString (cfg.ensureDatabases != []) ''
|
||||||
|
${concatMapStrings (database: ''
|
||||||
|
$PSQL -tAc "SELECT 1 FROM pg_database WHERE datname = '${database}'" | grep -q 1 || $PSQL -tAc 'CREATE DATABASE "${database}"'
|
||||||
|
'') cfg.ensureDatabases}
|
||||||
|
'' + ''
|
||||||
|
${concatMapStrings (user: ''
|
||||||
|
$PSQL -tAc "SELECT 1 FROM pg_roles WHERE rolname='${user.name}'" | grep -q 1 || $PSQL -tAc 'CREATE USER "${user.name}"'
|
||||||
|
${concatStringsSep "\n" (mapAttrsToList (database: permission: ''
|
||||||
|
$PSQL -tAc 'GRANT ${permission} ON ${database} TO "${user.name}"'
|
||||||
|
'') user.ensurePermissions)}
|
||||||
|
'') cfg.ensureUsers}
|
||||||
|
'';
|
||||||
|
|
||||||
serviceConfig = mkMerge [
|
serviceConfig = mkMerge [
|
||||||
{ ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
|
{ ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
|
||||||
User = "postgres";
|
User = "postgres";
|
||||||
|
@ -329,40 +359,6 @@ in
|
||||||
TimeoutSec = 120;
|
TimeoutSec = 120;
|
||||||
|
|
||||||
ExecStart = "${postgresql}/bin/postgres";
|
ExecStart = "${postgresql}/bin/postgres";
|
||||||
|
|
||||||
# Wait for PostgreSQL to be ready to accept connections.
|
|
||||||
ExecStartPost =
|
|
||||||
let
|
|
||||||
setupScript = pkgs.writeScript "postgresql-setup" (''
|
|
||||||
#!${pkgs.runtimeShell} -e
|
|
||||||
|
|
||||||
PSQL="${pkgs.utillinux}/bin/runuser -u ${cfg.superUser} -- psql --port=${toString cfg.port}"
|
|
||||||
|
|
||||||
while ! $PSQL -d postgres -c "" 2> /dev/null; do
|
|
||||||
if ! kill -0 "$MAINPID"; then exit 1; fi
|
|
||||||
sleep 0.1
|
|
||||||
done
|
|
||||||
|
|
||||||
if test -e "${cfg.dataDir}/.first_startup"; then
|
|
||||||
${optionalString (cfg.initialScript != null) ''
|
|
||||||
$PSQL -f "${cfg.initialScript}" -d postgres
|
|
||||||
''}
|
|
||||||
rm -f "${cfg.dataDir}/.first_startup"
|
|
||||||
fi
|
|
||||||
'' + optionalString (cfg.ensureDatabases != []) ''
|
|
||||||
${concatMapStrings (database: ''
|
|
||||||
$PSQL -tAc "SELECT 1 FROM pg_database WHERE datname = '${database}'" | grep -q 1 || $PSQL -tAc 'CREATE DATABASE "${database}"'
|
|
||||||
'') cfg.ensureDatabases}
|
|
||||||
'' + ''
|
|
||||||
${concatMapStrings (user: ''
|
|
||||||
$PSQL -tAc "SELECT 1 FROM pg_roles WHERE rolname='${user.name}'" | grep -q 1 || $PSQL -tAc 'CREATE USER "${user.name}"'
|
|
||||||
${concatStringsSep "\n" (mapAttrsToList (database: permission: ''
|
|
||||||
$PSQL -tAc 'GRANT ${permission} ON ${database} TO "${user.name}"'
|
|
||||||
'') user.ensurePermissions)}
|
|
||||||
'') cfg.ensureUsers}
|
|
||||||
'');
|
|
||||||
in
|
|
||||||
"+${setupScript}";
|
|
||||||
}
|
}
|
||||||
(mkIf (cfg.dataDir == "/var/lib/postgresql/${cfg.package.psqlSchema}") {
|
(mkIf (cfg.dataDir == "/var/lib/postgresql/${cfg.package.psqlSchema}") {
|
||||||
StateDirectory = "postgresql postgresql/${cfg.package.psqlSchema}";
|
StateDirectory = "postgresql postgresql/${cfg.package.psqlSchema}";
|
||||||
|
|
Loading…
Reference in a new issue