nixos/public-inbox: add tests
This commit is contained in:
parent
8514800c42
commit
0e290442ba
3 changed files with 231 additions and 3 deletions
|
@ -355,9 +355,9 @@ in
|
|||
groups.public-inbox = {};
|
||||
};
|
||||
networking.firewall = mkIf cfg.openFirewall
|
||||
{ allowedTCPPorts = mkMerge (map (proto:
|
||||
(mkIf (cfg.${proto}.enable && types.port.check cfg.proto.port) [ cfg.proto.port ])
|
||||
["imap" "http" "nntp"]));
|
||||
{ allowedTCPPorts = mkMerge
|
||||
(map (proto: (mkIf (cfg.${proto}.enable && types.port.check cfg.${proto}.port) [ cfg.${proto}.port ]))
|
||||
["imap" "http" "nntp"]);
|
||||
};
|
||||
services.postfix = mkIf (cfg.postfix.enable && cfg.mda.enable) {
|
||||
# Not sure limiting to 1 is necessary, but better safe than sorry.
|
||||
|
|
|
@ -412,6 +412,7 @@ in
|
|||
proxy = handleTest ./proxy.nix {};
|
||||
prowlarr = handleTest ./prowlarr.nix {};
|
||||
pt2-clone = handleTest ./pt2-clone.nix {};
|
||||
public-inbox = handleTest ./public-inbox.nix {};
|
||||
pulseaudio = discoverTests (import ./pulseaudio.nix);
|
||||
qboot = handleTestOn ["x86_64-linux" "i686-linux"] ./qboot.nix {};
|
||||
quorum = handleTest ./quorum.nix {};
|
||||
|
|
227
nixos/tests/public-inbox.nix
Normal file
227
nixos/tests/public-inbox.nix
Normal file
|
@ -0,0 +1,227 @@
|
|||
import ./make-test-python.nix ({ pkgs, lib, ... }:
|
||||
let
|
||||
orga = "example";
|
||||
domain = "${orga}.localdomain";
|
||||
|
||||
tls-cert = pkgs.runCommand "selfSignedCert" { buildInputs = [ pkgs.openssl ]; } ''
|
||||
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -nodes -days 36500 \
|
||||
-subj '/CN=machine.${domain}'
|
||||
install -D -t $out key.pem cert.pem
|
||||
'';
|
||||
in
|
||||
{
|
||||
name = "public-inbox";
|
||||
|
||||
meta.maintainers = with pkgs.lib.maintainers; [ julm ];
|
||||
|
||||
machine = { config, pkgs, nodes, ... }: let
|
||||
inherit (config.services) gitolite public-inbox;
|
||||
# Git repositories paths in Gitolite.
|
||||
# Only their baseNameOf is used for configuring public-inbox.
|
||||
repositories = [
|
||||
"user/repo1"
|
||||
"user/repo2"
|
||||
];
|
||||
in
|
||||
{
|
||||
virtualisation.diskSize = 1 * 1024;
|
||||
virtualisation.memorySize = 1 * 1024;
|
||||
networking.domain = domain;
|
||||
|
||||
security.pki.certificateFiles = [ "${tls-cert}/cert.pem" ];
|
||||
# If using security.acme:
|
||||
#security.acme.certs."${domain}".postRun = ''
|
||||
# systemctl try-restart public-inbox-nntpd public-inbox-imapd
|
||||
#'';
|
||||
|
||||
services.public-inbox = {
|
||||
enable = true;
|
||||
postfix.enable = true;
|
||||
openFirewall = true;
|
||||
settings.publicinbox = {
|
||||
css = [ "href=https://machine.${domain}/style/light.css" ];
|
||||
nntpserver = [ "nntps://machine.${domain}" ];
|
||||
wwwlisting = "match=domain";
|
||||
};
|
||||
mda = {
|
||||
enable = true;
|
||||
args = [ "--no-precheck" ]; # Allow Bcc:
|
||||
};
|
||||
http = {
|
||||
enable = true;
|
||||
port = "/run/public-inbox-http.sock";
|
||||
#port = 8080;
|
||||
args = ["-W0"];
|
||||
mounts = [
|
||||
"https://machine.${domain}/inbox"
|
||||
];
|
||||
};
|
||||
nntp = {
|
||||
enable = true;
|
||||
#port = 563;
|
||||
args = ["-W0"];
|
||||
cert = "${tls-cert}/cert.pem";
|
||||
key = "${tls-cert}/key.pem";
|
||||
};
|
||||
imap = {
|
||||
enable = true;
|
||||
#port = 993;
|
||||
args = ["-W0"];
|
||||
cert = "${tls-cert}/cert.pem";
|
||||
key = "${tls-cert}/key.pem";
|
||||
};
|
||||
inboxes = lib.recursiveUpdate (lib.genAttrs (map baseNameOf repositories) (repo: {
|
||||
address = [
|
||||
# Routed to the "public-inbox:" transport in services.postfix.transport
|
||||
"${repo}@${domain}"
|
||||
];
|
||||
description = ''
|
||||
${repo}@${domain} :
|
||||
discussions about ${repo}.
|
||||
'';
|
||||
url = "https://machine.${domain}/inbox/${repo}";
|
||||
newsgroup = "inbox.comp.${orga}.${repo}";
|
||||
coderepo = [ repo ];
|
||||
}))
|
||||
{
|
||||
repo2 = {
|
||||
hide = [
|
||||
"imap" # FIXME: doesn't work for IMAP as of public-inbox 1.6.1
|
||||
"manifest"
|
||||
"www"
|
||||
];
|
||||
};
|
||||
};
|
||||
settings.coderepo = lib.listToAttrs (map (path: lib.nameValuePair (baseNameOf path) {
|
||||
dir = "/var/lib/gitolite/repositories/${path}.git";
|
||||
cgitUrl = "https://git.${domain}/${path}.git";
|
||||
}) repositories);
|
||||
};
|
||||
|
||||
# Use gitolite to store Git repositories listed in coderepo entries
|
||||
services.gitolite = {
|
||||
enable = true;
|
||||
adminPubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJmoTOQnGqX+//us5oye8UuE+tQBx9QEM7PN13jrwgqY root@localhost";
|
||||
};
|
||||
systemd.services.public-inbox-httpd = {
|
||||
serviceConfig.SupplementaryGroups = [ gitolite.group ];
|
||||
};
|
||||
|
||||
# Use nginx as a reverse proxy for public-inbox-httpd
|
||||
services.nginx = {
|
||||
enable = true;
|
||||
recommendedGzipSettings = true;
|
||||
recommendedOptimisation = true;
|
||||
recommendedTlsSettings = true;
|
||||
recommendedProxySettings = true;
|
||||
virtualHosts."machine.${domain}" = {
|
||||
forceSSL = true;
|
||||
sslCertificate = "${tls-cert}/cert.pem";
|
||||
sslCertificateKey = "${tls-cert}/key.pem";
|
||||
locations."/".return = "302 /inbox";
|
||||
locations."= /inbox".return = "302 /inbox/";
|
||||
locations."/inbox".proxyPass = "http://unix:${public-inbox.http.port}:/inbox";
|
||||
# If using TCP instead of a Unix socket:
|
||||
#locations."/inbox".proxyPass = "http://127.0.0.1:${toString public-inbox.http.port}/inbox";
|
||||
# Referred to by settings.publicinbox.css
|
||||
# See http://public-inbox.org/meta/_/text/color/
|
||||
locations."= /style/light.css".alias = pkgs.writeText "light.css" ''
|
||||
* { background:#fff; color:#000 }
|
||||
|
||||
a { color:#00f; text-decoration:none }
|
||||
a:visited { color:#808 }
|
||||
|
||||
*.q { color:#008 }
|
||||
|
||||
*.add { color:#060 }
|
||||
*.del {color:#900 }
|
||||
*.head { color:#000 }
|
||||
*.hunk { color:#960 }
|
||||
|
||||
.hl.num { color:#f30 } /* number */
|
||||
.hl.esc { color:#f0f } /* escape character */
|
||||
.hl.str { color:#f30 } /* string */
|
||||
.hl.ppc { color:#c3c } /* preprocessor */
|
||||
.hl.pps { color:#f30 } /* preprocessor string */
|
||||
.hl.slc { color:#099 } /* single-line comment */
|
||||
.hl.com { color:#099 } /* multi-line comment */
|
||||
/* .hl.opt { color:#ccc } */ /* operator */
|
||||
/* .hl.ipl { color:#ccc } */ /* interpolation */
|
||||
|
||||
/* keyword groups kw[a-z] */
|
||||
.hl.kwa { color:#f90 }
|
||||
.hl.kwb { color:#060 }
|
||||
.hl.kwc { color:#f90 }
|
||||
/* .hl.kwd { color:#ccc } */
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
services.postfix = {
|
||||
enable = true;
|
||||
setSendmail = true;
|
||||
#sslCert = "${tls-cert}/cert.pem";
|
||||
#sslKey = "${tls-cert}/key.pem";
|
||||
recipientDelimiter = "+";
|
||||
};
|
||||
|
||||
environment.systemPackages = [
|
||||
pkgs.mailutils
|
||||
pkgs.openssl
|
||||
];
|
||||
|
||||
};
|
||||
|
||||
testScript = ''
|
||||
start_all()
|
||||
machine.wait_for_unit("multi-user.target")
|
||||
machine.wait_for_unit("public-inbox-init.service")
|
||||
|
||||
# Very basic check that Gitolite can work;
|
||||
# Gitolite is not needed for the rest of this testScript
|
||||
machine.wait_for_unit("gitolite-init.service")
|
||||
|
||||
# List inboxes through public-inbox-httpd
|
||||
machine.wait_for_unit("nginx.service")
|
||||
machine.succeed("curl -L https://machine.${domain} | grep repo1@${domain}")
|
||||
# The repo2 inbox is hidden
|
||||
machine.fail("curl -L https://machine.${domain} | grep repo2@${domain}")
|
||||
machine.wait_for_unit("public-inbox-httpd.service")
|
||||
|
||||
# Send a mail and read it through public-inbox-httpd
|
||||
# Must work too when using a recipientDelimiter.
|
||||
machine.wait_for_unit("postfix.service")
|
||||
machine.succeed("mail -t <${pkgs.writeText "mail" ''
|
||||
Subject: Testing mail
|
||||
From: root@localhost
|
||||
To: repo1+extension@${domain}
|
||||
Message-ID: <repo1@root-1>
|
||||
Content-Type: text/plain; charset=utf-8
|
||||
Content-Disposition: inline
|
||||
|
||||
This is a testing mail.
|
||||
''}")
|
||||
machine.sleep(5)
|
||||
machine.succeed("curl -L 'https://machine.${domain}/inbox/repo1/repo1@root-1/T/#u' | grep 'This is a testing mail.'")
|
||||
|
||||
# Read a mail through public-inbox-imapd
|
||||
machine.wait_for_open_port(993)
|
||||
machine.wait_for_unit("public-inbox-imapd.service")
|
||||
machine.succeed("openssl s_client -ign_eof -crlf -connect machine.${domain}:993 <${pkgs.writeText "imap-commands" ''
|
||||
tag login anonymous@${domain} anonymous
|
||||
tag SELECT INBOX.comp.${orga}.repo1.0
|
||||
tag FETCH 1 (BODY[HEADER])
|
||||
tag LOGOUT
|
||||
''} | grep '^Message-ID: <repo1@root-1>'")
|
||||
|
||||
# TODO: Read a mail through public-inbox-nntpd
|
||||
#machine.wait_for_open_port(563)
|
||||
#machine.wait_for_unit("public-inbox-nntpd.service")
|
||||
|
||||
# Delete a mail.
|
||||
# Note that the use of an extension not listed in the addresses
|
||||
# require to use --all
|
||||
machine.succeed("curl -L https://machine.example.localdomain/inbox/repo1/repo1@root-1/raw | sudo -u public-inbox public-inbox-learn rm --all")
|
||||
machine.fail("curl -L https://machine.example.localdomain/inbox/repo1/repo1@root-1/T/#u | grep 'This is a testing mail.'")
|
||||
'';
|
||||
})
|
Loading…
Reference in a new issue