diff --git a/nixos/modules/services/databases/mysql.nix b/nixos/modules/services/databases/mysql.nix index 467feb09b3a3..89291d4438ff 100644 --- a/nixos/modules/services/databases/mysql.nix +++ b/nixos/modules/services/databases/mysql.nix @@ -103,6 +103,24 @@ in }; initialDatabases = mkOption { + type = types.listOf (types.submodule { + options = { + name = mkOption { + type = types.str; + description = '' + The name of the database to create. + ''; + }; + schema = mkOption { + type = types.nullOr types.path; + default = null; + description = '' + The initial schema of the database; if null (the default), + an empty database is created. + ''; + }; + }; + }); default = []; description = '' List of database names and their initial schemas that should be used to create databases on the first startup @@ -115,11 +133,13 @@ in }; initialScript = mkOption { + type = types.nullOr types.lines; 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 { + type = types.listOf types.str; default = []; description = '' Ensures that the specified databases exist. @@ -134,6 +154,38 @@ in }; 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 attribute set. + The attribute names specify the database and tables to grant the permissions for, + separated by a dot. You may use wildcards here. + The attribute values specfiy 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 + GRANT syntax. + The attributes are used as GRANT ''${attrName} ON ''${attrValue}. + ''; + example = literalExample '' + { + "database.*" = "ALL PRIVILEGES"; + "*.*" = "SELECT, LOCK TABLES"; + } + ''; + }; + }; + }); default = []; description = '' Ensures that the specified users exist and have at least the ensured permissions. @@ -143,20 +195,22 @@ in 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 = { - "nextcloud.*" = "ALL PRIVILEGES"; - }; - } - { - name = "backup"; - ensurePermissions = { - "*.*" = "SELECT, LOCK TABLES"; - }; - } - ]''; + example = literalExample '' + [ + { + name = "nextcloud"; + ensurePermissions = { + "nextcloud.*" = "ALL PRIVILEGES"; + }; + } + { + name = "backup"; + ensurePermissions = { + "*.*" = "SELECT, LOCK TABLES"; + }; + } + ] + ''; }; # FIXME: remove this option; it's a really bad idea. diff --git a/nixos/tests/mysql.nix b/nixos/tests/mysql.nix index 1a6117793664..fedc7f0ab1f0 100644 --- a/nixos/tests/mysql.nix +++ b/nixos/tests/mysql.nix @@ -5,7 +5,7 @@ import ./make-test.nix ({ pkgs, ...} : { }; nodes = { - master = + mysql = { pkgs, ... }: { @@ -13,12 +13,34 @@ import ./make-test.nix ({ pkgs, ...} : { services.mysql.initialDatabases = [ { name = "testdb"; schema = ./testdb.sql; } ]; services.mysql.package = pkgs.mysql; }; + + mariadb = + { pkgs, ... }: + + { + users.users.testuser = { }; + services.mysql.enable = true; + services.mysql.ensureDatabases = [ "testdb" ]; + services.mysql.ensureUsers = [{ + name = "testuser"; + ensurePermissions = { + "testdb.*" = "ALL PRIVILEGES"; + }; + }]; + services.mysql.package = pkgs.mariadb; + }; + }; testScript = '' startAll; - $master->waitForUnit("mysql"); - $master->succeed("echo 'use testdb; select * from tests' | mysql -u root -N | grep 4"); + $mysql->waitForUnit("mysql"); + $mysql->succeed("echo 'use testdb; select * from tests' | mysql -u root -N | grep 4"); + + $mariadb->waitForUnit("mysql"); + $mariadb->succeed("echo 'use testdb; create table tests (test_id INT, PRIMARY KEY (test_id));' | sudo -u testuser mysql -u testuser"); + $mariadb->succeed("echo 'use testdb; insert into tests values (42);' | sudo -u testuser mysql -u testuser"); + $mariadb->succeed("echo 'use testdb; select test_id from tests' | sudo -u testuser mysql -u testuser -N | grep 42"); ''; })