diff options
Diffstat (limited to 'systems/backup-2/databases/redis_replication.nix')
-rw-r--r-- | systems/backup-2/databases/redis_replication.nix | 171 |
1 files changed, 171 insertions, 0 deletions
diff --git a/systems/backup-2/databases/redis_replication.nix b/systems/backup-2/databases/redis_replication.nix new file mode 100644 index 0000000..53fa904 --- /dev/null +++ b/systems/backup-2/databases/redis_replication.nix | |||
@@ -0,0 +1,171 @@ | |||
1 | { pkgs, config, lib, ... }: | ||
2 | let | ||
3 | cfg = config.myServices.databasesReplication.redis; | ||
4 | in | ||
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 = "${lib.head config.myEnv.servers.eldiron.ips.main.ip4}:16379"; | ||
67 | keyfile = config.secrets.fullPaths."redis/spiped_eldiron_keyfile"; | ||
68 | }; | ||
69 | }; | ||
70 | |||
71 | secrets.keys = lib.mapAttrs' (name: hcfg: | ||
72 | lib.nameValuePair "redis_replication/${name}/config" { | ||
73 | user = "redis"; | ||
74 | group = "redis"; | ||
75 | permissions = "0400"; | ||
76 | text = '' | ||
77 | pidfile ${cfg.base}/${name}/redis/redis.pid | ||
78 | port 0 | ||
79 | unixsocket /run/redis_${name}/redis.sock | ||
80 | loglevel notice | ||
81 | logfile /dev/null | ||
82 | syslog-enabled yes | ||
83 | databases 16 | ||
84 | save 900 1 | ||
85 | save 300 10 | ||
86 | save 60 10000 | ||
87 | dbfilename dump.rdb | ||
88 | dir ${cfg.base}/${name}/redis/ | ||
89 | slaveof ${hcfg.host} ${hcfg.port} | ||
90 | ${if hcfg.password != null then "masterauth ${hcfg.password}" else ""} | ||
91 | appendOnly no | ||
92 | appendfsync everysec | ||
93 | slowlog-log-slower-than 10000 | ||
94 | slowlog-max-len 128 | ||
95 | unixsocketperm 777 | ||
96 | maxclients 1024 | ||
97 | ''; | ||
98 | } | ||
99 | ) cfg.hosts // { | ||
100 | "redis/spiped_eldiron_keyfile" = { # For eldiron only | ||
101 | user = "spiped"; | ||
102 | group = "spiped"; | ||
103 | permissions = "0400"; | ||
104 | text = config.myEnv.databases.redis.spiped_key; | ||
105 | }; | ||
106 | }; | ||
107 | |||
108 | services.cron = { | ||
109 | enable = true; | ||
110 | systemCronJobs = lib.flatten (lib.mapAttrsToList (name: hcfg: | ||
111 | let | ||
112 | dataDir = "${cfg.base}/${name}/redis"; | ||
113 | backupDir = "${cfg.base}/${name}/redis_backup"; | ||
114 | backup_script = pkgs.writeScript "backup_redis_${name}" '' | ||
115 | #!${pkgs.stdenv.shell} | ||
116 | |||
117 | ${pkgs.coreutils}/bin/cp ${cfg.base}/${name}/redis/dump.rdb \ | ||
118 | ${backupDir}/$(${pkgs.coreutils}/bin/date -Iminutes).rdb | ||
119 | ''; | ||
120 | u = pkgs.callPackage ./utils.nix {}; | ||
121 | cleanup_script = pkgs.writeScript "cleanup_redis_${name}" (u.exponentialDumps "rdb" backupDir); | ||
122 | in [ | ||
123 | "0 22,4,10,16 * * * root ${backup_script}" | ||
124 | "0 3 * * * root ${cleanup_script}" | ||
125 | ]) cfg.hosts); | ||
126 | }; | ||
127 | |||
128 | system.activationScripts = lib.attrsets.mapAttrs' (name: hcfg: | ||
129 | lib.attrsets.nameValuePair "redis_replication_${name}" { | ||
130 | deps = [ "users" "groups" ]; | ||
131 | text = '' | ||
132 | install -m 0700 -o redis -g redis -d ${cfg.base}/${name}/redis | ||
133 | install -m 0700 -o redis -g redis -d ${cfg.base}/${name}/redis_backup | ||
134 | ''; | ||
135 | }) cfg.hosts; | ||
136 | |||
137 | systemd.services = { | ||
138 | spiped_redis = { # For eldiron | ||
139 | description = "Secure pipe 'redis'"; | ||
140 | after = [ "network.target" ]; | ||
141 | wantedBy = [ "multi-user.target" ]; | ||
142 | |||
143 | serviceConfig = { | ||
144 | Restart = "always"; | ||
145 | User = "spiped"; | ||
146 | PermissionsStartOnly = true; | ||
147 | SupplementaryGroups = "keys"; | ||
148 | }; | ||
149 | |||
150 | script = "exec ${pkgs.spiped}/bin/spiped -F `cat /etc/spiped/redis.spec`"; | ||
151 | }; | ||
152 | } // lib.attrsets.mapAttrs' (name: hcfg: | ||
153 | let | ||
154 | dataDir = "${cfg.base}/${name}/redis"; | ||
155 | in | ||
156 | lib.attrsets.nameValuePair "redis_backup_${name}" { | ||
157 | description = "Redis replication for ${name}"; | ||
158 | wantedBy = [ "multi-user.target" ]; | ||
159 | after = [ "network.target" ]; | ||
160 | unitConfig.RequiresMountsFor = dataDir; | ||
161 | |||
162 | serviceConfig = { | ||
163 | ExecStart = "${hcfg.package}/bin/redis-server ${config.secrets.fullPaths."redis_replication/${name}/config"}"; | ||
164 | User = "redis"; | ||
165 | RuntimeDirectory = "redis_${name}"; | ||
166 | }; | ||
167 | }) cfg.hosts; | ||
168 | }; | ||
169 | } | ||
170 | |||
171 | |||