87 lines
No EOL
3.3 KiB
Nix
87 lines
No EOL
3.3 KiB
Nix
{ config, pkgs, lib, ... }:
|
|
|
|
let
|
|
# Import nodes
|
|
nodes = import ./../../nodes.nix;
|
|
myName = config.hostName;
|
|
myNode = nodes."${myName}";
|
|
|
|
# And mapping
|
|
mapping = import ./../../mapping.nix;
|
|
|
|
cfg = config.services.postgresql;
|
|
|
|
masterNode = nodes.${mapping.db.master};
|
|
masterIP = "172.19.${toString masterNode.zone}.${toString masterNode.id}";
|
|
in
|
|
{
|
|
services.postgresql = {
|
|
enable = true;
|
|
# Force postgres package major version
|
|
# to avoid any unwanted upgrades
|
|
package = pkgs.postgresql_17;
|
|
identMap = ''
|
|
# ArbitraryMapName systemUser DBUser
|
|
superuser_map root postgres
|
|
superuser_map postgres postgres
|
|
'';
|
|
# Replication tasks are not authenticated
|
|
# The wireguard mesh cryptographically
|
|
# ensures the sender is who we expect.
|
|
authentication = lib.mkForce (lib.strings.concatStringsSep "\n" ([''
|
|
#type database DBuser auth-method optional_ident_map
|
|
local all all peer map=superuser_map
|
|
'']
|
|
++ lib.optionals (myName == mapping.db.master)
|
|
(map (slaveName: let slaveNode = nodes.${slaveName}; in
|
|
"host replication replication 172.19.${toString slaveNode.zone}.${toString slaveNode.id}/32 trust"
|
|
) mapping.db.slaves)
|
|
++ lib.optionals (lib.elem myName mapping.db.slaves) [
|
|
"host replication replication ${masterIP}/32 trust"
|
|
]));
|
|
ensureUsers = lib.mkIf (myName == mapping.db.master) [{
|
|
name = "replication";
|
|
ensureClauses.replication = true;
|
|
}];
|
|
settings = {
|
|
listen_addresses = lib.mkForce "localhost,172.19.${toString myNode.zone}.${toString myNode.id}";
|
|
port = 5432;
|
|
log_connections = true;
|
|
log_statement = "none";
|
|
logging_collector = true;
|
|
log_disconnections = true;
|
|
max_wal_senders = 16;
|
|
wal_level = "logical";
|
|
} // lib.optionalAttrs (myName == mapping.db.master) {
|
|
wal_sender_timeout = "60s";
|
|
wal_keep_size = 1000; # In MB
|
|
} // lib.optionalAttrs (lib.elem myName mapping.db.slaves) {
|
|
wal_receiver_timeout = "60s";
|
|
hot_standby = "on";
|
|
primary_conninfo = "host=${masterIP} port=5432 user=replication";
|
|
};
|
|
};
|
|
# This preStart script sync the slaves to the master
|
|
# systemd.services.<name>.preStart has a mergeable type,
|
|
# this code will be prepend to the default one
|
|
systemd.services.postgresql.preStart = lib.mkIf (lib.elem myName mapping.db.slaves) (lib.mkBefore ''
|
|
if ! test -e ${cfg.dataDir}/PG_VERSION; then
|
|
echo "Setting up PostgreSQL slave replication..."
|
|
|
|
# Perform base backup from master
|
|
echo "Starting base backup from master: ${masterIP}"
|
|
${cfg.package}/bin/pg_basebackup \
|
|
-h "${masterIP}" \
|
|
-U replication \
|
|
-p ${toString cfg.settings.port} \
|
|
-D "${cfg.dataDir}" \
|
|
-P \
|
|
-Xs \
|
|
-R
|
|
|
|
echo "PostgreSQL slave setup completed successfully"
|
|
else
|
|
echo "PostgreSQL dataDir not empty, skipping initial master to slave replication"
|
|
fi
|
|
'');
|
|
} |