summary refs log tree commit diff
path: root/nixos/modules
diff options
context:
space:
mode:
authorDominique Martinet <asmadeus@codewreck.org>2022-03-01 06:54:12 +0900
committerDominique Martinet <asmadeus@codewreck.org>2022-04-01 07:09:26 +0900
commite92c05349c6053df22cf21eb9f424251ba2b114f (patch)
treec545f68e95ef9d37ad28a66e2eb174c9b9727182 /nixos/modules
parent3cc8ea28d1c20320b674d3d4131d02e4df8df5fa (diff)
downloadnixpkgs-e92c05349c6053df22cf21eb9f424251ba2b114f.tar
nixpkgs-e92c05349c6053df22cf21eb9f424251ba2b114f.tar.gz
nixpkgs-e92c05349c6053df22cf21eb9f424251ba2b114f.tar.bz2
nixpkgs-e92c05349c6053df22cf21eb9f424251ba2b114f.tar.lz
nixpkgs-e92c05349c6053df22cf21eb9f424251ba2b114f.tar.xz
nixpkgs-e92c05349c6053df22cf21eb9f424251ba2b114f.tar.zst
nixpkgs-e92c05349c6053df22cf21eb9f424251ba2b114f.zip
nixos/logrotate: convert to freeform
using freeform is the new standard way of using modules and should replace
extraConfig.
In particular, this will allow us to place a condition on mails
Diffstat (limited to 'nixos/modules')
-rw-r--r--nixos/modules/services/logging/logrotate.nix192
-rw-r--r--nixos/modules/services/misc/gitlab.nix16
-rw-r--r--nixos/modules/services/networking/lxd-image-server.nix18
-rw-r--r--nixos/modules/services/web-servers/apache-httpd/default.nix21
-rw-r--r--nixos/modules/services/web-servers/nginx/default.nix16
-rw-r--r--nixos/modules/system/boot/systemd.nix18
-rw-r--r--nixos/modules/virtualisation/azure-agent.nix14
7 files changed, 201 insertions, 94 deletions
diff --git a/nixos/modules/services/logging/logrotate.nix b/nixos/modules/services/logging/logrotate.nix
index d16a5a571ba..6a9ed469fd3 100644
--- a/nixos/modules/services/logging/logrotate.nix
+++ b/nixos/modules/services/logging/logrotate.nix
@@ -5,6 +5,9 @@ with lib;
 let
   cfg = config.services.logrotate;
 
