nixos/logrotate: switch paths option type from listOf to attrsOf

This commit is contained in:
Aaron Andersen 2020-08-19 12:36:54 -04:00
parent e7139f46cd
commit 00f08005af

View File

@ -5,54 +5,93 @@ with lib;
let let
cfg = config.services.logrotate; cfg = config.services.logrotate;
pathOptions = { pathOpts = {
options = { options = {
enable = mkOption {
type = types.bool;
default = true;
description = ''
Whether to enable log rotation for this path. This can be used to explicitly disable
logging that has been configured by NixOS.
'';
};
path = mkOption { path = mkOption {
type = types.str; type = types.str;
description = "The path to log files to be rotated"; description = ''
The path to log files to be rotated.
'';
}; };
user = mkOption { user = mkOption {
type = types.str; type = with types; nullOr str;
description = "The user account to use for rotation"; default = null;
description = ''
The user account to use for rotation.
'';
}; };
group = mkOption { group = mkOption {
type = types.str; type = with types; nullOr str;
description = "The group to use for rotation"; default = null;
description = ''
The group to use for rotation.
'';
}; };
frequency = mkOption { frequency = mkOption {
type = types.enum [ type = types.enum [ "daily" "weekly" "monthly" "yearly" ];
"daily" "weekly" "monthly" "yearly"
];
default = "daily"; default = "daily";
description = "How often to rotate the logs"; description = ''
How often to rotate the logs.
'';
}; };
keep = mkOption { keep = mkOption {
type = types.int; type = types.int;
default = 20; default = 20;
description = "How many rotations to keep"; description = ''
How many rotations to keep.
'';
}; };
extraConfig = mkOption { extraConfig = mkOption {
type = types.lines; type = types.lines;
default = ""; default = "";
description = "Extra logrotate config options for this path"; description = ''
Extra logrotate config options for this path. Refer to
<link xlink:href="https://linux.die.net/man/8/logrotate"/> for details.
'';
};
priority = mkOption {
type = types.int;
default = 1000;
description = ''
Order of this logrotate block in relation to the others. The semantics are
the same as with `lib.mkOrder`. Smaller values have a greater priority.
'';
}; };
}; };
};
pathConfig = options: '' config.extraConfig = ''
"${options.path}" {
su ${options.user} ${options.group}
${options.frequency}
missingok missingok
notifempty notifempty
rotate ${toString options.keep} '';
${options.extraConfig} };
mkConf = pathOpts: ''
# generated by NixOS using the `services.logrotate.paths.${pathOpts.name}` attribute set
"${pathOpts.path}" {
${optionalString (pathOpts.user != null || pathOpts.group != null) "su ${pathOpts.user} ${pathOpts.group}"}
${pathOpts.frequency}
rotate ${toString pathOpts.keep}
${pathOpts.extraConfig}
} }
''; '';
configFile = pkgs.writeText "logrotate.conf" ( paths = sortProperties (mapAttrsToList (name: pathOpts: pathOpts // { name = name; }) (filterAttrs (_: pathOpts: pathOpts.enable) cfg.paths));
(concatStringsSep "\n" ((map pathConfig cfg.paths) ++ [cfg.extraConfig])) configFile = pkgs.writeText "logrotate.conf" (concatStringsSep "\n" ((map mkConf paths) ++ [ cfg.extraConfig ]));
);
in in
{ {
@ -65,41 +104,66 @@ in
enable = mkEnableOption "the logrotate systemd service"; enable = mkEnableOption "the logrotate systemd service";
paths = mkOption { paths = mkOption {
type = types.listOf (types.submodule pathOptions); type = with types; attrsOf (submodule pathOpts);
default = []; default = {};
description = "List of attribute sets with paths to rotate"; description = ''
example = { Attribute set of paths to rotate. The order each block appears in the generated configuration file
"/var/log/myapp/*.log" = { can be controlled by the <link linkend="opt-services.logrotate._name_.priority">priority</link> option
user = "myuser"; using the same semantics as `lib.mkOrder`. Smaller values have a greater priority.
group = "mygroup"; '';
rotate = "weekly"; example = literalExample ''
keep = 5; {
}; httpd = {
}; path = "/var/log/httpd/*.log";
user = config.services.httpd.user;
group = config.services.httpd.group;
keep = 7;
};
myapp = {
path = "/var/log/myapp/*.log";
user = "myuser";
group = "mygroup";
frequency = "weekly";
keep = 5;
priority = 1;
};
}
'';
}; };
extraConfig = mkOption { extraConfig = mkOption {
default = ""; default = "";
type = types.lines; type = types.lines;
description = '' description = ''
Extra contents to add to the logrotate config file. Extra contents to append to the logrotate configuration file. Refer to
See https://linux.die.net/man/8/logrotate <link xlink:href="https://linux.die.net/man/8/logrotate"/> for details.
''; '';
}; };
}; };
}; };
config = mkIf cfg.enable { config = mkIf cfg.enable {
systemd.services.logrotate = { assertions = mapAttrsToList (name: pathOpts:
description = "Logrotate Service"; { assertion = (pathOpts.user != null) == (pathOpts.group != null);
wantedBy = [ "multi-user.target" ]; message = ''
startAt = "*-*-* *:05:00"; If either of `services.logrotate.paths.${name}.user` or `services.logrotate.paths.${name}.group` are specified then *both* must be specified.
'';
}
) cfg.paths;
serviceConfig.Restart = "no"; systemd.services.logrotate = {
serviceConfig.User = "root"; description = "Logrotate Service";
wantedBy = [ "multi-user.target" ];
startAt = "*-*-* *:05:00";
script = '' script = ''
exec ${pkgs.logrotate}/sbin/logrotate ${configFile} exec ${pkgs.logrotate}/sbin/logrotate ${configFile}
''; '';
serviceConfig = {
Restart = "no";
User = "root";
};
}; };
}; };
} }