about summary refs log tree commit diff
path: root/nixpkgs
diff options
context:
space:
mode:
authorAlyssa Ross <hi@alyssa.is>2021-04-15 10:07:42 +0000
committerAlyssa Ross <hi@alyssa.is>2021-06-09 14:50:26 +0000
commit2f53a8b049234f14d5e698ca5aefdc06a3270383 (patch)
tree37545a77de8e91694c3d88a838fa70adbcbb443c /nixpkgs
parent1982260c6767eb5f8fc64cea390eed797bbf6d65 (diff)
downloadnixlib-2f53a8b049234f14d5e698ca5aefdc06a3270383.tar
nixlib-2f53a8b049234f14d5e698ca5aefdc06a3270383.tar.gz
nixlib-2f53a8b049234f14d5e698ca5aefdc06a3270383.tar.bz2
nixlib-2f53a8b049234f14d5e698ca5aefdc06a3270383.tar.lz
nixlib-2f53a8b049234f14d5e698ca5aefdc06a3270383.tar.xz
nixlib-2f53a8b049234f14d5e698ca5aefdc06a3270383.tar.zst
nixlib-2f53a8b049234f14d5e698ca5aefdc06a3270383.zip
nixos/public-inbox: move closer to the upstream PR
public-inbox isn't in upstream Nixpkgs, but there is a PR, and that
should be treated as upstream for now.
Diffstat (limited to 'nixpkgs')
-rw-r--r--nixpkgs/nixos/modules/services/mail/public-inbox.nix440
1 files changed, 212 insertions, 228 deletions
diff --git a/nixpkgs/nixos/modules/services/mail/public-inbox.nix b/nixpkgs/nixos/modules/services/mail/public-inbox.nix
index d503f5aa2ef6..c45ea7385b96 100644
--- a/nixpkgs/nixos/modules/services/mail/public-inbox.nix
+++ b/nixpkgs/nixos/modules/services/mail/public-inbox.nix
@@ -4,8 +4,9 @@ with lib;
 
 let
   cfg = config.services.public-inbox;
+  stateDir = "/var/lib/public-inbox";
 
-  inboxesDir = "/var/lib/public-inbox/inboxes";
+  inboxesDir = "${stateDir}/inboxes";
   inboxPath = name: "${inboxesDir}/${name}";
   gitPath = name: "${inboxPath name}/all.git";
 
@@ -48,25 +49,12 @@ let
     (concatStrings (map ({ name, value }: gitConfig name value) configList));
 
   environment = {
-    PI_EMERGENCY = "/var/lib/public-inbox/emergency";
+    PI_EMERGENCY = "${stateDir}/emergency";
     PI_CONFIG = configFile;
   };
 
   envList = mapAttrsToList (n: v: "${n}=${v}") environment;
 
-  # Can't use pkgs.linkFarm,
-  # because Postfix rejects .forward if it's a symlink.
-  home = pkgs.runCommand "public-inbox-home" {
-    forward = ''
-      |"env ${concatStringsSep " " envList} PATH=\"${makeBinPath cfg.path}:$PATH\" ${cfg.package}/bin/public-inbox-mda ${escapeShellArgs cfg.mda.args}
-    '';
-    passAsFile = [ "forward" ];
-  } ''
-    mkdir $out
-    ln -s /var/lib/public-inbox/spamassassin $out/.spamassassin
-    cp $forwardPath $out/.forward
-  '';
-
   psgi = pkgs.writeText "public-inbox.psgi" ''
     #!${cfg.package.fullperl} -w
     # Copyright (C) 2014-2019 all contributors <meta@public-inbox.org>
