dovecot: use marker option as unit name migration indicator

In nixpkgs we expose `services.dovecot.hasNewUnitName` option that can be
safely inspected to understand that whether to use the `dovecot` systemd
service name instead of `dovecot2`.
This commit is contained in:
Martin Weinelt 2025-07-06 23:57:22 +02:00
parent 6004878dc6
commit d6d2053b80
No known key found for this signature in database
GPG key ID: 87C1E9888F856759
7 changed files with 89 additions and 45 deletions

View file

@ -16,6 +16,7 @@
{ {
config, config,
options,
pkgs, pkgs,
lib, lib,
}: }:
@ -86,4 +87,6 @@ in
chmod 600 ${destination} chmod 600 ${destination}
''; '';
dovecotUnitName = if options.services.dovecot2 ? hasNewUnitName then "dovecot" else "dovecot2";
} }

View file

@ -16,22 +16,24 @@
{ {
config, config,
options,
pkgs, pkgs,
lib, lib,
... ...
}: }:
with (import ./common.nix { inherit config pkgs lib; }); with (import ./common.nix {
inherit
config
options
pkgs
lib
;
});
let let
cfg = config.mailserver; cfg = config.mailserver;
dovecotPreStart =
''
${genPasswdScript}
''
+ (lib.optionalString cfg.ldap.enable setPwdInLdapConfFile);
passwdDir = "/run/dovecot2"; passwdDir = "/run/dovecot2";
passwdFile = "${passwdDir}/passwd"; passwdFile = "${passwdDir}/passwd";
userdbFile = "${passwdDir}/userdb"; userdbFile = "${passwdDir}/userdb";
@ -445,10 +447,13 @@ in
''; '';
}; };
systemd.services.dovecot.preStart = lib.mkIf (config.systemd.services ? "dovecot") dovecotPreStart; systemd.services.${dovecotUnitName} = {
systemd.services.dovecot2.preStart = lib.mkIf ( preStart =
config.systemd.services ? "dovecot2" ''
) dovecotPreStart; ${genPasswdScript}
''
+ (lib.optionalString cfg.ldap.enable setPwdInLdapConfFile);
};
systemd.services.postfix.restartTriggers = [ systemd.services.postfix.restartTriggers = [
genPasswdScript genPasswdScript

View file

@ -16,12 +16,20 @@
{ {
config, config,
options,
pkgs, pkgs,
lib, lib,
... ...
}: }:
with (import ./common.nix { inherit config lib pkgs; }); with (import ./common.nix {
inherit
config
options
lib
pkgs
;
});
let let
cfg = config.mailserver; cfg = config.mailserver;
@ -42,7 +50,7 @@ in
security.acme.certs."${cfg.acmeCertificateName}".reloadServices = [ security.acme.certs."${cfg.acmeCertificateName}".reloadServices = [
"postfix.service" "postfix.service"
"dovecot2.service" "${dovecotUnitName}.service"
]; ];
}; };
} }

View file

@ -16,12 +16,20 @@
{ {
config, config,
options,
pkgs, pkgs,
lib, lib,
... ...
}: }:
with (import ./common.nix { inherit config pkgs lib; }); with (import ./common.nix {
inherit
config
options
lib
pkgs
;
});
let let
inherit (lib.strings) concatStringsSep; inherit (lib.strings) concatStringsSep;

View file

@ -16,11 +16,21 @@
{ {
config, config,
options,
pkgs, pkgs,
lib, lib,
... ...
}: }:
with (import ./common.nix {
inherit
config
options
lib
pkgs
;
});
let let
cfg = config.mailserver; cfg = config.mailserver;
certificatesDeps = certificatesDeps =
@ -31,25 +41,6 @@ let
else else
[ "acme-finished-${cfg.fqdn}.target" ]; [ "acme-finished-${cfg.fqdn}.target" ];
dovecotUnitSettings = {
wants = certificatesDeps;
after = certificatesDeps;
preStart =
let
directories = lib.strings.escapeShellArgs (
[ cfg.mailDirectory ] ++ lib.optional (cfg.indexDir != null) cfg.indexDir
);
in
''
# Create mail directory and set permissions. See
# <https://doc.dovecot.org/main/core/config/shared_mailboxes.html#filesystem-permissions-1>.
# Prevent world-readable paths, even temporarily.
umask 007
mkdir -p ${directories}
chgrp "${cfg.vmailGroupName}" ${directories}
chmod 02770 ${directories}
'';
};
in in
{ {
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
@ -80,15 +71,34 @@ in
}; };
# Create maildir folder before dovecot startup # Create maildir folder before dovecot startup
systemd.services.dovecot = dovecotUnitSettings; systemd.services.${dovecotUnitName} = {
# TODO: remove after 25.11 release wants = certificatesDeps;
systemd.services.dovecot2 = dovecotUnitSettings; after = certificatesDeps;
preStart =
let
directories = lib.strings.escapeShellArgs (
[ cfg.mailDirectory ] ++ lib.optional (cfg.indexDir != null) cfg.indexDir
);
in
''
# Create mail directory and set permissions. See
# <https://doc.dovecot.org/main/core/config/shared_mailboxes.html#filesystem-permissions-1>.
# Prevent world-readable paths, even temporarily.
umask 007
mkdir -p ${directories}
chgrp "${cfg.vmailGroupName}" ${directories}
chmod 02770 ${directories}
'';
};
# Postfix requires dovecot lmtp socket, dovecot auth socket and certificate to work # Postfix requires dovecot lmtp socket, dovecot auth socket and certificate to work
systemd.services.postfix = { systemd.services.postfix = {
wants = certificatesDeps; wants = certificatesDeps;
after = [ "dovecot2.service" ] ++ lib.optional cfg.dkimSigning "rspamd.service" ++ certificatesDeps; after =
requires = [ "dovecot2.service" ] ++ lib.optional cfg.dkimSigning "rspamd.service"; [ "${dovecotUnitName}.service" ]
++ lib.optional cfg.dkimSigning "rspamd.service"
++ certificatesDeps;
requires = [ "${dovecotUnitName}.service" ] ++ lib.optional cfg.dkimSigning "rspamd.service";
}; };
}; };
} }

