nixos/mysql: turn ExecStartPost into a shell script and simplify code

This commit is contained in:
Aaron Andersen 2019-06-30 21:58:27 -04:00
parent 76a50f0f85
commit e0590da813

View file

@ -317,104 +317,103 @@ in
RuntimeDirectoryMode = "0755"; RuntimeDirectoryMode = "0755";
# The last two environment variables are used for starting Galera clusters # The last two environment variables are used for starting Galera clusters
ExecStart = "${mysql}/bin/mysqld --defaults-file=/etc/my.cnf ${mysqldOptions} $_WSREP_NEW_CLUSTER $_WSREP_START_POSITION"; ExecStart = "${mysql}/bin/mysqld --defaults-file=/etc/my.cnf ${mysqldOptions} $_WSREP_NEW_CLUSTER $_WSREP_START_POSITION";
}; ExecStartPost =
let
setupScript = pkgs.writeShellScript "mysql-setup" ''
${optionalString (!hasNotify) ''
# Wait until the MySQL server is available for use
count=0
while [ ! -e /run/mysqld/mysqld.sock ]
do
if [ $count -eq 30 ]
then
echo "Tried 30 times, giving up..."
exit 1
fi
postStart = echo "MySQL daemon not yet started. Waiting for 1 second..."
let count=$((count++))
cmdWatchForMysqlSocket = '' sleep 1
# Wait until the MySQL server is available for use done
count=0 ''}
while [ ! -e /run/mysqld/mysqld.sock ]
do
if [ $count -eq 30 ]
then
echo "Tried 30 times, giving up..."
exit 1
fi
echo "MySQL daemon not yet started. Waiting for 1 second..." if [ -f /tmp/mysql_init ]
count=$((count++)) then
sleep 1 ${concatMapStrings (database: ''
done # Create initial databases
''; if ! test -e "${cfg.dataDir}/${database.name}"; then
cmdInitialDatabases = concatMapStrings (database: '' echo "Creating initial database: ${database.name}"
# Create initial databases ( echo 'create database `${database.name}`;'
if ! test -e "${cfg.dataDir}/${database.name}"; then
echo "Creating initial database: ${database.name}"
( echo 'create database `${database.name}`;'
${optionalString (database.schema != null) '' ${optionalString (database.schema != null) ''
echo 'use `${database.name}`;' echo 'use `${database.name}`;'
# TODO: this silently falls through if database.schema does not exist, # 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. # we should catch this somehow and exit, but can't do it here because we're in a subshell.
if [ -f "${database.schema}" ] if [ -f "${database.schema}" ]
then then
cat ${database.schema} cat ${database.schema}
elif [ -d "${database.schema}" ] elif [ -d "${database.schema}" ]
then then
cat ${database.schema}/mysql-databases/*.sql cat ${database.schema}/mysql-databases/*.sql
fi fi
''} ''}
) | ${mysql}/bin/mysql -u root -N
fi
'') cfg.initialDatabases}
${optionalString (cfg.replication.role == "master")
''
# Set up the replication master
( echo "use mysql;"
echo "CREATE USER '${cfg.replication.masterUser}'@'${cfg.replication.slaveHost}' IDENTIFIED WITH mysql_native_password;"
echo "SET PASSWORD FOR '${cfg.replication.masterUser}'@'${cfg.replication.slaveHost}' = PASSWORD('${cfg.replication.masterPassword}');"
echo "GRANT REPLICATION SLAVE ON *.* TO '${cfg.replication.masterUser}'@'${cfg.replication.slaveHost}';"
) | ${mysql}/bin/mysql -u root -N
''}
${optionalString (cfg.replication.role == "slave")
''
# Set up the replication slave
( echo "stop slave;"
echo "change master to master_host='${cfg.replication.masterHost}', master_user='${cfg.replication.masterUser}', master_password='${cfg.replication.masterPassword}';"
echo "start slave;"
) | ${mysql}/bin/mysql -u root -N
''}
${optionalString (cfg.initialScript != null)
''
# Execute initial script
# 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
''}
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 ) | ${mysql}/bin/mysql -u root -N
fi ''}
'') cfg.initialDatabases;
in
lib.optionalString (!hasNotify) cmdWatchForMysqlSocket + '' ${concatMapStrings (user:
if [ -f /tmp/mysql_init ]
then
${cmdInitialDatabases}
${optionalString (cfg.replication.role == "master")
'' ''
# Set up the replication master ( echo "CREATE USER IF NOT EXISTS '${user.name}'@'localhost' IDENTIFIED WITH ${if isMariaDB then "unix_socket" else "auth_socket"};"
${concatStringsSep "\n" (mapAttrsToList (database: permission: ''
( echo "use mysql;" echo "GRANT ${permission} ON ${database} TO '${user.name}'@'localhost';"
echo "CREATE USER '${cfg.replication.masterUser}'@'${cfg.replication.slaveHost}' IDENTIFIED WITH mysql_native_password;" '') user.ensurePermissions)}
echo "SET PASSWORD FOR '${cfg.replication.masterUser}'@'${cfg.replication.slaveHost}' = PASSWORD('${cfg.replication.masterPassword}');"
echo "GRANT REPLICATION SLAVE ON *.* TO '${cfg.replication.masterUser}'@'${cfg.replication.slaveHost}';"
) | ${mysql}/bin/mysql -u root -N ) | ${mysql}/bin/mysql -u root -N
''} '') cfg.ensureUsers}
'';
${optionalString (cfg.replication.role == "slave") in
'' setupScript;
# Set up the replication slave };
( echo "stop slave;"
echo "change master to master_host='${cfg.replication.masterHost}', master_user='${cfg.replication.masterUser}', master_password='${cfg.replication.masterPassword}';"
echo "start slave;"
) | ${mysql}/bin/mysql -u root -N
''}
${optionalString (cfg.initialScript != null)
''
# Execute initial script
# 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
''}
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 isMariaDB 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}
''; # */
}; };
}; };