mirror of
https://github.com/NixOS/nixpkgs.git
synced 2025-01-22 14:45:27 +00:00
nixos/postgresql: add ensureDatabases & ensureUsers options (#56720)
nixos/postgresql: add ensureDatabases & ensureUsers options
This commit is contained in:
commit
cd96b50d90
|
@ -105,6 +105,80 @@ in
|
|||
'';
|
||||
};
|
||||
|
||||
ensureDatabases = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [];
|
||||
description = ''
|
||||
Ensures that the specified databases exist.
|
||||
This option will never delete existing databases, especially not when the value of this
|
||||
option is changed. This means that databases created once through this option or
|
||||
otherwise have to be removed manually.
|
||||
'';
|
||||
example = [
|
||||
"gitea"
|
||||
"nextcloud"
|
||||
];
|
||||
};
|
||||
|
||||
ensureUsers = mkOption {
|
||||
type = types.listOf (types.submodule {
|
||||
options = {
|
||||
name = mkOption {
|
||||
type = types.str;
|
||||
description = ''
|
||||
Name of the user to ensure.
|
||||
'';
|
||||
};
|
||||
ensurePermissions = mkOption {
|
||||
type = types.attrsOf types.str;
|
||||
default = {};
|
||||
description = ''
|
||||
Permissions to ensure for the user, specified as an attribute set.
|
||||
The attribute names specify the database and tables to grant the permissions for.
|
||||
The attribute values specify the permissions to grant. You may specify one or
|
||||
multiple comma-separated SQL privileges here.
|
||||
|
||||
For more information on how to specify the target
|
||||
and on which privileges exist, see the
|
||||
<link xlink:href="https://www.postgresql.org/docs/current/sql-grant.html">GRANT syntax</link>.
|
||||
The attributes are used as <code>GRANT ''${attrName} ON ''${attrValue}</code>.
|
||||
'';
|
||||
example = literalExample ''
|
||||
{
|
||||
"DATABASE nextcloud" = "ALL PRIVILEGES";
|
||||
"ALL TABLES IN SCHEMA public" = "ALL PRIVILEGES";
|
||||
}
|
||||
'';
|
||||
};
|
||||
};
|
||||
});
|
||||
default = [];
|
||||
description = ''
|
||||
Ensures that the specified users exist and have at least the ensured permissions.
|
||||
The PostgreSQL users will be identified using peer authentication. This authenticates the Unix user with the
|
||||
same name only, and that without the need for a password.
|
||||
This option will never delete existing users or remove permissions, especially not when the value of this
|
||||
option is changed. This means that users created and permissions assigned once through this option or
|
||||
otherwise have to be removed manually.
|
||||
'';
|
||||
example = literalExample ''
|
||||
[
|
||||
{
|
||||
name = "nextcloud";
|
||||
ensurePermissions = {
|
||||
"DATABASE nextcloud" = "ALL PRIVILEGES";
|
||||
};
|
||||
}
|
||||
{
|
||||
name = "superuser";
|
||||
ensurePermissions = {
|
||||
"ALL TABLES IN SCHEMA public" = "ALL PRIVILEGES";
|
||||
};
|
||||
}
|
||||
]
|
||||
'';
|
||||
};
|
||||
|
||||
enableTCPIP = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
|
@ -256,17 +330,30 @@ in
|
|||
# Wait for PostgreSQL to be ready to accept connections.
|
||||
postStart =
|
||||
''
|
||||
while ! ${pkgs.sudo}/bin/sudo -u ${cfg.superUser} psql --port=${toString cfg.port} -d postgres -c "" 2> /dev/null; do
|
||||
PSQL="${pkgs.sudo}/bin/sudo -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) ''
|
||||
${pkgs.sudo}/bin/sudo -u ${cfg.superUser} psql -f "${cfg.initialScript}" --port=${toString cfg.port} -d postgres
|
||||
$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}
|
||||
'';
|
||||
|
||||
unitConfig.RequiresMountsFor = "${cfg.dataDir}";
|
||||
|
|
|
@ -7,7 +7,7 @@ with import ../lib/testing.nix { inherit system pkgs; };
|
|||
with pkgs.lib;
|
||||
|
||||
let
|
||||
redmineTest = package: makeTest {
|
||||
mysqlTest = package: makeTest {
|
||||
machine =
|
||||
{ config, pkgs, ... }:
|
||||
{ services.mysql.enable = true;
|
||||
|
@ -21,6 +21,7 @@ let
|
|||
|
||||
services.redmine.enable = true;
|
||||
services.redmine.package = package;
|
||||
services.redmine.database.type = "mysql2";
|
||||
services.redmine.database.socket = "/run/mysqld/mysqld.sock";
|
||||
services.redmine.plugins = {
|
||||
redmine_env_auth = pkgs.fetchurl {
|
||||
|
@ -38,7 +39,44 @@ let
|
|||
|
||||
testScript = ''
|
||||
startAll;
|
||||
$machine->waitForUnit('redmine.service');
|
||||
$machine->waitForOpenPort('3000');
|
||||
$machine->succeed("curl --fail http://localhost:3000/");
|
||||
'';
|
||||
};
|
||||
|
||||
pgsqlTest = package: makeTest {
|
||||
machine =
|
||||
{ config, pkgs, ... }:
|
||||
{ services.postgresql.enable = true;
|
||||
services.postgresql.ensureDatabases = [ "redmine" ];
|
||||
services.postgresql.ensureUsers = [
|
||||
{ name = "redmine";
|
||||
ensurePermissions = { "DATABASE redmine" = "ALL PRIVILEGES"; };
|
||||
}
|
||||
];
|
||||
|
||||
services.redmine.enable = true;
|
||||
services.redmine.package = package;
|
||||
services.redmine.database.type = "postgresql";
|
||||
services.redmine.database.host = "";
|
||||
services.redmine.database.port = 5432;
|
||||
services.redmine.plugins = {
|
||||
redmine_env_auth = pkgs.fetchurl {
|
||||
url = https://github.com/Intera/redmine_env_auth/archive/0.7.zip;
|
||||
sha256 = "1xb8lyarc7mpi86yflnlgyllh9hfwb9z304f19dx409gqpia99sc";
|
||||
};
|
||||
};
|
||||
services.redmine.themes = {
|
||||
dkuk-redmine_alex_skin = pkgs.fetchurl {
|
||||
url = https://bitbucket.org/dkuk/redmine_alex_skin/get/1842ef675ef3.zip;
|
||||
sha256 = "0hrin9lzyi50k4w2bd2b30vrf1i4fi1c0gyas5801wn8i7kpm9yl";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
testScript = ''
|
||||
startAll;
|
||||
$machine->waitForUnit('redmine.service');
|
||||
$machine->waitForOpenPort('3000');
|
||||
$machine->succeed("curl --fail http://localhost:3000/");
|
||||
|
@ -46,13 +84,18 @@ let
|
|||
};
|
||||
in
|
||||
{
|
||||
redmine_3 = redmineTest pkgs.redmine // {
|
||||
name = "redmine_3";
|
||||
v3-mysql = mysqlTest pkgs.redmine // {
|
||||
name = "v3-mysql";
|
||||
meta.maintainers = [ maintainers.aanderse ];
|
||||
};
|
||||
|
||||
redmine_4 = redmineTest pkgs.redmine_4 // {
|
||||
name = "redmine_4";
|
||||
v4-mysql = mysqlTest pkgs.redmine_4 // {
|
||||
name = "v4-mysql";
|
||||
meta.maintainers = [ maintainers.aanderse ];
|
||||
};
|
||||
|
||||
v4-pgsql = pgsqlTest pkgs.redmine_4 // {
|
||||
name = "v4-pgsql";
|
||||
meta.maintainers = [ maintainers.aanderse ];
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue