feat(mail): channel → nixos-26.05 [upgrade 4/6 · bump] #107
Labels
No labels
bug
enhancement
in-progress
needs-info
needs-triage
p0
ready-for-agent
ready-for-human
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
Cloonar/nixos#107
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
▶ Hold until [3/6 · verify] is closed. Then arm: relabel
ready-for-agent.Task: bump
hosts/mail/channeltonixos-26.05; open PR. Heaviest agent work in the rollout.26.05 specifics for mail:
services.dovecot2module is converted to RFC-42-style structured settings.hosts/mail/modules/dovecot.nixcarries extensive raw config + LDAP passdb/userdb. Fix all eval breakage; preserve the LDAP auth wiring.services.postfix.sslCert/sslKeyare removed → migrate tosettings.main.smtpd_tls_chain_filesonly if used. Current config appears to usesmtpd_tls_*settings already — verify, migrate only if eval flags it. (Touches recently-hardened TLS, ADR-0016.)22.11.Acceptance: pre-commit eval green against 26.05; PR notes every dovecot/postfix/rspamd change made.
Scope addition: drop promtail on the 26.05 bump
26.05 removed
services.promtail(promtail is EOL), so this bump must also drop mail's./utils/modules/promtailimport -- otherwise eval fails on an unknown option. Mirror nb/nas: replace the import with a short comment noting central journald->loki shipping is paused pending the SEPARATE promtail->grafana-alloy migration (#118). Local journald is unaffected; alloy setup is NOT in scope here.mail is a plain promtail client -- no Loki server side to worry about.
Full agent brief will be posted when this issue is armed.
Agent Brief
Category: enhancement (channel upgrade)
Summary: Bump mail to nixos-26.05 — flip the host channel, port
services.dovecot2to its 26.05 module shape while preserving the LDAP passdb/userdb auth, handle any postfix/rspamd 26.05 option changes, and — the part the eval-only convention misses — validate the generated dovecot/postfix/rspamd configs against the 26.05 binaries, not just nix eval. Minimal diff: channel flip + forced fixes only.Current behavior:
mail tracks nixos-25.11,
system.stateVersion = "22.11". It is two keystones at once: the fleet-auth anchor (OpenLDAP — every host authenticates against it) and the production mail server (Postfix MTA, Dovecot IMAP/LMTP/sieve, rspamd).services.dovecot2with structured options (enable,enableImap,enableLmtp,mailLocation,mailUser/mailGroup,sieve.extensions,protocols) plus a large rawextraConfigblob that carries the real config:ssl_*,mail_plugins,service {}listener definitions (lmtp / doveadm / auth / imap-login / managesieve-login / quota-*),userdb/passdbblocks (driver = ldap,argspointing at runtime-generated/run/dovecot2/ldap.conf+ldap-fallback.conf), and aplugin {}block (sieve, fts lucene, quota). LDAP auth is wired by generating those two ldap.conf files in the dovecotpreStart— asedinjects thedovecot-ldap-passwordsops secret into awriteTexttemplate. A second module (the rspamd integration) also appends toservices.dovecot2.extraConfig(imapsieve +sieve_extprograms+ acallPackage'd sieve-spam-filter).services.postfixwithenable,enableSubmission,settings.main.*, and aconfig = { }block holding the main.cf body. TLS uses rawsmtpd_tls_cert_file/smtpd_tls_key_file/smtpd_tls_CAfile(ACME certs) — not theservices.postfix.sslCert/sslKeyoptions. Outbound is pinned to IPv4 (#97); TLS was hardened per ADR-0016.services.rspamdwithextraConfig,locals, and acontrollerworker with hashed passwords. Single-instance (no sharded Redis).alloymodule). The earlier "drop promtail" note on this issue is obsolete — that migration landed in #124/#125.nixpkgs.configinsecure/unfree allowances today.environmentFile(landed with #128) — no further lego change needed here.Desired behavior: mail evaluates, builds, and its generated service configs parse on the 26.05 binaries; OpenLDAP auth, IMAP/LMTP, submission, sieve, and spam filtering all keep working. Diff = channel flip + the forced fixes below.
Known 26.05 specifics for mail:
Dovecot — the headline risk, two layers:
a. Module refactor (eval-catchable). 26.05 restructures the dovecot NixOS module (reported as an RFC-42
settings-style conversion). Port the structured options to their 26.05 shape and preserve theextraConfigescape-hatch contents — or migrate them into the newsettingsinterface ifextraConfigis removed. Both the main dovecot module and the rspamd-integration module feed the dovecot config; keep both working.b. Possible Dovecot upstream major bump (runtime-only — NOT caught by eval or nix-build). Determine the dovecot version 26.05 ships. If it is a major bump (e.g. 2.3 → 2.4), the raw config syntax (
service {},userdb/passdb,plugin {},ssl_*) may use removed/renamed directives that only fail whendovecot.servicestarts. You must validate the generated dovecot config against the 26.05 dovecot binary — build the closure and run a config parse (doveconf -n/dovecotconfig-check) — and fix any syntax migration. Eval-green is necessary but not sufficient.c. Preserve the LDAP auth wiring exactly: the two runtime-generated ldap.conf files (primary + fallback), the
preStartthat injects thedovecot-ldap-passwordsops secret, and theuserdb/passdbdriver = ldapreferences. Breaking auth = total IMAP lockout for every mailbox.Postfix (low, eval-catchable):
services.postfix.sslCert/sslKeyare removed on 26.05, but mail doesn't use them (TLS is via rawsmtpd_tls_*_filekeys) — that migration is N/A; confirm. The likely chore is migrating the remainingservices.postfix.config = { }block tosettings.main(theconfigalias may be gone; the module already usessettings.mainfor one key). Keep the IPv4 outbound pin (#97) and the ADR-0016 TLS hardening intact. Runpostfix checkagainst the built config.rspamd → 4.0 (medium): confirm config compatibility. mail is single-instance, so the 4.0 sharded-Redis change doesn't apply. Watch for renamed modules/symbols in the local config (
dkim_signing,arc,dmarc,neural,phishing,milter_headers) and the controller worker password format. Confirm rspamd loads its config on 4.0.Insecure packages (low): mail carries no
permittedInsecurePackagestoday, but it will likely hit the samepypy2.7-*makePythonWriterguard nb/nas/fw hit (force-evaluated viafetch-cargo-vendor-utilfor any Rust pkg in the closure, pulled in by the users-groups shell-program-check). If eval/build flags it, addnixpkgs.config.allowInsecurePredicatepermittinglib.hasPrefix "pypy2.7-"using the same predicate shape as the other hosts (readpkg.namewith apname/versionfallback). Don't add it speculatively if eval is clean.system.stateVersionstays"22.11".Acceptance criteria:
doveconf/ parse check passes); any syntax migration applied and documented in the PR.postfix checkpasses against the built config; rspamd loads its config on 4.0.preStartwith the sops password injected;userdb/passdbstilldriver = ldap.allowInsecurePredicate(pypy2.7-prefix), justified in the PR; no leftoverpermittedInsecurePackagesthe predicate would silently disable.system.stateVersionstays"22.11"; diff limited to channel flip + required fixes.Out of scope:
environmentFilevia #128).⚠ Note for the human landing this PR (not the agent):
bentoauto-switches and restarts dovecot/postfix on deploy. Unlike a build failure (which never deploys), a config-syntax break that slips validation deploys cleanly and then kills the service on restart — a live IMAP/SMTP outage before the #108 verify. Land with a console ready, and consider pausing mail'sbento-upgradeuntil you deploy by hand.