nixos/mysql: declarative users & databases using Unix socket authentication, ensured on every rebuild.

Changed files
+62
nixos
modules
services
databases
+62
nixos/modules/services/databases/mysql.nix
···
master-password = ${cfg.replication.masterPassword}
master-port = ${toString cfg.replication.masterPort}
''}
${cfg.extraOptions}
'';
···
initialScript = mkOption {
default = null;
description = "A file containing SQL statements to be executed on the first startup. Can be used for granting certain permissions on the database";
};
# FIXME: remove this option; it's a really bad idea.
···
rm /tmp/mysql_init
fi
''; # */
};
···
master-password = ${cfg.replication.masterPassword}
master-port = ${toString cfg.replication.masterPort}
''}
+
${optionalString (cfg.ensureUsers != [])
+
''
+
plugin-load-add = auth_socket.so
+
''}
${cfg.extraOptions}
'';
···
initialScript = mkOption {
default = null;
description = "A file containing SQL statements to be executed on the first startup. Can be used for granting certain permissions on the database";
+
};
+
+
ensureDatabases = mkOption {
+
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 = [
+
"nextcloud"
+
"piwik"
+
];
+
};
+
+
ensureUsers = mkOption {
+
default = [];
+
description = ''
+
Ensures that the specified users exist and have at least the ensured permissions.
+
The MySQL users will be identified using Unix socket 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 = [
+
{
+
name = "nextcloud";
+
ensurePermissions = {
+
"nextcloud.*" = "ALL PRIVILEGES";
+
};
+
}
+
{
+
name = "backup";
+
ensurePermissions = {
+
"*.*" = "SELECT, LOCK TABLES";
+
};
+
}
+
];
};
# FIXME: remove this option; it's a really bad idea.
···
rm /tmp/mysql_init
fi
+
+
${optionalString (cfg.ensureDatabases != []) ''
+
(
+
${concatMapStrings (database: ''
+
echo "CREATE DATABASE IF NOT EXISTS ${database};"
+
'') cfg.ensureDatabases}
+
) | ${mysql}/bin/mysql -u root -N
+
''}
+
+
${concatMapStrings (user:
+
''
+
( echo "CREATE USER IF NOT EXISTS '${user.name}'@'localhost' IDENTIFIED WITH ${if mysql == pkgs.mariadb then "unix_socket" else "auth_socket"};"
+
${concatStringsSep "\n" (mapAttrsToList (database: permission: ''
+
echo "GRANT ${permission} ON ${database} TO '${user.name}'@'localhost';"
+
'') user.ensurePermissions)}
+
) | ${mysql}/bin/mysql -u root -N
+
'') cfg.ensureUsers}
+
''; # */
};