aboutsummaryrefslogtreecommitdiff
path: root/modules/private/databases
diff options
context:
space:
mode:
authorIsmaël Bouya <ismael.bouya@normalesup.org>2019-12-07 08:05:53 +0100
committerIsmaël Bouya <ismael.bouya@normalesup.org>2019-12-07 08:05:53 +0100
commitdded66995529a0419cc56778f4ebb4247c2ab765 (patch)
treed355e6adda5b833c50c473062fb51f078918878c /modules/private/databases
parent9f6a78629aad1d22dc8b928860fd05eb40f07352 (diff)
downloadNix-dded66995529a0419cc56778f4ebb4247c2ab765.tar.gz
Nix-dded66995529a0419cc56778f4ebb4247c2ab765.tar.zst
Nix-dded66995529a0419cc56778f4ebb4247c2ab765.zip
Add replication for redis
Diffstat (limited to 'modules/private/databases')
-rw-r--r--modules/private/databases/mariadb_replication.nix2
-rw-r--r--modules/private/databases/postgresql_replication.nix2
-rw-r--r--modules/private/databases/redis.nix84
-rw-r--r--modules/private/databases/redis_replication.nix173
-rw-r--r--modules/private/databases/utils.nix10
5 files changed, 263 insertions, 8 deletions
diff --git a/modules/private/databases/mariadb_replication.nix b/modules/private/databases/mariadb_replication.nix
index 23648bb..5f97e84 100644
--- a/modules/private/databases/mariadb_replication.nix
+++ b/modules/private/databases/mariadb_replication.nix
@@ -136,7 +136,7 @@ in
136 --all-databases > ${backupDir}/$(${pkgs.coreutils}/bin/date -Iseconds).sql 136 --all-databases > ${backupDir}/$(${pkgs.coreutils}/bin/date -Iseconds).sql
137 ''; 137 '';
138 u = pkgs.callPackage ./utils.nix {}; 138 u = pkgs.callPackage ./utils.nix {};
139 cleanup_script = pkgs.writeScript "cleanup_mysql_${name}" (u.exponentialDumps backupDir); 139 cleanup_script = pkgs.writeScript "cleanup_mysql_${name}" (u.exponentialDumps "sql" backupDir);
140 in [ 140 in [
141 "0 22,4,10,16 * * * root ${backup_script}" 141 "0 22,4,10,16 * * * root ${backup_script}"
142 "0 3 * * * root ${cleanup_script}" 142 "0 3 * * * root ${cleanup_script}"
diff --git a/modules/private/databases/postgresql_replication.nix b/modules/private/databases/postgresql_replication.nix
index cc32c2b..19ec168 100644
--- a/modules/private/databases/postgresql_replication.nix
+++ b/modules/private/databases/postgresql_replication.nix
@@ -116,7 +116,7 @@ in
116 ${hcfg.package}/bin/pg_dumpall -h ${dataDir} -f ${backupDir}/$(${pkgs.coreutils}/bin/date -Iseconds).sql 116 ${hcfg.package}/bin/pg_dumpall -h ${dataDir} -f ${backupDir}/$(${pkgs.coreutils}/bin/date -Iseconds).sql
117 ''; 117 '';
118 u = pkgs.callPackage ./utils.nix {}; 118 u = pkgs.callPackage ./utils.nix {};
119 cleanup_script = pkgs.writeScript "cleanup_postgresql_${name}" (u.keepLastNDumps backupDir 12); 119 cleanup_script = pkgs.writeScript "cleanup_postgresql_${name}" (u.keepLastNDumps "sql" backupDir 12);
120 in [ 120 in [
121 "0 22,4,10,16 * * * postgres ${backup_script}" 121 "0 22,4,10,16 * * * postgres ${backup_script}"
122 "0 3 * * * postgres ${cleanup_script}" 122 "0 3 * * * postgres ${cleanup_script}"
diff --git a/modules/private/databases/redis.nix b/modules/private/databases/redis.nix
index c23ffec..693f402 100644
--- a/modules/private/databases/redis.nix
+++ b/modules/private/databases/redis.nix
@@ -1,4 +1,4 @@
1{ lib, config, ... }: 1{ lib, config, pkgs, myconfig, ... }:
2let 2let
3 cfg = config.myServices.databases.redis; 3 cfg = config.myServices.databases.redis;
4in { 4in {
@@ -52,6 +52,88 @@ in {
52 ''; 52 '';
53 }; 53 };
54 systemd.services.redis.serviceConfig.RuntimeDirectory = cfg.systemdRuntimeDirectory; 54 systemd.services.redis.serviceConfig.RuntimeDirectory = cfg.systemdRuntimeDirectory;
55
56 services.spiped = {
57 enable = true;
58 config.redis = {
59 decrypt = true;
60 source = "0.0.0.0:16379";
61 target = "/run/redis/redis.sock";
62 keyfile = "${config.secrets.location}/redis/spiped_keyfile";
63 };
64 };
65 systemd.services.spiped_redis = {
66 description = "Secure pipe 'redis'";
67 after = [ "network.target" ];
68 wantedBy = [ "multi-user.target" ];
69
70 serviceConfig = {
71 Restart = "always";
72 User = "spiped";
73 PermissionsStartOnly = true;
74 SupplementaryGroups = "keys";
75 };
76
77 script = "exec ${pkgs.spiped}/bin/spiped -F `cat /etc/spiped/redis.spec`";
78 };
79
80 services.filesWatcher.predixy = {
81 restart = true;
82 paths = [ "${config.secrets.location}/redis/predixy.conf" ];
83 };
84
85 networking.firewall.allowedTCPPorts = [ 7617 16379 ];
86 secrets.keys = [
87 {
88 dest = "redis/predixy.conf";
89 user = "redis";
90 group = "redis";
91 permissions = "0400";
92 text = ''
93 Name Predixy
94 Bind 127.0.0.1:7617
95 ClientTimeout 300
96 WorkerThreads 1
97
98 Authority {
99 Auth "${myconfig.env.databases.redis.predixy.read}" {
100 Mode read
101 }
102 }
103
104 StandaloneServerPool {
105 Databases 16
106 RefreshMethod fixed
107 Group shard001 {
108 + ${myconfig.env.databases.redis.socket}
109 }
110 }
111 '';
112 }
113 {
114 dest = "redis/spiped_keyfile";
115 user = "spiped";
116 group = "spiped";
117 permissions = "0400";
118 text = myconfig.env.databases.redis.spiped_key;
119 }
120 ];
121
122 systemd.services.predixy = {
123 description = "Redis proxy";
124 wantedBy = [ "multi-user.target" ];
125 after = [ "redis.service" ];
126
127 serviceConfig = {
128 User = "redis";
129 Group = "redis";
130 SupplementaryGroups = "keys";
131 Type = "simple";
132
133 ExecStart = "${pkgs.predixy}/bin/predixy ${config.secrets.location}/redis/predixy.conf";
134 };
135
136 };
55 }; 137 };
56} 138}
57 139
diff --git a/modules/private/databases/redis_replication.nix b/modules/private/databases/redis_replication.nix
new file mode 100644
index 0000000..cc626f5
--- /dev/null
+++ b/modules/private/databases/redis_replication.nix
@@ -0,0 +1,173 @@
1{ pkgs, config, myconfig, lib, ... }:
2let
3 cfg = config.myServices.databasesReplication.redis;
4in
5{
6 options.myServices.databasesReplication.redis = {
7 enable = lib.mkEnableOption "Enable redis replication";
8 base = lib.mkOption {
9 type = lib.types.path;
10 description = ''
11 Base path to put the replications
12 '';
13 };
14 hosts = lib.mkOption {
15 default = {};
16 description = ''
17 Hosts to backup
18 '';
19 type = lib.types.attrsOf (lib.types.submodule {
20 options = {
21 package = lib.mkOption {
22 type = lib.types.package;
23 default = pkgs.redis;
24 description = ''
25 Redis package for this host
26 '';
27 };
28 host = lib.mkOption {
29 type = lib.types.str;
30 description = ''
31 Host to connect to
32 '';
33 };
34 port = lib.mkOption {
35 type = lib.types.str;
36 description = ''
37 Port to connect to
38 '';
39 };
40 password = lib.mkOption {
41 type = lib.types.nullOr lib.types.str;
42 default = null;
43 description = ''
44 Password to use
45 '';
46 };
47 };
48 });
49 };
50 };
51
52 config = lib.mkIf cfg.enable {
53 users.users.redis = {
54 description = "Redis database user";
55 group = "redis";
56 uid = config.ids.uids.redis;
57 extraGroups = [ "keys" ];
58 };
59 users.groups.redis.gid = config.ids.gids.redis;
60
61 services.spiped = { # sync from eldiron
62 enable = true;
63 config.redis = {
64 encrypt = true;
65 source = "127.0.0.1:16379";
66 target = "${myconfig.env.servers.eldiron.ips.main.ip4}:16379";
67 keyfile = "${config.secrets.location}/redis/spiped_eldiron_keyfile";
68 };
69 };
70
71 secrets.keys = lib.flatten (lib.mapAttrsToList (name: hcfg: [
72 {
73 dest = "redis_replication/${name}/config";
74 user = "redis";
75 group = "redis";
76 permissions = "0400";
77 text = ''
78 pidfile ${cfg.base}/${name}/redis/redis.pid
79 port 0
80 unixsocket /run/redis_${name}/redis.sock
81 loglevel notice
82 logfile /dev/null
83 syslog-enabled yes
84 databases 16
85 save 900 1
86 save 300 10
87 save 60 10000
88 dbfilename dump.rdb
89 dir ${cfg.base}/${name}/redis/
90 slaveof ${hcfg.host} ${hcfg.port}
91 ${if hcfg.password != null then "masterauth ${hcfg.password}" else ""}
92 appendOnly no
93 appendfsync everysec
94 slowlog-log-slower-than 10000
95 slowlog-max-len 128
96 unixsocketperm 777
97 maxclients 1024
98 '';
99 }
100 ]) cfg.hosts) ++ [
101 { # For eldiron only
102 dest = "redis/spiped_eldiron_keyfile";
103 user = "spiped";
104 group = "spiped";
105 permissions = "0400";
106 text = myconfig.env.databases.redis.spiped_key;
107 }
108 ];
109
110 services.cron = {
111 enable = true;
112 systemCronJobs = lib.flatten (lib.mapAttrsToList (name: hcfg:
113 let
114 dataDir = "${cfg.base}/${name}/redis";
115 backupDir = "${cfg.base}/${name}/redis_backup";
116 backup_script = pkgs.writeScript "backup_redis_${name}" ''
117 #!${pkgs.stdenv.shell}
118
119 ${pkgs.coreutils}/bin/cp ${cfg.base}/${name}/redis/dump.rdb \
120 ${backupDir}/$(${pkgs.coreutils}/bin/date -Iseconds).rdb
121 '';
122 u = pkgs.callPackage ./utils.nix {};
123 cleanup_script = pkgs.writeScript "cleanup_redis_${name}" (u.exponentialDumps "rdb" backupDir);
124 in [
125 "0 22,4,10,16 * * * root ${backup_script}"
126 "0 3 * * * root ${cleanup_script}"
127 ]) cfg.hosts);
128 };
129
130 system.activationScripts = lib.attrsets.mapAttrs' (name: hcfg:
131 lib.attrsets.nameValuePair "redis_replication_${name}" {
132 deps = [ "users" "groups" ];
133 text = ''
134 install -m 0700 -o redis -g redis -d ${cfg.base}/${name}/redis
135 install -m 0700 -o redis -g redis -d ${cfg.base}/${name}/redis_backup
136 '';
137 }) cfg.hosts;
138
139 systemd.services = {
140 spiped_redis = { # For eldiron
141 description = "Secure pipe 'redis'";
142 after = [ "network.target" ];
143 wantedBy = [ "multi-user.target" ];
144
145 serviceConfig = {
146 Restart = "always";
147 User = "spiped";
148 PermissionsStartOnly = true;
149 SupplementaryGroups = "keys";
150 };
151
152 script = "exec ${pkgs.spiped}/bin/spiped -F `cat /etc/spiped/redis.spec`";
153 };
154 } // lib.attrsets.mapAttrs' (name: hcfg:
155 let
156 dataDir = "${cfg.base}/${name}/redis";
157 in
158 lib.attrsets.nameValuePair "redis_backup_${name}" {
159 description = "Redis replication for ${name}";
160 wantedBy = [ "multi-user.target" ];
161 after = [ "network.target" ];
162 unitConfig.RequiresMountsFor = dataDir;
163
164 serviceConfig = {
165 ExecStart = "${hcfg.package}/bin/redis-server ${config.secrets.location}/redis_replication/${name}/config";
166 User = "redis";
167 RuntimeDirectory = "redis_${name}";
168 };
169 }) cfg.hosts;
170 };
171}
172
173
diff --git a/modules/private/databases/utils.nix b/modules/private/databases/utils.nix
index c296f49..06ce2cc 100644
--- a/modules/private/databases/utils.nix
+++ b/modules/private/databases/utils.nix
@@ -1,15 +1,15 @@
1{ pkgs }: 1{ pkgs }:
2{ 2{
3 keepLastNDumps = backupDir: n: '' 3 keepLastNDumps = ext: backupDir: n: ''
4 #!${pkgs.stdenv.shell} 4 #!${pkgs.stdenv.shell}
5 5
6 cd ${backupDir} 6 cd ${backupDir}
7 ${pkgs.coreutils}/bin/rm -f \ 7 ${pkgs.coreutils}/bin/rm -f \
8 $(${pkgs.coreutils}/bin/ls -1 *.sql \ 8 $(${pkgs.coreutils}/bin/ls -1 *.${ext} \
9 | ${pkgs.coreutils}/bin/sort -r \ 9 | ${pkgs.coreutils}/bin/sort -r \
10 | ${pkgs.gnused}/bin/sed -e '1,${builtins.toString n}d') 10 | ${pkgs.gnused}/bin/sed -e '1,${builtins.toString n}d')
11 ''; 11 '';
12 exponentialDumps = backupDir: let 12 exponentialDumps = ext: backupDir: let
13 log2rotateSrc = builtins.fetchGit { 13 log2rotateSrc = builtins.fetchGit {
14 url = "https://github.com/avian2/pylog2rotate"; 14 url = "https://github.com/avian2/pylog2rotate";
15 ref = "master"; 15 ref = "master";
@@ -24,7 +24,7 @@
24 #!${pkgs.stdenv.shell} 24 #!${pkgs.stdenv.shell}
25 25
26 cd ${backupDir} 26 cd ${backupDir}
27 ${pkgs.coreutils}/bin/rm -f $(ls -1 *.sql | grep -v 'T22:' | sort -r | sed -e '1,12d') 27 ${pkgs.coreutils}/bin/rm -f $(ls -1 *.${ext} | grep -v 'T22:' | sort -r | sed -e '1,12d')
28 ${pkgs.coreutils}/bin/rm -f $(ls -1 *T22*.sql | ${log2rotate} --skip 7 --fuzz 7 --delete --format='%Y-%m-%dT%H:%M:%S+00:00.sql') 28 ${pkgs.coreutils}/bin/rm -f $(ls -1 *T22*.${ext} | ${log2rotate} --skip 7 --fuzz 7 --delete --format='%Y-%m-%dT%H:%M:%S+00:00.${ext}')
29 ''; 29 '';
30} 30}