parent
8514800c42
commit
0e290442ba
@ -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 new issue