1{ pkgs, ... }:
2
3let
4 certs = import ../common/acme/server/snakeoil-certs.nix;
5
6 serverDomain = certs.domain;
7
8 admin = {
9 username = "admin";
10 password = "snakeoilpass";
11 };
12 # An API token that we manually insert into the db as a valid one.
13 apiToken = "OVJh65sXaAfQMZ4NTcIGbFZIyBZbEZqWTi7azdDf";
14in
15{
16 name = "weblate";
17 meta.maintainers = with pkgs.lib.maintainers; [ erictapen ];
18
19 nodes.server =
20 { pkgs, lib, ... }:
21 {
22 virtualisation.memorySize = 2048;
23
24 services.weblate = {
25 enable = true;
26 localDomain = "${serverDomain}";
27 djangoSecretKeyFile = pkgs.writeText "weblate-django-secret" "thisissnakeoilsecretwithmorethan50characterscorrecthorsebatterystaple";
28 extraConfig = ''
29 # Weblate tries to fetch Avatars from the network
30 ENABLE_AVATARS = False
31 '';
32 };
33
34 services.nginx.virtualHosts."${serverDomain}" = {
35 enableACME = lib.mkForce false;
36 sslCertificate = certs."${serverDomain}".cert;
37 sslCertificateKey = certs."${serverDomain}".key;
38 };
39
40 security.pki.certificateFiles = [ certs.ca.cert ];
41
42 networking.hosts."::1" = [ "${serverDomain}" ];
43 networking.firewall.allowedTCPPorts = [
44 80
45 443
46 ];
47
48 users.users.weblate.shell = pkgs.bashInteractive;
49 };
50
51 nodes.client =
52 { pkgs, nodes, ... }:
53 {
54 environment.systemPackages = [ pkgs.wlc ];
55
56 environment.etc."xdg/weblate".text = ''
57 [weblate]
58 url = https://${serverDomain}/api/
59 key = ${apiToken}
60 '';
61
62 networking.hosts."${nodes.server.networking.primaryIPAddress}" = [ "${serverDomain}" ];
63
64 security.pki.certificateFiles = [ certs.ca.cert ];
65 };
66
67 testScript = ''
68 import json
69
70 start_all()
71 server.wait_for_unit("weblate.socket")
72 server.wait_until_succeeds("curl -f https://${serverDomain}/")
73 server.succeed("sudo -iu weblate -- weblate createadmin --username ${admin.username} --password ${admin.password} --email weblate@example.org")
74
75 # It's easier to replace the generated API token with a predefined one than
76 # to extract it at runtime.
77 server.succeed("sudo -iu weblate -- psql -d weblate -c \"UPDATE authtoken_token SET key = '${apiToken}' WHERE user_id = (SELECT id FROM weblate_auth_user WHERE username = 'admin');\"")
78
79 client.wait_for_unit("multi-user.target")
80
81 # Test the official Weblate client wlc.
82 client.wait_until_succeeds("REQUESTS_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt wlc --debug list-projects")
83
84 def call_wl_api(arg):
85 (rv, result) = client.execute("curl -H \"Content-Type: application/json\" -H \"Authorization: Token ${apiToken}\" https://${serverDomain}/api/{}".format(arg))
86 assert rv == 0
87 print(result)
88
89 call_wl_api("users/ --data '{}'".format(
90 json.dumps(
91 {"username": "test1",
92 "full_name": "test1",
93 "email": "test1@example.org"
94 })))
95
96 # TODO: Check sending and receiving email.
97 # server.wait_for_unit("postfix.service")
98
99 server.succeed("sudo -iu weblate -- weblate check")
100 # TODO: The goal is for this to succeed, but there are still some checks failing.
101 # server.succeed("sudo -iu weblate -- weblate check --deploy")
102 '';
103}