mirror of
https://github.com/NixOS/nixpkgs.git
synced 2025-06-13 05:05:29 +03:00
nixos/services.mysql: remove with lib;
This commit is contained in:
parent
8cf91e2c5b
commit
8e91c6b7b3
1 changed files with 74 additions and 77 deletions
|
@ -1,7 +1,4 @@
|
||||||
{ config, lib, pkgs, ... }:
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
with lib;
|
|
||||||
|
|
||||||
let
|
let
|
||||||
|
|
||||||
cfg = config.services.mysql;
|
cfg = config.services.mysql;
|
||||||
|
@ -9,7 +6,7 @@ let
|
||||||
isMariaDB = lib.getName cfg.package == lib.getName pkgs.mariadb;
|
isMariaDB = lib.getName cfg.package == lib.getName pkgs.mariadb;
|
||||||
isOracle = lib.getName cfg.package == lib.getName pkgs.mysql80;
|
isOracle = lib.getName cfg.package == lib.getName pkgs.mysql80;
|
||||||
# Oracle MySQL has supported "notify" service type since 8.0
|
# Oracle MySQL has supported "notify" service type since 8.0
|
||||||
hasNotify = isMariaDB || (isOracle && versionAtLeast cfg.package.version "8.0");
|
hasNotify = isMariaDB || (isOracle && lib.versionAtLeast cfg.package.version "8.0");
|
||||||
|
|
||||||
mysqldOptions =
|
mysqldOptions =
|
||||||
"--user=${cfg.user} --datadir=${cfg.dataDir} --basedir=${cfg.package}";
|
"--user=${cfg.user} --datadir=${cfg.dataDir} --basedir=${cfg.package}";
|
||||||
|
@ -21,11 +18,11 @@ in
|
||||||
|
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
(mkRemovedOptionModule [ "services" "mysql" "pidDir" ] "Don't wait for pidfiles, describe dependencies through systemd.")
|
(lib.mkRemovedOptionModule [ "services" "mysql" "pidDir" ] "Don't wait for pidfiles, describe dependencies through systemd.")
|
||||||
(mkRemovedOptionModule [ "services" "mysql" "rootPassword" ] "Use socket authentication or set the password outside of the nix store.")
|
(lib.mkRemovedOptionModule [ "services" "mysql" "rootPassword" ] "Use socket authentication or set the password outside of the nix store.")
|
||||||
(mkRemovedOptionModule [ "services" "mysql" "extraOptions" ] "Use services.mysql.settings.mysqld instead.")
|
(lib.mkRemovedOptionModule [ "services" "mysql" "extraOptions" ] "Use services.mysql.settings.mysqld instead.")
|
||||||
(mkRemovedOptionModule [ "services" "mysql" "bind" ] "Use services.mysql.settings.mysqld.bind-address instead.")
|
(lib.mkRemovedOptionModule [ "services" "mysql" "bind" ] "Use services.mysql.settings.mysqld.bind-address instead.")
|
||||||
(mkRemovedOptionModule [ "services" "mysql" "port" ] "Use services.mysql.settings.mysqld.port instead.")
|
(lib.mkRemovedOptionModule [ "services" "mysql" "port" ] "Use services.mysql.settings.mysqld.port instead.")
|
||||||
];
|
];
|
||||||
|
|
||||||
###### interface
|
###### interface
|
||||||
|
@ -34,18 +31,18 @@ in
|
||||||
|
|
||||||
services.mysql = {
|
services.mysql = {
|
||||||
|
|
||||||
enable = mkEnableOption "MySQL server";
|
enable = lib.mkEnableOption "MySQL server";
|
||||||
|
|
||||||
package = mkOption {
|
package = lib.mkOption {
|
||||||
type = types.package;
|
type = lib.types.package;
|
||||||
example = literalExpression "pkgs.mariadb";
|
example = lib.literalExpression "pkgs.mariadb";
|
||||||
description = ''
|
description = ''
|
||||||
Which MySQL derivation to use. MariaDB packages are supported too.
|
Which MySQL derivation to use. MariaDB packages are supported too.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
user = mkOption {
|
user = lib.mkOption {
|
||||||
type = types.str;
|
type = lib.types.str;
|
||||||
default = "mysql";
|
default = "mysql";
|
||||||
description = ''
|
description = ''
|
||||||
User account under which MySQL runs.
|
User account under which MySQL runs.
|
||||||
|
@ -58,8 +55,8 @@ in
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
group = mkOption {
|
group = lib.mkOption {
|
||||||
type = types.str;
|
type = lib.types.str;
|
||||||
default = "mysql";
|
default = "mysql";
|
||||||
description = ''
|
description = ''
|
||||||
Group account under which MySQL runs.
|
Group account under which MySQL runs.
|
||||||
|
@ -72,8 +69,8 @@ in
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
dataDir = mkOption {
|
dataDir = lib.mkOption {
|
||||||
type = types.path;
|
type = lib.types.path;
|
||||||
example = "/var/lib/mysql";
|
example = "/var/lib/mysql";
|
||||||
description = ''
|
description = ''
|
||||||
The data directory for MySQL.
|
The data directory for MySQL.
|
||||||
|
@ -85,8 +82,8 @@ in
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
configFile = mkOption {
|
configFile = lib.mkOption {
|
||||||
type = types.path;
|
type = lib.types.path;
|
||||||
default = configFile;
|
default = configFile;
|
||||||
defaultText = ''
|
defaultText = ''
|
||||||
A configuration file automatically generated by NixOS.
|
A configuration file automatically generated by NixOS.
|
||||||
|
@ -95,7 +92,7 @@ in
|
||||||
Override the configuration file used by MySQL. By default,
|
Override the configuration file used by MySQL. By default,
|
||||||
NixOS generates one automatically from {option}`services.mysql.settings`.
|
NixOS generates one automatically from {option}`services.mysql.settings`.
|
||||||
'';
|
'';
|
||||||
example = literalExpression ''
|
example = lib.literalExpression ''
|
||||||
pkgs.writeText "my.cnf" '''
|
pkgs.writeText "my.cnf" '''
|
||||||
[mysqld]
|
[mysqld]
|
||||||
datadir = /var/lib/mysql
|
datadir = /var/lib/mysql
|
||||||
|
@ -107,7 +104,7 @@ in
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
settings = mkOption {
|
settings = lib.mkOption {
|
||||||
type = format.type;
|
type = format.type;
|
||||||
default = {};
|
default = {};
|
||||||
description = ''
|
description = ''
|
||||||
|
@ -123,7 +120,7 @@ in
|
||||||
`1`, or `0`. See the provided example below.
|
`1`, or `0`. See the provided example below.
|
||||||
:::
|
:::
|
||||||
'';
|
'';
|
||||||
example = literalExpression ''
|
example = lib.literalExpression ''
|
||||||
{
|
{
|
||||||
mysqld = {
|
mysqld = {
|
||||||
key_buffer_size = "6G";
|
key_buffer_size = "6G";
|
||||||
|
@ -139,17 +136,17 @@ in
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
initialDatabases = mkOption {
|
initialDatabases = lib.mkOption {
|
||||||
type = types.listOf (types.submodule {
|
type = lib.types.listOf (lib.types.submodule {
|
||||||
options = {
|
options = {
|
||||||
name = mkOption {
|
name = lib.mkOption {
|
||||||
type = types.str;
|
type = lib.types.str;
|
||||||
description = ''
|
description = ''
|
||||||
The name of the database to create.
|
The name of the database to create.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
schema = mkOption {
|
schema = lib.mkOption {
|
||||||
type = types.nullOr types.path;
|
type = lib.types.nullOr lib.types.path;
|
||||||
default = null;
|
default = null;
|
||||||
description = ''
|
description = ''
|
||||||
The initial schema of the database; if null (the default),
|
The initial schema of the database; if null (the default),
|
||||||
|
@ -163,7 +160,7 @@ in
|
||||||
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
|
||||||
of MySQL. The schema attribute is optional: If not specified, an empty database is created.
|
of MySQL. The schema attribute is optional: If not specified, an empty database is created.
|
||||||
'';
|
'';
|
||||||
example = literalExpression ''
|
example = lib.literalExpression ''
|
||||||
[
|
[
|
||||||
{ name = "foodatabase"; schema = ./foodatabase.sql; }
|
{ name = "foodatabase"; schema = ./foodatabase.sql; }
|
||||||
{ name = "bardatabase"; }
|
{ name = "bardatabase"; }
|
||||||
|
@ -171,14 +168,14 @@ in
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
initialScript = mkOption {
|
initialScript = lib.mkOption {
|
||||||
type = types.nullOr types.path;
|
type = lib.types.nullOr lib.types.path;
|
||||||
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 = lib.mkOption {
|
||||||
type = types.listOf types.str;
|
type = lib.types.listOf lib.types.str;
|
||||||
default = [];
|
default = [];
|
||||||
description = ''
|
description = ''
|
||||||
Ensures that the specified databases exist.
|
Ensures that the specified databases exist.
|
||||||
|
@ -192,17 +189,17 @@ in
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
ensureUsers = mkOption {
|
ensureUsers = lib.mkOption {
|
||||||
type = types.listOf (types.submodule {
|
type = lib.types.listOf (lib.types.submodule {
|
||||||
options = {
|
options = {
|
||||||
name = mkOption {
|
name = lib.mkOption {
|
||||||
type = types.str;
|
type = lib.types.str;
|
||||||
description = ''
|
description = ''
|
||||||
Name of the user to ensure.
|
Name of the user to ensure.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
ensurePermissions = mkOption {
|
ensurePermissions = lib.mkOption {
|
||||||
type = types.attrsOf types.str;
|
type = lib.types.attrsOf lib.types.str;
|
||||||
default = {};
|
default = {};
|
||||||
description = ''
|
description = ''
|
||||||
Permissions to ensure for the user, specified as attribute set.
|
Permissions to ensure for the user, specified as attribute set.
|
||||||
|
@ -216,7 +213,7 @@ in
|
||||||
[GRANT syntax](https://mariadb.com/kb/en/library/grant/).
|
[GRANT syntax](https://mariadb.com/kb/en/library/grant/).
|
||||||
The attributes are used as `GRANT ''${attrName} ON ''${attrValue}`.
|
The attributes are used as `GRANT ''${attrName} ON ''${attrValue}`.
|
||||||
'';
|
'';
|
||||||
example = literalExpression ''
|
example = lib.literalExpression ''
|
||||||
{
|
{
|
||||||
"database.*" = "ALL PRIVILEGES";
|
"database.*" = "ALL PRIVILEGES";
|
||||||
"*.*" = "SELECT, LOCK TABLES";
|
"*.*" = "SELECT, LOCK TABLES";
|
||||||
|
@ -234,7 +231,7 @@ 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 = literalExpression ''
|
example = lib.literalExpression ''
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
name = "nextcloud";
|
name = "nextcloud";
|
||||||
|
@ -253,40 +250,40 @@ in
|
||||||
};
|
};
|
||||||
|
|
||||||
replication = {
|
replication = {
|
||||||
role = mkOption {
|
role = lib.mkOption {
|
||||||
type = types.enum [ "master" "slave" "none" ];
|
type = lib.types.enum [ "master" "slave" "none" ];
|
||||||
default = "none";
|
default = "none";
|
||||||
description = "Role of the MySQL server instance.";
|
description = "Role of the MySQL server instance.";
|
||||||
};
|
};
|
||||||
|
|
||||||
serverId = mkOption {
|
serverId = lib.mkOption {
|
||||||
type = types.int;
|
type = lib.types.int;
|
||||||
default = 1;
|
default = 1;
|
||||||
description = "Id of the MySQL server instance. This number must be unique for each instance.";
|
description = "Id of the MySQL server instance. This number must be unique for each instance.";
|
||||||
};
|
};
|
||||||
|
|
||||||
masterHost = mkOption {
|
masterHost = lib.mkOption {
|
||||||
type = types.str;
|
type = lib.types.str;
|
||||||
description = "Hostname of the MySQL master server.";
|
description = "Hostname of the MySQL master server.";
|
||||||
};
|
};
|
||||||
|
|
||||||
slaveHost = mkOption {
|
slaveHost = lib.mkOption {
|
||||||
type = types.str;
|
type = lib.types.str;
|
||||||
description = "Hostname of the MySQL slave server.";
|
description = "Hostname of the MySQL slave server.";
|
||||||
};
|
};
|
||||||
|
|
||||||
masterUser = mkOption {
|
masterUser = lib.mkOption {
|
||||||
type = types.str;
|
type = lib.types.str;
|
||||||
description = "Username of the MySQL replication user.";
|
description = "Username of the MySQL replication user.";
|
||||||
};
|
};
|
||||||
|
|
||||||
masterPassword = mkOption {
|
masterPassword = lib.mkOption {
|
||||||
type = types.str;
|
type = lib.types.str;
|
||||||
description = "Password of the MySQL replication user.";
|
description = "Password of the MySQL replication user.";
|
||||||
};
|
};
|
||||||
|
|
||||||
masterPort = mkOption {
|
masterPort = lib.mkOption {
|
||||||
type = types.port;
|
type = lib.types.port;
|
||||||
default = 3306;
|
default = 3306;
|
||||||
description = "Port number on which the MySQL master server runs.";
|
description = "Port number on which the MySQL master server runs.";
|
||||||
};
|
};
|
||||||
|
@ -298,30 +295,30 @@ in
|
||||||
|
|
||||||
###### implementation
|
###### implementation
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
config = lib.mkIf cfg.enable {
|
||||||
|
|
||||||
services.mysql.dataDir =
|
services.mysql.dataDir =
|
||||||
mkDefault (if versionAtLeast config.system.stateVersion "17.09" then "/var/lib/mysql"
|
lib.mkDefault (if lib.versionAtLeast config.system.stateVersion "17.09" then "/var/lib/mysql"
|
||||||
else "/var/mysql");
|
else "/var/mysql");
|
||||||
|
|
||||||
services.mysql.settings.mysqld = mkMerge [
|
services.mysql.settings.mysqld = lib.mkMerge [
|
||||||
{
|
{
|
||||||
datadir = cfg.dataDir;
|
datadir = cfg.dataDir;
|
||||||
port = mkDefault 3306;
|
port = lib.mkDefault 3306;
|
||||||
}
|
}
|
||||||
(mkIf (cfg.replication.role == "master" || cfg.replication.role == "slave") {
|
(lib.mkIf (cfg.replication.role == "master" || cfg.replication.role == "slave") {
|
||||||
log-bin = "mysql-bin-${toString cfg.replication.serverId}";
|
log-bin = "mysql-bin-${toString cfg.replication.serverId}";
|
||||||
log-bin-index = "mysql-bin-${toString cfg.replication.serverId}.index";
|
log-bin-index = "mysql-bin-${toString cfg.replication.serverId}.index";
|
||||||
relay-log = "mysql-relay-bin";
|
relay-log = "mysql-relay-bin";
|
||||||
server-id = cfg.replication.serverId;
|
server-id = cfg.replication.serverId;
|
||||||
binlog-ignore-db = [ "information_schema" "performance_schema" "mysql" ];
|
binlog-ignore-db = [ "information_schema" "performance_schema" "mysql" ];
|
||||||
})
|
})
|
||||||
(mkIf (!isMariaDB) {
|
(lib.mkIf (!isMariaDB) {
|
||||||
plugin-load-add = "auth_socket.so";
|
plugin-load-add = "auth_socket.so";
|
||||||
})
|
})
|
||||||
];
|
];
|
||||||
|
|
||||||
users.users = optionalAttrs (cfg.user == "mysql") {
|
users.users = lib.optionalAttrs (cfg.user == "mysql") {
|
||||||
mysql = {
|
mysql = {
|
||||||
description = "MySQL server user";
|
description = "MySQL server user";
|
||||||
group = cfg.group;
|
group = cfg.group;
|
||||||
|
@ -329,7 +326,7 @@ in
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
users.groups = optionalAttrs (cfg.group == "mysql") {
|
users.groups = lib.optionalAttrs (cfg.group == "mysql") {
|
||||||
mysql.gid = config.ids.gids.mysql;
|
mysql.gid = config.ids.gids.mysql;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -380,7 +377,7 @@ in
|
||||||
# The super user account to use on *first* run of MySQL server
|
# The super user account to use on *first* run of MySQL server
|
||||||
superUser = if isMariaDB then cfg.user else "root";
|
superUser = if isMariaDB then cfg.user else "root";
|
||||||
in ''
|
in ''
|
||||||
${optionalString (!hasNotify) ''
|
${lib.optionalString (!hasNotify) ''
|
||||||
# Wait until the MySQL server is available for use
|
# Wait until the MySQL server is available for use
|
||||||
while [ ! -e /run/mysqld/mysqld.sock ]
|
while [ ! -e /run/mysqld/mysqld.sock ]
|
||||||
do
|
do
|
||||||
|
@ -397,13 +394,13 @@ in
|
||||||
echo "GRANT ALL PRIVILEGES ON *.* TO '${cfg.user}'@'localhost' WITH GRANT OPTION;"
|
echo "GRANT ALL PRIVILEGES ON *.* TO '${cfg.user}'@'localhost' WITH GRANT OPTION;"
|
||||||
) | ${cfg.package}/bin/mysql -u ${superUser} -N
|
) | ${cfg.package}/bin/mysql -u ${superUser} -N
|
||||||
|
|
||||||
${concatMapStrings (database: ''
|
${lib.concatMapStrings (database: ''
|
||||||
# Create initial databases
|
# Create initial databases
|
||||||
if ! test -e "${cfg.dataDir}/${database.name}"; then
|
if ! test -e "${cfg.dataDir}/${database.name}"; then
|
||||||
echo "Creating initial database: ${database.name}"
|
echo "Creating initial database: ${database.name}"
|
||||||
( echo 'create database `${database.name}`;'
|
( echo 'create database `${database.name}`;'
|
||||||
|
|
||||||
${optionalString (database.schema != null) ''
|
${lib.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,
|
||||||
|
@ -420,7 +417,7 @@ in
|
||||||
fi
|
fi
|
||||||
'') cfg.initialDatabases}
|
'') cfg.initialDatabases}
|
||||||
|
|
||||||
${optionalString (cfg.replication.role == "master")
|
${lib.optionalString (cfg.replication.role == "master")
|
||||||
''
|
''
|
||||||
# Set up the replication master
|
# Set up the replication master
|
||||||
|
|
||||||
|
@ -431,7 +428,7 @@ in
|
||||||
) | ${cfg.package}/bin/mysql -u ${superUser} -N
|
) | ${cfg.package}/bin/mysql -u ${superUser} -N
|
||||||
''}
|
''}
|
||||||
|
|
||||||
${optionalString (cfg.replication.role == "slave")
|
${lib.optionalString (cfg.replication.role == "slave")
|
||||||
''
|
''
|
||||||
# Set up the replication slave
|
# Set up the replication slave
|
||||||
|
|
||||||
|
@ -441,7 +438,7 @@ in
|
||||||
) | ${cfg.package}/bin/mysql -u ${superUser} -N
|
) | ${cfg.package}/bin/mysql -u ${superUser} -N
|
||||||
''}
|
''}
|
||||||
|
|
||||||
${optionalString (cfg.initialScript != null)
|
${lib.optionalString (cfg.initialScript != null)
|
||||||
''
|
''
|
||||||
# Execute initial script
|
# Execute initial script
|
||||||
# using toString to avoid copying the file to nix store if given as path instead of string,
|
# using toString to avoid copying the file to nix store if given as path instead of string,
|
||||||
|
@ -452,25 +449,25 @@ in
|
||||||
rm ${cfg.dataDir}/mysql_init
|
rm ${cfg.dataDir}/mysql_init
|
||||||
fi
|
fi
|
||||||
|
|
||||||
${optionalString (cfg.ensureDatabases != []) ''
|
${lib.optionalString (cfg.ensureDatabases != []) ''
|
||||||
(
|
(
|
||||||
${concatMapStrings (database: ''
|
${lib.concatMapStrings (database: ''
|
||||||
echo "CREATE DATABASE IF NOT EXISTS \`${database}\`;"
|
echo "CREATE DATABASE IF NOT EXISTS \`${database}\`;"
|
||||||
'') cfg.ensureDatabases}
|
'') cfg.ensureDatabases}
|
||||||
) | ${cfg.package}/bin/mysql -N
|
) | ${cfg.package}/bin/mysql -N
|
||||||
''}
|
''}
|
||||||
|
|
||||||
${concatMapStrings (user:
|
${lib.concatMapStrings (user:
|
||||||
''
|
''
|
||||||
( echo "CREATE USER IF NOT EXISTS '${user.name}'@'localhost' IDENTIFIED WITH ${if isMariaDB then "unix_socket" else "auth_socket"};"
|
( echo "CREATE USER IF NOT EXISTS '${user.name}'@'localhost' IDENTIFIED WITH ${if isMariaDB then "unix_socket" else "auth_socket"};"
|
||||||
${concatStringsSep "\n" (mapAttrsToList (database: permission: ''
|
${lib.concatStringsSep "\n" (lib.mapAttrsToList (database: permission: ''
|
||||||
echo "GRANT ${permission} ON ${database} TO '${user.name}'@'localhost';"
|
echo "GRANT ${permission} ON ${database} TO '${user.name}'@'localhost';"
|
||||||
'') user.ensurePermissions)}
|
'') user.ensurePermissions)}
|
||||||
) | ${cfg.package}/bin/mysql -N
|
) | ${cfg.package}/bin/mysql -N
|
||||||
'') cfg.ensureUsers}
|
'') cfg.ensureUsers}
|
||||||
'';
|
'';
|
||||||
|
|
||||||
serviceConfig = mkMerge [
|
serviceConfig = lib.mkMerge [
|
||||||
{
|
{
|
||||||
Type = if hasNotify then "notify" else "simple";
|
Type = if hasNotify then "notify" else "simple";
|
||||||
Restart = "on-abort";
|
Restart = "on-abort";
|
||||||
|
@ -506,7 +503,7 @@ in
|
||||||
# System Call Filtering
|
# System Call Filtering
|
||||||
SystemCallArchitectures = "native";
|
SystemCallArchitectures = "native";
|
||||||
}
|
}
|
||||||
(mkIf (cfg.dataDir == "/var/lib/mysql") {
|
(lib.mkIf (cfg.dataDir == "/var/lib/mysql") {
|
||||||
StateDirectory = "mysql";
|
StateDirectory = "mysql";
|
||||||
StateDirectoryMode = "0700";
|
StateDirectoryMode = "0700";
|
||||||
})
|
})
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue