From c630e528739591351d851775a70f69e91d7d2d39 Mon Sep 17 00:00:00 2001 From: Sander van der Burg Date: Wed, 13 Jul 2011 20:58:48 +0000 Subject: [PATCH] Added MySQL replication support + 2 MySQL testcases (including replication) svn path=/nixos/trunk/; revision=27771 --- modules/services/databases/mysql.nix | 45 +++++++++++++++++++++- tests/default.nix | 2 + tests/mysql-replication.nix | 57 ++++++++++++++++++++++++++++ tests/mysql.nix | 22 +++++++++++ tests/testdb.sql | 10 +++++ 5 files changed, 135 insertions(+), 1 deletion(-) create mode 100644 tests/mysql-replication.nix create mode 100644 tests/mysql.nix create mode 100644 tests/testdb.sql diff --git a/modules/services/databases/mysql.nix b/modules/services/databases/mysql.nix index 9c97a15d751e..60410b133b2b 100644 --- a/modules/services/databases/mysql.nix +++ b/modules/services/databases/mysql.nix @@ -14,6 +14,20 @@ let "--user=${cfg.user} --datadir=${cfg.dataDir} " + "--log-error=${cfg.logError} --pid-file=${pidFile}"; + myCnf = pkgs.writeText "my.cnf" + '' + [mysqld] + ${optionalString (cfg.replication.role == "master" || cfg.replication.role == "slave") "log-bin=mysql-bin"} + ${optionalString (cfg.replication.role == "master" || cfg.replication.role == "slave") "server-id = ${toString cfg.replication.serverId}"} + ${optionalString (cfg.replication.role == "slave") + '' + master-host = ${cfg.replication.masterHost} + master-user = ${cfg.replication.masterUser} + master-password = ${cfg.replication.masterPassword} + master-port = ${toString cfg.replication.masterPort} + ''} + ''; + in { @@ -81,6 +95,35 @@ in 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."; }; + + replication = { + role = mkOption { + default = "none"; + description = "Role of the MySQL server instance. Can be either: master, slave or none"; + }; + + serverId = mkOption { + default = 1; + description = "Id of the MySQL server instance. This number must be unique for each instance"; + }; + + masterHost = mkOption { + description = "Hostname of the MySQL master server"; + }; + + masterUser = mkOption { + description = "Username of the MySQL replication user"; + }; + + masterPassword = mkOption { + description = "Password of the MySQL replication user"; + }; + + masterPort = mkOption { + default = 3306; + description = "Port number on which the MySQL master server runs"; + }; + }; }; }; @@ -115,7 +158,7 @@ in chown -R ${cfg.user} ${cfg.pidDir} ''; - exec = "${mysql}/libexec/mysqld ${mysqldOptions}"; + exec = "${mysql}/libexec/mysqld --defaults-extra-file=${myCnf} ${mysqldOptions}"; postStart = '' diff --git a/tests/default.nix b/tests/default.nix index 9b0295236e3c..767732b53b4f 100644 --- a/tests/default.nix +++ b/tests/default.nix @@ -14,6 +14,8 @@ with import ../lib/testing.nix { inherit nixpkgs system; }; kde4 = makeTest (import ./kde4.nix); login = makeTest (import ./login.nix); mpich = makeTest (import ./mpich.nix); + mysql = makeTest (import ./mysql.nix); + mysql_replication = makeTest (import ./mysql-replication.nix); nat = makeTest (import ./nat.nix); nfs = makeTest (import ./nfs.nix); openssh = makeTest (import ./openssh.nix); diff --git a/tests/mysql-replication.nix b/tests/mysql-replication.nix new file mode 100644 index 000000000000..836495a9e938 --- /dev/null +++ b/tests/mysql-replication.nix @@ -0,0 +1,57 @@ +{ pkgs, ... }: + +let + replicateUser = "replicate"; + replicatePassword = "secret"; +in +{ + nodes = { + master = + { pkgs, config, ... }: + + { + services.mysql.enable = true; + services.mysql.replication.role = "master"; + services.mysql.initialDatabases = [ { name = "testdb"; schema = ./testdb.sql; } ]; + services.mysql.initialScript = pkgs.writeText "initmysql" + '' + create user '${replicateUser}'@'%' identified by '${replicatePassword}'; + grant replication slave on *.* to '${replicateUser}'@'%'; + ''; + }; + + slave1 = + { pkgs, config, nodes, ... }: + + { + services.mysql.enable = true; + 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; + }; + + slave2 = + { pkgs, config, nodes, ... }: + + { + services.mysql.enable = true; + 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; + }; + }; + + testScript = '' + startAll; + + $master->waitForJob("mysql"); + $master->waitForJob("mysql"); + $slave2->waitForJob("mysql"); + $slave2->sleep(100); # Hopefully this is long enough!! + $slave2->mustSucceed("echo 'use testdb; select * from tests' | mysql -u root -N | grep 4"); + ''; +} diff --git a/tests/mysql.nix b/tests/mysql.nix new file mode 100644 index 000000000000..cb8f12479093 --- /dev/null +++ b/tests/mysql.nix @@ -0,0 +1,22 @@ +{ pkgs, ... }: + +{ + nodes = { + master = + { pkgs, config, ... }: + + { + services.mysql.enable = true; + services.mysql.replication.role = "master"; + services.mysql.initialDatabases = [ { name = "testdb"; schema = ./testdb.sql; } ]; + }; + }; + + testScript = '' + startAll; + + $master->waitForJob("mysql"); + $master->sleep(10); # Hopefully this is long enough!! + $master->mustSucceed("echo 'use testdb; select * from tests' | mysql -u root -N | grep 4"); + ''; +} diff --git a/tests/testdb.sql b/tests/testdb.sql new file mode 100644 index 000000000000..4fb28fea3df9 --- /dev/null +++ b/tests/testdb.sql @@ -0,0 +1,10 @@ +create table tests +( Id INTEGER NOT NULL, + Name VARCHAR(255) NOT NULL, + primary key(Id) +); + +insert into tests values (1, 'a'); +insert into tests values (2, 'b'); +insert into tests values (3, 'c'); +insert into tests values (4, 'd');