Files
nixos-config/overlays/postgresql-darwin.nix
Christoph Schmatzler acd58a2f53 format
Signed-off-by: Christoph Schmatzler <christoph@schmatzler.com>
2025-08-23 16:05:11 +00:00

80 lines
3.9 KiB
Nix

final: prev: {
postgresql = {
config,
lib,
...
}: let
cfg = config.services.postgresql;
postStartScript = prev.writeScript "postgresql-post-start" ''
#!${prev.bash}/bin/bash
set -e
# Wait for PostgreSQL to be ready
until ${cfg.package}/bin/pg_isready -h localhost -p ${toString cfg.port} -U ${cfg.superUser}; do
sleep 1
done
# Create databases if they don't exist
${prev.lib.concatMapStringsSep "\n" (db: ''
if ! ${cfg.package}/bin/psql -h localhost -p ${toString cfg.port} -U ${cfg.superUser} -lqt | cut -d'|' -f1 | grep -qw ${prev.lib.escapeShellArg db}; then
echo "Creating database: ${prev.lib.escapeShellArg db}"
${cfg.package}/bin/createdb -h localhost -p ${toString cfg.port} -U ${cfg.superUser} ${prev.lib.escapeShellArg db}
fi
'')
cfg.ensureDatabases}
# Create users and set permissions
${prev.lib.concatMapStringsSep "\n" (user: ''
# Create user if it doesn't exist
if ! ${cfg.package}/bin/psql -h localhost -p ${toString cfg.port} -U ${cfg.superUser} -tAc "SELECT 1 FROM pg_roles WHERE rolname='${prev.lib.escapeShellArg user.name}'" | grep -q 1; then
echo "Creating user: ${prev.lib.escapeShellArg user.name}"
${cfg.package}/bin/psql -h localhost -p ${toString cfg.port} -U ${cfg.superUser} -c "CREATE USER \"${prev.lib.escapeShellArg user.name}\""
fi
# Set user privileges
${prev.lib.optionalString (user ? ensureDBOwnership && user.ensureDBOwnership) ''
echo "Setting database ownership for ${prev.lib.escapeShellArg user.name}"
${cfg.package}/bin/psql -h localhost -p ${toString cfg.port} -U ${cfg.superUser} -c "ALTER USER \"${prev.lib.escapeShellArg user.name}\" CREATEDB CREATEROLE"
''}
${prev.lib.optionalString (user ? ensureClauses) ''
${prev.lib.optionalString (user.ensureClauses ? superuser && user.ensureClauses.superuser) ''
echo "Granting superuser to ${prev.lib.escapeShellArg user.name}"
${cfg.package}/bin/psql -h localhost -p ${toString cfg.port} -U ${cfg.superUser} -c "ALTER USER \"${prev.lib.escapeShellArg user.name}\" SUPERUSER"
''}
${prev.lib.optionalString (user.ensureClauses ? createdb && user.ensureClauses.createdb) ''
echo "Granting createdb to ${prev.lib.escapeShellArg user.name}"
${cfg.package}/bin/psql -h localhost -p ${toString cfg.port} -U ${cfg.superUser} -c "ALTER USER \"${prev.lib.escapeShellArg user.name}\" CREATEDB"
''}
''}
# Grant permissions (legacy support)
${prev.lib.concatMapStringsSep "\n" (perm: ''
echo "Granting ${prev.lib.escapeShellArg perm} to ${prev.lib.escapeShellArg user.name}"
${cfg.package}/bin/psql -h localhost -p ${toString cfg.port} -U ${cfg.superUser} -c "GRANT ${prev.lib.escapeShellArg perm} TO \"${prev.lib.escapeShellArg user.name}\""
'') (prev.lib.optionals (user ? ensurePermissions) (prev.lib.mapAttrsToList (target: perm: "${perm} ON ${target}") user.ensurePermissions))}
'')
cfg.ensureUsers}
# Run initial script if provided
${prev.lib.optionalString (cfg.initialScript != null) ''
echo "Running initial script"
${cfg.package}/bin/psql -h localhost -p ${toString cfg.port} -U ${cfg.superUser} -f ${cfg.initialScript}
''}
'';
in {
config = prev.lib.mkIf cfg.enable {
launchd.user.agents.postgresql = prev.lib.mkIf (cfg.ensureDatabases != [] || cfg.ensureUsers != [] || cfg.initialScript != null) {
script = prev.lib.mkAfter ''
# Run post-start script in background after PostgreSQL starts
(
sleep 5 # Give PostgreSQL a moment to fully start
${prev.bash}/bin/bash ${postStartScript}
) &
'';
};
};
};
}