1{ config, lib, pkgs, ... }:
2
3with lib;
4
5let
6 cfg = config.services.mwlib;
7 pypkgs = pkgs.python27Packages;
8
9 inherit (pypkgs) python mwlib;
10
11 user = mkOption {
12 default = "nobody";
13 type = types.str;
14 description = "User to run as.";
15 };
16
17in
18{
19
20 options.services.mwlib = {
21
22 nserve = {
23 enable = mkOption {
24 default = false;
25 type = types.bool;
26 description = ''
27 Whether to enable nserve. Nserve is a HTTP
28 server. The Collection extension is talking to
29 that program directly. Nserve uses at least
30 one qserve instance in order to distribute
31 and manage jobs.
32 '';
33 }; # nserve.enable
34
35 port = mkOption {
36 default = 8899;
37 type = types.port;
38 description = "Specify port to listen on.";
39 }; # nserve.port
40
41 address = mkOption {
42 default = "127.0.0.1";
43 type = types.str;
44 description = "Specify network interface to listen on.";
45 }; # nserve.address
46
47 qserve = mkOption {
48 default = [ "${cfg.qserve.address}:${toString cfg.qserve.port}" ];
49 type = types.listOf types.str;
50 description = "Register qserve instance.";
51 }; # nserve.qserve
52
53 inherit user;
54 }; # nserve
55
56 qserve = {
57 enable = mkOption {
58 default = false;
59 type = types.bool;
60 description = ''
61 A job queue server used to distribute and manage
62 jobs. You should start one qserve instance
63 for each machine that is supposed to render pdf
64 files. Unless you’re operating the Wikipedia
65 installation, one machine should suffice.
66 '';
67 }; # qserve.enable
68
69 port = mkOption {
70 default = 14311;
71 type = types.port;
72 description = "Specify port to listen on.";
73 }; # qserve.port
74
75 address = mkOption {
76 default = "127.0.0.1";
77 type = types.str;
78 description = "Specify network interface to listen on.";
79 }; # qserve.address
80
81 datadir = mkOption {
82 default = "/var/lib/mwlib-qserve";
83 type = types.path;
84 description = "qserve data directory (FIXME: unused?)";
85 }; # qserve.datadir
86
87 allow = mkOption {
88 default = [ "127.0.0.1" ];
89 type = types.listOf types.str;
90 description = "List of allowed client IPs. Empty means any.";
91 }; # qserve.allow
92
93 inherit user;
94 }; # qserve
95
96 nslave = {
97 enable = mkOption {
98 default = cfg.qserve.enable;
99 type = types.bool;
100 description = ''
101 Pulls new jobs from exactly one qserve instance
102 and calls the zip and render programs
103 in order to download article collections and
104 convert them to different output formats. Nslave
105 uses a cache directory to store the generated
106 documents. Nslave also starts an internal http
107 server serving the content of the cache directory.
108 '';
109 }; # nslave.enable
110
111 cachedir = mkOption {
112 default = "/var/cache/mwlib-nslave";
113 type = types.path;
114 description = "Directory to store generated documents.";
115 }; # nslave.cachedir
116
117 numprocs = mkOption {
118 default = 10;
119 type = types.int;
120 description = "Number of parallel jobs to be executed.";
121 }; # nslave.numprocs
122
123 http = mkOption {
124 default = {};
125 description = ''
126 Internal http server serving the content of the cache directory.
127 You have to enable it, or use your own way for serving files
128 and set the http.url option accordingly.
129 '';
130 type = types.submodule ({
131 options = {
132 enable = mkOption {
133 default = true;
134 type = types.bool;
135 description = "Enable internal http server.";
136 }; # nslave.http.enable
137
138 port = mkOption {
139 default = 8898;
140 type = types.port;
141 description = "Port to listen to when serving files from cache.";
142 }; # nslave.http.port
143
144 address = mkOption {
145 default = "127.0.0.1";
146 type = types.str;
147 description = "Specify network interface to listen on.";
148 }; # nslave.http.address
149
150 url = mkOption {
151 default = "http://localhost:${toString cfg.nslave.http.port}/cache";
152 type = types.str;
153 description = ''
154 Specify URL for accessing generated files from cache.
155 The Collection extension of Mediawiki won't be able to
156 download files without it.
157 '';
158 }; # nslave.http.url
159 };
160 }); # types.submodule
161 }; # nslave.http
162
163 inherit user;
164 }; # nslave
165
166 }; # options.services
167
168 config = {
169
170 systemd.services.mwlib-nserve = mkIf cfg.nserve.enable
171 {
172 description = "mwlib network interface";
173
174 wantedBy = [ "multi-user.target" ];
175 after = [ "network.target" "mwlib-qserve.service" ];
176
177 serviceConfig = {
178 ExecStart = concatStringsSep " " (
179 [
180 "${mwlib}/bin/nserve"
181 "--port ${toString cfg.nserve.port}"
182 "--interface ${cfg.nserve.address}"
183 ] ++ cfg.nserve.qserve
184 );
185 User = cfg.nserve.user;
186 };
187 }; # systemd.services.mwlib-nserve
188
189 systemd.services.mwlib-qserve = mkIf cfg.qserve.enable
190 {
191 description = "mwlib job queue server";
192
193 wantedBy = [ "multi-user.target" ];
194
195 preStart = ''
196 mkdir -pv '${cfg.qserve.datadir}'
197 chown -Rc ${cfg.qserve.user}:`id -ng ${cfg.qserve.user}` '${cfg.qserve.datadir}'
198 chmod -Rc u=rwX,go= '${cfg.qserve.datadir}'
199 '';
200
201 serviceConfig = {
202 ExecStart = concatStringsSep " " (
203 [
204 "${mwlib}/bin/mw-qserve"
205 "-p ${toString cfg.qserve.port}"
206 "-i ${cfg.qserve.address}"
207 "-d ${cfg.qserve.datadir}"
208 ] ++ map (a: "-a ${a}") cfg.qserve.allow
209 );
210 User = cfg.qserve.user;
211 PermissionsStartOnly = true;
212 };
213 }; # systemd.services.mwlib-qserve
214
215 systemd.services.mwlib-nslave = mkIf cfg.nslave.enable
216 {
217 description = "mwlib worker";
218
219 wantedBy = [ "multi-user.target" ];
220 after = [ "network.target" ];
221
222 preStart = ''
223 mkdir -pv '${cfg.nslave.cachedir}'
224 chown -Rc ${cfg.nslave.user}:`id -ng ${cfg.nslave.user}` '${cfg.nslave.cachedir}'
225 chmod -Rc u=rwX,go= '${cfg.nslave.cachedir}'
226 '';
227
228 path = with pkgs; [ imagemagick pdftk ];
229 environment = {
230 PYTHONPATH = concatMapStringsSep ":"
231 (m: "${pypkgs.${m}}/lib/${python.libPrefix}/site-packages")
232 [ "mwlib-rl" "mwlib-ext" "pygments" "pyfribidi" ];
233 };
234
235 serviceConfig = {
236 ExecStart = concatStringsSep " " (
237 [
238 "${mwlib}/bin/nslave"
239 "--cachedir ${cfg.nslave.cachedir}"
240 "--numprocs ${toString cfg.nslave.numprocs}"
241 "--url ${cfg.nslave.http.url}"
242 ] ++ (
243 if cfg.nslave.http.enable then
244 [
245 "--serve-files-port ${toString cfg.nslave.http.port}"
246 "--serve-files-address ${cfg.nslave.http.address}"
247 ] else
248 [
249 "--no-serve-files"
250 ]
251 ));
252 User = cfg.nslave.user;
253 PermissionsStartOnly = true;
254 };
255 }; # systemd.services.mwlib-nslave
256
257 }; # config
258}