diff --git a/nixos/doc/manual/from_md/release-notes/rl-2205.section.xml b/nixos/doc/manual/from_md/release-notes/rl-2205.section.xml index 9a7b16b464b2..fc4073c49363 100644 --- a/nixos/doc/manual/from_md/release-notes/rl-2205.section.xml +++ b/nixos/doc/manual/from_md/release-notes/rl-2205.section.xml @@ -534,6 +534,19 @@ will now correctly remove those domains during rebuild/renew. + + + MariaDB is now offered in several versions, not just the + newest one. So if you have a need for running MariaDB 10.4 for + example, you can now just set + services.mysql.package = pkgs.mariadb_104;. + In general, it is recommended to run the newest version, to + get the newest features, while sticking with an LTS version + will most likely provide a more stable experience. Sometimes + software is also incompatible with the newest version of + MariaDB. + + The option diff --git a/nixos/doc/manual/release-notes/rl-2205.section.md b/nixos/doc/manual/release-notes/rl-2205.section.md index 747fcacff10b..dee532e77d4c 100644 --- a/nixos/doc/manual/release-notes/rl-2205.section.md +++ b/nixos/doc/manual/release-notes/rl-2205.section.md @@ -184,6 +184,11 @@ In addition to numerous new and upgraded packages, this release has the followin - Removing domains from `security.acme.certs._name_.extraDomainNames` will now correctly remove those domains during rebuild/renew. +- MariaDB is now offered in several versions, not just the newest one. + So if you have a need for running MariaDB 10.4 for example, you can now just set `services.mysql.package = pkgs.mariadb_104;`. + In general, it is recommended to run the newest version, to get the newest features, while sticking with an LTS version will most likely provide a more stable experience. + Sometimes software is also incompatible with the newest version of MariaDB. + - The option [programs.ssh.enableAskPassword](#opt-programs.ssh.enableAskPassword) was added, decoupling the setting of `SSH_ASKPASS` from diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index 940ae11ddd1f..93950277c279 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -268,8 +268,7 @@ in mailcatcher = handleTest ./mailcatcher.nix {}; mailhog = handleTest ./mailhog.nix {}; man = handleTest ./man.nix {}; - mariadb-galera-mariabackup = handleTest ./mysql/mariadb-galera-mariabackup.nix {}; - mariadb-galera-rsync = handleTest ./mysql/mariadb-galera-rsync.nix {}; + mariadb-galera = handleTest ./mysql/mariadb-galera.nix {}; matomo = handleTest ./matomo.nix {}; matrix-appservice-irc = handleTest ./matrix-appservice-irc.nix {}; matrix-conduit = handleTest ./matrix-conduit.nix {}; diff --git a/nixos/tests/mysql/common.nix b/nixos/tests/mysql/common.nix new file mode 100644 index 000000000000..968253d109cc --- /dev/null +++ b/nixos/tests/mysql/common.nix @@ -0,0 +1,10 @@ +{ lib, pkgs }: { + mariadbPackages = lib.filterAttrs (n: _: lib.hasPrefix "mariadb" n) (pkgs.callPackage ../../../pkgs/servers/sql/mariadb { + inherit (pkgs.darwin) cctools; + inherit (pkgs.darwin.apple_sdk.frameworks) CoreServices; + }); + mysqlPackage = { + inherit (pkgs) mysql57 mysql80; + }; + mkTestName = pkg: "mariadb_${builtins.replaceStrings ["."] [""] (lib.versions.majorMinor pkg.version)}"; +} diff --git a/nixos/tests/mysql/mariadb-galera-mariabackup.nix b/nixos/tests/mysql/mariadb-galera-mariabackup.nix deleted file mode 100644 index 10682c361d1d..000000000000 --- a/nixos/tests/mysql/mariadb-galera-mariabackup.nix +++ /dev/null @@ -1,233 +0,0 @@ -import ./../make-test-python.nix ({ pkgs, ...} : - -let - mysqlenv-common = pkgs.buildEnv { name = "mysql-path-env-common"; pathsToLink = [ "/bin" ]; paths = with pkgs; [ bash gawk gnutar inetutils which ]; }; - mysqlenv-mariabackup = pkgs.buildEnv { name = "mysql-path-env-mariabackup"; pathsToLink = [ "/bin" ]; paths = with pkgs; [ gzip iproute2 netcat procps pv socat ]; }; - - # Common user configuration - users = { ... }: - { - users.users.testuser = { - isSystemUser = true; - group = "testusers"; - }; - users.groups.testusers = { }; - }; - -in { - name = "mariadb-galera-mariabackup"; - meta = with pkgs.lib.maintainers; { - maintainers = [ izorkin ]; - }; - - # The test creates a Galera cluster with 3 nodes and is checking if mariabackup-based SST works. The cluster is tested by creating a DB and an empty table on one node, - # and checking the table's presence on the other node. - - nodes = { - galera_01 = - { pkgs, ... }: - { - imports = [ users ]; - networking = { - interfaces.eth1 = { - ipv4.addresses = [ - { address = "192.168.1.1"; prefixLength = 24; } - ]; - }; - extraHosts = '' - 192.168.1.1 galera_01 - 192.168.1.2 galera_02 - 192.168.1.3 galera_03 - ''; - firewall.allowedTCPPorts = [ 3306 4444 4567 4568 ]; - firewall.allowedUDPPorts = [ 4567 ]; - }; - systemd.services.mysql = with pkgs; { - path = [ mysqlenv-common mysqlenv-mariabackup ]; - }; - services.mysql = { - enable = true; - package = pkgs.mariadb; - ensureDatabases = [ "testdb" ]; - ensureUsers = [{ - name = "testuser"; - ensurePermissions = { - "testdb.*" = "ALL PRIVILEGES"; - }; - }]; - initialScript = pkgs.writeText "mariadb-init.sql" '' - GRANT ALL PRIVILEGES ON *.* TO 'check_repl'@'localhost' IDENTIFIED BY 'check_pass' WITH GRANT OPTION; - FLUSH PRIVILEGES; - ''; - settings = { - mysqld = { - bind_address = "0.0.0.0"; - }; - galera = { - wsrep_on = "ON"; - wsrep_debug = "NONE"; - wsrep_retry_autocommit = "3"; - wsrep_provider = "${pkgs.mariadb-galera}/lib/galera/libgalera_smm.so"; - wsrep_cluster_address = "gcomm://"; - wsrep_cluster_name = "galera"; - wsrep_node_address = "192.168.1.1"; - wsrep_node_name = "galera_01"; - wsrep_sst_method = "mariabackup"; - wsrep_sst_auth = "check_repl:check_pass"; - binlog_format = "ROW"; - enforce_storage_engine = "InnoDB"; - innodb_autoinc_lock_mode = "2"; - }; - }; - }; - }; - - galera_02 = - { pkgs, ... }: - { - imports = [ users ]; - networking = { - interfaces.eth1 = { - ipv4.addresses = [ - { address = "192.168.1.2"; prefixLength = 24; } - ]; - }; - extraHosts = '' - 192.168.1.1 galera_01 - 192.168.1.2 galera_02 - 192.168.1.3 galera_03 - ''; - firewall.allowedTCPPorts = [ 3306 4444 4567 4568 ]; - firewall.allowedUDPPorts = [ 4567 ]; - }; - systemd.services.mysql = with pkgs; { - path = [ mysqlenv-common mysqlenv-mariabackup ]; - }; - services.mysql = { - enable = true; - package = pkgs.mariadb; - settings = { - mysqld = { - bind_address = "0.0.0.0"; - }; - galera = { - wsrep_on = "ON"; - wsrep_debug = "NONE"; - wsrep_retry_autocommit = "3"; - wsrep_provider = "${pkgs.mariadb-galera}/lib/galera/libgalera_smm.so"; - wsrep_cluster_address = "gcomm://galera_01,galera_02,galera_03"; - wsrep_cluster_name = "galera"; - wsrep_node_address = "192.168.1.2"; - wsrep_node_name = "galera_02"; - wsrep_sst_method = "mariabackup"; - wsrep_sst_auth = "check_repl:check_pass"; - binlog_format = "ROW"; - enforce_storage_engine = "InnoDB"; - innodb_autoinc_lock_mode = "2"; - }; - }; - }; - }; - - galera_03 = - { pkgs, ... }: - { - imports = [ users ]; - networking = { - interfaces.eth1 = { - ipv4.addresses = [ - { address = "192.168.1.3"; prefixLength = 24; } - ]; - }; - extraHosts = '' - 192.168.1.1 galera_01 - 192.168.1.2 galera_02 - 192.168.1.3 galera_03 - ''; - firewall.allowedTCPPorts = [ 3306 4444 4567 4568 ]; - firewall.allowedUDPPorts = [ 4567 ]; - }; - systemd.services.mysql = with pkgs; { - path = [ mysqlenv-common mysqlenv-mariabackup ]; - }; - services.mysql = { - enable = true; - package = pkgs.mariadb; - settings = { - mysqld = { - bind_address = "0.0.0.0"; - }; - galera = { - wsrep_on = "ON"; - wsrep_debug = "NONE"; - wsrep_retry_autocommit = "3"; - wsrep_provider = "${pkgs.mariadb-galera}/lib/galera/libgalera_smm.so"; - wsrep_cluster_address = "gcomm://galera_01,galera_02,galera_03"; - wsrep_cluster_name = "galera"; - wsrep_node_address = "192.168.1.3"; - wsrep_node_name = "galera_03"; - wsrep_sst_method = "mariabackup"; - wsrep_sst_auth = "check_repl:check_pass"; - binlog_format = "ROW"; - enforce_storage_engine = "InnoDB"; - innodb_autoinc_lock_mode = "2"; - }; - }; - }; - }; - }; - - testScript = '' - galera_01.start() - galera_01.wait_for_unit("mysql") - galera_01.wait_for_open_port(3306) - galera_01.succeed( - "sudo -u testuser mysql -u testuser -e 'use testdb; create table db1 (test_id INT, PRIMARY KEY (test_id)) ENGINE = InnoDB;'" - ) - galera_01.succeed( - "sudo -u testuser mysql -u testuser -e 'use testdb; insert into db1 values (37);'" - ) - galera_02.start() - galera_02.wait_for_unit("mysql") - galera_02.wait_for_open_port(3306) - galera_03.start() - galera_03.wait_for_unit("mysql") - galera_03.wait_for_open_port(3306) - galera_02.succeed( - "sudo -u testuser mysql -u testuser -e 'use testdb; select test_id from db1;' -N | grep 37" - ) - galera_02.succeed( - "sudo -u testuser mysql -u testuser -e 'use testdb; create table db2 (test_id INT, PRIMARY KEY (test_id)) ENGINE = InnoDB;'" - ) - galera_02.succeed("systemctl stop mysql") - galera_01.succeed( - "sudo -u testuser mysql -u testuser -e 'use testdb; insert into db2 values (38);'" - ) - galera_03.succeed( - "sudo -u testuser mysql -u testuser -e 'use testdb; create table db3 (test_id INT, PRIMARY KEY (test_id)) ENGINE = InnoDB;'" - ) - galera_01.succeed( - "sudo -u testuser mysql -u testuser -e 'use testdb; insert into db3 values (39);'" - ) - galera_02.succeed("systemctl start mysql") - galera_02.wait_for_open_port(3306) - galera_02.succeed( - "sudo -u testuser mysql -u testuser -e 'show status' -N | grep 'wsrep_cluster_size.*3'" - ) - galera_03.succeed( - "sudo -u testuser mysql -u testuser -e 'show status' -N | grep 'wsrep_local_state_comment.*Synced'" - ) - galera_01.succeed( - "sudo -u testuser mysql -u testuser -e 'use testdb; select test_id from db3;' -N | grep 39" - ) - galera_02.succeed( - "sudo -u testuser mysql -u testuser -e 'use testdb; select test_id from db2;' -N | grep 38" - ) - galera_03.succeed( - "sudo -u testuser mysql -u testuser -e 'use testdb; select test_id from db1;' -N | grep 37" - ) - galera_01.succeed("sudo -u testuser mysql -u testuser -e 'use testdb; drop table db3;'") - galera_02.succeed("sudo -u testuser mysql -u testuser -e 'use testdb; drop table db2;'") - galera_03.succeed("sudo -u testuser mysql -u testuser -e 'use testdb; drop table db1;'") - ''; -}) diff --git a/nixos/tests/mysql/mariadb-galera-rsync.nix b/nixos/tests/mysql/mariadb-galera-rsync.nix deleted file mode 100644 index 701e01e88718..000000000000 --- a/nixos/tests/mysql/mariadb-galera-rsync.nix +++ /dev/null @@ -1,226 +0,0 @@ -import ./../make-test-python.nix ({ pkgs, ...} : - -let - mysqlenv-common = pkgs.buildEnv { name = "mysql-path-env-common"; pathsToLink = [ "/bin" ]; paths = with pkgs; [ bash gawk gnutar inetutils which ]; }; - mysqlenv-rsync = pkgs.buildEnv { name = "mysql-path-env-rsync"; pathsToLink = [ "/bin" ]; paths = with pkgs; [ lsof procps rsync stunnel ]; }; - - # Common user configuration - users = { ... }: - { - users.users.testuser = { - isSystemUser = true; - group = "testusers"; - }; - users.groups.testusers = { }; - }; - -in { - name = "mariadb-galera-rsync"; - meta = with pkgs.lib.maintainers; { - maintainers = [ izorkin ]; - }; - - # The test creates a Galera cluster with 3 nodes and is checking if rsync-based SST works. The cluster is tested by creating a DB and an empty table on one node, - # and checking the table's presence on the other node. - - nodes = { - galera_04 = - { pkgs, ... }: - { - imports = [ users ]; - networking = { - interfaces.eth1 = { - ipv4.addresses = [ - { address = "192.168.2.1"; prefixLength = 24; } - ]; - }; - extraHosts = '' - 192.168.2.1 galera_04 - 192.168.2.2 galera_05 - 192.168.2.3 galera_06 - ''; - firewall.allowedTCPPorts = [ 3306 4444 4567 4568 ]; - firewall.allowedUDPPorts = [ 4567 ]; - }; - systemd.services.mysql = with pkgs; { - path = [ mysqlenv-common mysqlenv-rsync ]; - }; - services.mysql = { - enable = true; - package = pkgs.mariadb; - ensureDatabases = [ "testdb" ]; - ensureUsers = [{ - name = "testuser"; - ensurePermissions = { - "testdb.*" = "ALL PRIVILEGES"; - }; - }]; - settings = { - mysqld = { - bind_address = "0.0.0.0"; - }; - galera = { - wsrep_on = "ON"; - wsrep_debug = "NONE"; - wsrep_retry_autocommit = "3"; - wsrep_provider = "${pkgs.mariadb-galera}/lib/galera/libgalera_smm.so"; - wsrep_cluster_address = "gcomm://"; - wsrep_cluster_name = "galera-rsync"; - wsrep_node_address = "192.168.2.1"; - wsrep_node_name = "galera_04"; - wsrep_sst_method = "rsync"; - binlog_format = "ROW"; - enforce_storage_engine = "InnoDB"; - innodb_autoinc_lock_mode = "2"; - }; - }; - }; - }; - - galera_05 = - { pkgs, ... }: - { - imports = [ users ]; - networking = { - interfaces.eth1 = { - ipv4.addresses = [ - { address = "192.168.2.2"; prefixLength = 24; } - ]; - }; - extraHosts = '' - 192.168.2.1 galera_04 - 192.168.2.2 galera_05 - 192.168.2.3 galera_06 - ''; - firewall.allowedTCPPorts = [ 3306 4444 4567 4568 ]; - firewall.allowedUDPPorts = [ 4567 ]; - }; - systemd.services.mysql = with pkgs; { - path = [ mysqlenv-common mysqlenv-rsync ]; - }; - services.mysql = { - enable = true; - package = pkgs.mariadb; - settings = { - mysqld = { - bind_address = "0.0.0.0"; - }; - galera = { - wsrep_on = "ON"; - wsrep_debug = "NONE"; - wsrep_retry_autocommit = "3"; - wsrep_provider = "${pkgs.mariadb-galera}/lib/galera/libgalera_smm.so"; - wsrep_cluster_address = "gcomm://galera_04,galera_05,galera_06"; - wsrep_cluster_name = "galera-rsync"; - wsrep_node_address = "192.168.2.2"; - wsrep_node_name = "galera_05"; - wsrep_sst_method = "rsync"; - binlog_format = "ROW"; - enforce_storage_engine = "InnoDB"; - innodb_autoinc_lock_mode = "2"; - }; - }; - }; - }; - - galera_06 = - { pkgs, ... }: - { - imports = [ users ]; - networking = { - interfaces.eth1 = { - ipv4.addresses = [ - { address = "192.168.2.3"; prefixLength = 24; } - ]; - }; - extraHosts = '' - 192.168.2.1 galera_04 - 192.168.2.2 galera_05 - 192.168.2.3 galera_06 - ''; - firewall.allowedTCPPorts = [ 3306 4444 4567 4568 ]; - firewall.allowedUDPPorts = [ 4567 ]; - }; - systemd.services.mysql = with pkgs; { - path = [ mysqlenv-common mysqlenv-rsync ]; - }; - services.mysql = { - enable = true; - package = pkgs.mariadb; - settings = { - mysqld = { - bind_address = "0.0.0.0"; - }; - galera = { - wsrep_on = "ON"; - wsrep_debug = "NONE"; - wsrep_retry_autocommit = "3"; - wsrep_provider = "${pkgs.mariadb-galera}/lib/galera/libgalera_smm.so"; - wsrep_cluster_address = "gcomm://galera_04,galera_05,galera_06"; - wsrep_cluster_name = "galera-rsync"; - wsrep_node_address = "192.168.2.3"; - wsrep_node_name = "galera_06"; - wsrep_sst_method = "rsync"; - binlog_format = "ROW"; - enforce_storage_engine = "InnoDB"; - innodb_autoinc_lock_mode = "2"; - }; - }; - }; - }; - }; - - testScript = '' - galera_04.start() - galera_04.wait_for_unit("mysql") - galera_04.wait_for_open_port(3306) - galera_04.succeed( - "sudo -u testuser mysql -u testuser -e 'use testdb; create table db1 (test_id INT, PRIMARY KEY (test_id)) ENGINE = InnoDB;'" - ) - galera_04.succeed( - "sudo -u testuser mysql -u testuser -e 'use testdb; insert into db1 values (41);'" - ) - galera_05.start() - galera_05.wait_for_unit("mysql") - galera_05.wait_for_open_port(3306) - galera_06.start() - galera_06.wait_for_unit("mysql") - galera_06.wait_for_open_port(3306) - galera_05.succeed( - "sudo -u testuser mysql -u testuser -e 'use testdb; select test_id from db1;' -N | grep 41" - ) - galera_05.succeed( - "sudo -u testuser mysql -u testuser -e 'use testdb; create table db2 (test_id INT, PRIMARY KEY (test_id)) ENGINE = InnoDB;'" - ) - galera_05.succeed("systemctl stop mysql") - galera_04.succeed( - "sudo -u testuser mysql -u testuser -e 'use testdb; insert into db2 values (42);'" - ) - galera_06.succeed( - "sudo -u testuser mysql -u testuser -e 'use testdb; create table db3 (test_id INT, PRIMARY KEY (test_id)) ENGINE = InnoDB;'" - ) - galera_04.succeed( - "sudo -u testuser mysql -u testuser -e 'use testdb; insert into db3 values (43);'" - ) - galera_05.succeed("systemctl start mysql") - galera_05.wait_for_open_port(3306) - galera_05.succeed( - "sudo -u testuser mysql -u testuser -e 'show status' -N | grep 'wsrep_cluster_size.*3'" - ) - galera_06.succeed( - "sudo -u testuser mysql -u testuser -e 'show status' -N | grep 'wsrep_local_state_comment.*Synced'" - ) - galera_04.succeed( - "sudo -u testuser mysql -u testuser -e 'use testdb; select test_id from db3;' -N | grep 43" - ) - galera_05.succeed( - "sudo -u testuser mysql -u testuser -e 'use testdb; select test_id from db2;' -N | grep 42" - ) - galera_06.succeed( - "sudo -u testuser mysql -u testuser -e 'use testdb; select test_id from db1;' -N | grep 41" - ) - galera_04.succeed("sudo -u testuser mysql -u testuser -e 'use testdb; drop table db3;'") - galera_05.succeed("sudo -u testuser mysql -u testuser -e 'use testdb; drop table db2;'") - galera_06.succeed("sudo -u testuser mysql -u testuser -e 'use testdb; drop table db1;'") - ''; -}) diff --git a/nixos/tests/mysql/mariadb-galera.nix b/nixos/tests/mysql/mariadb-galera.nix new file mode 100644 index 000000000000..c9962f49c02f --- /dev/null +++ b/nixos/tests/mysql/mariadb-galera.nix @@ -0,0 +1,250 @@ +{ + system ? builtins.currentSystem, + config ? {}, + pkgs ? import ../../.. { inherit system config; }, + lib ? pkgs.lib +}: + +let + inherit (import ./common.nix { inherit pkgs lib; }) mkTestName mariadbPackages; + + makeTest = import ./../make-test-python.nix; + + # Common user configuration + makeGaleraTest = { + mariadbPackage, + name ? mkTestName mariadbPackage, + galeraPackage ? pkgs.mariadb-galera + }: makeTest { + name = "${name}-galera-mariabackup"; + meta = with pkgs.lib.maintainers; { + maintainers = [ izorkin ajs124 das_j ]; + }; + + # The test creates a Galera cluster with 3 nodes and is checking if mariabackup-based SST works. The cluster is tested by creating a DB and an empty table on one node, + # and checking the table's presence on the other node. + nodes = let + mkGaleraNode = { + id, + method + }: let + address = "192.168.1.${toString id}"; + isFirstClusterNode = id == 1 || id == 4; + in { + users = { + users.testuser = { + isSystemUser = true; + group = "testusers"; + }; + groups.testusers = { }; + }; + + networking = { + interfaces.eth1 = { + ipv4.addresses = [ + { inherit address; prefixLength = 24; } + ]; + }; + extraHosts = lib.concatMapStringsSep "\n" (i: "192.168.1.${toString i} galera_0${toString i}") (lib.range 1 6); + firewall.allowedTCPPorts = [ 3306 4444 4567 4568 ]; + firewall.allowedUDPPorts = [ 4567 ]; + }; + systemd.services.mysql = with pkgs; { + path = with pkgs; [ + bash + gawk + gnutar + gzip + inetutils + iproute2 + netcat + procps + pv + rsync + socat + stunnel + which + ]; + }; + services.mysql = { + enable = true; + package = mariadbPackage; + ensureDatabases = lib.mkIf isFirstClusterNode [ "testdb" ]; + ensureUsers = lib.mkIf isFirstClusterNode [{ + name = "testuser"; + ensurePermissions = { + "testdb.*" = "ALL PRIVILEGES"; + }; + }]; + initialScript = lib.mkIf isFirstClusterNode (pkgs.writeText "mariadb-init.sql" '' + GRANT ALL PRIVILEGES ON *.* TO 'check_repl'@'localhost' IDENTIFIED BY 'check_pass' WITH GRANT OPTION; + FLUSH PRIVILEGES; + ''); + settings = { + mysqld = { + bind_address = "0.0.0.0"; + }; + galera = { + wsrep_on = "ON"; + wsrep_debug = "NONE"; + wsrep_retry_autocommit = "3"; + wsrep_provider = "${galeraPackage}/lib/galera/libgalera_smm.so"; + wsrep_cluster_address = "gcomm://" + + lib.optionalString (id == 2 || id == 3) "galera_01,galera_02,galera_03" + + lib.optionalString (id == 5 || id == 6) "galera_04,galera_05,galera_06"; + wsrep_cluster_name = "galera"; + wsrep_node_address = address; + wsrep_node_name = "galera_0${toString id}"; + wsrep_sst_method = method; + wsrep_sst_auth = "check_repl:check_pass"; + binlog_format = "ROW"; + enforce_storage_engine = "InnoDB"; + innodb_autoinc_lock_mode = "2"; + }; + }; + }; + }; + in { + galera_01 = mkGaleraNode { + id = 1; + method = "mariabackup"; + }; + + galera_02 = mkGaleraNode { + id = 2; + method = "mariabackup"; + }; + + galera_03 = mkGaleraNode { + id = 3; + method = "mariabackup"; + }; + + galera_04 = mkGaleraNode { + id = 4; + method = "rsync"; + }; + + galera_05 = mkGaleraNode { + id = 5; + method = "rsync"; + }; + + galera_06 = mkGaleraNode { + id = 6; + method = "rsync"; + }; + + }; + + testScript = '' + galera_01.start() + galera_01.wait_for_unit("mysql") + galera_01.wait_for_open_port(3306) + galera_01.succeed( + "sudo -u testuser mysql -u testuser -e 'use testdb; create table db1 (test_id INT, PRIMARY KEY (test_id)) ENGINE = InnoDB;'" + ) + galera_01.succeed( + "sudo -u testuser mysql -u testuser -e 'use testdb; insert into db1 values (37);'" + ) + galera_02.start() + galera_02.wait_for_unit("mysql") + galera_02.wait_for_open_port(3306) + galera_03.start() + galera_03.wait_for_unit("mysql") + galera_03.wait_for_open_port(3306) + galera_02.succeed( + "sudo -u testuser mysql -u testuser -e 'use testdb; select test_id from db1;' -N | grep 37" + ) + galera_02.succeed( + "sudo -u testuser mysql -u testuser -e 'use testdb; create table db2 (test_id INT, PRIMARY KEY (test_id)) ENGINE = InnoDB;'" + ) + galera_02.succeed("systemctl stop mysql") + galera_01.succeed( + "sudo -u testuser mysql -u testuser -e 'use testdb; insert into db2 values (38);'" + ) + galera_03.succeed( + "sudo -u testuser mysql -u testuser -e 'use testdb; create table db3 (test_id INT, PRIMARY KEY (test_id)) ENGINE = InnoDB;'" + ) + galera_01.succeed( + "sudo -u testuser mysql -u testuser -e 'use testdb; insert into db3 values (39);'" + ) + galera_02.succeed("systemctl start mysql") + galera_02.wait_for_open_port(3306) + galera_02.succeed( + "sudo -u testuser mysql -u testuser -e 'show status' -N | grep 'wsrep_cluster_size.*3'" + ) + galera_03.succeed( + "sudo -u testuser mysql -u testuser -e 'show status' -N | grep 'wsrep_local_state_comment.*Synced'" + ) + galera_01.succeed( + "sudo -u testuser mysql -u testuser -e 'use testdb; select test_id from db3;' -N | grep 39" + ) + galera_02.succeed( + "sudo -u testuser mysql -u testuser -e 'use testdb; select test_id from db2;' -N | grep 38" + ) + galera_03.succeed( + "sudo -u testuser mysql -u testuser -e 'use testdb; select test_id from db1;' -N | grep 37" + ) + galera_01.succeed("sudo -u testuser mysql -u testuser -e 'use testdb; drop table db3;'") + galera_02.succeed("sudo -u testuser mysql -u testuser -e 'use testdb; drop table db2;'") + galera_03.succeed("sudo -u testuser mysql -u testuser -e 'use testdb; drop table db1;'") + galera_01.crash() + galera_02.crash() + galera_03.crash() + + galera_04.start() + galera_04.wait_for_unit("mysql") + galera_04.wait_for_open_port(3306) + galera_04.succeed( + "sudo -u testuser mysql -u testuser -e 'use testdb; create table db1 (test_id INT, PRIMARY KEY (test_id)) ENGINE = InnoDB;'" + ) + galera_04.succeed( + "sudo -u testuser mysql -u testuser -e 'use testdb; insert into db1 values (41);'" + ) + galera_05.start() + galera_05.wait_for_unit("mysql") + galera_05.wait_for_open_port(3306) + galera_06.start() + galera_06.wait_for_unit("mysql") + galera_06.wait_for_open_port(3306) + galera_05.succeed( + "sudo -u testuser mysql -u testuser -e 'use testdb; select test_id from db1;' -N | grep 41" + ) + galera_05.succeed( + "sudo -u testuser mysql -u testuser -e 'use testdb; create table db2 (test_id INT, PRIMARY KEY (test_id)) ENGINE = InnoDB;'" + ) + galera_05.succeed("systemctl stop mysql") + galera_04.succeed( + "sudo -u testuser mysql -u testuser -e 'use testdb; insert into db2 values (42);'" + ) + galera_06.succeed( + "sudo -u testuser mysql -u testuser -e 'use testdb; create table db3 (test_id INT, PRIMARY KEY (test_id)) ENGINE = InnoDB;'" + ) + galera_04.succeed( + "sudo -u testuser mysql -u testuser -e 'use testdb; insert into db3 values (43);'" + ) + galera_05.succeed("systemctl start mysql") + galera_05.wait_for_open_port(3306) + galera_05.succeed( + "sudo -u testuser mysql -u testuser -e 'show status' -N | grep 'wsrep_cluster_size.*3'" + ) + galera_06.succeed( + "sudo -u testuser mysql -u testuser -e 'show status' -N | grep 'wsrep_local_state_comment.*Synced'" + ) + galera_04.succeed( + "sudo -u testuser mysql -u testuser -e 'use testdb; select test_id from db3;' -N | grep 43" + ) + galera_05.succeed( + "sudo -u testuser mysql -u testuser -e 'use testdb; select test_id from db2;' -N | grep 42" + ) + galera_06.succeed( + "sudo -u testuser mysql -u testuser -e 'use testdb; select test_id from db1;' -N | grep 41" + ) + galera_04.succeed("sudo -u testuser mysql -u testuser -e 'use testdb; drop table db3;'") + galera_05.succeed("sudo -u testuser mysql -u testuser -e 'use testdb; drop table db2;'") + galera_06.succeed("sudo -u testuser mysql -u testuser -e 'use testdb; drop table db1;'") + ''; + }; +in + lib.mapAttrs (_: mariadbPackage: makeGaleraTest { inherit mariadbPackage; }) mariadbPackages diff --git a/nixos/tests/mysql/mysql-autobackup.nix b/nixos/tests/mysql/mysql-autobackup.nix index b0ec7daaf054..101122f7bdef 100644 --- a/nixos/tests/mysql/mysql-autobackup.nix +++ b/nixos/tests/mysql/mysql-autobackup.nix @@ -1,38 +1,53 @@ -import ./../make-test-python.nix ({ pkgs, lib, ... }: - { - name = "automysqlbackup"; - meta.maintainers = [ lib.maintainers.aanderse ]; + system ? builtins.currentSystem, + config ? {}, + pkgs ? import ../../.. { inherit system config; }, + lib ? pkgs.lib +}: - machine = - { pkgs, ... }: - { - services.mysql.enable = true; - services.mysql.package = pkgs.mariadb; - services.mysql.initialDatabases = [ { name = "testdb"; schema = ./testdb.sql; } ]; +let + inherit (import ./common.nix { inherit pkgs lib; }) mkTestName mariadbPackages; + + makeTest = import ./../make-test-python.nix; + + makeAutobackupTest = { + package, + name ? mkTestName package, + }: makeTest { + name = "${name}-automysqlbackup"; + meta.maintainers = [ lib.maintainers.aanderse ]; + + machine = { + services.mysql = { + inherit package; + enable = true; + initialDatabases = [ { name = "testdb"; schema = ./testdb.sql; } ]; + }; services.automysqlbackup.enable = true; }; - testScript = '' - start_all() + testScript = '' + start_all() - # Need to have mysql started so that it can be populated with data. - machine.wait_for_unit("mysql.service") + # Need to have mysql started so that it can be populated with data. + machine.wait_for_unit("mysql.service") - with subtest("Wait for testdb to be fully populated (5 rows)."): - machine.wait_until_succeeds( - "mysql -u root -D testdb -N -B -e 'select count(id) from tests' | grep -q 5" - ) + with subtest("Wait for testdb to be fully populated (5 rows)."): + machine.wait_until_succeeds( + "mysql -u root -D testdb -N -B -e 'select count(id) from tests' | grep -q 5" + ) - with subtest("Do a backup and wait for it to start"): - machine.start_job("automysqlbackup.service") - machine.wait_for_job("automysqlbackup.service") + with subtest("Do a backup and wait for it to start"): + machine.start_job("automysqlbackup.service") + machine.wait_for_job("automysqlbackup.service") - with subtest("wait for backup file and check that data appears in backup"): - machine.wait_for_file("/var/backup/mysql/daily/testdb") - machine.succeed( - "${pkgs.gzip}/bin/zcat /var/backup/mysql/daily/testdb/daily_testdb_*.sql.gz | grep hello" - ) - ''; -}) + with subtest("wait for backup file and check that data appears in backup"): + machine.wait_for_file("/var/backup/mysql/daily/testdb") + machine.succeed( + "${pkgs.gzip}/bin/zcat /var/backup/mysql/daily/testdb/daily_testdb_*.sql.gz | grep hello" + ) + ''; + }; +in + lib.mapAttrs (_: package: makeAutobackupTest { inherit package; }) mariadbPackages diff --git a/nixos/tests/mysql/mysql-backup.nix b/nixos/tests/mysql/mysql-backup.nix index 269fddc66e1d..9335b233327a 100644 --- a/nixos/tests/mysql/mysql-backup.nix +++ b/nixos/tests/mysql/mysql-backup.nix @@ -1,56 +1,72 @@ -# Test whether mysqlBackup option works -import ./../make-test-python.nix ({ pkgs, ... } : { - name = "mysql-backup"; - meta = with pkgs.lib.maintainers; { - maintainers = [ rvl ]; - }; +{ + system ? builtins.currentSystem, + config ? {}, + pkgs ? import ../../.. { inherit system config; }, + lib ? pkgs.lib +}: - nodes = { - master = { pkgs, ... }: { - services.mysql = { - enable = true; - initialDatabases = [ { name = "testdb"; schema = ./testdb.sql; } ]; - package = pkgs.mariadb; - }; +let + inherit (import ./common.nix { inherit pkgs lib; }) mkTestName mariadbPackages; - services.mysqlBackup = { - enable = true; - databases = [ "doesnotexist" "testdb" ]; + makeTest = import ./../make-test-python.nix; + + makeBackupTest = { + package, + name ? mkTestName package + }: makeTest { + name = "${name}-backup"; + meta = with pkgs.lib.maintainers; { + maintainers = [ rvl ]; + }; + + nodes = { + master = { pkgs, ... }: { + services.mysql = { + inherit package; + enable = true; + initialDatabases = [ { name = "testdb"; schema = ./testdb.sql; } ]; + }; + + services.mysqlBackup = { + enable = true; + databases = [ "doesnotexist" "testdb" ]; + }; }; }; + + testScript = '' + start_all() + + # Delete backup file that may be left over from a previous test run. + # This is not needed on Hydra but useful for repeated local test runs. + master.execute("rm -f /var/backup/mysql/testdb.gz") + + # Need to have mysql started so that it can be populated with data. + master.wait_for_unit("mysql.service") + + # Wait for testdb to be fully populated (5 rows). + master.wait_until_succeeds( + "mysql -u root -D testdb -N -B -e 'select count(id) from tests' | grep -q 5" + ) + + # Do a backup and wait for it to start + master.start_job("mysql-backup.service") + master.wait_for_unit("mysql-backup.service") + + # wait for backup to fail, because of database 'doesnotexist' + master.wait_until_fails("systemctl is-active -q mysql-backup.service") + + # wait for backup file and check that data appears in backup + master.wait_for_file("/var/backup/mysql/testdb.gz") + master.succeed( + "${pkgs.gzip}/bin/zcat /var/backup/mysql/testdb.gz | grep hello" + ) + + # Check that a failed backup is logged + master.succeed( + "journalctl -u mysql-backup.service | grep 'fail.*doesnotexist' > /dev/null" + ) + ''; }; - - testScript = '' - start_all() - - # Delete backup file that may be left over from a previous test run. - # This is not needed on Hydra but useful for repeated local test runs. - master.execute("rm -f /var/backup/mysql/testdb.gz") - - # Need to have mysql started so that it can be populated with data. - master.wait_for_unit("mysql.service") - - # Wait for testdb to be fully populated (5 rows). - master.wait_until_succeeds( - "mysql -u root -D testdb -N -B -e 'select count(id) from tests' | grep -q 5" - ) - - # Do a backup and wait for it to start - master.start_job("mysql-backup.service") - master.wait_for_unit("mysql-backup.service") - - # wait for backup to fail, because of database 'doesnotexist' - master.wait_until_fails("systemctl is-active -q mysql-backup.service") - - # wait for backup file and check that data appears in backup - master.wait_for_file("/var/backup/mysql/testdb.gz") - master.succeed( - "${pkgs.gzip}/bin/zcat /var/backup/mysql/testdb.gz | grep hello" - ) - - # Check that a failed backup is logged - master.succeed( - "journalctl -u mysql-backup.service | grep 'fail.*doesnotexist' > /dev/null" - ) - ''; -}) +in + lib.mapAttrs (_: package: makeBackupTest { inherit package; }) mariadbPackages diff --git a/nixos/tests/mysql/mysql-replication.nix b/nixos/tests/mysql/mysql-replication.nix index a52372ca47ce..f6014019bd53 100644 --- a/nixos/tests/mysql/mysql-replication.nix +++ b/nixos/tests/mysql/mysql-replication.nix @@ -1,91 +1,101 @@ -import ./../make-test-python.nix ({ pkgs, ...} : +{ + system ? builtins.currentSystem, + config ? {}, + pkgs ? import ../../.. { inherit system config; }, + lib ? pkgs.lib +}: let + inherit (import ./common.nix { inherit pkgs lib; }) mkTestName mariadbPackages; + replicateUser = "replicate"; replicatePassword = "secret"; -in -{ - name = "mysql-replication"; - meta = with pkgs.lib.maintainers; { - maintainers = [ eelco shlevy ]; - }; + makeTest = import ./../make-test-python.nix; - nodes = { - master = - { pkgs, ... }: + makeReplicationTest = { + package, + name ? mkTestName package, + }: makeTest { + name = "${name}-replication"; + meta = with pkgs.lib.maintainers; { + maintainers = [ ajs124 das_j ]; + }; - { - services.mysql.enable = true; - services.mysql.package = pkgs.mariadb; - services.mysql.replication.role = "master"; - services.mysql.replication.slaveHost = "%"; - services.mysql.replication.masterUser = replicateUser; - services.mysql.replication.masterPassword = replicatePassword; - services.mysql.initialDatabases = [ { name = "testdb"; schema = ./testdb.sql; } ]; + nodes = { + primary = { + services.mysql = { + inherit package; + enable = true; + replication.role = "master"; + replication.slaveHost = "%"; + replication.masterUser = replicateUser; + replication.masterPassword = replicatePassword; + initialDatabases = [ { name = "testdb"; schema = ./testdb.sql; } ]; + }; networking.firewall.allowedTCPPorts = [ 3306 ]; }; - slave1 = - { pkgs, nodes, ... }: - - { - services.mysql.enable = true; - services.mysql.package = pkgs.mariadb; - services.mysql.replication.role = "slave"; - services.mysql.replication.serverId = 2; - services.mysql.replication.masterHost = nodes.master.config.networking.hostName; - services.mysql.replication.masterUser = replicateUser; - services.mysql.replication.masterPassword = replicatePassword; + secondary1 = { nodes, ... }: { + services.mysql = { + inherit package; + enable = true; + replication.role = "slave"; + replication.serverId = 2; + replication.masterHost = nodes.primary.config.networking.hostName; + replication.masterUser = replicateUser; + replication.masterPassword = replicatePassword; + }; }; - slave2 = - { pkgs, nodes, ... }: - - { - services.mysql.enable = true; - services.mysql.package = pkgs.mariadb; - services.mysql.replication.role = "slave"; - services.mysql.replication.serverId = 3; - services.mysql.replication.masterHost = nodes.master.config.networking.hostName; - services.mysql.replication.masterUser = replicateUser; - services.mysql.replication.masterPassword = replicatePassword; + secondary2 = { nodes, ... }: { + services.mysql = { + inherit package; + enable = true; + replication.role = "slave"; + replication.serverId = 3; + replication.masterHost = nodes.primary.config.networking.hostName; + replication.masterUser = replicateUser; + replication.masterPassword = replicatePassword; + }; }; + }; + + testScript = '' + primary.start() + primary.wait_for_unit("mysql") + primary.wait_for_open_port(3306) + # Wait for testdb to be fully populated (5 rows). + primary.wait_until_succeeds( + "sudo -u mysql mysql -u mysql -D testdb -N -B -e 'select count(id) from tests' | grep -q 5" + ) + + secondary1.start() + secondary2.start() + secondary1.wait_for_unit("mysql") + secondary1.wait_for_open_port(3306) + secondary2.wait_for_unit("mysql") + secondary2.wait_for_open_port(3306) + + # wait for replications to finish + secondary1.wait_until_succeeds( + "sudo -u mysql mysql -u mysql -D testdb -N -B -e 'select count(id) from tests' | grep -q 5" + ) + secondary2.wait_until_succeeds( + "sudo -u mysql mysql -u mysql -D testdb -N -B -e 'select count(id) from tests' | grep -q 5" + ) + + secondary2.succeed("systemctl stop mysql") + primary.succeed( + "echo 'insert into testdb.tests values (123, 456);' | sudo -u mysql mysql -u mysql -N" + ) + secondary2.succeed("systemctl start mysql") + secondary2.wait_for_unit("mysql") + secondary2.wait_for_open_port(3306) + secondary2.wait_until_succeeds( + "echo 'select * from testdb.tests where Id = 123;' | sudo -u mysql mysql -u mysql -N | grep 456" + ) + ''; }; - - testScript = '' - master.start() - master.wait_for_unit("mysql") - master.wait_for_open_port(3306) - # Wait for testdb to be fully populated (5 rows). - master.wait_until_succeeds( - "sudo -u mysql mysql -u mysql -D testdb -N -B -e 'select count(id) from tests' | grep -q 5" - ) - - slave1.start() - slave2.start() - slave1.wait_for_unit("mysql") - slave1.wait_for_open_port(3306) - slave2.wait_for_unit("mysql") - slave2.wait_for_open_port(3306) - - # wait for replications to finish - slave1.wait_until_succeeds( - "sudo -u mysql mysql -u mysql -D testdb -N -B -e 'select count(id) from tests' | grep -q 5" - ) - slave2.wait_until_succeeds( - "sudo -u mysql mysql -u mysql -D testdb -N -B -e 'select count(id) from tests' | grep -q 5" - ) - - slave2.succeed("systemctl stop mysql") - master.succeed( - "echo 'insert into testdb.tests values (123, 456);' | sudo -u mysql mysql -u mysql -N" - ) - slave2.succeed("systemctl start mysql") - slave2.wait_for_unit("mysql") - slave2.wait_for_open_port(3306) - slave2.wait_until_succeeds( - "echo 'select * from testdb.tests where Id = 123;' | sudo -u mysql mysql -u mysql -N | grep 456" - ) - ''; -}) +in + lib.mapAttrs (_: package: makeReplicationTest { inherit package; }) mariadbPackages diff --git a/nixos/tests/mysql/mysql.nix b/nixos/tests/mysql/mysql.nix index 2ac2b34a18e2..a5e42f85a7fb 100644 --- a/nixos/tests/mysql/mysql.nix +++ b/nixos/tests/mysql/mysql.nix @@ -1,221 +1,149 @@ -import ./../make-test-python.nix ({ pkgs, ...}: - +{ + system ? builtins.currentSystem, + config ? {}, + pkgs ? import ../../.. { inherit system config; }, + lib ? pkgs.lib +}: let + inherit (import ./common.nix { inherit pkgs lib; }) mkTestName mariadbPackages mysqlPackages; + + makeTest = import ./../make-test-python.nix; # Setup common users - users = { ... }: - { - users.groups.testusers = { }; - - users.users.testuser = { - isSystemUser = true; - group = "testusers"; + makeMySQLTest = { + package, + name ? mkTestName package, + useSocketAuth ? true, + hasMroonga ? true, + hasRocksDB ? true + }: makeTest { + inherit name; + meta = with lib.maintainers; { + maintainers = [ ajs124 das_j ]; }; - users.users.testuser2 = { - isSystemUser = true; - group = "testusers"; - }; - }; + nodes = { + ${name} = + { pkgs, ... }: { -in + users = { + groups.testusers = { }; -{ - name = "mysql"; - meta = with pkgs.lib.maintainers; { - maintainers = [ eelco shlevy ]; - }; + users.testuser = { + isSystemUser = true; + group = "testusers"; + }; - nodes = { - mysql57 = - { pkgs, ... }: - - { - imports = [ users ]; - - services.mysql.enable = true; - services.mysql.initialDatabases = [ - { name = "testdb3"; schema = ./testdb.sql; } - ]; - # 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 'testuser3'@'localhost' IDENTIFIED BY 'secure'; - GRANT ALL PRIVILEGES ON testdb3.* TO 'testuser3'@'localhost'; - ''; - services.mysql.ensureDatabases = [ "testdb" "testdb2" ]; - services.mysql.ensureUsers = [{ - name = "testuser"; - ensurePermissions = { - "testdb.*" = "ALL PRIVILEGES"; + users.testuser2 = { + isSystemUser = true; + group = "testusers"; + }; }; - } { - name = "testuser2"; - ensurePermissions = { - "testdb2.*" = "ALL PRIVILEGES"; - }; - }]; - services.mysql.package = pkgs.mysql57; - }; - mysql80 = - { pkgs, ... }: + services.mysql = { + enable = true; + initialDatabases = [ + { name = "testdb3"; schema = ./testdb.sql; } + ]; + # note that using pkgs.writeText here is generally not a good idea, + # as it will store the password in world-readable /nix/store ;) + initialScript = pkgs.writeText "mysql-init.sql" (if (!useSocketAuth) then '' + CREATE USER 'testuser3'@'localhost' IDENTIFIED BY 'secure'; + GRANT ALL PRIVILEGES ON testdb3.* TO 'testuser3'@'localhost'; + '' else '' + ALTER USER root@localhost IDENTIFIED WITH unix_socket; + DELETE FROM mysql.user WHERE password = ''' AND plugin = '''; + DELETE FROM mysql.user WHERE user = '''; + FLUSH PRIVILEGES; + ''); - { - imports = [ users ]; - - services.mysql.enable = true; - services.mysql.initialDatabases = [ - { name = "testdb3"; schema = ./testdb.sql; } - ]; - # 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 'testuser3'@'localhost' IDENTIFIED BY 'secure'; - GRANT ALL PRIVILEGES ON testdb3.* TO 'testuser3'@'localhost'; - ''; - services.mysql.ensureDatabases = [ "testdb" "testdb2" ]; - services.mysql.ensureUsers = [{ - name = "testuser"; - ensurePermissions = { - "testdb.*" = "ALL PRIVILEGES"; - }; - } { - name = "testuser2"; - ensurePermissions = { - "testdb2.*" = "ALL PRIVILEGES"; - }; - }]; - services.mysql.package = pkgs.mysql80; - }; - - mariadb = - { pkgs, ... }: - - { - imports = [ users ]; - - services.mysql.enable = true; - services.mysql.initialScript = pkgs.writeText "mariadb-init.sql" '' - ALTER USER root@localhost IDENTIFIED WITH unix_socket; - DELETE FROM mysql.user WHERE password = ''' AND plugin = '''; - DELETE FROM mysql.user WHERE user = '''; - FLUSH PRIVILEGES; - ''; - services.mysql.ensureDatabases = [ "testdb" "testdb2" ]; - services.mysql.ensureUsers = [{ - name = "testuser"; - ensurePermissions = { - "testdb.*" = "ALL PRIVILEGES"; - }; - } { - name = "testuser2"; - ensurePermissions = { - "testdb2.*" = "ALL PRIVILEGES"; - }; - }]; - services.mysql.settings = { - mysqld = { - plugin-load-add = [ "ha_mroonga.so" "ha_rocksdb.so" ]; + ensureDatabases = [ "testdb" "testdb2" ]; + ensureUsers = [{ + name = "testuser"; + ensurePermissions = { + "testdb.*" = "ALL PRIVILEGES"; + }; + } { + name = "testuser2"; + ensurePermissions = { + "testdb2.*" = "ALL PRIVILEGES"; + }; + }]; + package = package; + settings = { + mysqld = { + plugin-load-add = lib.optional hasMroonga "ha_mroonga.so" + ++ lib.optional hasRocksDB "ha_rocksdb.so"; + }; + }; }; }; - services.mysql.package = pkgs.mariadb; - }; + mariadb = { + }; + }; + + testScript = '' + start_all() + + machine = ${name} + machine.wait_for_unit("mysql") + machine.succeed( + "echo 'use testdb; create table tests (test_id INT, PRIMARY KEY (test_id));' | sudo -u testuser mysql -u testuser" + ) + machine.succeed( + "echo 'use testdb; insert into tests values (42);' | sudo -u testuser mysql -u testuser" + ) + # Ensure testuser2 is not able to insert into testdb as mysql testuser2 + machine.fail( + "echo 'use testdb; insert into tests values (23);' | sudo -u testuser2 mysql -u testuser2" + ) + # Ensure testuser2 is not able to authenticate as mysql testuser + machine.fail( + "echo 'use testdb; insert into tests values (23);' | sudo -u testuser2 mysql -u testuser" + ) + machine.succeed( + "echo 'use testdb; select test_id from tests;' | sudo -u testuser mysql -u testuser -N | grep 42" + ) + + ${lib.optionalString hasMroonga '' + # Check if Mroonga plugin works + machine.succeed( + "echo 'use testdb; create table mroongadb (test_id INT, PRIMARY KEY (test_id)) ENGINE = Mroonga;' | sudo -u testuser mysql -u testuser" + ) + machine.succeed( + "echo 'use testdb; insert into mroongadb values (25);' | sudo -u testuser mysql -u testuser" + ) + machine.succeed( + "echo 'use testdb; select test_id from mroongadb;' | sudo -u testuser mysql -u testuser -N | grep 25" + ) + machine.succeed( + "echo 'use testdb; drop table mroongadb;' | sudo -u testuser mysql -u testuser" + ) + ''} + + ${lib.optionalString hasRocksDB '' + # Check if RocksDB plugin works + machine.succeed( + "echo 'use testdb; create table rocksdb (test_id INT, PRIMARY KEY (test_id)) ENGINE = RocksDB;' | sudo -u testuser mysql -u testuser" + ) + machine.succeed( + "echo 'use testdb; insert into rocksdb values (28);' | sudo -u testuser mysql -u testuser" + ) + machine.succeed( + "echo 'use testdb; select test_id from rocksdb;' | sudo -u testuser mysql -u testuser -N | grep 28" + ) + machine.succeed( + "echo 'use testdb; drop table rocksdb;' | sudo -u testuser mysql -u testuser" + ) + ''} + ''; }; - - testScript = '' - start_all() - - mysql57.wait_for_unit("mysql") - mysql57.succeed( - "echo 'use testdb; create table tests (test_id INT, PRIMARY KEY (test_id));' | sudo -u testuser mysql -u testuser" - ) - mysql57.succeed( - "echo 'use testdb; insert into tests values (41);' | sudo -u testuser mysql -u testuser" - ) - # Ensure testuser2 is not able to insert into testdb as mysql testuser2 - mysql57.fail( - "echo 'use testdb; insert into tests values (22);' | sudo -u testuser2 mysql -u testuser2" - ) - # Ensure testuser2 is not able to authenticate as mysql testuser - mysql57.fail( - "echo 'use testdb; insert into tests values (22);' | sudo -u testuser2 mysql -u testuser" - ) - mysql57.succeed( - "echo 'use testdb; select test_id from tests;' | sudo -u testuser mysql -u testuser -N | grep 41" - ) - mysql57.succeed( - "echo 'use testdb3; select * from tests;' | mysql -u testuser3 --password=secure -N | grep 4" - ) - - mysql80.wait_for_unit("mysql") - mysql80.succeed( - "echo 'use testdb; create table tests (test_id INT, PRIMARY KEY (test_id));' | sudo -u testuser mysql -u testuser" - ) - mysql80.succeed( - "echo 'use testdb; insert into tests values (41);' | sudo -u testuser mysql -u testuser" - ) - # Ensure testuser2 is not able to insert into testdb as mysql testuser2 - mysql80.fail( - "echo 'use testdb; insert into tests values (22);' | sudo -u testuser2 mysql -u testuser2" - ) - # Ensure testuser2 is not able to authenticate as mysql testuser - mysql80.fail( - "echo 'use testdb; insert into tests values (22);' | sudo -u testuser2 mysql -u testuser" - ) - mysql80.succeed( - "echo 'use testdb; select test_id from tests;' | sudo -u testuser mysql -u testuser -N | grep 41" - ) - mysql80.succeed( - "echo 'use testdb3; select * from tests;' | mysql -u testuser3 --password=secure -N | grep 4" - ) - - mariadb.wait_for_unit("mysql") - mariadb.succeed( - "echo 'use testdb; create table tests (test_id INT, PRIMARY KEY (test_id));' | sudo -u testuser mysql -u testuser" - ) - mariadb.succeed( - "echo 'use testdb; insert into tests values (42);' | sudo -u testuser mysql -u testuser" - ) - # Ensure testuser2 is not able to insert into testdb as mysql testuser2 - mariadb.fail( - "echo 'use testdb; insert into tests values (23);' | sudo -u testuser2 mysql -u testuser2" - ) - # Ensure testuser2 is not able to authenticate as mysql testuser - mariadb.fail( - "echo 'use testdb; insert into tests values (23);' | sudo -u testuser2 mysql -u testuser" - ) - mariadb.succeed( - "echo 'use testdb; select test_id from tests;' | sudo -u testuser mysql -u testuser -N | grep 42" - ) - - # Check if Mroonga plugin works - mariadb.succeed( - "echo 'use testdb; create table mroongadb (test_id INT, PRIMARY KEY (test_id)) ENGINE = Mroonga;' | sudo -u testuser mysql -u testuser" - ) - mariadb.succeed( - "echo 'use testdb; insert into mroongadb values (25);' | sudo -u testuser mysql -u testuser" - ) - mariadb.succeed( - "echo 'use testdb; select test_id from mroongadb;' | sudo -u testuser mysql -u testuser -N | grep 25" - ) - mariadb.succeed( - "echo 'use testdb; drop table mroongadb;' | sudo -u testuser mysql -u testuser" - ) - - # Check if RocksDB plugin works - mariadb.succeed( - "echo 'use testdb; create table rocksdb (test_id INT, PRIMARY KEY (test_id)) ENGINE = RocksDB;' | sudo -u testuser mysql -u testuser" - ) - mariadb.succeed( - "echo 'use testdb; insert into rocksdb values (28);' | sudo -u testuser mysql -u testuser" - ) - mariadb.succeed( - "echo 'use testdb; select test_id from rocksdb;' | sudo -u testuser mysql -u testuser -N | grep 28" - ) - mariadb.succeed( - "echo 'use testdb; drop table rocksdb;' | sudo -u testuser mysql -u testuser" - ) - ''; -}) +in + lib.mapAttrs (_: package: makeMySQLTest { + inherit package; + hasRocksDB = false; hasMroonga = false; + }) mysqlPackages + // (lib.mapAttrs (_: package: makeMySQLTest { + inherit package; + }) mariadbPackages) diff --git a/pkgs/servers/sql/mariadb/default.nix b/pkgs/servers/sql/mariadb/default.nix index 82fdc2a3a38b..3f1f3448dad8 100644 --- a/pkgs/servers/sql/mariadb/default.nix +++ b/pkgs/servers/sql/mariadb/default.nix @@ -2,8 +2,8 @@ # Native buildInputs components , bison, boost, cmake, fixDarwinDylibNames, flex, makeWrapper, pkg-config # Common components -, curl, libiconv, ncurses, openssl, pcre2 -, libkrb5, liburing, systemd +, curl, libiconv, ncurses, openssl, pcre, pcre2 +, libkrb5, libaio, liburing, systemd , CoreServices, cctools, perl , jemalloc, less # Server components @@ -14,36 +14,37 @@ , withStorageRocks ? true }: -with lib; - let # in mariadb # spans the whole file libExt = stdenv.hostPlatform.extensions.sharedLibrary; mytopEnv = perl.withPackages (p: with p; [ DBDmysql DBI TermReadKey ]); -mariadb = server // { - inherit client; # MariaDB Client - server = server; # MariaDB Server +mariadbPackage = packageSettings: (server packageSettings) // { + client = client packageSettings; # MariaDB Client + server = server packageSettings; # MariaDB Server }; -common = rec { # attributes common to both builds - version = "10.6.5"; +commonOptions = packageSettings: rec { # attributes common to both builds + inherit (packageSettings) version; src = fetchurl { url = "https://downloads.mariadb.com/MariaDB/mariadb-${version}/source/mariadb-${version}.tar.gz"; - sha256 = "sha256-4L4EBCjZpCqLtL0iG1Z/8lIs1vqJBjhic9pPA8XCCo8="; + inherit (packageSettings) sha256; }; nativeBuildInputs = [ cmake pkg-config ] - ++ optional stdenv.hostPlatform.isDarwin fixDarwinDylibNames - ++ optional (!stdenv.hostPlatform.isDarwin) makeWrapper; + ++ lib.optional stdenv.hostPlatform.isDarwin fixDarwinDylibNames + ++ lib.optional (!stdenv.hostPlatform.isDarwin) makeWrapper; buildInputs = [ - curl libiconv ncurses openssl pcre2 zlib - ] ++ optionals stdenv.hostPlatform.isLinux [ libkrb5 liburing systemd ] - ++ optionals stdenv.hostPlatform.isDarwin [ CoreServices cctools perl ] - ++ optional (!stdenv.hostPlatform.isDarwin) [ jemalloc ]; + curl libiconv ncurses openssl zlib + ] ++ (packageSettings.extraBuildInputs or []) + ++ lib.optionals stdenv.hostPlatform.isLinux ([ libkrb5 systemd ] + ++ (if (lib.versionOlder version "10.6") then [ libaio ] else [ liburing ])) + ++ lib.optionals stdenv.hostPlatform.isDarwin [ CoreServices cctools perl ] + ++ lib.optional (!stdenv.hostPlatform.isDarwin) [ jemalloc ] + ++ (if (lib.versionOlder version "10.5") then [ pcre ] else [ pcre2 ]); prePatch = '' sed -i 's,[^"]*/var/log,/var/log,g' storage/mroonga/vendor/groonga/CMakeLists.txt @@ -54,7 +55,7 @@ common = rec { # attributes common to both builds ] # Fixes a build issue as documented on # https://jira.mariadb.org/browse/MDEV-26769?focusedCommentId=206073&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-206073 - ++ lib.optional (!stdenv.isLinux) ./patch/macos-MDEV-26769-regression-fix.patch; + ++ lib.optional (!stdenv.hostPlatform.isLinux && lib.versionAtLeast version "10.6") ./patch/macos-MDEV-26769-regression-fix.patch; cmakeFlags = [ "-DBUILD_CONFIG=mysql_release" @@ -86,7 +87,7 @@ common = rec { # attributes common to both builds "-DWITH_SAFEMALLOC=OFF" "-DWITH_UNIT_TESTS=OFF" "-DEMBEDDED_LIBRARY=OFF" - ] ++ optionals stdenv.hostPlatform.isDarwin [ + ] ++ lib.optionals stdenv.hostPlatform.isDarwin [ # On Darwin without sandbox, CMake will find the system java and attempt to build with java support, but # then it will fail during the actual build. Let's just disable the flag explicitly until someone decides # to pass in java explicitly. @@ -98,37 +99,39 @@ common = rec { # attributes common to both builds # Remove Development components. Need to use libmysqlclient. rm "$out"/lib/mysql/plugin/daemon_example.ini rm "$out"/lib/{libmariadbclient.a,libmysqlclient.a,libmysqlclient_r.a,libmysqlservices.a} - rm "$out"/bin/{mariadb-config,mariadb_config,mysql_config} + rm -f "$out"/bin/{mariadb-config,mariadb_config,mysql_config} rm -r $out/include rm -r $out/lib/pkgconfig ''; # perlPackages.DBDmysql is broken on darwin - postFixup = optionalString (!stdenv.hostPlatform.isDarwin) '' - wrapProgram $out/bin/mytop --set PATH ${makeBinPath [ less ncurses ]} + postFixup = lib.optionalString (!stdenv.hostPlatform.isDarwin) '' + wrapProgram $out/bin/mytop --set PATH ${lib.makeBinPath [ less ncurses ]} ''; - passthru.mysqlVersion = "5.7"; - - passthru.tests = { - mariadb-galera-mariabackup = nixosTests.mariadb-galera-mariabackup; - mariadb-galera-rsync = nixosTests.mariadb-galera-rsync; - mysql = nixosTests.mysql; - mysql-autobackup = nixosTests.mysql-autobackup; - mysql-backup = nixosTests.mysql-backup; - mysql-replication = nixosTests.mysql-replication; + passthru.tests = let + testVersion = "mariadb_${builtins.replaceStrings ["."] [""] (lib.versions.majorMinor (packageSettings.version))}"; + in { + mariadb-galera-rsync = nixosTests.mariadb-galera.${testVersion}; + mysql = nixosTests.mysql.${testVersion}; + mysql-autobackup = nixosTests.mysql-autobackup.${testVersion}; + mysql-backup = nixosTests.mysql-backup.${testVersion}; + mysql-replication = nixosTests.mysql-replication.${testVersion}; }; - meta = { + meta = with lib; { description = "An enhanced, drop-in replacement for MySQL"; homepage = "https://mariadb.org/"; license = licenses.gpl2; - maintainers = with maintainers; [ thoughtpolice ]; + maintainers = with maintainers; [ thoughtpolice ajs124 das_j ]; platforms = platforms.all; }; }; -client = stdenv.mkDerivation (common // { +client = packageSettings: let + common = commonOptions packageSettings; + +in stdenv.mkDerivation (common // { pname = "mariadb-client"; outputs = [ "out" "man" ]; @@ -153,7 +156,10 @@ client = stdenv.mkDerivation (common // { ''; }); -server = stdenv.mkDerivation (common // { +server = packageSettings: let + common = commonOptions packageSettings; + +in stdenv.mkDerivation (common // { pname = "mariadb-server"; outputs = [ "out" "man" ]; @@ -163,11 +169,11 @@ server = stdenv.mkDerivation (common // { buildInputs = common.buildInputs ++ [ bzip2 lz4 lzo snappy xz zstd cracklib judy libevent libxml2 - ] ++ optional (stdenv.hostPlatform.isLinux && !stdenv.hostPlatform.isAarch32) numactl - ++ optionals stdenv.hostPlatform.isLinux [ linux-pam ] - ++ optional (stdenv.hostPlatform.isLinux && stdenv.hostPlatform.isx86_64) pmdk.dev - ++ optional (!stdenv.hostPlatform.isDarwin) mytopEnv - ++ optionals withStorageMroonga [ kytea libsodium msgpack zeromq ]; + ] ++ lib.optional (stdenv.hostPlatform.isLinux && !stdenv.hostPlatform.isAarch32) numactl + ++ lib.optionals stdenv.hostPlatform.isLinux [ linux-pam ] + ++ lib.optional (stdenv.hostPlatform.isLinux && stdenv.hostPlatform.isx86_64) pmdk.dev + ++ lib.optional (!stdenv.hostPlatform.isDarwin) mytopEnv + ++ lib.optionals withStorageMroonga [ kytea libsodium msgpack zeromq ]; patches = common.patches; @@ -188,38 +194,54 @@ server = stdenv.mkDerivation (common // { "-DWITHOUT_EXAMPLE=1" "-DWITHOUT_FEDERATED=1" "-DWITHOUT_TOKUDB=1" - ] ++ optional (stdenv.hostPlatform.isLinux && !stdenv.hostPlatform.isAarch32) [ + ] ++ lib.optional (stdenv.hostPlatform.isLinux && !stdenv.hostPlatform.isAarch32) [ "-DWITH_NUMA=ON" - ] ++ optional (!withStorageMroonga) [ + ] ++ lib.optional (!withStorageMroonga) [ "-DWITHOUT_MROONGA=1" - ] ++ optional (!withStorageRocks) [ + ] ++ lib.optional (!withStorageRocks) [ "-DWITHOUT_ROCKSDB=1" - ] ++ optional (!stdenv.hostPlatform.isDarwin && withStorageRocks) [ + ] ++ lib.optional (!stdenv.hostPlatform.isDarwin && withStorageRocks) [ "-DWITH_ROCKSDB_JEMALLOC=ON" - ] ++ optional (!stdenv.hostPlatform.isDarwin) [ + ] ++ lib.optional (!stdenv.hostPlatform.isDarwin) [ "-DWITH_JEMALLOC=yes" - ] ++ optionals stdenv.hostPlatform.isDarwin [ + ] ++ lib.optionals stdenv.hostPlatform.isDarwin [ "-DPLUGIN_AUTH_PAM=OFF" "-DWITHOUT_OQGRAPH=1" "-DWITHOUT_PLUGIN_S3=1" ]; - preConfigure = optionalString (!stdenv.hostPlatform.isDarwin) '' + preConfigure = lib.optionalString (!stdenv.hostPlatform.isDarwin) '' patchShebangs scripts/mytop.sh ''; postInstall = common.postInstall + '' rm -r "$out"/share/aclocal chmod +x "$out"/bin/wsrep_sst_common - rm "$out"/bin/{mariadb-client-test,mariadb-test,mysql_client_test,mysqltest} - '' + optionalString withStorageMroonga '' + rm -f "$out"/bin/{mariadb-client-test,mariadb-test,mysql_client_test,mysqltest} + '' + lib.optionalString withStorageMroonga '' mv "$out"/share/{groonga,groonga-normalizer-mysql} "$out"/share/doc/mysql - '' + optionalString (!stdenv.hostPlatform.isDarwin) '' + '' + lib.optionalString (!stdenv.hostPlatform.isDarwin && lib.versionAtLeast common.version "10.4") '' mv "$out"/OFF/suite/plugins/pam/pam_mariadb_mtr.so "$out"/share/pam/lib/security mv "$out"/OFF/suite/plugins/pam/mariadb_mtr "$out"/share/pam/etc/security rm -r "$out"/OFF ''; - CXXFLAGS = optionalString stdenv.hostPlatform.isi686 "-fpermissive"; + CXXFLAGS = lib.optionalString stdenv.hostPlatform.isi686 "-fpermissive"; }); -in mariadb +in { + mariadb_104 = mariadbPackage { + # Supported until 2024-06-18 + version = "10.4.22"; + sha256 = "000ca1hdnj2jg051cjgdd2ralgwgh2p8nwb1x6b85202xdpc7ga4"; + }; + mariadb_105 = mariadbPackage { + # Supported until 2025-06-24 + version = "10.5.13"; + sha256 = "0n0w1pyypv6wsknaqyykj3lc9zv6smji4q5jcf90w4rid330iw0n"; + }; + mariadb_106 = mariadbPackage { + # Supported until 2026-07 + version = "10.6.5"; + sha256 = "13qaqb2h6kysfdi3h1l9zbb2qlpjgxb1n8mxnj5jm96r50209gp0"; + }; +} diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index 921185591acf..b297c3183c0c 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -21429,10 +21429,15 @@ with pkgs; asio = asio_1_10; }; - mariadb = callPackage ../servers/sql/mariadb { + inherit (callPackage ../servers/sql/mariadb { inherit (darwin) cctools; inherit (darwin.apple_sdk.frameworks) CoreServices; - }; + }) + mariadb_104 + mariadb_105 + mariadb_106 + ; + mariadb = mariadb_106; mongodb = hiPrio mongodb-3_4;