2009-12-03 12:20:24 +00:00
|
|
|
{ config, pkgs, ... }:
|
|
|
|
|
|
|
|
with pkgs.lib;
|
2009-03-06 12:27:02 +00:00
|
|
|
|
2007-12-03 04:48:31 +00:00
|
|
|
let
|
|
|
|
|
2008-02-18 11:56:43 +00:00
|
|
|
cfg = config.services.postgresql;
|
|
|
|
|
2010-05-09 21:42:00 +01:00
|
|
|
# see description of extraPlugins
|
|
|
|
postgresqlAndPlugins = pg:
|
|
|
|
if cfg.extraPlugins == [] then pg
|
2010-11-03 22:37:39 +00:00
|
|
|
else pkgs.buildEnv {
|
2012-03-19 18:06:18 +00:00
|
|
|
name = "postgresql-and-plugins-${(builtins.parseDrvName pg.name).version}";
|
2010-05-09 21:42:00 +01:00
|
|
|
paths = [ pg ] ++ cfg.extraPlugins;
|
2010-11-03 22:37:39 +00:00
|
|
|
postBuild =
|
|
|
|
''
|
|
|
|
mkdir -p $out/bin
|
|
|
|
rm $out/bin/{pg_config,postgres,pg_ctl}
|
|
|
|
cp --target-directory=$out/bin ${pg}/bin/{postgres,pg_config,pg_ctl}
|
|
|
|
'';
|
|
|
|
};
|
2010-05-09 21:42:00 +01:00
|
|
|
|
2012-08-15 22:01:19 +01:00
|
|
|
postgresql = postgresqlAndPlugins cfg.package;
|
2008-02-18 11:56:43 +00:00
|
|
|
|
2009-12-03 12:20:24 +00:00
|
|
|
flags = optional cfg.enableTCPIP "-i";
|
2009-05-15 09:00:20 +01:00
|
|
|
|
2009-12-02 17:18:25 +00:00
|
|
|
# The main PostgreSQL configuration file.
|
|
|
|
configFile = pkgs.writeText "postgresql.conf"
|
|
|
|
''
|
|
|
|
hba_file = '${pkgs.writeText "pg_hba.conf" cfg.authentication}'
|
|
|
|
ident_file = '${pkgs.writeText "pg_ident.conf" cfg.identMap}'
|
2013-07-14 03:57:50 +01:00
|
|
|
log_destination = 'stderr'
|
2013-11-27 11:36:32 +00:00
|
|
|
port = ${toString cfg.port}
|
2011-06-27 11:15:26 +01:00
|
|
|
${cfg.extraConfig}
|
2011-09-14 19:20:50 +01:00
|
|
|
'';
|
2009-12-02 17:18:25 +00:00
|
|
|
|
2012-03-19 18:06:18 +00:00
|
|
|
pre84 = versionOlder (builtins.parseDrvName postgresql.name).version "8.4";
|
2012-08-06 16:45:59 +01:00
|
|
|
|
2007-12-03 04:48:31 +00:00
|
|
|
in
|
2008-02-18 11:56:43 +00:00
|
|
|
|
2009-07-15 12:19:11 +01:00
|
|
|
{
|
|
|
|
|
|
|
|
###### interface
|
2011-09-14 19:20:50 +01:00
|
|
|
|
2009-07-15 12:19:11 +01:00
|
|
|
options = {
|
2011-09-14 19:20:50 +01:00
|
|
|
|
2009-07-15 12:19:11 +01:00
|
|
|
services.postgresql = {
|
2011-09-14 19:20:50 +01:00
|
|
|
|
2009-07-15 12:19:11 +01:00
|
|
|
enable = mkOption {
|
2013-10-30 16:37:45 +00:00
|
|
|
type = types.bool;
|
2009-07-15 12:19:11 +01:00
|
|
|
default = false;
|
|
|
|
description = ''
|
|
|
|
Whether to run PostgreSQL.
|
|
|
|
'';
|
|
|
|
};
|
2011-09-14 19:20:50 +01:00
|
|
|
|
2012-08-15 22:01:19 +01:00
|
|
|
package = mkOption {
|
2014-02-27 12:22:04 +00:00
|
|
|
type = types.package;
|
2013-04-04 17:21:51 +01:00
|
|
|
example = literalExample "pkgs.postgresql92";
|
2012-08-15 22:01:19 +01:00
|
|
|
description = ''
|
|
|
|
PostgreSQL package to use.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
2009-07-15 12:19:11 +01:00
|
|
|
port = mkOption {
|
2013-10-30 16:37:45 +00:00
|
|
|
type = types.int;
|
2013-11-27 11:36:32 +00:00
|
|
|
default = 5432;
|
2009-07-15 12:19:11 +01:00
|
|
|
description = ''
|
2013-11-27 11:36:32 +00:00
|
|
|
The port on which PostgreSQL listens.
|
2009-07-15 12:19:11 +01:00
|
|
|
'';
|
|
|
|
};
|
2011-09-14 19:20:50 +01:00
|
|
|
|
2009-07-15 12:19:11 +01:00
|
|
|
dataDir = mkOption {
|
2013-10-30 16:37:45 +00:00
|
|
|
type = types.path;
|
2013-04-05 14:20:50 +01:00
|
|
|
default = "/var/db/postgresql";
|
2009-07-15 12:19:11 +01:00
|
|
|
description = ''
|
|
|
|
Data directory for PostgreSQL.
|
|
|
|
'';
|
|
|
|
};
|
2011-09-14 19:20:50 +01:00
|
|
|
|
2009-07-15 12:19:11 +01:00
|
|
|
authentication = mkOption {
|
2013-10-30 16:37:45 +00:00
|
|
|
type = types.lines;
|
2012-03-19 16:49:13 +00:00
|
|
|
default = "";
|
2009-07-15 12:19:11 +01:00
|
|
|
description = ''
|
2014-01-11 22:01:21 +00:00
|
|
|
Defines how users authenticate themselves to the server. By
|
|
|
|
default, "trust" access to local users will always be granted
|
|
|
|
along with any other custom options. If you do not want this,
|
|
|
|
set this option using "pkgs.lib.mkForce" to override this
|
|
|
|
behaviour.
|
2009-07-15 12:19:11 +01:00
|
|
|
'';
|
|
|
|
};
|
2011-09-14 19:20:50 +01:00
|
|
|
|
2009-12-02 17:18:25 +00:00
|
|
|
identMap = mkOption {
|
2013-10-30 16:37:45 +00:00
|
|
|
type = types.lines;
|
2009-12-02 17:18:25 +00:00
|
|
|
default = "";
|
2009-07-15 12:19:11 +01:00
|
|
|
description = ''
|
2009-12-02 17:18:25 +00:00
|
|
|
Defines the mapping from system users to database users.
|
2009-07-15 12:19:11 +01:00
|
|
|
'';
|
|
|
|
};
|
2011-09-14 19:20:50 +01:00
|
|
|
|
2013-07-14 04:01:48 +01:00
|
|
|
initialScript = mkOption {
|
|
|
|
type = types.nullOr types.path;
|
2013-10-30 16:37:45 +00:00
|
|
|
default = null;
|
2013-07-14 04:01:48 +01:00
|
|
|
description = ''
|
|
|
|
A file containing SQL statements to execute on first startup.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
2009-07-15 12:19:11 +01:00
|
|
|
enableTCPIP = mkOption {
|
2013-10-30 16:37:45 +00:00
|
|
|
type = types.bool;
|
2009-07-15 12:19:11 +01:00
|
|
|
default = false;
|
|
|
|
description = ''
|
2013-11-27 11:36:32 +00:00
|
|
|
Whether PostgreSQL should listen on all network interfaces.
|
|
|
|
If disabled, the database can only be accessed via its Unix
|
|
|
|
domain socket or via TCP connections to localhost.
|
2009-07-15 12:19:11 +01:00
|
|
|
'';
|
|
|
|
};
|
2010-05-09 21:42:00 +01:00
|
|
|
|
|
|
|
extraPlugins = mkOption {
|
2013-10-30 16:37:45 +00:00
|
|
|
type = types.listOf types.path;
|
2010-05-09 21:42:00 +01:00
|
|
|
default = [];
|
2013-10-30 16:37:45 +00:00
|
|
|
example = literalExample "pkgs.postgis";
|
2010-05-09 21:42:00 +01:00
|
|
|
description = ''
|
2010-06-13 21:59:49 +01:00
|
|
|
When this list contains elements a new store path is created.
|
|
|
|
PostgreSQL and the elments are symlinked into it. Then pg_config,
|
2010-05-09 21:42:00 +01:00
|
|
|
postgres and pc_ctl are copied to make them use the new
|
2010-06-13 21:59:49 +01:00
|
|
|
$out/lib directory as pkglibdir. This makes it possible to use postgis
|
2010-05-09 21:42:00 +01:00
|
|
|
without patching the .sql files which reference $libdir/postgis-1.5.
|
|
|
|
'';
|
|
|
|
# Note: the duplication of executables is about 4MB size.
|
|
|
|
# So a nicer solution was patching postgresql to allow setting the
|
|
|
|
# libdir explicitely.
|
|
|
|
};
|
2011-09-14 19:20:50 +01:00
|
|
|
|
2011-06-27 11:15:26 +01:00
|
|
|
extraConfig = mkOption {
|
2013-10-30 16:37:45 +00:00
|
|
|
type = types.lines;
|
2011-06-27 11:15:26 +01:00
|
|
|
default = "";
|
|
|
|
description = "Additional text to be appended to <filename>postgresql.conf</filename>.";
|
|
|
|
};
|
2013-07-14 04:04:10 +01:00
|
|
|
|
|
|
|
recoveryConfig = mkOption {
|
2013-10-30 16:37:45 +00:00
|
|
|
type = types.nullOr types.lines;
|
2013-07-14 04:04:10 +01:00
|
|
|
default = null;
|
|
|
|
description = ''
|
2013-10-30 16:37:45 +00:00
|
|
|
Contents of the <filename>recovery.conf</filename> file.
|
2013-07-14 04:04:10 +01:00
|
|
|
'';
|
|
|
|
};
|
2009-07-15 12:19:11 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
};
|
2008-02-18 11:56:43 +00:00
|
|
|
|
|
|
|
|
2009-07-15 12:19:11 +01:00
|
|
|
###### implementation
|
2011-09-14 19:20:50 +01:00
|
|
|
|
2009-07-15 12:19:11 +01:00
|
|
|
config = mkIf config.services.postgresql.enable {
|
|
|
|
|
2012-03-19 16:49:13 +00:00
|
|
|
services.postgresql.authentication =
|
|
|
|
''
|
|
|
|
# Generated file; do not edit!
|
2012-03-19 18:06:18 +00:00
|
|
|
local all all ident ${optionalString pre84 "sameuser"}
|
2012-03-19 16:49:13 +00:00
|
|
|
host all all 127.0.0.1/32 md5
|
|
|
|
host all all ::1/128 md5
|
|
|
|
'';
|
2012-08-06 16:45:59 +01:00
|
|
|
|
2013-08-23 10:33:24 +01:00
|
|
|
users.extraUsers.postgres =
|
2009-03-06 12:27:02 +00:00
|
|
|
{ name = "postgres";
|
2013-08-23 10:33:24 +01:00
|
|
|
uid = config.ids.uids.postgres;
|
|
|
|
group = "postgres";
|
2009-03-06 12:27:02 +00:00
|
|
|
description = "PostgreSQL server user";
|
2009-07-15 12:19:11 +01:00
|
|
|
};
|
2009-03-06 12:27:02 +00:00
|
|
|
|
2013-08-23 10:33:24 +01:00
|
|
|
users.extraGroups.postgres.gid = config.ids.gids.postgres;
|
2009-03-06 12:27:02 +00:00
|
|
|
|
2009-07-15 12:19:11 +01:00
|
|
|
environment.systemPackages = [postgresql];
|
2009-03-06 12:27:02 +00:00
|
|
|
|
2013-01-16 11:33:18 +00:00
|
|
|
systemd.services.postgresql =
|
2012-12-18 12:40:04 +00:00
|
|
|
{ description = "PostgreSQL Server";
|
2009-03-06 12:27:02 +00:00
|
|
|
|
2012-08-14 23:15:37 +01:00
|
|
|
wantedBy = [ "multi-user.target" ];
|
2012-12-18 12:40:04 +00:00
|
|
|
after = [ "network.target" ];
|
2009-03-06 12:27:02 +00:00
|
|
|
|
2013-04-22 17:56:19 +01:00
|
|
|
environment.PGDATA = cfg.dataDir;
|
2009-11-06 22:56:47 +00:00
|
|
|
|
2012-03-19 16:49:13 +00:00
|
|
|
path = [ pkgs.su postgresql ];
|
|
|
|
|
2009-10-12 18:09:38 +01:00
|
|
|
preStart =
|
|
|
|
''
|
2009-11-06 23:37:31 +00:00
|
|
|
# Initialise the database.
|
2009-03-06 12:27:02 +00:00
|
|
|
if ! test -e ${cfg.dataDir}; then
|
|
|
|
mkdir -m 0700 -p ${cfg.dataDir}
|
2013-11-18 15:51:39 +00:00
|
|
|
if [ "$(id -u)" = 0 ]; then
|
|
|
|
chown -R postgres ${cfg.dataDir}
|
2014-04-12 00:23:03 +01:00
|
|
|
su -s ${pkgs.stdenv.shell} postgres -c 'initdb -U root'
|
2013-11-18 15:51:39 +00:00
|
|
|
else
|
|
|
|
# For non-root operation.
|
|
|
|
initdb
|
|
|
|
fi
|
2009-12-02 17:18:25 +00:00
|
|
|
rm -f ${cfg.dataDir}/*.conf
|
2013-07-14 04:01:48 +01:00
|
|
|
touch "${cfg.dataDir}/.first_startup"
|
2009-03-06 12:27:02 +00:00
|
|
|
fi
|
2009-12-02 17:18:25 +00:00
|
|
|
|
2013-07-14 04:04:10 +01:00
|
|
|
ln -sfn "${configFile}" "${cfg.dataDir}/postgresql.conf"
|
|
|
|
${optionalString (cfg.recoveryConfig != null) ''
|
|
|
|
ln -sfn "${pkgs.writeText "recovery.conf" cfg.recoveryConfig}" \
|
|
|
|
"${cfg.dataDir}/recovery.conf"
|
|
|
|
''}
|
2012-03-19 16:49:13 +00:00
|
|
|
''; # */
|
2009-11-06 23:37:31 +00:00
|
|
|
|
2012-08-06 16:45:59 +01:00
|
|
|
serviceConfig =
|
2012-10-01 21:47:54 +01:00
|
|
|
{ ExecStart = "@${postgresql}/bin/postgres postgres ${toString flags}";
|
|
|
|
User = "postgres";
|
|
|
|
Group = "postgres";
|
|
|
|
PermissionsStartOnly = true;
|
|
|
|
|
|
|
|
# Shut down Postgres using SIGINT ("Fast Shutdown mode"). See
|
2012-04-30 19:15:32 +01:00
|
|
|
# http://www.postgresql.org/docs/current/static/server-shutdown.html
|
2012-10-01 21:27:42 +01:00
|
|
|
KillSignal = "SIGINT";
|
2013-12-03 16:35:57 +00:00
|
|
|
KillMode = "process"; # FIXME: this may cause processes to be left behind in the cgroup even after the final SIGKILL
|
2012-04-30 19:15:32 +01:00
|
|
|
|
2012-03-19 16:49:13 +00:00
|
|
|
# Give Postgres a decent amount of time to clean up after
|
2012-08-06 16:45:59 +01:00
|
|
|
# receiving systemd's SIGINT.
|
2013-05-07 13:59:08 +01:00
|
|
|
TimeoutSec = 120;
|
2012-10-01 21:27:42 +01:00
|
|
|
};
|
2012-10-01 21:47:54 +01:00
|
|
|
|
|
|
|
# Wait for PostgreSQL to be ready to accept connections.
|
|
|
|
postStart =
|
|
|
|
''
|
2014-04-12 00:22:43 +01:00
|
|
|
while ! psql postgres -c "" 2> /dev/null; do
|
2012-12-19 11:59:28 +00:00
|
|
|
if ! kill -0 "$MAINPID"; then exit 1; fi
|
2012-10-01 22:32:03 +01:00
|
|
|
sleep 0.1
|
2012-10-01 21:47:54 +01:00
|
|
|
done
|
2013-07-14 04:01:48 +01:00
|
|
|
|
|
|
|
if test -e "${cfg.dataDir}/.first_startup"; then
|
|
|
|
${optionalString (cfg.initialScript != null) ''
|
2014-04-12 00:22:43 +01:00
|
|
|
cat "${cfg.initialScript}" | psql postgres
|
2013-07-14 04:01:48 +01:00
|
|
|
''}
|
|
|
|
rm -f "${cfg.dataDir}/.first_startup"
|
|
|
|
fi
|
2012-10-01 21:47:54 +01:00
|
|
|
'';
|
2012-10-01 21:53:13 +01:00
|
|
|
|
|
|
|
unitConfig.RequiresMountsFor = "${cfg.dataDir}";
|
2009-10-12 18:09:38 +01:00
|
|
|
};
|
2009-07-15 12:19:11 +01:00
|
|
|
|
2009-03-06 12:27:02 +00:00
|
|
|
};
|
2011-09-14 19:20:50 +01:00
|
|
|
|
2007-12-03 04:48:31 +00:00
|
|
|
}
|