diff --git a/modules/services/databases/mysql.nix b/modules/services/databases/mysql.nix index 9ec77e2d4746..19c0bcc418a2 100644 --- a/modules/services/databases/mysql.nix +++ b/modules/services/databases/mysql.nix @@ -61,7 +61,7 @@ in pidDir = mkOption { default = "/var/run/mysql"; description = "Location of the file which stores the PID of the MySQL server"; - }; + }; initialDatabases = mkOption { default = []; @@ -71,6 +71,16 @@ in { name = "bardatabase"; schema = ./bardatabase.sql; } ]; }; + + 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"; + }; + + rootPassword = mkOption { + default = null; + description = "Path to a file containing the root password, modified on the first startup. Not specifying a root password will leave the root password empty."; + }; }; }; @@ -98,6 +108,7 @@ in mkdir -m 0700 -p ${cfg.dataDir} chown -R ${cfg.user} ${cfg.dataDir} ${mysql}/bin/mysql_install_db ${mysqldOptions} + touch /tmp/mysql_init fi mkdir -m 0700 -p ${cfg.pidDir} @@ -114,35 +125,57 @@ in do if [ $count -eq 30 ] then - echo "Tried 30 times, giving up..." - exit 1 - fi + echo "Tried 30 times, giving up..." + exit 1 + fi - echo "MySQL daemon not yet started. Waiting for 1 second..." - count=$((count++)) - sleep 1 + echo "MySQL daemon not yet started. Waiting for 1 second..." + count=$((count++)) + sleep 1 done - # Create initial databases + if [ -f /tmp/mysql_init ] + then + # Create initial databases - ${concatMapStrings (database: - '' - if ! test -e "${cfg.dataDir}/${database.name}"; then - echo "Creating initial database: ${database.name}" - ( echo "create database ${database.name};" - echo "use ${database.name};" - if [ -f "${database.schema}" ] - then - cat ${database.schema} - elif [ -d "${database.schema}" ] - then - cat ${database.schema}/mysql-databases/*.sql - fi + ${concatMapStrings (database: + '' + if ! test -e "${cfg.dataDir}/${database.name}"; then + echo "Creating initial database: ${database.name}" + ( echo "create database ${database.name};" + echo "use ${database.name};" + if [ -f "${database.schema}" ] + then + cat ${database.schema} + elif [ -d "${database.schema}" ] + then + cat ${database.schema}/mysql-databases/*.sql + fi + ) | ${mysql}/bin/mysql -u root -N + fi + '') cfg.initialDatabases} + + # Execute initial script + + ${optionalString (cfg.initialScript != null) + '' + cat ${cfg.initialScript} | ${mysql}/bin/mysql -u root -N + ''} + + # Change root password + + ${optionalString (cfg.rootPassword != null) + '' + ( echo "use mysql;" + echo "update user set Password=password('$(cat ${cfg.rootPassword})') where User='root';" + echo "flush privileges;" ) | ${mysql}/bin/mysql -u root -N - fi - '') cfg.initialDatabases} + ''} + + rm /tmp/mysql_init + fi ''; - + # !!! Need a postStart script to wait until mysqld is ready to # accept connections.