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