1{ config, lib, pkgs, ... }:
2
3let
4 inherit (lib) generators literalExample mkEnableOption mkIf mkOption recursiveUpdate types;
5 cfg = config.services.zeronet;
6 dataDir = "/var/lib/zeronet";
7 configFile = pkgs.writeText "zeronet.conf" (generators.toINI {} (recursiveUpdate defaultSettings cfg.settings));
8
9 defaultSettings = {
10 global = {
11 data_dir = dataDir;
12 log_dir = dataDir;
13 ui_port = cfg.port;
14 fileserver_port = cfg.fileserverPort;
15 tor = if !cfg.tor then "disable" else if cfg.torAlways then "always" else "enable";
16 };
17 };
18in with lib; {
19 options.services.zeronet = {
20 enable = mkEnableOption "zeronet";
21
22 settings = mkOption {
23 type = with types; attrsOf (oneOf [ str int bool (listOf str) ]);
24 default = {};
25 example = literalExample "global.tor = enable;";
26
27 description = ''
28 <filename>zeronet.conf</filename> configuration. Refer to
29 <link xlink:href="https://zeronet.readthedocs.io/en/latest/faq/#is-it-possible-to-use-a-configuration-file"/>
30 for details on supported values;
31 '';
32 };
33
34 port = mkOption {
35 type = types.int;
36 default = 43110;
37 example = 43110;
38 description = "Optional zeronet web UI port.";
39 };
40
41 fileserverPort = mkOption {
42 # Not optional: when absent zeronet tries to write one to the
43 # read-only config file and crashes
44 type = types.int;
45 default = 12261;
46 example = 12261;
47 description = "Zeronet fileserver port.";
48 };
49
50 tor = mkOption {
51 type = types.bool;
52 default = false;
53 description = "Use TOR for zeronet traffic where possible.";
54 };
55
56 torAlways = mkOption {
57 type = types.bool;
58 default = false;
59 description = "Use TOR for all zeronet traffic.";
60 };
61 };
62
63 config = mkIf cfg.enable {
64 services.tor = mkIf cfg.tor {
65 enable = true;
66 controlPort = 9051;
67
68 extraConfig = ''
69 CacheDirectoryGroupReadable 1
70 CookieAuthentication 1
71 CookieAuthFileGroupReadable 1
72 '';
73 };
74
75 systemd.services.zeronet = {
76 description = "zeronet";
77 after = [ "network.target" (optionalString cfg.tor "tor.service") ];
78 wantedBy = [ "multi-user.target" ];
79
80 serviceConfig = {
81 User = "zeronet";
82 DynamicUser = true;
83 StateDirectory = "zeronet";
84 SupplementaryGroups = mkIf cfg.tor [ "tor" ];
85 ExecStart = "${pkgs.zeronet}/bin/zeronet --config_file ${configFile}";
86 };
87 };
88 };
89
90 imports = [
91 (mkRemovedOptionModule [ "services" "zeronet" "dataDir" ] "Zeronet will store data by default in /var/lib/zeronet")
92 (mkRemovedOptionModule [ "services" "zeronet" "logDir" ] "Zeronet will log by default in /var/lib/zeronet")
93 ];
94
95 meta.maintainers = with maintainers; [ chiiruno ];
96}