From df12a8501034ee22260c2f32e198905f91bd2474 Mon Sep 17 00:00:00 2001 From: derped Date: Mon, 1 Jul 2019 18:01:23 +0200 Subject: [PATCH] Added options for mailman3 core. --- options/mailman3/options.nix | 421 +++++++++++++++++++++++++++++++++++ 1 file changed, 421 insertions(+) create mode 100644 options/mailman3/options.nix diff --git a/options/mailman3/options.nix b/options/mailman3/options.nix new file mode 100644 index 0000000..570bb42 --- /dev/null +++ b/options/mailman3/options.nix @@ -0,0 +1,421 @@ +{ pkgs, lib, config, ... }: + +with lib; + +let + mailman3 = import ./release.nix { }; + cfg = config.services.mailman3; + usePostgresql = cfg.database.type == "postgresql"; + useSqlite = cfg.database.type == "sqlite3"; + useMysql = cfg.database.type == "mysql"; + usePostfix = cfg.mta.type == "postfix"; + configFile_postfix = pkgs.writeText "postfix.cfg" '' + [postfix] + transport_file_type: hash + postmap_command: ${pkgs.postfix}/bin/postmap + ''; + configFile = pkgs.writeText "mailman.cfg" '' + # This File was automatically generated by the mailman3 nixos submodule. + # Do not manually edit this file. + + [mailman] + site_owner: ${cfg.site_owner} + layout: custom + + [paths.custom] + archive_dir: ${cfg.paths.archive_dir} + bin_dir: ${cfg.paths.bin_dir} + cache_dir: ${cfg.paths.cache_dir} + data_dir: ${cfg.paths.data_dir} + etc_dir: ${cfg.paths.etc_dir} + lock_dir: ${cfg.paths.lock_dir} + log_dir: ${cfg.paths.log_dir} + messages_dir: ${cfg.paths.messages_dir} + template_dir: ${cfg.paths.template_dir} + var_dir: ${cfg.paths.var_dir} + lock_file: ${cfg.paths.lock_file} + pid_file: ${cfg.paths.pid_file} + + # The Database Documentation can be found here: + # https://mailman.readthedocs.io/en/latest/src/mailman/docs/database.html + # https://docs.sqlalchemy.org/en/latest/core/engines.html#database-urls + [database] + ${optionalString useSqlite '' + [database] + url: sqlite:///${cfg.database.socket} + ''} + ${optionalString usePostgresql '' + class: mailman.database.postgresql.PostgreSQLDatabase + url: postgres://${cfg.database.user}:#dbpass#@${database.host}:${toString cfg.database.port}/${cfg.database.name} + ''} + ${optionalString useMysql '' + class: mailman.database.mysql.MySQLDatabase + url: mysql+pymysql://${cfg.database.user}:#dbpass#@${cfg.database.host}:${toString cfg.database.port}/${cfg.database.name}?charset=utf8&use_unicode=1 + ''} + + [mta] + incoming: ${cfg.mta.incoming} + outgoing: ${cfg.mta.outgoing} + lmtp_host: ${cfg.mta.lmtp_host} + lmtp_port: ${toString cfg.mta.lmtp_port} + smtp_host: ${cfg.mta.smtp_host} + smtp_port: ${toString cfg.mta.smtp_port} + smtp_user: ${cfg.mta.smtp_user} + smtp_pass: #smtppass# + # One of smtp/smtps/starttls, specifies the protocol Mailman will use when + # connecting. Typically will correspond to smtp_port: 25 -> smtp, 465 -> smtps, + # 587 -> starttls. + smtp_secure_mode: smtp + configuration: ${configFile_postfix} + + [ARC] + enabled: no + + ${cfg.extraConfig} + ''; +in { + options.services.mailman3 = { + enable = mkOption { + type = types.bool; + default = false; + example = true; + description = '' + Wether to enable mailman3 mailing list management system (core). + ''; + }; + + site_owner = mkOption { + type = types.str; + default = "changeme@example.com"; + description = '' + mailman3 site owner address. + ''; + }; + + user = mkOption { + type = types.str; + default = "mailman3"; + description = '' + User account under which mailman runs. + ''; + }; + + database = { + type = mkOption { + type = types.enum [ "sqlite3" "mysql" "postgres" ]; + default = "sqlite3"; + example = "mysql"; + description = '' + Database type to use. + ''; + }; + + host = mkOption { + type = types.str; + default = "172.0.0.1"; + description = '' + Database host adress. + ''; + }; + + port = mkOption { + type = types.nullOr types.int; + default = null; + description = '' + + ''; + }; + + name = mkOption { + type = types.str; + default = "mailman3"; + description = '' + Database name. + ''; + }; + + user = mkOption { + type = types.str; + default = "mailman3"; + description = '' + Database user. + ''; + }; + + password = mkOption { + type = types.str; + default = ""; + description = '' + The password corresponding to . + Warning: this is stored in cleartext in the Nix store! + Use instead. + ''; + }; + + passwordFile = mkOption { + type = types.nullOr types.path; + default = null; + example = "/run/keys/mailman3-dbpassword"; + description = '' + A file containing the password corresponding to + . + ''; + }; + + socket = mkOption { + type = types.nullOr types.path; + default = null; + example = "/run/mysqld/mysqld.sock"; + description = "Path to the unix socket file to use for authentication."; + }; + }; + + paths = { + archive_dir = mkOption { + type = types.str; + default = "${cfg.paths.var_dir}/archives"; + description = '' + + ''; + }; + + bin_dir = mkOption { + type = types.str; + default = "${mailman3.core}/bin"; + description = '' + + ''; + }; + + cache_dir = mkOption { + type = types.str; + default = "${cfg.paths.var_dir}/cache"; + description = '' + + ''; + }; + + data_dir = mkOption { + type = types.str; + default = "${cfg.paths.var_dir}/data"; + description = '' + + ''; + }; + + etc_dir = mkOption { + type = types.str; + default = "${cfg.paths.var_dir}/etc"; + description = '' + + ''; + }; + + lock_dir = mkOption { + type = types.str; + default = "${cfg.paths.var_dir}/locks"; + description = '' + + ''; + }; + + log_dir = mkOption { + type = types.str; + default = "${cfg.paths.var_dir}/logs"; + description = '' + + ''; + }; + + messages_dir = mkOption { + type = types.str; + default = "${cfg.paths.var_dir}/messages"; + description = '' + + ''; + }; + + template_dir = mkOption { + type = types.str; + default = "${cfg.paths.var_dir}/templates"; + description = '' + + ''; + }; + + var_dir = mkOption { + type = types.str; + default = "/var/lib/mailman3"; + description = '' + + ''; + }; + + lock_file = mkOption { + type = types.path; + default = "${cfg.paths.lock_dir}/master.lck"; + description = '' + + ''; + }; + + pid_file = mkOption { + type = types.path; + default = "${cfg.paths.var_dir}/master.pid"; + description = '' + + ''; + }; + }; + + mta = { + # TODO: add Sentmail and qmail + type = mkOption { + type = types.enum [ "postfix" "exim4" ]; + default = "postfix"; + example = "exim4"; + description = '' + Database type to use. + ''; + }; + incoming = mkOption { + type = types.str; + default = "mailman.mta.${cfg.mta.type}.LMTP"; + description = '' + + ''; + }; + outgoing = mkOption { + type = types.str; + default = "mailman.mta.deliver.deliver"; + description = '' + + ''; + }; + lmtp_host = mkOption { + type = types.str; + default = "mail.example.com"; + description = '' + + ''; + }; + lmtp_port = mkOption { + type = types.int; + default = 8024; + description = '' + + ''; + }; + smtp_host = mkOption { + type = types.str; + default = "mail.example.com"; + description = '' + + ''; + }; + smtp_port = mkOption { + type = types.int; + default = 25; + description = '' + + ''; + }; + smtp_user = mkOption { + type = types.str; + default = ""; + description = '' + + ''; + }; + smtp_pass = mkOption { + type = types.str; + default = ""; + description = '' + + ''; + }; + smtp_passFile = mkOption { + type = types.str; + default = ""; + description = '' + + ''; + }; + }; + + extraConfig = mkOption { + type = types.str; + default = ""; + example = '' + [devmode] + enabled: yes + recipient: your.address@your.domain + ''; + description = '' + Configuration lines appended to the generated mailman3 configuration file. + ''; + }; + }; + + + config = mkIf cfg.enable { + users = mkIf (cfg.user == "mailman3") { + users.mailman3 = { + description = "Mailman3 Service"; + home = cfg.paths.var_dir; + createHome = true; + useDefaultShell = true; + packages = [ mailman3.core ]; + }; + }; + + services.postfix.recipientDelimiter = mkIf usePostfix (mkDefault "+"); + services.postfix.mapFiles."transport_maps" = mkIf usePostfix (mkDefault "${cfg.paths.data_dir}/postfix_lmtp"); + services.postfix.mapFiles."local_recipient_maps" = mkIf usePostfix (mkDefault "${cfg.paths.data_dir}/postfix_lmtp"); + services.postfix.mapFiles."relay_domains" = mkIf usePostfix (mkDefault "${cfg.paths.data_dir}/postfix_domains"); + + warnings = optional (cfg.database.password != "") + ''config.services.mailman3.database.password will be stored as plaintext + in the Nix store. Use database.passwordFile instead.''; + + # Create database passwordFile default when password is configured. + services.mailman3.database.passwordFile = + (mkDefault (toString (pkgs.writeTextFile { + name = "mailman3-database-password"; + text = cfg.database.password; + }))); + + systemd.services.mailman3 = { + description = "GNU Mailing List Manager"; + after = [ "network.target" ] ++ lib.optional usePostgresql "postgresql.service" ++ lib.optional useMysql "mysql.service"; + wantedBy = [ "multi-user.target" ]; + + preStart = let + dbpass = (fileContents cfg.database.passwordFile); + smtppass = (fileContents cfg.mta.smtp_passFile); + in '' + mkdir -p ${cfg.paths.etc_dir} + cp ${configFile} ${cfg.paths.etc_dir}/mailman.cfg + ${optionalString (useMysql || usePostgresql) '' + sed -e "s/#dbpass#/${dbpass}/g" -e "s/#smtppass#/${smtppass}/g" -i ${cfg.paths.etc_dir}/mailman.cfg + ''} + chmod 640 ${cfg.paths.etc_dir}/mailman.cfg + ''; + + serviceConfig = { + Type = "forking"; + User = cfg.user; + WorkingDirectory = cfg.paths.var_dir; + ExecStart = "${mailman3.core}/bin/mailman start -f"; + ExecReload = "${mailman3.core}/bin/mailman restart"; + ExecStop = "${mailman3.core}/bin/mailman stop"; + }; + + environment = { + USER = cfg.user; + HOME = cfg.paths.var_dir; + MAILMAN_CONFIG_FILE = "${cfg.paths.etc_dir}/mailman.cfg"; + }; + }; + }; +}