nixos/mysql: fix initialScript option

which was wrongly specified as types.lines
Prevent it from getting copied to nix store as people might use it for
credentials, and make the tests cover it.
This commit is contained in:
Florian Jacob 2019-04-01 21:08:47 +02:00
parent 77978c1518
commit 14571f5ed0
2 changed files with 13 additions and 2 deletions

View File

@ -133,7 +133,7 @@ in
};
initialScript = mkOption {
type = types.nullOr types.lines;
type = types.nullOr types.path;
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";
};
@ -363,6 +363,8 @@ in
${optionalString (database.schema != null) ''
echo 'use `${database.name}`;'
# TODO: this silently falls through if database.schema does not exist,
# we should catch this somehow and exit, but can't do it here because we're in a subshell.
if [ -f "${database.schema}" ]
then
cat ${database.schema}
@ -399,7 +401,9 @@ in
${optionalString (cfg.initialScript != null)
''
# Execute initial script
cat ${cfg.initialScript} | ${mysql}/bin/mysql -u root -N
# using toString to avoid copying the file to nix store if given as path instead of string,
# as it might contain credentials
cat ${toString cfg.initialScript} | ${mysql}/bin/mysql -u root -N
''}
${optionalString (cfg.rootPassword != null)

View File

@ -14,6 +14,11 @@ import ./make-test.nix ({ pkgs, ...} : {
{ name = "testdb"; schema = ./testdb.sql; }
{ name = "empty_testdb"; }
];
# note that using pkgs.writeText here is generally not a good idea,
# as it will store the password in world-readable /nix/store ;)
services.mysql.initialScript = pkgs.writeText "mysql-init.sql" ''
CREATE USER 'passworduser'@'localhost' IDENTIFIED BY 'password123';
'';
services.mysql.package = pkgs.mysql;
};
@ -41,6 +46,8 @@ import ./make-test.nix ({ pkgs, ...} : {
$mysql->waitForUnit("mysql");
$mysql->succeed("echo 'use empty_testdb;' | mysql -u root");
$mysql->succeed("echo 'use testdb; select * from tests;' | mysql -u root -N | grep 4");
# ';' acts as no-op, just check whether login succeeds with the user created from the initialScript
$mysql->succeed("echo ';' | mysql -u passworduser --password=password123");
$mariadb->waitForUnit("mysql");
$mariadb->succeed("echo 'use testdb; create table tests (test_id INT, PRIMARY KEY (test_id));' | sudo -u testuser mysql -u testuser");