1{
2 config,
3 lib,
4 pkgs,
5 ...
6}:
7let
8
9 cfg = config.services.parsoid;
10
11 parsoid = pkgs.nodePackages.parsoid;
12
13 confTree = {
14 worker_heartbeat_timeout = 300000;
15 logging = {
16 level = "info";
17 };
18 services = [
19 {
20 module = "lib/index.js";
21 entrypoint = "apiServiceWorker";
22 conf = {
23 mwApis = map (x: if lib.isAttrs x then x else { uri = x; }) cfg.wikis;
24 serverInterface = cfg.interface;
25 serverPort = cfg.port;
26 };
27 }
28 ];
29 };
30
31 confFile = pkgs.writeText "config.yml" (
32 builtins.toJSON (lib.recursiveUpdate confTree cfg.extraConfig)
33 );
34
35in
36{
37 imports = [
38 (lib.mkRemovedOptionModule [
39 "services"
40 "parsoid"
41 "interwikis"
42 ] "Use services.parsoid.wikis instead")
43 ];
44
45 ##### interface
46
47 options = {
48
49 services.parsoid = {
50
51 enable = lib.mkOption {
52 type = lib.types.bool;
53 default = false;
54 description = ''
55 Whether to enable Parsoid -- bidirectional
56 wikitext parser.
57 '';
58 };
59
60 wikis = lib.mkOption {
61 type = lib.types.listOf (lib.types.either lib.types.str lib.types.attrs);
62 example = [ "http://localhost/api.php" ];
63 description = ''
64 Used MediaWiki API endpoints.
65 '';
66 };
67
68 workers = lib.mkOption {
69 type = lib.types.int;
70 default = 2;
71 description = ''
72 Number of Parsoid workers.
73 '';
74 };
75
76 interface = lib.mkOption {
77 type = lib.types.str;
78 default = "127.0.0.1";
79 description = ''
80 Interface to listen on.
81 '';
82 };
83
84 port = lib.mkOption {
85 type = lib.types.port;
86 default = 8000;
87 description = ''
88 Port to listen on.
89 '';
90 };
91
92 extraConfig = lib.mkOption {
93 type = lib.types.attrs;
94 default = { };
95 description = ''
96 Extra configuration to add to parsoid configuration.
97 '';
98 };
99
100 };
101
102 };
103
104 ##### implementation
105
106 config = lib.mkIf cfg.enable {
107
108 systemd.services.parsoid = {
109 description = "Bidirectional wikitext parser";
110 wantedBy = [ "multi-user.target" ];
111 after = [ "network.target" ];
112 serviceConfig = {
113 ExecStart = "${parsoid}/lib/node_modules/parsoid/bin/server.js -c ${confFile} -n ${toString cfg.workers}";
114
115 DynamicUser = true;
116 User = "parsoid";
117 Group = "parsoid";
118
119 CapabilityBoundingSet = "";
120 NoNewPrivileges = true;
121 ProtectSystem = "strict";
122 ProtectHome = true;
123 PrivateTmp = true;
124 PrivateDevices = true;
125 ProtectHostname = true;
126 ProtectKernelTunables = true;
127 ProtectKernelModules = true;
128 ProtectControlGroups = true;
129 RestrictAddressFamilies = [
130 "AF_INET"
131 "AF_INET6"
132 ];
133 RestrictNamespaces = true;
134 LockPersonality = true;
135 #MemoryDenyWriteExecute = true;
136 RestrictRealtime = true;
137 RestrictSUIDSGID = true;
138 RemoveIPC = true;
139 };
140 };
141
142 };
143
144}