diff options
author | V <v@unfathomable.blue> | 2021-06-09 15:43:16 +0200 |
---|---|---|
committer | V <v@unfathomable.blue> | 2021-08-17 03:09:34 +0200 |
commit | ec0965e2672899d25a5a3a8c072de3ea734076a2 (patch) | |
tree | ddf53e6cc5ae47fa1a925f7a7d6414ba03718a84 /fleet/modules/public-inbox.nix | |
parent | db7c54f92f386a94db8af7a12626d2657b4dd640 (diff) | |
download | unf-legacy-ec0965e2672899d25a5a3a8c072de3ea734076a2.tar.zst |
fleet: init
Co-authored-by: edef <edef@unfathomable.blue> Change-Id: I36d2c4cca542ed91630b1b832f3c7a7b97b33c65
Diffstat (limited to 'fleet/modules/public-inbox.nix')
-rw-r--r-- | fleet/modules/public-inbox.nix | 134 |
1 files changed, 134 insertions, 0 deletions
diff --git a/fleet/modules/public-inbox.nix b/fleet/modules/public-inbox.nix new file mode 100644 index 0000000..a8aa06b --- /dev/null +++ b/fleet/modules/public-inbox.nix @@ -0,0 +1,134 @@ +# SPDX-FileCopyrightText: V <v@unfathomable.blue> +# SPDX-License-Identifier: OSL-3.0 + +# TODO(V): Figure out what the coderepo/cgit stuff is about +# TODO(V): Consider a different architecture to what we're currently using + +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.services.public-inbox; + + environment.PI_CONFIG = "${pkgs.writeText "public-inbox-config" (generators.toGitINI public-inbox-config)}"; + + # TODO(V): Port this to a Nix type + # $ng =~ m![^A-Za-z0-9/_\.\-\~\@\+\=:]! and + # die "--newsgroup `$ng' is not valid\n"; + # ($ng =~ m!\A\.! || $ng =~ m!\.\z!) and + # die "--newsgroup `$ng' must not start or end with `.'\n"; + + public-inbox-config = recursiveUpdate { + publicinbox = mapAttrs (inbox: config: { + address = [ "${inbox}@${config.domain}" ]; + url = "https://${config.domain}/${inbox}"; # TODO(V): Allow using a different location than this + inboxdir = "/var/lib/public-inbox/${inbox}.git"; + inherit (config) watch; + }) cfg.inboxes; + } cfg.settings; + + inboxOpts = { + options = { + description = mkOption { + description = "Description of the inbox."; + type = types.str; + }; + + domain = mkOption { + description = "Domain of the inbox."; + type = types.str; + example = "example.org"; + }; + + watch = mkOption { + description = "Directory to watch for incoming mails in."; + type = types.str; + }; + }; + }; +in { + options.services.public-inbox = { + enable = mkOption { + type = types.bool; + default = false; + }; + + inboxes = mkOption { + type = with types; attrsOf (submodule inboxOpts); + default = {}; + }; + + settings = mkOption { + type = types.attrs; # TODO: Use freeformType + default = {}; + }; + }; + + config = mkIf cfg.enable { + users.users.public-inbox = { + isSystemUser = true; + group = "public-inbox"; + + home = "/var/lib/public-inbox"; + createHome = true; + }; + + users.groups.public-inbox = {}; + + systemd.services.public-inbox-init = { + description = "public-inbox mailing-list archive (initialization)"; + + wantedBy = [ "public-inbox-watch.service" "multi-user.target" ]; + before = [ "public-inbox-watch.service" ]; + + # TODO(V): Add ${pi-config.inboxdir}/description to the reload conditions, since new descriptions don't get picked up after being updated. + script = concatStrings (mapAttrsToList (inbox: config: let pi-config = public-inbox-config.publicinbox.${inbox}; in '' + ${pkgs.public-inbox-init-lite}/bin/public-inbox-init-lite ${inbox} ${pi-config.inboxdir} ${head pi-config.address} + ln -sf ${pkgs.writeText "public-inbox-description" config.description} ${pi-config.inboxdir}/description + ${pkgs.public-inbox}/bin/public-inbox-index ${pi-config.inboxdir} + '') cfg.inboxes); + + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = true; + User = "public-inbox"; + }; + }; + + # FIXME(V): Currently, if new mail appears in the mlmmj archive while public-inbox-watch is not running, it never gets added! + # This directly contradicts what the manpage states: "Upon startup, it scans the mailbox for new messages to be imported while it was not running." + # This might be a bug in public-inbox! + # We currently save a copy of all mails received by mlmmj to ensure none are lost if this happens. + systemd.services.public-inbox-watch = { + description = "public-inbox mailing-list archive (incoming mail monitor)"; + wantedBy = [ "multi-user.target" ]; + inherit environment; + serviceConfig = { + ExecStart = "${pkgs.public-inbox}/bin/public-inbox-watch"; + # TODO(V): ExecReload + User = "public-inbox"; + SupplementaryGroups = [ "mlmmj" ]; + }; + }; + + # TODO(V): Consider using public-inbox.cgi + cgiserver instead? + systemd.sockets.public-inbox-httpd = { + description = "public-inbox mailing-list archive (web server)"; + listenStreams = [ "/run/public-inbox/httpd.sock" ]; + wantedBy = [ "sockets.target" ]; + }; + + systemd.services.public-inbox-httpd = { + description = "public-inbox mailing-list archive (web server)"; + inherit environment; + serviceConfig = { + ExecStart = "${pkgs.public-inbox}/bin/public-inbox-httpd"; + DynamicUser = true; + SupplementaryGroups = [ "public-inbox" ]; + }; + }; + }; + + meta.maintainers = with maintainers; [ V ]; +} |