blob: a3fe3bb775f0f412d846bc80f7b9049035fe38f6 (
plain) (
tree)
|
|
{ pkgs, config, lib, ... }:
let
cfg = config.myServices.databasesReplication.redis;
in
{
options.myServices.databasesReplication.redis = {
enable = lib.mkEnableOption "Enable redis replication";
base = lib.mkOption {
type = lib.types.path;
description = ''
Base path to put the replications
'';
};
hosts = lib.mkOption {
default = {};
description = ''
Hosts to backup
'';
type = lib.types.attrsOf (lib.types.submodule {
options = {
package = lib.mkOption {
type = lib.types.package;
default = pkgs.redis;
description = ''
Redis package for this host
'';
};
host = lib.mkOption {
type = lib.types.str;
description = ''
Host to connect to
'';
};
port = lib.mkOption {
type = lib.types.str;
description = ''
Port to connect to
'';
};
password = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = null;
description = ''
Password to use
'';
};
};
});
};
};
config = lib.mkIf cfg.enable {
users.users.redis = {
description = "Redis database user";
group = "redis";
uid = config.ids.uids.redis;
extraGroups = [ "keys" ];
};
users.groups.redis.gid = config.ids.gids.redis;
services.spiped = { # sync from eldiron
enable = true;
config.redis = {
encrypt = true;
source = "127.0.0.1:16379";
target = "${config.myEnv.servers.eldiron.ips.main.ip4}:16379";
keyfile = "${config.secrets.location}/redis/spiped_eldiron_keyfile";
};
};
secrets.keys = lib.flatten (lib.mapAttrsToList (name: hcfg: [
{
dest = "redis_replication/${name}/config";
user = "redis";
group = "redis";
permissions = "0400";
text = ''
pidfile ${cfg.base}/${name}/redis/redis.pid
port 0
unixsocket /run/redis_${name}/redis.sock
loglevel notice
logfile /dev/null
syslog-enabled yes
databases 16
save 900 1
save 300 10
save 60 10000
dbfilename dump.rdb
dir ${cfg.base}/${name}/redis/
slaveof ${hcfg.host} ${hcfg.port}
${if hcfg.password != null then "masterauth ${hcfg.password}" else ""}
appendOnly no
appendfsync everysec
slowlog-log-slower-than 10000
slowlog-max-len 128
unixsocketperm 777
maxclients 1024
'';
}
]) cfg.hosts) ++ [
{ # For eldiron only
dest = "redis/spiped_eldiron_keyfile";
user = "spiped";
group = "spiped";
permissions = "0400";
text = config.myEnv.databases.redis.spiped_key;
}
];
services.cron = {
enable = true;
systemCronJobs = lib.flatten (lib.mapAttrsToList (name: hcfg:
let
dataDir = "${cfg.base}/${name}/redis";
backupDir = "${cfg.base}/${name}/redis_backup";
backup_script = pkgs.writeScript "backup_redis_${name}" ''
#!${pkgs.stdenv.shell}
${pkgs.coreutils}/bin/cp ${cfg.base}/${name}/redis/dump.rdb \
${backupDir}/$(${pkgs.coreutils}/bin/date -Iminutes).rdb
'';
u = pkgs.callPackage ./utils.nix {};
cleanup_script = pkgs.writeScript "cleanup_redis_${name}" (u.exponentialDumps "rdb" backupDir);
in [
"0 22,4,10,16 * * * root ${backup_script}"
"0 3 * * * root ${cleanup_script}"
]) cfg.hosts);
};
system.activationScripts = lib.attrsets.mapAttrs' (name: hcfg:
lib.attrsets.nameValuePair "redis_replication_${name}" {
deps = [ "users" "groups" ];
text = ''
install -m 0700 -o redis -g redis -d ${cfg.base}/${name}/redis
install -m 0700 -o redis -g redis -d ${cfg.base}/${name}/redis_backup
'';
}) cfg.hosts;
systemd.services = {
spiped_redis = { # For eldiron
description = "Secure pipe 'redis'";
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
serviceConfig = {
Restart = "always";
User = "spiped";
PermissionsStartOnly = true;
SupplementaryGroups = "keys";
};
script = "exec ${pkgs.spiped}/bin/spiped -F `cat /etc/spiped/redis.spec`";
};
} // lib.attrsets.mapAttrs' (name: hcfg:
let
dataDir = "${cfg.base}/${name}/redis";
in
lib.attrsets.nameValuePair "redis_backup_${name}" {
description = "Redis replication for ${name}";
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ];
unitConfig.RequiresMountsFor = dataDir;
serviceConfig = {
ExecStart = "${hcfg.package}/bin/redis-server ${config.secrets.location}/redis_replication/${name}/config";
User = "redis";
RuntimeDirectory = "redis_${name}";
};
}) cfg.hosts;
};
}
|