123 lines
3.2 KiB
Nix
123 lines
3.2 KiB
Nix
{
|
|
config,
|
|
pkgs,
|
|
siteConfig,
|
|
...
|
|
}:
|
|
let
|
|
dbName = siteConfig.database.name;
|
|
wikiUser = siteConfig.database.mediawikiUser;
|
|
replicationUser = siteConfig.database.replicationUser;
|
|
mysqlCli = "${pkgs.mariadb}/bin/mysql -u root";
|
|
bootstrapSql = pkgs.writeText "mysql-bootstrap.sql" ''
|
|
SET @wiki_pass = FROM_BASE64('$wiki_pass_b64');
|
|
SET @repl_pass = FROM_BASE64('$repl_pass_b64');
|
|
|
|
CREATE DATABASE IF NOT EXISTS \`${dbName}\`;
|
|
|
|
SET @create_wiki_user = CONCAT(
|
|
"CREATE USER IF NOT EXISTS '${wikiUser}'@'localhost' IDENTIFIED BY ",
|
|
QUOTE(@wiki_pass)
|
|
);
|
|
PREPARE stmt FROM @create_wiki_user;
|
|
EXECUTE stmt;
|
|
DEALLOCATE PREPARE stmt;
|
|
|
|
SET @alter_wiki_user = CONCAT(
|
|
"ALTER USER '${wikiUser}'@'localhost' IDENTIFIED BY ",
|
|
QUOTE(@wiki_pass)
|
|
);
|
|
PREPARE stmt FROM @alter_wiki_user;
|
|
EXECUTE stmt;
|
|
DEALLOCATE PREPARE stmt;
|
|
|
|
GRANT ALL PRIVILEGES ON \`${dbName}\`.* TO '${wikiUser}'@'localhost';
|
|
|
|
SET @create_repl_user = CONCAT(
|
|
"CREATE USER IF NOT EXISTS '${replicationUser}'@'%' IDENTIFIED BY ",
|
|
QUOTE(@repl_pass)
|
|
);
|
|
PREPARE stmt FROM @create_repl_user;
|
|
EXECUTE stmt;
|
|
DEALLOCATE PREPARE stmt;
|
|
|
|
SET @alter_repl_user = CONCAT(
|
|
"ALTER USER '${replicationUser}'@'%' IDENTIFIED BY ",
|
|
QUOTE(@repl_pass)
|
|
);
|
|
PREPARE stmt FROM @alter_repl_user;
|
|
EXECUTE stmt;
|
|
DEALLOCATE PREPARE stmt;
|
|
|
|
GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO '${replicationUser}'@'%';
|
|
FLUSH PRIVILEGES;
|
|
'';
|
|
in
|
|
{
|
|
services.mysql = {
|
|
enable = true;
|
|
package = pkgs.mariadb;
|
|
|
|
settings.mysqld = {
|
|
bind-address = "0.0.0.0";
|
|
server-id = 1;
|
|
log_bin = "mysql-bin";
|
|
log_slave_updates = 1;
|
|
binlog_format = "ROW";
|
|
gtid_strict_mode = 1;
|
|
innodb_file_per_table = 1;
|
|
innodb_buffer_pool_size = "4G";
|
|
innodb_log_file_size = "512M";
|
|
innodb_flush_method = "O_DIRECT";
|
|
innodb_flush_neighbors = 0;
|
|
innodb_io_capacity = 1000;
|
|
innodb_io_capacity_max = 2000;
|
|
max_connections = 80;
|
|
thread_cache_size = 100;
|
|
table_open_cache = 4000;
|
|
tmp_table_size = "64M";
|
|
max_heap_table_size = "64M";
|
|
performance_schema = true;
|
|
slow_query_log = 1;
|
|
long_query_time = 1;
|
|
skip_name_resolve = 1;
|
|
};
|
|
};
|
|
|
|
age.secrets.mysql-replication = {
|
|
file = ../../secrets/mysql-replication.age;
|
|
owner = "mysql";
|
|
group = "mysql";
|
|
mode = "0400";
|
|
};
|
|
|
|
systemd.services.mysql-bootstrap = {
|
|
description = "Create MediaWiki database and users";
|
|
after = [ "mysql.service" ];
|
|
requires = [ "mysql.service" ];
|
|
wantedBy = [ "multi-user.target" ];
|
|
serviceConfig = {
|
|
Type = "oneshot";
|
|
RemainAfterExit = true;
|
|
};
|
|
script = ''
|
|
set -euo pipefail
|
|
|
|
read_secret_b64() {
|
|
tr -d '\n' < "$1" | base64 -w0
|
|
}
|
|
|
|
wiki_pass_b64="$(read_secret_b64 ${config.age.secrets.mysql-mediawiki.path})"
|
|
repl_pass_b64="$(read_secret_b64 ${config.age.secrets.mysql-replication.path})"
|
|
|
|
${mysqlCli} <<SQL
|
|
$(< ${bootstrapSql})
|
|
SQL
|
|
'';
|
|
};
|
|
|
|
systemd.services.mediawiki-init = {
|
|
after = [ "mysql-bootstrap.service" ];
|
|
requires = [ "mysql-bootstrap.service" ];
|
|
};
|
|
}
|