@@ -99,236 +87,219 @@ let
 in
 
 {
-  options = {
-    services.public-inbox = {
-      enable = mkEnableOption "the public-inbox mail archiver";
+  options.services.public-inbox = {
+    enable = mkEnableOption "the public-inbox mail archiver";
+    package = mkOption {
+      type = types.package;
+      default = pkgs.public-inbox;
+      description = "public-inbox package to use.";
+    };
+    path = mkOption {
+      type = with types; listOf package;
+      default = [];
+      example = literalExample "with pkgs; [ spamassassin ]";
+      description = ''
+        Additional packages to place in the path of public-inbox-mda,
+        public-inbox-watch, etc.
+      '';
+    };
+    inboxes = mkOption {
+      description = ''
+        Inboxes to configure, where attribute names are inbox names.
+      '';
+      type = with types; loaOf (submodule {
+        options = {
+          address = mkOption {
+            type = listOf str;
+            example = "example-discuss@example.org";
+          };
 
-      package = mkOption {
-        type = types.package;
-        default = pkgs.public-inbox;
-        description = ''
-          public-inbox package to use with the public-inbox module
-        '';
-      };
+          url = mkOption {
+            type = nullOr str;
+            default = null;
+            example = "https://example.org/lists/example-discuss";
+            description = ''
+              URL where this inbox can be accessed over HTTP
+            '';
+          };
 
-      path = mkOption {
-        type = with types; listOf package;
-        default = [];
-        example = literalExample "with pkgs; [ spamassassin ]";
-        description = ''
-          Additional packages to place in the path of public-inbox-mda,
-          public-inbox-watch, etc.
-        '';
-      };
+          description = mkOption {
+            type = str;
+            example = "user/dev discussion of public-inbox itself";
+            description = ''
+              User-visible description for the repository
+            '';
+          };
 
-      inboxes = mkOption {
-        description = ''
-          Inboxes to configure, where attribute names are inbox names
-        '';
-        type = with types; loaOf (submodule {
-          options = {
-            address = mkOption {
-              type = listOf str;
-              example = "example-discuss@example.org";
-            };
-
-            url = mkOption {
-              type = nullOr str;
-              default = null;
-              example = "https://example.org/lists/example-discuss";
-              description = ''
-                URL where this inbox can be accessed over HTTP
-              '';
-            };
-
-            description = mkOption {
-              type = str;
-              example = "user/dev discussion of public-inbox itself";
-              description = ''
-                User-visible description for the repository
-              '';
-            };
-
-            config = mkOption {
-              type = attrs;
-              default = {};
-              description = ''
-                Additional structured config for the inbox
-              '';
-            };
-
-            newsgroup = mkOption {
-              type = nullOr str;
-              default = null;
-              description = ''
-                NNTP group name for the inbox
-              '';
-            };
-
-            watch = mkOption {
-              type = listOf str;
-              default = [];
-              description = ''
-                Paths for public-inbox-watch(1) to monitor for new mail
-              '';
-              example = [ "maildir:/path/to/test.example.com.git" ];
-            };
-
-            watchHeader = mkOption {
-              type = nullOr str;
-              default = null;
-              example = "List-Id:<test@example.com>";
-              description = ''
-                If specified, public-inbox-watch(1) will only process
-                mail containing a matching header.
-              '';
-            };
+          config = mkOption {
+            type = attrs;
+            default = {};
+            description = ''
+              Additional structured config for the inbox
+            '';
           };
-        });
-      };
 
-      mda = {
-        args = mkOption {
-          type = with types; listOf str;
-          default = [];
-          description = ''
-            Command-line arguments to pass to public-inbox-mda(1).
-          '';
-        };
+          newsgroup = mkOption {
+            type = nullOr str;
+            default = null;
+            description = ''
+              NNTP group name for the inbox
+            '';
+          };
 
-        spamCheck = mkOption {
-          type = with types; nullOr (enum [ "spamc" ]);
-          default = "spamc";
-          description = ''
-            If set to spamc, public-inbox-mda(1) will filter spam
-            using SpamAssassin
-          '';
-        };
-      };
+          watch = mkOption {
+            type = listOf str;
+            default = [];
+            description = ''
+              Paths for public-inbox-watch(1) to monitor for new mail
+            '';
+            example = [ "maildir:/path/to/test.example.com.git" ];
+          };
 
-      watch = {
-        spamCheck = mkOption {
-          type = with types; nullOr (enum [ "spamc" ]);
-          default = "spamc";
-          description = ''
-            If set to spamc, public-inbox-watch(1) will filter spam
-            using SpamAssassin
-          '';
+          watchHeader = mkOption {
+            type = nullOr str;
+            default = null;
+            example = "List-Id:<test@example.com>";
+            description = ''
+              If specified, public-inbox-watch(1) will only process
+              mail containing a matching header.
+            '';
+          };
         };
+      });
+    };
 
-        watchSpam = mkOption {
-          type = with types; nullOr str;
-          default = null;
-          example = "maildir:/path/to/spam";
-          description = ''
-            If set, mail in this maildir will be trained as spam and
-            deleted from all watched inboxes
-          '';
-        };
+    mda = {
+      args = mkOption {
+        type = with types; listOf str;
+        default = [];
+        description = ''
+          Command-line arguments to pass to public-inbox-mda(1).
+        '';
       };
 
-      http = {
-        mounts = mkOption {
-          type = with types; listOf str;
-          default = [ "/" ];
-          example = [ "/lists/archives" ];
-          description = ''
-            Root paths or URLs that public-inbox will be served on.
-            If domain parts are present, only requests to those
-            domains will be accepted.
-          '';
-        };
-
-        listenStreams = mkOption {
-          type = with types; listOf str;
-          default = [ "/run/public-inbox-httpd.sock" ];
-          description = ''
-            systemd.socket(5) ListenStream values for the
-            public-inbox-httpd service to listen on
-          '';
-        };
+      spamCheck = mkOption {
+        type = with types; nullOr (enum [ "spamc" ]);
+        default = "spamc";
+        description = ''
+          If set to spamc, public-inbox-mda(1) will filter spam
+          using SpamAssassin
+        '';
       };
+    };
 
-      nntp = {
-        listenStreams = mkOption {
-          type = with types; listOf str;
-          default = [ "0.0.0.0:119" "0.0.0.0:563" ];
-          description = ''
-            systemd.socket(5) ListenStream values for the
-            public-inbox-nntpd service to listen on
-          '';
-        };
-
-        cert = mkOption {
-          type = with types; nullOr str;
-          default = null;
-          example = "/path/to/fullchain.pem";
-          description = ''
-            Path to TLS certificate to use for public-inbox NNTP connections
-          '';
-        };
-
-        key = mkOption {
-          type = with types; nullOr str;
-          default = null;
-          example = "/path/to/key.pem";
-          description = ''
-            Path to TLS key to use for public-inbox NNTP connections
-          '';
-        };
+    watch = {
+      spamCheck = mkOption {
+        type = with types; nullOr (enum [ "spamc" ]);
+        default = "spamc";
+        description = ''
+          If set to spamc, public-inbox-watch(1) will filter spam
+          using SpamAssassin
+        '';
+      };
 
-        extraGroups = mkOption {
-          type = with types; listOf str;
-          default = [];
-          example = [ "tls" ];
-          description = ''
-            Secondary groups to assign to the systemd DynamicUser
-            running public-inbox-nntpd, in addition to the
-            public-inbox group.  This is useful for giving
-            public-inbox-nntpd access to a TLS certificate / key, for
-            example.
-          '';
-        };
+      watchSpam = mkOption {
+        type = with types; nullOr str;
+        default = null;
+        example = "maildir:/path/to/spam";
+        description = ''
+          If set, mail in this maildir will be trained as spam and
+          deleted from all watched inboxes
+        '';
       };
+    };
 
-      nntpServer = mkOption {
+    http = {
+      enable = mkEnableOption "the public-inbox HTTP server";
+      mounts = mkOption {
         type = with types; listOf str;
-        default = [];
-        example = [ "nntp://news.public-inbox.org" "nntps://news.public-inbox.org" ];
+        default = [ "/" ];
+        example = [ "/lists/archives" ];
         description = ''
-          NNTP URLs to this public-inbox instance
+          Root paths or URLs that public-inbox will be served on.
+          If domain parts are present, only requests to those
+          domains will be accepted.
         '';
       };
-
-      wwwListing = mkOption {
-        type = with types; enum [ "all" "404" "match=domain" ];
-        default = "404";
+      listenStreams = mkOption {
+        type = with types; listOf str;
+        default = [ "/run/public-inbox-httpd.sock" ];
         description = ''
-          Controls which lists (if any) are listed for when the root
-          public-inbox URL is accessed over HTTP.
+          systemd.socket(5) ListenStream values for the
+          public-inbox-httpd service to listen on
         '';
       };
-
-      spamAssassinRules = mkOption {
-        type = with types; nullOr path;
-        default = "${cfg.package.sa_config}/user/.spamassassin/user_prefs";
+    };
+    nntp = {
+      enable = mkEnableOption "the public-inbox NNTP server";
+      listenStreams = mkOption {
+        type = with types; listOf str;
+        default = [ "0.0.0.0:119" "0.0.0.0:563" ];
         description = ''
-          SpamAssassin configuration specific to public-inbox
+          systemd.socket(5) ListenStream values for the
+          public-inbox-nntpd service to listen on
         '';
       };
+      cert = mkOption {
+        type = with types; nullOr str;
+        default = null;
+        example = "/path/to/fullchain.pem";
+        description = "Path to TLS certificate to use for public-inbox NNTP connections";
+      };
+      key = mkOption {
+        type = with types; nullOr str;
+        default = null;
+        example = "/path/to/key.pem";
+        description = "Path to TLS key to use for public-inbox NNTP connections.";
+      };
 
-      config = mkOption {
-        type = with types; attrsOf attrs;
-        default = {};
+      extraGroups = mkOption {
+        type = with types; listOf str;
+        default = [];
+        example = [ "tls" ];
         description = ''
-          Additional structured config for the public-inbox config file
+          Secondary groups to assign to the systemd DynamicUser
+          running public-inbox-nntpd, in addition to the
+          public-inbox group.  This is useful for giving
+          public-inbox-nntpd access to a TLS certificate / key, for
+          example.
         '';
       };
     };
-  };
 
-  config = mkIf cfg.enable {
+    nntpServer = mkOption {
+      type = with types; listOf str;
+      default = [];
+      example = [ "nntp://news.public-inbox.org" "nntps://news.public-inbox.org" ];
+      description = ''
+        NNTP URLs to this public-inbox instance
+      '';
+    };
 
+    wwwListing = mkOption {
+      type = with types; enum [ "all" "404" "match=domain" ];
+      default = "404";
+      description = ''
+        Controls which lists (if any) are listed for when the root
+        public-inbox URL is accessed over HTTP.
+      '';
+    };
+
+    spamAssassinRules = mkOption {
+      type = with types; nullOr path;
+      default = "${cfg.package.sa_config}/user/.spamassassin/user_prefs";
+      description = "SpamAssassin configuration specific to public-inbox.";
+    };
+
+    config = mkOption {
+      type = with types; attrsOf attrs;
+      default = {};
+      description = ''
+        Additional structured config for the public-inbox config file
+      '';
+    };
+  };
+  config = mkIf cfg.enable {
     assertions = [
       { assertion = config.services.spamassassin.enable || !useSpamAssassin;
         message = ''
@@ -349,25 +320,38 @@ in
       }
     ];
 
-    users.users.public-inbox = {
-      inherit home;
-      group = "public-inbox";
-      isSystemUser = true;
-    };
 
-    users.groups.public-inbox = {};
+    users = {
+      users.public-inbox = {
+        # Use runCommand instead of linkFarm,
+        # because Postfix rejects .forward if it's a symlink.
+        home = pkgs.runCommand "public-inbox-home" {
+          forward = ''
+            |"env ${concatStringsSep " " envList} PATH=\"${makeBinPath cfg.path}:$PATH\" ${cfg.package}/bin/public-inbox-mda ${escapeShellArgs cfg.mda.args}
+          '';
+          passAsFile = [ "forward" ];
+        } ''
+          mkdir $out
+          ln -s ${stateDir}/spamassassin $out/.spamassassin
+          cp $forwardPath $out/.forward
+        '';
+        group = "public-inbox";
+        isSystemUser = true;
+      };
+      groups.public-inbox = {};
+    };
 
-    systemd.sockets.public-inbox-httpd = {
+    systemd.sockets.public-inbox-httpd = mkIf cfg.http.enable {
       inherit (cfg.http) listenStreams;
       wantedBy = [ "sockets.target" ];
     };
 
-    systemd.sockets.public-inbox-nntpd = {
+    systemd.sockets.public-inbox-nntpd = mkIf cfg.nntp.enable {
       inherit (cfg.nntp) listenStreams;
       wantedBy = [ "sockets.target" ];
     };
 
-    systemd.services.public-inbox-httpd = {
+    systemd.services.public-inbox-httpd = mkIf cfg.http.enable {
       inherit environment;
       serviceConfig.ExecStart = "${cfg.package}/bin/public-inbox-httpd ${psgi}";
       serviceConfig.NonBlocking = true;
@@ -375,7 +359,7 @@ in
       serviceConfig.SupplementaryGroups = [ "public-inbox" ];
     };
 
-    systemd.services.public-inbox-nntpd = {
+    systemd.services.public-inbox-nntpd = mkIf cfg.nntp.enable {
       inherit environment;
       serviceConfig.ExecStart = escapeShellArgs (
         [ "${cfg.package}/bin/public-inbox-nntpd" ] ++
@@ -398,14 +382,14 @@ in
     };
 
     system.activationScripts.public-inbox = stringAfter [ "users" ] ''
-      install -m 0755 -o public-inbox -g public-inbox -d /var/lib/public-inbox
+      install -m 0755 -o public-inbox -g public-inbox -d ${stateDir}
       install -m 0750 -o public-inbox -g public-inbox -d ${inboxesDir}
-      install -m 0700 -o public-inbox -g public-inbox -d /var/lib/public-inbox/emergency
+      install -m 0700 -o public-inbox -g public-inbox -d ${stateDir}/emergency
 
       ${optionalString useSpamAssassin ''
-        install -m 0700 -o spamd -d /var/lib/public-inbox/spamassassin
+        install -m 0700 -o spamd -d ${stateDir}/spamassassin
         ${optionalString (cfg.spamAssassinRules != null) ''
-          ln -sf ${cfg.spamAssassinRules} /var/lib/public-inbox/spamassassin/user_prefs
+          ln -sf ${cfg.spamAssassinRules} ${stateDir}/spamassassin/user_prefs
         ''}
       ''}
 
@@ -436,7 +420,7 @@ in
         fi
       '') cfg.inboxes)}
 
-      for inbox in /var/lib/public-inbox/inboxes/*/; do
+      for inbox in ${stateDir}/inboxes/*/; do
           ls -1 "$inbox" | grep -q '^xap' && continue
 
           # This should be idempotent, but only do it for new
@@ -450,6 +434,6 @@ in
     '';
 
     environment.systemPackages = with pkgs; [ cfg.package ];
-
   };
+  meta.maintainers = with lib.maintainers; [ julm ];
 }