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.int; 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 youre operating the Wikipedia 65 installation, one machine should suffice. 66 ''; 67 }; # qserve.enable 68 69 port = mkOption { 70 default = 14311; 71 type = types.int; 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.int; 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 after = [ "network.target" "local-fs.target" ]; 195 196 preStart = '' 197 mkdir -pv '${cfg.qserve.datadir}' 198 chown -Rc ${cfg.qserve.user}:`id -ng ${cfg.qserve.user}` '${cfg.qserve.datadir}' 199 chmod -Rc u=rwX,go= '${cfg.qserve.datadir}' 200 ''; 201 202 serviceConfig = { 203 ExecStart = concatStringsSep " " ( 204 [ 205 "${mwlib}/bin/mw-qserve" 206 "-p ${toString cfg.qserve.port}" 207 "-i ${cfg.qserve.address}" 208 "-d ${cfg.qserve.datadir}" 209 ] ++ map (a: "-a ${a}") cfg.qserve.allow 210 ); 211 User = cfg.qserve.user; 212 PermissionsStartOnly = true; 213 }; 214 }; # systemd.services.mwlib-qserve 215 216 systemd.services.mwlib-nslave = mkIf cfg.nslave.enable 217 { 218 description = "mwlib worker"; 219 220 wantedBy = [ "multi-user.target" ]; 221 after = [ "network.target" "local-fs.target" ]; 222 223 preStart = '' 224 mkdir -pv '${cfg.nslave.cachedir}' 225 chown -Rc ${cfg.nslave.user}:`id -ng ${cfg.nslave.user}` '${cfg.nslave.cachedir}' 226 chmod -Rc u=rwX,go= '${cfg.nslave.cachedir}' 227 ''; 228 229 path = with pkgs; [ imagemagick pdftk ]; 230 environment = { 231 PYTHONPATH = concatMapStringsSep ":" 232 (m: "${pypkgs.${m}}/lib/${python.libPrefix}/site-packages") 233 [ "mwlib-rl" "mwlib-ext" "pygments" "pyfribidi" ]; 234 }; 235 236 serviceConfig = { 237 ExecStart = concatStringsSep " " ( 238 [ 239 "${mwlib}/bin/nslave" 240 "--cachedir ${cfg.nslave.cachedir}" 241 "--numprocs ${toString cfg.nslave.numprocs}" 242 "--url ${cfg.nslave.http.url}" 243 ] ++ ( 244 if cfg.nslave.http.enable then 245 [ 246 "--serve-files-port ${toString cfg.nslave.http.port}" 247 "--serve-files-address ${cfg.nslave.http.address}" 248 ] else 249 [ 250 "--no-serve-files" 251 ] 252 )); 253 User = cfg.nslave.user; 254 PermissionsStartOnly = true; 255 }; 256 }; # systemd.services.mwlib-nslave 257 258 }; # config 259}