View file

@ -16,11 +16,21 @@
{ {
config, config,
options,
pkgs, pkgs,
lib, lib,
... ...
}: }:
with (import ./common.nix {
inherit
config
options
lib
pkgs
;
});
with config.mailserver; with config.mailserver;
let let
@ -107,7 +117,7 @@ in
systemd.services.activate-virtual-mail-users = { systemd.services.activate-virtual-mail-users = {
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
before = [ "dovecot2.service" ]; before = [ "${dovecotUnitName}.service" ];
serviceConfig = { serviceConfig = {
ExecStart = virtualMailUsersActivationScript; ExecStart = virtualMailUsersActivationScript;
}; };

View file

@ -490,9 +490,9 @@
server.wait_until_fails('[ "$(postqueue -p)" != "Mail queue is empty" ]') server.wait_until_fails('[ "$(postqueue -p)" != "Mail queue is empty" ]')
client.succeed("imap-mark-spam >&2") client.succeed("imap-mark-spam >&2")
server.wait_until_succeeds("journalctl -u dovecot2 | grep -i rspamd-learn-spam.sh >&2") server.wait_until_succeeds("journalctl -u dovecot -u dovecot2 | grep -i rspamd-learn-spam.sh >&2")
client.succeed("imap-mark-ham >&2") client.succeed("imap-mark-ham >&2")
server.wait_until_succeeds("journalctl -u dovecot2 | grep -i rspamd-learn-ham.sh >&2") server.wait_until_succeeds("journalctl -u dovecot -u dovecot2 | grep -i rspamd-learn-ham.sh >&2")
with subtest("full text search and indexation"): with subtest("full text search and indexation"):
# send 2 email from user2 to user1 # send 2 email from user2 to user1
@ -510,9 +510,9 @@
# should fail because this folder is not indexed # should fail because this folder is not indexed
client.fail("search Junk a >&2") client.fail("search Junk a >&2")
# check that search really goes through the indexer # check that search really goes through the indexer
server.succeed("journalctl -u dovecot2 | grep 'fts-flatcurve(INBOX): Query ' >&2") server.succeed("journalctl -u dovecot -u dovecot2 | grep 'fts-flatcurve(INBOX): Query ' >&2")
# check that Junk is not indexed # check that Junk is not indexed
server.fail("journalctl -u dovecot2 | grep 'fts-flatcurve(JUNK): Indexing ' >&2") server.fail("journalctl -u dovecot -u dovecot2 | grep 'fts-flatcurve(JUNK): Indexing ' >&2")
with subtest("dmarc reporting"): with subtest("dmarc reporting"):
server.systemctl("start rspamd-dmarc-reporter.service") server.systemctl("start rspamd-dmarc-reporter.service")
@ -520,10 +520,10 @@
with subtest("no warnings or errors"): with subtest("no warnings or errors"):
server.fail("journalctl -u postfix | grep -i error >&2") server.fail("journalctl -u postfix | grep -i error >&2")
server.fail("journalctl -u postfix | grep -i warning >&2") server.fail("journalctl -u postfix | grep -i warning >&2")
server.fail("journalctl -u dovecot2 | grep -v 'imap-login: Debug: SSL error: Connection closed' | grep -i error >&2") server.fail("journalctl -u dovecot -u dovecot2 | grep -v 'imap-login: Debug: SSL error: Connection closed' | grep -i error >&2")
# harmless ? https://dovecot.org/pipermail/dovecot/2020-August/119575.html # harmless ? https://dovecot.org/pipermail/dovecot/2020-August/119575.html
server.fail( server.fail(
"journalctl -u dovecot2 | \ "journalctl -u dovecot -u dovecot2 | \
grep -v 'Expunged message reappeared, giving a new UID' | \ grep -v 'Expunged message reappeared, giving a new UID' | \
grep -v 'Time moved forwards' | \ grep -v 'Time moved forwards' | \
grep -i warning >&2" grep -i warning >&2"