nixos/redis: unbreak module

The redis module currently fails to start up, most likely due to running
a chown as non-root in preStart.

While at it, I hardcoded it to use systemd's StateDirectory and
DynamicUser to manage directory permissions, removed the unused
appendOnlyFilename option, and the pidFile option.

We properly tell redis now it's daemonized, and it'll use notify support
to signal readiness.
This commit is contained in:
Florian Klink 2019-08-31 20:08:49 +02:00
parent d4283f47dc
commit ff2fd6c4e5
3 changed files with 25 additions and 47 deletions

View file

@ -599,6 +599,11 @@
package and <literal>crashplan-small-business</literal> service have been
removed from nixpkgs due to lack of maintainer.
</para>
<para>
The <link linkend="opt-services.redis.enable">redis module</link> was hardcoded to use the <literal>redis</literal> user,
<filename class="directory">/run/redis</filename> as runtime directory and
<filename class="directory">/var/lib/redis</filename> as state directory.
</para>
</listitem>
<listitem>
<para>

View file

@ -256,7 +256,7 @@ with lib;
# binfmt
(mkRenamedOptionModule [ "boot" "binfmtMiscRegistrations" ] [ "boot" "binfmt" "registrations" ])
# ACME
(mkRemovedOptionModule [ "security" "acme" "directory"] "ACME Directory is now hardcoded to /var/lib/acme and its permisisons are managed by systemd. See https://github.com/NixOS/nixpkgs/issues/53852 for more info.")
(mkRemovedOptionModule [ "security" "acme" "preDelay"] "This option has been removed. If you want to make sure that something executes before certificates are provisioned, add a RequiredBy=acme-\${cert}.service to the service you want to execute before the cert renewal")
@ -285,6 +285,13 @@ with lib;
throw "services.redshift.longitude is set to null, you can remove this"
else builtins.fromJSON value))
# Redis
(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" "dbFilename" ] "The redis module now uses /var/lib/redis/dump.rdb as database dump location.")
(mkRemovedOptionModule [ "services" "redis" "appendOnlyFilename" ] "This option was never used.")
(mkRemovedOptionModule [ "services" "redis" "pidFile" ] "This option was removed.")
] ++ (forEach [ "blackboxExporter" "collectdExporter" "fritzboxExporter"
"jsonExporter" "minioExporter" "nginxExporter" "nodeExporter"
"snmpExporter" "unifiExporter" "varnishExporter" ]

View file

@ -8,17 +8,19 @@ let
condOption = name: value: if value != null then "${name} ${toString value}" else "";
redisConfig = pkgs.writeText "redis.conf" ''
pidfile ${cfg.pidFile}
port ${toString cfg.port}
${condOption "bind" cfg.bind}
${condOption "unixsocket" cfg.unixSocket}
daemonize yes
supervised systemd
loglevel ${cfg.logLevel}
logfile ${cfg.logfile}
syslog-enabled ${redisBool cfg.syslog}
pidfile /run/redis/redis.pid
databases ${toString cfg.databases}
${concatMapStrings (d: "save ${toString (builtins.elemAt d 0)} ${toString (builtins.elemAt d 1)}\n") cfg.save}
dbfilename ${cfg.dbFilename}
dir ${toString cfg.dbpath}
dbfilename dump.rdb
dir /var/lib/redis
${if cfg.slaveOf != null then "slaveof ${cfg.slaveOf.ip} ${toString cfg.slaveOf.port}" else ""}
${condOption "masterauth" cfg.masterAuth}
${condOption "requirepass" cfg.requirePass}
@ -55,18 +57,6 @@ in
description = "Which Redis derivation to use.";
};
user = mkOption {
type = types.str;
default = "redis";
description = "User account under which Redis runs.";
};
pidFile = mkOption {
type = types.path;
default = "/var/lib/redis/redis.pid";
description = "";
};
port = mkOption {
type = types.int;
default = 6379;
@ -100,7 +90,7 @@ in
type = with types; nullOr path;
default = null;
description = "The path to the socket to bind to.";
example = "/run/redis.sock";
example = "/run/redis/redis.sock";
};
logLevel = mkOption {
@ -136,18 +126,6 @@ in
example = [ [900 1] [300 10] [60 10000] ];
};
dbFilename = mkOption {
type = types.str;
default = "dump.rdb";
description = "The filename where to dump the DB.";
};
dbpath = mkOption {
type = types.path;
default = "/var/lib/redis";
description = "The DB will be written inside this directory, with the filename specified using the 'dbFilename' configuration.";
};
slaveOf = mkOption {
default = null; # { ip, port }
description = "An attribute set with two attributes: ip and port to which this redis instance acts as a slave.";
@ -175,12 +153,6 @@ in
description = "By default data is only periodically persisted to disk, enable this option to use an append-only file for improved persistence.";
};
appendOnlyFilename = mkOption {
type = types.str;
default = "appendonly.aof";
description = "Filename for the append-only file (stored inside of dbpath)";
};
appendFsync = mkOption {
type = types.str;
default = "everysec"; # no, always, everysec
@ -222,19 +194,15 @@ in
allowedTCPPorts = [ cfg.port ];
};
users.users.redis =
{ name = cfg.user;
description = "Redis database user";
};
users.users.redis.description = "Redis database user";
environment.systemPackages = [ cfg.package ];
systemd.services.disable-transparent-huge-pages = {
enable = config.services.redis.enable;
description = "Disable Transparent Huge Pages (required by Redis)";
before = [ "redis.service" ];
wantedBy = [ "redis.service" ];
script = "echo never >/sys/kernel/mm/transparent_hugepage/enabled";
script = "echo never > /sys/kernel/mm/transparent_hugepage/enabled";
serviceConfig.Type = "oneshot";
};
@ -244,14 +212,12 @@ in
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ];
preStart = ''
install -d -m0700 -o ${cfg.user} ${cfg.dbpath}
chown -R ${cfg.user} ${cfg.dbpath}
'';
serviceConfig = {
ExecStart = "${cfg.package}/bin/redis-server ${redisConfig}";
User = cfg.user;
RuntimeDirectory = "redis";
StateDirectory = "redis";
Type = "notify";
User = "redis";
};
};