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