+  # deprecated legacy compat settings
+  # these options will be removed before 22.11 in the following PR:
+  # https://github.com/NixOS/nixpkgs/pull/164169
   pathOpts = { name, ... }: {
     options = {
       enable = mkOption {
@@ -86,27 +89,77 @@ let
     config.name = name;
   };
 
-  mkConf = pathOpts: ''
-    # generated by NixOS using the `services.logrotate.paths.${pathOpts.name}` attribute set
-    ${concatMapStringsSep " " (path: ''"${path}"'') (toList pathOpts.path)} {
-      ${optionalString (pathOpts.user != null || pathOpts.group != null) "su ${pathOpts.user} ${pathOpts.group}"}
-      ${pathOpts.frequency}
-      rotate ${toString pathOpts.keep}
-      ${pathOpts.extraConfig}
-    }
-  '';
-
-  paths = sortProperties (attrValues (filterAttrs (_: pathOpts: pathOpts.enable) cfg.paths));
-  configText = concatStringsSep "\n" (
-    [ "missingok" "notifempty" cfg.extraConfig ] ++ (map mkConf paths)
+  generateLine = n: v:
+    if builtins.elem n [ "files" "priority" "enable" "global" ] || v == null then null
+    else if builtins.elem n [ "extraConfig" "frequency" ] then "${v}\n"
+    else if builtins.elem n [ "firstaction" "lastaction" "prerotate" "postrotate" "preremove" ]
+         then "${n}\n    ${v}\n  endscript\n"
+    else if isInt v then "${n} ${toString v}\n"
+    else if v == true then "${n}\n"
+    else if v == false then "no${n}\n"
+    else "${n} ${v}\n";
+  generateSection = indent: settings: concatStringsSep (fixedWidthString indent " " "") (
+    filter (x: x != null) (mapAttrsToList generateLine settings)
+  );
+
+  # generateSection includes a final newline hence weird closing brace
+  mkConf = settings:
+    if settings.global or false then generateSection 0 settings
+    else ''
+      ${concatMapStringsSep "\n" (files: ''"${files}"'') (toList settings.files)} {
+        ${generateSection 2 settings}}
+    '';
+
+  # below two mapPaths are compat functions
+  mapPathOptToSetting = n: v:
+    if n == "keep" then nameValuePair "rotate" v
+    else if n == "path" then nameValuePair "files" v
+    else nameValuePair n v;
+
+  mapPathsToSettings = path: pathOpts:
+    nameValuePair path (
+      filterAttrs (n: v: ! builtins.elem n [ "user" "group" "name" ] && v != "") (
+        (mapAttrs' mapPathOptToSetting pathOpts) //
+        {
+          su =
+            if pathOpts.user != null
+            then "${pathOpts.user} ${pathOpts.group}"
+            else null;
+        }
+      )
+    );
+
+  settings = sortProperties (attrValues (filterAttrs (_: settings: settings.enable) (
+    foldAttrs recursiveUpdate { } [
+      {
+        header = {
+          enable = true;
+          missingok = true;
+          notifempty = true;
+          frequency = "weekly";
+          rotate = 4;
+        };
+        # compat section
+        extraConfig = {
+          enable = (cfg.extraConfig != "");
+          global = true;
+          extraConfig = cfg.extraConfig;
+          priority = 101;
+        };
+      }
+      (mapAttrs' mapPathsToSettings cfg.paths)
+      cfg.settings
+      { header = { global = true; priority = 100; }; }
+    ]
+  )));
+  configFile = pkgs.writeText "logrotate.conf" (
+    concatStringsSep "\n" (
+      map mkConf settings
+    )
   );
-  configFile = pkgs.writeText "logrotate.conf" configText;
 
   mailOption =
-    # add mail option to service if a mail is requested in config
-    # this ugly match will be replaced by cleaner attribute check in
-    # the near future
-    if builtins.match "(.*[[:space:]])?mail[[:space:]].*" configText != null
+    if foldr (n: a: a || n ? mail) false (attrValues cfg.settings)
     then "--mail=${pkgs.mailutils}/bin/mail"
     else "";
 in
@@ -118,8 +171,68 @@ in
   options = {
     services.logrotate = {
       enable = mkEnableOption "the logrotate systemd service" // {
-        default = foldr (n: a: a || n.enable) false (attrValues cfg.paths);
-        defaultText = literalExpression "cfg.paths != {}";
+        default = foldr (n: a: a || n.enable) false (attrValues cfg.settings);
+        defaultText = literalExpression "cfg.settings != {}";
+      };
+
+      settings = mkOption {
+        default = { };
+        description = ''
+          logrotate freeform settings: each attribute here will define its own section,
+          ordered by priority, which can either define files to rotate with their settings
+          or settings common to all further files settings.
+          Refer to <link xlink:href="https://linux.die.net/man/8/logrotate"/> for details.
+        '';
+        type = types.attrsOf (types.submodule ({ name, ... }: {
+          freeformType = with types; attrsOf (nullOr (oneOf [ int bool str ]));
+
+          options = {
+            enable = mkEnableOption "setting individual kill switch" // {
+              default = true;
+            };
+
+            global = mkOption {
+              type = types.bool;
+              default = false;
+              description = ''
+                Whether this setting is a global option or not: set to have these
+                settings apply to all files settings with a higher priority.
+              '';
+            };
+            files = mkOption {
+              type = with types; either str (listOf str);
+              default = name;
+              defaultText = ''
+                The attrset name if not specified
+              '';
+              description = ''
+                Single or list of files for which rules are defined.
+                The files are quoted with double-quotes in logrotate configuration,
+                so globs and spaces are supported.
+                Note this setting is ignored if globals is true.
+              '';
+            };
+
+            frequency = mkOption {
+              type = types.nullOr types.str;
+              default = null;
+              description = ''
+                How often to rotate the logs. Defaults to previously set global setting,
+                which itself defauts to weekly.
+              '';
+            };
+
+            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 are inserted first.
+              '';
+            };
+          };
+
+        }));
       };
 
       configFile = mkOption {
@@ -130,7 +243,7 @@ in
         '';
         description = ''
           Override the configuration file used by MySQL. By default,
-          NixOS generates one automatically from <option>services.logrotate.settings</option>.
+          NixOS generates one automatically from <xref linkend="opt-services.logrotate.settings"/>.
         '';
         example = literalExpression ''
           pkgs.writeText "logrotate.conf" '''
@@ -143,6 +256,7 @@ in
         '';
       };
 
+      # deprecated legacy compat settings
       paths = mkOption {
         type = with types; attrsOf (submodule pathOpts);
         default = { };
@@ -150,6 +264,7 @@ in
           Attribute set of paths to rotate. The order each block appears in the generated configuration file
           can be controlled by the <link linkend="opt-services.logrotate.paths._name_.priority">priority</link> option
           using the same semantics as `lib.mkOrder`. Smaller values have a greater priority.
+          This setting has been deprecated in favor of <link linkend="opt-services.logrotate.settings">logrotate settings</link>.
         '';
         example = literalExpression ''
           {
@@ -178,22 +293,37 @@ in
         description = ''
           Extra contents to append to the logrotate configuration file. Refer to
           <link xlink:href="https://linux.die.net/man/8/logrotate"/> for details.
+          This setting has been deprecated in favor of
+          <link linkend="opt-services.logrotate.settings">logrotate settings</link>.
         '';
       };
     };
   };
 
   config = mkIf cfg.enable {
-    assertions = mapAttrsToList
-      (name: pathOpts:
-        {
-          assertion = (pathOpts.user != null) == (pathOpts.group != null);
-          message = ''
-            If either of `services.logrotate.paths.${name}.user` or `services.logrotate.paths.${name}.group` are specified then *both* must be specified.
-          '';
-        }
-      )
-      cfg.paths;
+    assertions =
+      mapAttrsToList
+        (name: pathOpts:
+          {
+            assertion = (pathOpts.user != null) == (pathOpts.group != null);
+            message = ''
+              If either of `services.logrotate.paths.${name}.user` or `services.logrotate.paths.${name}.group` are specified then *both* must be specified.
+            '';
+          })
+        cfg.paths;
+
+    warnings =
+      (mapAttrsToList
+        (name: pathOpts: ''
+          Using config.services.logrotate.paths.${name} is deprecated and will become unsupported in a future release.
+          Please use services.logrotate.settings instead.
+        '')
+        cfg.paths
+      ) ++
+      (optional (cfg.extraConfig != "") ''
+        Using config.services.logrotate.extraConfig is deprecated and will become unsupported in a future release.
+        Please use services.logrotate.settings with globals=true instead.
+      '');
 
     systemd.services.logrotate = {
       description = "Logrotate Service";
diff --git a/nixos/modules/services/misc/gitlab.nix b/nixos/modules/services/misc/gitlab.nix
index e48444f7161..488c3be7b65 100644
--- a/nixos/modules/services/misc/gitlab.nix
+++ b/nixos/modules/services/misc/gitlab.nix
@@ -848,10 +848,7 @@ in {
 
         extraConfig = mkOption {
           type = types.lines;
-          default = ''
-            copytruncate
-            compress
-          '';
+          default = "";
           description = ''
             Extra logrotate config options for this path. Refer to
             <link xlink:href="https://linux.die.net/man/8/logrotate"/> for details.
@@ -977,13 +974,14 @@ in {
     # Enable rotation of log files
     services.logrotate = {
       enable = cfg.logrotate.enable;
-      paths = {
+      settings = {
         gitlab = {
-          path = "${cfg.statePath}/log/*.log";
-          user = cfg.user;
-          group = cfg.group;
+          files = "${cfg.statePath}/log/*.log";
+          su = "${cfg.user} ${cfg.group}";
           frequency = cfg.logrotate.frequency;
-          keep = cfg.logrotate.keep;
+          rotate = cfg.logrotate.keep;
+          copytruncate = true;
+          compress = true;
           extraConfig = cfg.logrotate.extraConfig;
         };
       };
diff --git a/nixos/modules/services/networking/lxd-image-server.nix b/nixos/modules/services/networking/lxd-image-server.nix
index b119ba8acf6..d326626eed4 100644
--- a/nixos/modules/services/networking/lxd-image-server.nix
+++ b/nixos/modules/services/networking/lxd-image-server.nix
@@ -51,18 +51,14 @@ in
 
       environment.etc."lxd-image-server/config.toml".source = format.generate "config.toml" cfg.settings;
 
-      services.logrotate.paths.lxd-image-server = {
-        path = "/var/log/lxd-image-server/lxd-image-server.log";
+      services.logrotate.settings.lxd-image-server = {
+        files = "/var/log/lxd-image-server/lxd-image-server.log";
         frequency = "daily";
-        keep = 21;
-        extraConfig = ''
-          create 755 lxd-image-server ${cfg.group}
-          missingok
-          compress
-          delaycompress
-          copytruncate
-          notifempty
-        '';
+        rotate = 21;
+        create = "755 lxd-image-server ${cfg.group}";
+        compress = true;
+        delaycompress = true;
+        copytruncate = true;
       };
 
       systemd.tmpfiles.rules = [
diff --git a/nixos/modules/services/web-servers/apache-httpd/default.nix b/nixos/modules/services/web-servers/apache-httpd/default.nix
index d817ff6019a..3099705acbe 100644
--- a/nixos/modules/services/web-servers/apache-httpd/default.nix
+++ b/nixos/modules/services/web-servers/apache-httpd/default.nix
@@ -710,20 +710,15 @@ in
 
     services.logrotate = optionalAttrs (cfg.logFormat != "none") {
       enable = mkDefault true;
-      paths.httpd = {
-        path = "${cfg.logDir}/*.log";
-        user = cfg.user;
-        group = cfg.group;
+      settings.httpd = {
+        files = "${cfg.logDir}/*.log";
+        su = "${cfg.user} ${cfg.group}";
         frequency = "daily";
-        keep = 28;
-        extraConfig = ''
-          sharedscripts
-          compress
-          delaycompress
-          postrotate
-            systemctl reload httpd.service > /dev/null 2>/dev/null || true
-          endscript
-        '';
+        rotate = 28;
+        sharedscripts = true;
+        compress = true;
+        delaycompress = true;
+        postrotate = "systemctl reload httpd.service > /dev/null 2>/dev/null || true";
       };
     };
 
diff --git a/nixos/modules/services/web-servers/nginx/default.nix b/nixos/modules/services/web-servers/nginx/default.nix
index e046c28dd6b..1e18956c2dc 100644
--- a/nixos/modules/services/web-servers/nginx/default.nix
+++ b/nixos/modules/services/web-servers/nginx/default.nix
@@ -989,17 +989,13 @@ in
       nginx.gid = config.ids.gids.nginx;
     };
 
-    services.logrotate.paths.nginx = mapAttrs (_: mkDefault) {
-      path = "/var/log/nginx/*.log";
+    services.logrotate.settings.nginx = mapAttrs (_: mkDefault) {
+      files = "/var/log/nginx/*.log";
       frequency = "weekly";
-      keep = 26;
-      extraConfig = ''
-        compress
-        delaycompress
-        postrotate
-          [ ! -f /var/run/nginx/nginx.pid ] || kill -USR1 `cat /var/run/nginx/nginx.pid`
-        endscript
-      '';
+      rotate = 26;
+      compress = true;
+      delaycompress = true;
+      postrotate = "[ ! -f /var/run/nginx/nginx.pid ] || kill -USR1 `cat /var/run/nginx/nginx.pid`";
     };
   };
 }
diff --git a/nixos/modules/system/boot/systemd.nix b/nixos/modules/system/boot/systemd.nix
index 297a80d4681..f69c5d3d5a6 100644
--- a/nixos/modules/system/boot/systemd.nix
+++ b/nixos/modules/system/boot/systemd.nix
@@ -612,22 +612,18 @@ in
 
     boot.kernelParams = optional (!cfg.enableUnifiedCgroupHierarchy) "systemd.unified_cgroup_hierarchy=0";
 
-    services.logrotate.paths = {
+    services.logrotate.settings = {
       "/var/log/btmp" = mapAttrs (_: mkDefault) {
         frequency = "monthly";
-        keep = 1;
-        extraConfig = ''
-          create 0660 root ${config.users.groups.utmp.name}
-          minsize 1M
-        '';
+        rotate = 1;
+        create = "0660 root ${config.users.groups.utmp.name}";
+        minsize = "1M";
       };
       "/var/log/wtmp" = mapAttrs (_: mkDefault) {
         frequency = "monthly";
-        keep = 1;
-        extraConfig = ''
-          create 0664 root ${config.users.groups.utmp.name}
-          minsize 1M
-        '';
+        rotate = 1;
+        create = "0664 root ${config.users.groups.utmp.name}";
+        minsize = "1M";
       };
     };
   };
diff --git a/nixos/modules/virtualisation/azure-agent.nix b/nixos/modules/virtualisation/azure-agent.nix
index bd8c7f8c1ee..e2425b44eac 100644
--- a/nixos/modules/virtualisation/azure-agent.nix
+++ b/nixos/modules/virtualisation/azure-agent.nix
@@ -146,15 +146,11 @@ in
 
     services.logrotate = {
       enable = true;
-      extraConfig = ''
-        /var/log/waagent.log {
-            compress
-            monthly
-            rotate 6
-            notifempty
-            missingok
-        }
-      '';
+      settings."/var/log/waagent.log" = {
+        compress = true;
+        frequency = "monthly";
+        rotate = 6;
+      };
     };
 
     systemd.targets.provisioned = {