Skip to content

Commit d86f963

Browse files
authored
Merge pull request #329657 from flyingcircusio/mailpit-module
nixos/mailpit: init
2 parents 67d0a62 + f07601c commit d86f963

File tree

5 files changed

+150
-3
lines changed

5 files changed

+150
-3
lines changed

nixos/modules/module-list.nix

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -664,6 +664,7 @@
664664
./services/mail/mailcatcher.nix
665665
./services/mail/mailhog.nix
666666
./services/mail/mailman.nix
667+
./services/mail/mailpit.nix
667668
./services/mail/mlmmj.nix
668669
./services/mail/nullmailer.nix
669670
./services/mail/offlineimap.nix
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
{
2+
config,
3+
lib,
4+
pkgs,
5+
...
6+
}:
7+
8+
let
9+
inherit (config.services.mailpit) instances;
10+
inherit (lib)
11+
cli
12+
concatStringsSep
13+
const
14+
filterAttrs
15+
getExe
16+
mapAttrs'
17+
mkIf
18+
mkOption
19+
nameValuePair
20+
types
21+
;
22+
23+
isNonNull = v: v != null;
24+
genCliFlags =
25+
settings: concatStringsSep " " (cli.toGNUCommandLine { } (filterAttrs (const isNonNull) settings));
26+
in
27+
{
28+
options.services.mailpit.instances = mkOption {
29+
default = { };
30+
type = types.attrsOf (
31+
types.submodule {
32+
freeformType = types.attrsOf (
33+
types.oneOf [
34+
types.str
35+
types.int
36+
types.bool
37+
]
38+
);
39+
options = {
40+
database = mkOption {
41+
type = types.nullOr types.str;
42+
default = null;
43+
example = "mailpit.db";
44+
description = ''
45+
Specify the local database filename to store persistent data.
46+
If `null`, a temporary file will be created that will be removed when the application stops.
47+
It's recommended to specify a relative path. The database will be written into the service's
48+
state directory then.
49+
'';
50+
};
51+
max = mkOption {
52+
type = types.ints.unsigned;
53+
default = 500;
54+
description = ''
55+
Maximum number of emails to keep. If the number is exceeded, old emails
56+
will be deleted.
57+
58+
Set to `0` to never prune old emails.
59+
'';
60+
};
61+
listen = mkOption {
62+
default = "127.0.0.1:8025";
63+
type = types.str;
64+
description = ''
65+
HTTP bind interface and port for UI.
66+
'';
67+
};
68+
smtp = mkOption {
69+
default = "127.0.0.1:1025";
70+
type = types.str;
71+
description = ''
72+
SMTP bind interface and port.
73+
'';
74+
};
75+
};
76+
}
77+
);
78+
description = ''
79+
Configure mailpit instances. The attribute-set values are
80+
CLI flags passed to the `mailpit` CLI.
81+
82+
See [upstream docs](https://mailpit.axllent.org/docs/configuration/runtime-options/)
83+
for all available options.
84+
'';
85+
};
86+
87+
config = mkIf (instances != { }) {
88+
systemd.services = mapAttrs' (
89+
name: cfg:
90+
nameValuePair "mailpit-${name}" {
91+
wantedBy = [ "multi-user.target" ];
92+
after = [ "network-online.target" ];
93+
wants = [ "network-online.target" ];
94+
serviceConfig = {
95+
DynamicUser = true;
96+
StateDirectory = "mailpit";
97+
WorkingDirectory = "%S/mailpit";
98+
ExecStart = "${getExe pkgs.mailpit} ${genCliFlags cfg}";
99+
Restart = "on-failure";
100+
};
101+
}
102+
) instances;
103+
};
104+
105+
meta.maintainers = lib.teams.flyingcircus.members;
106+
}

nixos/tests/all-tests.nix

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -552,6 +552,7 @@ in {
552552
magnetico = handleTest ./magnetico.nix {};
553553
mailcatcher = handleTest ./mailcatcher.nix {};
554554
mailhog = handleTest ./mailhog.nix {};
555+
mailpit = handleTest ./mailpit.nix {};
555556
mailman = handleTest ./mailman.nix {};
556557
man = handleTest ./man.nix {};
557558
mariadb-galera = handleTest ./mysql/mariadb-galera.nix {};

nixos/tests/mailpit.nix

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import ./make-test-python.nix (
2+
{ lib, ... }:
3+
{
4+
name = "mailpit";
5+
meta.maintainers = lib.teams.flyingcircus.members;
6+
7+
nodes.machine =
8+
{ pkgs, ... }:
9+
{
10+
services.mailpit.instances.default = { };
11+
12+
environment.systemPackages = with pkgs; [ swaks ];
13+
};
14+
15+
testScript = ''
16+
start_all()
17+
18+
from json import loads
19+
20+
machine.wait_for_unit("mailpit-default.service")
21+
machine.wait_for_open_port(1025)
22+
machine.wait_for_open_port(8025)
23+
machine.succeed(
24+
'echo "this is the body of the email" | swaks --to [email protected] --body - --server localhost:1025'
25+
)
26+
27+
received = loads(machine.succeed("curl http://localhost:8025/api/v1/messages"))
28+
assert received['total'] == 1
29+
message = received["messages"][0]
30+
assert len(message['To']) == 1
31+
assert message['To'][0]['Address'] == '[email protected]'
32+
assert "this is the body of the email" in message['Snippet']
33+
'';
34+
}
35+
)

pkgs/servers/mail/mailpit/default.nix

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
fetchNpmDeps,
1111
testers,
1212
mailpit,
13+
nixosTests,
1314
}:
1415

1516
let
@@ -78,9 +79,12 @@ buildGoModule {
7879
cp -r ${ui} server/ui/dist
7980
'';
8081

81-
passthru.tests.version = testers.testVersion {
82-
package = mailpit;
83-
command = "mailpit version";
82+
passthru.tests = {
83+
inherit (nixosTests) mailpit;
84+
version = testers.testVersion {
85+
package = mailpit;
86+
command = "mailpit version";
87+
};
8488
};
8589

8690
passthru.updateScript = {

0 commit comments

Comments
 (0)