197 lines
5.8 KiB
Nix
197 lines
5.8 KiB
Nix
{ pkgs }:
|
|
let
|
|
inherit (pkgs) lib;
|
|
runtime = ".compose";
|
|
in
|
|
{
|
|
mkWrapper =
|
|
{
|
|
config,
|
|
name,
|
|
enableTui ? false,
|
|
modules ? [ ],
|
|
}:
|
|
let
|
|
merged_config = lib.foldl' (acc: elem: lib.recursiveUpdate acc elem) config modules;
|
|
# checks = lib.concatStringsSep "\n" (
|
|
# lib.concatMap (
|
|
# attrs:
|
|
# lib.mapAttrsToList (k: v: ''
|
|
# echo "Running ${k}"
|
|
# ${v}/bin/check
|
|
# echo "Passed ${k}"
|
|
# '') attrs.checks
|
|
# ) modules
|
|
# );
|
|
removeNullAndEmptyAttrs =
|
|
attrs:
|
|
let
|
|
f = lib.filterAttrsRecursive (key: value: value != null && value != { });
|
|
in
|
|
# filterAttrsRecursive doesn't delete the *resulting* empty attrs, so we must
|
|
# evaluate it again and to get rid of it.
|
|
lib.pipe attrs [
|
|
f
|
|
f
|
|
];
|
|
toPCJson =
|
|
name: attrs:
|
|
pkgs.writeTextFile {
|
|
name = "process-compose-${name}.json";
|
|
text = builtins.toJSON attrs;
|
|
};
|
|
configFile = toPCJson name (
|
|
removeNullAndEmptyAttrs (
|
|
merged_config
|
|
// {
|
|
is_tui_disabled = !enableTui;
|
|
}
|
|
)
|
|
);
|
|
in
|
|
# {
|
|
# inherit configFile merged_config;
|
|
# };
|
|
pkgs.writeShellApplication {
|
|
inherit name;
|
|
text = ''
|
|
|
|
PC_CONFIG_FILES=${configFile} RUNTIME_PATH=$(pwd)/${runtime} ${pkgs.process-compose}/bin/process-compose "$@"
|
|
'';
|
|
};
|
|
mkPostgres =
|
|
{
|
|
name,
|
|
default_config ? true,
|
|
config ? { },
|
|
extra_config ? '''',
|
|
package ? pkgs.postgresql,
|
|
port ? 5432,
|
|
listen_addresses ? "localhost",
|
|
initialDatabases ? [ ],
|
|
...
|
|
}:
|
|
let
|
|
merged_config =
|
|
(
|
|
if default_config then
|
|
{
|
|
listen_addresses = "localhost";
|
|
port = 5432;
|
|
shared_buffers = "128MB";
|
|
work_mem = "4MB";
|
|
logging_collector = false;
|
|
|
|
}
|
|
else
|
|
{ }
|
|
)
|
|
// config
|
|
// {
|
|
unix_socket_directories = ".";
|
|
inherit port listen_addresses;
|
|
};
|
|
toStr =
|
|
value:
|
|
if true == value then
|
|
"yes"
|
|
else if false == value then
|
|
"no"
|
|
else if lib.isString value then
|
|
"'${lib.replaceStrings [ "'" ] [ "''" ] value}'"
|
|
else
|
|
builtins.toString value;
|
|
configFile = pkgs.writeTextFile {
|
|
name = "postgresql.conf";
|
|
text = lib.concatStringsSep "\n" (
|
|
lib.mapAttrsToList (n: v: "${n} = ${toStr v}") (
|
|
lib.filterAttrs (lib.const (x: x != null)) merged_config
|
|
)
|
|
);
|
|
};
|
|
setupInitialDatabases =
|
|
if initialDatabases != [ ] then
|
|
(lib.concatMapStrings (db: ''
|
|
echo "Checking presence of database ${db.name}"
|
|
dbAlreadyExists="$(echo "SELECT 1 AS result FROM pg_database WHERE datname='${db.name}';" | psql --dbname postgres | ${pkgs.gnugrep}/bin/grep -c 'exists = "1"' || true)"
|
|
echo "$dbAlreadyExists"
|
|
if [ 1 -ne "$dbAlreadyExists" ]; then
|
|
echo "Creating database ${db.name}"
|
|
echo 'CREATE DATABASE "${db.name}";' | psql --dbname postgres
|
|
${lib.optionalString (db.user != null && db.password != null) ''
|
|
echo "Creating user ${db.user}"
|
|
psql --dbname postgres <<'EOF'
|
|
DO $$
|
|
BEGIN
|
|
CREATE ROLE "${db.user}" WITH LOGIN PASSWORD '${db.password}';
|
|
EXCEPTION WHEN duplicate_object THEN RAISE NOTICE '%, skipping', SQLERRM USING ERRCODE = SQLSTATE;
|
|
END
|
|
$$;
|
|
GRANT ALL PRIVILEGES ON DATABASE "${db.name}" TO "${db.user}";
|
|
\c ${db.name}
|
|
GRANT ALL PRIVILEGES ON SCHEMA public TO "${db.user}";
|
|
EOF
|
|
''}
|
|
else
|
|
echo "Database ${db.name} already exists"
|
|
fi
|
|
'') initialDatabases)
|
|
else
|
|
"";
|
|
setupScript = pkgs.writeShellApplication {
|
|
name = "setup-postgres";
|
|
runtimeInputs = [
|
|
package
|
|
pkgs.coreutils
|
|
];
|
|
text = ''
|
|
POSTGRES_RUN_INITIAL_SCRIPT="false"
|
|
if [[ ! -d "$PGDATA" ]]; then
|
|
initdb --no-instructions
|
|
POSTGRES_RUN_INITIAL_SCRIPT="true"
|
|
echo
|
|
echo "PostgreSQL initdb process completed"
|
|
echo
|
|
fi
|
|
cp ${configFile} "$PGDATA"/postgresql.conf
|
|
if [[ "$POSTGRES_RUN_INITIAL_SCRIPT" == "true" ]]; then
|
|
echo
|
|
echo "PostgreSQL is setting up the initial database"
|
|
echo
|
|
pg_ctl -w start -o "-c listen_addresses= -p ${builtins.toString port}"
|
|
${setupInitialDatabases}
|
|
pg_ctl -m fast -w stop
|
|
else
|
|
echo
|
|
echo "Database directory exists. Skipping initialization"
|
|
echo
|
|
fi
|
|
unset POSTGRES_RUN_INITIAL_SCRIPT
|
|
'';
|
|
};
|
|
|
|
script = pkgs.writeShellApplication {
|
|
name = "run-postgres";
|
|
text = ''
|
|
set -euo pipefail
|
|
PGDATA=$RUNTIME_PATH/${name}
|
|
PGHOST=$RUNTIME_PATH/${name}
|
|
PGPORT=${builtins.toString port}
|
|
echo "Starting postgres with PGDATA=''${PGDATA} PGHOST=''${PGHOST} PGPORT=''${PGPORT}"
|
|
export PGDATA PGHOST PGPORT
|
|
${setupScript}/bin/setup-postgres
|
|
${package}/bin/postgres
|
|
'';
|
|
};
|
|
in
|
|
# configFileCheck = pkgs.runCommand {} ''
|
|
# ${package}/bin/postgres -D${configFile} -C config_file
|
|
# touch $out
|
|
# '';
|
|
{
|
|
processes."${name}" = {
|
|
command = "${script}/bin/run-postgres";
|
|
};
|
|
};
|
|
}
|