Merge pull request #57550 from florianjacob/typed-mysql-options

nixos/mysql: specify option types, add tests
This commit is contained in:
Silvan Mosberger 2019-03-28 18:55:53 +01:00 committed by GitHub
commit 9d4a6cceb7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 93 additions and 17 deletions

View File

@ -103,6 +103,24 @@ in
}; };
initialDatabases = mkOption { 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 = []; default = [];
description = '' description = ''
List of database names and their initial schemas that should be used to create databases on the first startup 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 { initialScript = mkOption {
type = types.nullOr types.lines;
default = null; 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"; 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 { ensureDatabases = mkOption {
type = types.listOf types.str;
default = []; default = [];
description = '' description = ''
Ensures that the specified databases exist. Ensures that the specified databases exist.
@ -134,6 +154,38 @@ in
}; };
ensureUsers = mkOption { 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
<link xlink:href="https://mariadb.com/kb/en/library/grant/">GRANT syntax</link>.
The attributes are used as <code>GRANT ''${attrName} ON ''${attrValue}</code>.
'';
example = literalExample ''
{
"database.*" = "ALL PRIVILEGES";
"*.*" = "SELECT, LOCK TABLES";
}
'';
};
};
});
default = []; default = [];
description = '' description = ''
Ensures that the specified users exist and have at least the ensured permissions. 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 option is changed. This means that users created and permissions assigned once through this option or
otherwise have to be removed manually. otherwise have to be removed manually.
''; '';
example = literalExample ''[ example = literalExample ''
{ [
name = "nextcloud"; {
ensurePermissions = { name = "nextcloud";
"nextcloud.*" = "ALL PRIVILEGES"; ensurePermissions = {
}; "nextcloud.*" = "ALL PRIVILEGES";
} };
{ }
name = "backup"; {
ensurePermissions = { name = "backup";
"*.*" = "SELECT, LOCK TABLES"; ensurePermissions = {
}; "*.*" = "SELECT, LOCK TABLES";
} };
]''; }
]
'';
}; };
# FIXME: remove this option; it's a really bad idea. # FIXME: remove this option; it's a really bad idea.

View File

@ -5,7 +5,7 @@ import ./make-test.nix ({ pkgs, ...} : {
}; };
nodes = { nodes = {
master = mysql =
{ pkgs, ... }: { pkgs, ... }:
{ {
@ -13,12 +13,34 @@ import ./make-test.nix ({ pkgs, ...} : {
services.mysql.initialDatabases = [ { name = "testdb"; schema = ./testdb.sql; } ]; services.mysql.initialDatabases = [ { name = "testdb"; schema = ./testdb.sql; } ];
services.mysql.package = pkgs.mysql; 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 = '' testScript = ''
startAll; startAll;
$master->waitForUnit("mysql"); $mysql->waitForUnit("mysql");
$master->succeed("echo 'use testdb; select * from tests' | mysql -u root -N | grep 4"); $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");
''; '';
}) })