From fb2fa1b50fe32e4d4f4e251b5892598f38f40a71 Mon Sep 17 00:00:00 2001 From: Alyssa Ross Date: Tue, 5 Apr 2022 10:03:25 +0000 Subject: [PATCH 1/2] nixos/postfix: pull setup into its own unit Consider a service that generates postfix lookup tables with postmap(1), like Mailman. It needs the Postfix configuration file to exist, but Postfix qmgr needs all the lookup tables its configured with to exist before it starts. So the service that runs postmap needs to run after the Postfix configuration and directory structure is generated, but before Postfix itself is started. To enable this, we split Postfix into two units: a oneshot unit that sets up the configuration, and a longrun unit that supervises the Postfix daemons. The postmap services can then be inserted in between these two units. --- nixos/modules/services/mail/mailman.nix | 3 +- nixos/modules/services/mail/postfix.nix | 39 ++++++++++++++----------- 2 files changed, 24 insertions(+), 18 deletions(-) diff --git a/nixos/modules/services/mail/mailman.nix b/nixos/modules/services/mail/mailman.nix index 0c9b38b44b24..f36abadf9d77 100644 --- a/nixos/modules/services/mail/mailman.nix +++ b/nixos/modules/services/mail/mailman.nix @@ -313,7 +313,8 @@ in { systemd.services = { mailman = { description = "GNU Mailman Master Process"; - after = [ "network.target" ]; + after = [ "network.target" ] + ++ lib.optional cfg.enablePostfix "postfix-setup.service"; restartTriggers = [ config.environment.etc."mailman.cfg".source ]; wantedBy = [ "multi-user.target" ]; serviceConfig = { diff --git a/nixos/modules/services/mail/postfix.nix b/nixos/modules/services/mail/postfix.nix index 23d3574ae27c..da14b6eef7ed 100644 --- a/nixos/modules/services/mail/postfix.nix +++ b/nixos/modules/services/mail/postfix.nix @@ -723,23 +723,10 @@ in { ${setgidGroup}.gid = config.ids.gids.postdrop; }; - systemd.services.postfix = - { description = "Postfix mail server"; - - wantedBy = [ "multi-user.target" ]; - after = [ "network.target" ]; - path = [ pkgs.postfix ]; - - serviceConfig = { - Type = "forking"; - Restart = "always"; - PIDFile = "/var/lib/postfix/queue/pid/master.pid"; - ExecStart = "${pkgs.postfix}/bin/postfix start"; - ExecStop = "${pkgs.postfix}/bin/postfix stop"; - ExecReload = "${pkgs.postfix}/bin/postfix reload"; - }; - - preStart = '' + systemd.services.postfix-setup = + { description = "Setup for Postfix mail server"; + serviceConfig.Type = "oneshot"; + script = '' # Backwards compatibility if [ ! -d /var/lib/postfix ] && [ -d /var/postfix ]; then mkdir -p /var/lib @@ -777,6 +764,24 @@ in ''; }; + systemd.services.postfix = + { description = "Postfix mail server"; + + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" "postfix-setup.service" ]; + requires = [ "postfix-setup.service" ]; + path = [ pkgs.postfix ]; + + serviceConfig = { + Type = "forking"; + Restart = "always"; + PIDFile = "/var/lib/postfix/queue/pid/master.pid"; + ExecStart = "${pkgs.postfix}/bin/postfix start"; + ExecStop = "${pkgs.postfix}/bin/postfix stop"; + ExecReload = "${pkgs.postfix}/bin/postfix reload"; + }; + }; + services.postfix.config = (mapAttrs (_: v: mkDefault v) { compatibility_level = pkgs.postfix.version; mail_owner = cfg.user; From 572131c6a945069dba5a12a0354df8254224a458 Mon Sep 17 00:00:00 2001 From: Alyssa Ross Date: Tue, 5 Apr 2022 10:10:51 +0000 Subject: [PATCH 2/2] nixos/mailman: ensure Postfix is started after Mailman On first run, Postfix will refuse to start if it's started before Mailman is up, because it'll try to read the map files generated Mailman the first time it's started, and they won't exist yet. To fix this, make sure Postfix isn't started until after Mailman is up if they're both activated at the same time. --- nixos/modules/services/mail/mailman.nix | 1 + 1 file changed, 1 insertion(+) diff --git a/nixos/modules/services/mail/mailman.nix b/nixos/modules/services/mail/mailman.nix index f36abadf9d77..eee413df56da 100644 --- a/nixos/modules/services/mail/mailman.nix +++ b/nixos/modules/services/mail/mailman.nix @@ -313,6 +313,7 @@ in { systemd.services = { mailman = { description = "GNU Mailman Master Process"; + before = lib.optional cfg.enablePostfix "postfix.service"; after = [ "network.target" ] ++ lib.optional cfg.enablePostfix "postfix-setup.service"; restartTriggers = [ config.environment.etc."mailman.cfg".source ];