else if value == false then "no"
else generators.mkValueStringDefault { } value;
- redisConfig = settings: pkgs.writeText "redis.conf" (generators.toKeyValue {
- listsAsDuplicateKeys = true;
- mkKeyValue = generators.mkKeyValueDefault { inherit mkValueString; } " ";
- } settings);
-
- redisName = name: "redis" + optionalString (name != "") ("-"+name);
- enabledServers = filterAttrs (name: conf: conf.enable) config.services.redis.servers;
-
-in {
+ redisConfig = settings: pkgs.writeText "redis.conf" (generators.toKeyValue
+ {
+ listsAsDuplicateKeys = true;
+ mkKeyValue = generators.mkKeyValueDefault { inherit mkValueString; } " ";
+ }
+ settings);
+
+ redisName = name: "redis" + optionalString (name != "") ("-" + name);
+ enabledServers = filterAttrs (_name: conf: conf.enable) config.services.redis.servers;
+
+in
+{
imports = [
(mkRemovedOptionModule [ "services" "redis" "user" ] "The redis module now is hardcoded to the redis user.")
(mkRemovedOptionModule [ "services" "redis" "dbpath" ] "The redis module now uses /var/lib/redis as data directory.")
(mkRemovedOptionModule [ "services" "redis" "appendOnlyFilename" ] "This option was never used.")
(mkRemovedOptionModule [ "services" "redis" "pidFile" ] "This option was removed.")
(mkRemovedOptionModule [ "services" "redis" "extraConfig" ] "Use services.redis.settings instead.")
- (mkRenamedOptionModule [ "services" "redis" "enable"] [ "services" "redis" "servers" "" "enable" ])
- (mkRenamedOptionModule [ "services" "redis" "port"] [ "services" "redis" "servers" "" "port" ])
- (mkRenamedOptionModule [ "services" "redis" "openFirewall"] [ "services" "redis" "servers" "" "openFirewall" ])
- (mkRenamedOptionModule [ "services" "redis" "bind"] [ "services" "redis" "servers" "" "bind" ])
- (mkRenamedOptionModule [ "services" "redis" "unixSocket"] [ "services" "redis" "servers" "" "unixSocket" ])
- (mkRenamedOptionModule [ "services" "redis" "unixSocketPerm"] [ "services" "redis" "servers" "" "unixSocketPerm" ])
- (mkRenamedOptionModule [ "services" "redis" "logLevel"] [ "services" "redis" "servers" "" "logLevel" ])
- (mkRenamedOptionModule [ "services" "redis" "logfile"] [ "services" "redis" "servers" "" "logfile" ])
- (mkRenamedOptionModule [ "services" "redis" "syslog"] [ "services" "redis" "servers" "" "syslog" ])
- (mkRenamedOptionModule [ "services" "redis" "databases"] [ "services" "redis" "servers" "" "databases" ])
- (mkRenamedOptionModule [ "services" "redis" "maxclients"] [ "services" "redis" "servers" "" "maxclients" ])
- (mkRenamedOptionModule [ "services" "redis" "save"] [ "services" "redis" "servers" "" "save" ])
- (mkRenamedOptionModule [ "services" "redis" "slaveOf"] [ "services" "redis" "servers" "" "slaveOf" ])
- (mkRenamedOptionModule [ "services" "redis" "masterAuth"] [ "services" "redis" "servers" "" "masterAuth" ])
- (mkRenamedOptionModule [ "services" "redis" "requirePass"] [ "services" "redis" "servers" "" "requirePass" ])
- (mkRenamedOptionModule [ "services" "redis" "requirePassFile"] [ "services" "redis" "servers" "" "requirePassFile" ])
- (mkRenamedOptionModule [ "services" "redis" "appendOnly"] [ "services" "redis" "servers" "" "appendOnly" ])
- (mkRenamedOptionModule [ "services" "redis" "appendFsync"] [ "services" "redis" "servers" "" "appendFsync" ])
- (mkRenamedOptionModule [ "services" "redis" "slowLogLogSlowerThan"] [ "services" "redis" "servers" "" "slowLogLogSlowerThan" ])
- (mkRenamedOptionModule [ "services" "redis" "slowLogMaxLen"] [ "services" "redis" "servers" "" "slowLogMaxLen" ])
- (mkRenamedOptionModule [ "services" "redis" "settings"] [ "services" "redis" "servers" "" "settings" ])
+ (mkRenamedOptionModule [ "services" "redis" "enable" ] [ "services" "redis" "servers" "" "enable" ])
+ (mkRenamedOptionModule [ "services" "redis" "port" ] [ "services" "redis" "servers" "" "port" ])
+ (mkRenamedOptionModule [ "services" "redis" "openFirewall" ] [ "services" "redis" "servers" "" "openFirewall" ])
+ (mkRenamedOptionModule [ "services" "redis" "bind" ] [ "services" "redis" "servers" "" "bind" ])
+ (mkRenamedOptionModule [ "services" "redis" "unixSocket" ] [ "services" "redis" "servers" "" "unixSocket" ])
+ (mkRenamedOptionModule [ "services" "redis" "unixSocketPerm" ] [ "services" "redis" "servers" "" "unixSocketPerm" ])
+ (mkRenamedOptionModule [ "services" "redis" "logLevel" ] [ "services" "redis" "servers" "" "logLevel" ])
+ (mkRenamedOptionModule [ "services" "redis" "logfile" ] [ "services" "redis" "servers" "" "logfile" ])
+ (mkRenamedOptionModule [ "services" "redis" "syslog" ] [ "services" "redis" "servers" "" "syslog" ])
+ (mkRenamedOptionModule [ "services" "redis" "databases" ] [ "services" "redis" "servers" "" "databases" ])
+ (mkRenamedOptionModule [ "services" "redis" "maxclients" ] [ "services" "redis" "servers" "" "maxclients" ])
+ (mkRenamedOptionModule [ "services" "redis" "save" ] [ "services" "redis" "servers" "" "save" ])
+ (mkRenamedOptionModule [ "services" "redis" "slaveOf" ] [ "services" "redis" "servers" "" "slaveOf" ])
+ (mkRenamedOptionModule [ "services" "redis" "masterAuth" ] [ "services" "redis" "servers" "" "masterAuth" ])
+ (mkRenamedOptionModule [ "services" "redis" "requirePass" ] [ "services" "redis" "servers" "" "requirePass" ])
+ (mkRenamedOptionModule [ "services" "redis" "requirePassFile" ] [ "services" "redis" "servers" "" "requirePassFile" ])
+ (mkRenamedOptionModule [ "services" "redis" "appendOnly" ] [ "services" "redis" "servers" "" "appendOnly" ])
+ (mkRenamedOptionModule [ "services" "redis" "appendFsync" ] [ "services" "redis" "servers" "" "appendFsync" ])
+ (mkRenamedOptionModule [ "services" "redis" "slowLogLogSlowerThan" ] [ "services" "redis" "servers" "" "slowLogLogSlowerThan" ])
+ (mkRenamedOptionModule [ "services" "redis" "slowLogMaxLen" ] [ "services" "redis" "servers" "" "slowLogMaxLen" ])
+ (mkRenamedOptionModule [ "services" "redis" "settings" ] [ "services" "redis" "servers" "" "settings" ])
];
###### interface
'';
servers = mkOption {
- type = with types; attrsOf (submodule ({config, name, ...}@args: {
+ type = with types; attrsOf (submodule ({ config, name, ... }: {
options = {
enable = mkEnableOption ''
Redis server.
save = mkOption {
type = with types; listOf (listOf int);
- default = [ [900 1] [300 10] [60 10000] ];
+ default = [ [ 900 1 ] [ 300 10 ] [ 60 10000 ] ];
description = "The schedule in which data is persisted to disk, represented as a list of lists where the first element represent the amount of seconds and the second the number of changes.";
- example = [ [900 1] [300 10] [60 10000] ];
+ example = [ [ 900 1 ] [ 300 10 ] [ 60 10000 ] ];
};
slaveOf = mkOption {
settings = mkOption {
# TODO: this should be converted to freeformType
type = with types; attrsOf (oneOf [ bool int str (listOf str) ]);
- default = {};
+ default = { };
description = ''
Redis configuration. Refer to
<link xlink:href="https://redis.io/topics/config"/>
};
config.settings = mkMerge [
{
- port = config.port;
+ port = if config.bind == null then 0 else config.port;
daemonize = false;
supervised = "systemd";
loglevel = config.logLevel;
];
}));
description = "Configuration of multiple <literal>redis-server</literal> instances.";
- default = {};
+ default = { };
};
};
###### implementation
- config = mkIf (enabledServers != {}) {
+ config = mkIf (enabledServers != { }) {
- assertions = attrValues (mapAttrs (name: conf: {
- assertion = conf.requirePass != null -> conf.requirePassFile == null;
- message = ''
- You can only set one services.redis.servers.${name}.requirePass
- or services.redis.servers.${name}.requirePassFile
- '';
- }) enabledServers);
+ assertions = attrValues (mapAttrs
+ (name: conf: {
+ assertion = conf.requirePass != null -> conf.requirePassFile == null;
+ message = ''
+ You can only set one services.redis.servers.${name}.requirePass
+ or services.redis.servers.${name}.requirePassFile
+ '';
+ })
+ enabledServers);
boot.kernel.sysctl = mkMerge [
{ "vm.nr_hugepages" = "0"; }
- ( mkIf cfg.vmOverCommit { "vm.overcommit_memory" = "1"; } )
+ (mkIf cfg.vmOverCommit { "vm.overcommit_memory" = "1"; })
];
- networking.firewall.allowedTCPPorts = concatMap (conf:
- optional conf.openFirewall conf.port
- ) (attrValues enabledServers);
+ networking.firewall.allowedTCPPorts = concatMap
+ (conf:
+ optional conf.openFirewall conf.port
+ )
+ (attrValues enabledServers);
environment.systemPackages = [ cfg.package ];
- users.users = mapAttrs' (name: conf: nameValuePair (redisName name) {
- description = "System user for the redis-server instance ${name}";
- isSystemUser = true;
- }) enabledServers;
- users.groups = mapAttrs' (name: conf: nameValuePair (redisName name) {
- }) enabledServers;
-
- systemd.services = mapAttrs' (name: conf: nameValuePair (redisName name) {
- description = "Redis Server - ${redisName name}";
-
- wantedBy = [ "multi-user.target" ];
- after = [ "network.target" ];
-
- serviceConfig = {
- ExecStart = "${cfg.package}/bin/redis-server /run/${redisName name}/redis.conf";
- ExecStartPre = [("+"+pkgs.writeShellScript "${redisName name}-credentials" (''
- install -o '${conf.user}' -m 600 ${redisConfig conf.settings} /run/${redisName name}/redis.conf
- '' + optionalString (conf.requirePassFile != null) ''
- {
- printf requirePass' '
- cat ${escapeShellArg conf.requirePassFile}
- } >>/run/${redisName name}/redis.conf
- '')
- )];
- Type = "notify";
- # User and group
- User = conf.user;
- Group = conf.user;
- # Runtime directory and mode
- RuntimeDirectory = redisName name;
- RuntimeDirectoryMode = "0750";
- # State directory and mode
- StateDirectory = redisName name;
- StateDirectoryMode = "0700";
- # Access write directories
- UMask = "0077";
- # Capabilities
- CapabilityBoundingSet = "";
- # Security
- NoNewPrivileges = true;
- # Process Properties
- LimitNOFILE = mkDefault "${toString (conf.maxclients + 32)}";
- # Sandboxing
- ProtectSystem = "strict";
- ProtectHome = true;
- PrivateTmp = true;
- PrivateDevices = true;
- PrivateUsers = true;
- ProtectClock = true;
- ProtectHostname = true;
- ProtectKernelLogs = true;
- ProtectKernelModules = true;
- ProtectKernelTunables = true;
- ProtectControlGroups = true;
- RestrictAddressFamilies =
- optionals (conf.bind != null) ["AF_INET" "AF_INET6"] ++
- optional (conf.unixSocket != null) "AF_UNIX";
- RestrictNamespaces = true;
- LockPersonality = true;
- MemoryDenyWriteExecute = true;
- RestrictRealtime = true;
- RestrictSUIDSGID = true;
- PrivateMounts = true;
- # System Call Filtering
- SystemCallArchitectures = "native";
- SystemCallFilter = "~@cpu-emulation @debug @keyring @memlock @mount @obsolete @privileged @resources @setuid";
- };
- }) enabledServers;
+ users.users = mapAttrs'
+ (name: _conf: nameValuePair (redisName name) {
+ description = "System user for the redis-server instance ${name}";
+ isSystemUser = true;
+ group = redisName name;
+ })
+ enabledServers;
+ users.groups = mapAttrs'
+ (name: _conf: nameValuePair (redisName name) { })
+ enabledServers;
+
+ systemd.services = mapAttrs'
+ (name: conf: nameValuePair (redisName name) {
+ description = "Redis Server - ${redisName name}";
+
+ wantedBy = [ "multi-user.target" ];
+ after = [ "network.target" ];
+
+ serviceConfig = {
+ ExecStart = "${cfg.package}/bin/redis-server /run/${redisName name}/redis.conf";
+ ExecStartPre = [
+ ("+" + pkgs.writeShellScript "${redisName name}-credentials" (''
+ install -o '${conf.user}' -m 600 ${redisConfig conf.settings} /run/${redisName name}/redis.conf
+ '' + optionalString (conf.requirePassFile != null) ''
+ {
+ printf requirePass' '
+ cat ${escapeShellArg conf.requirePassFile}
+ } >>/run/${redisName name}/redis.conf
+ '')
+ )
+ ];
+ Type = "notify";
+ # User and group
+ User = conf.user;
+ Group = conf.user;
+ # Runtime directory and mode
+ RuntimeDirectory = redisName name;
+ RuntimeDirectoryMode = "0750";
+ # State directory and mode
+ StateDirectory = redisName name;
+ StateDirectoryMode = "0700";
+ # Access write directories
+ UMask = "0077";
+ # Capabilities
+ CapabilityBoundingSet = "";
+ # Security
+ NoNewPrivileges = true;
+ # Process Properties
+ LimitNOFILE = mkDefault "${toString (conf.maxclients + 32)}";
+ # Sandboxing
+ ProtectSystem = "strict";
+ ProtectHome = true;
+ PrivateTmp = true;
+ PrivateDevices = true;
+ PrivateUsers = true;
+ ProtectClock = true;
+ ProtectHostname = true;
+ ProtectKernelLogs = true;
+ ProtectKernelModules = true;
+ ProtectKernelTunables = true;
+ ProtectControlGroups = true;
+ RestrictAddressFamilies =
+ optionals (conf.bind != null) [ "AF_INET" "AF_INET6" ] ++
+ optional (conf.unixSocket != null) "AF_UNIX";
+ RestrictNamespaces = true;
+ LockPersonality = true;
+ MemoryDenyWriteExecute = true;
+ RestrictRealtime = true;
+ RestrictSUIDSGID = true;
+ PrivateMounts = true;
+ # System Call Filtering
+ SystemCallArchitectures = "native";
+ SystemCallFilter = "~@cpu-emulation @debug @keyring @memlock @mount @obsolete @privileged @resources @setuid";
+ };
+ })
+ enabledServers;
};
}