nixos/preload: init
[NixPkgs.git] / nixos / modules / services / web-servers / zope2.nix
bloba17fe6bc20823e98c47e35436f93c841a5cc8792
1 { config, lib, pkgs, ... }:
3 with lib;
5 let
7   cfg = config.services.zope2;
9   zope2Opts = { name, ... }: {
10     options = {
12       name = mkOption {
13         default = "${name}";
14         type = types.str;
15         description = lib.mdDoc "The name of the zope2 instance. If undefined, the name of the attribute set will be used.";
16       };
18       threads = mkOption {
19         default = 2;
20         type = types.int;
21         description = lib.mdDoc "Specify the number of threads that Zope's ZServer web server will use to service requests. ";
22       };
24       http_address = mkOption {
25         default = "localhost:8080";
26         type = types.str;
27         description = lib.mdDoc "Give a port and address for the HTTP server.";
28       };
30       user = mkOption {
31         default = "zope2";
32         type = types.str;
33         description = lib.mdDoc "The name of the effective user for the Zope process.";
34       };
36       clientHome = mkOption {
37         default = "/var/lib/zope2/${name}";
38         type = types.path;
39         description = lib.mdDoc "Home directory of zope2 instance.";
40       };
41       extra = mkOption {
42         default =
43           ''
44           <zodb_db main>
45             mount-point /
46             cache-size 30000
47             <blobstorage>
48                 blob-dir /var/lib/zope2/${name}/blobstorage
49                 <filestorage>
50                 path /var/lib/zope2/${name}/filestorage/Data.fs
51                 </filestorage>
52             </blobstorage>
53           </zodb_db>
54           '';
55         type = types.lines;
56         description = lib.mdDoc "Extra zope.conf";
57       };
59       packages = mkOption {
60         type = types.listOf types.package;
61         description = lib.mdDoc "The list of packages you want to make available to the zope2 instance.";
62       };
64     };
65   };
71   ###### interface
73   options = {
75     services.zope2.instances = mkOption {
76       default = {};
77       type = with types; attrsOf (submodule zope2Opts);
78       example = literalExpression ''
79         {
80           plone01 = {
81             http_address = "127.0.0.1:8080";
82             extra =
83               '''
84               <zodb_db main>
85                 mount-point /
86                 cache-size 30000
87                 <blobstorage>
88                     blob-dir /var/lib/zope2/plone01/blobstorage
89                     <filestorage>
90                     path /var/lib/zope2/plone01/filestorage/Data.fs
91                     </filestorage>
92                 </blobstorage>
93               </zodb_db>
94               ''';
95           };
96         }
97       '';
98       description = lib.mdDoc "zope2 instances to be created automatically by the system.";
99     };
100   };
102   ###### implementation
104   config = mkIf (cfg.instances != {}) {
106     users.users.zope2 = {
107       isSystemUser = true;
108       group = "zope2";
109     };
110     users.groups.zope2 = {};
112     systemd.services =
113       let
115         createZope2Instance = opts: name:
116           let
117             interpreter = pkgs.writeScript "interpreter"
118               ''
119               import sys
121               _interactive = True
122               if len(sys.argv) > 1:
123                   _options, _args = __import__("getopt").getopt(sys.argv[1:], 'ic:m:')
124                   _interactive = False
125                   for (_opt, _val) in _options:
126                       if _opt == '-i':
127                           _interactive = True
128                       elif _opt == '-c':
129                           exec _val
130                       elif _opt == '-m':
131                           sys.argv[1:] = _args
132                           _args = []
133                           __import__("runpy").run_module(
134                               _val, {}, "__main__", alter_sys=True)
136                   if _args:
137                       sys.argv[:] = _args
138                       __file__ = _args[0]
139                       del _options, _args
140                       execfile(__file__)
142               if _interactive:
143                   del _interactive
144                   __import__("code").interact(banner="", local=globals())
145               '';
146             env = pkgs.buildEnv {
147               name = "zope2-${name}-env";
148               paths = [
149                 pkgs.python27
150                 pkgs.python27Packages.recursivePthLoader
151                 pkgs.python27Packages."plone.recipe.zope2instance"
152               ] ++ attrValues pkgs.python27.modules
153                 ++ opts.packages;
154               postBuild =
155                 ''
156                 echo "#!$out/bin/python" > $out/bin/interpreter
157                 cat ${interpreter} >> $out/bin/interpreter
158                 '';
159             };
160             conf = pkgs.writeText "zope2-${name}-conf"
161               ''
162               %define INSTANCEHOME ${env}
163               instancehome $INSTANCEHOME
164               %define CLIENTHOME ${opts.clientHome}/${opts.name}
165               clienthome $CLIENTHOME
167               debug-mode off
168               security-policy-implementation C
169               verbose-security off
170               default-zpublisher-encoding utf-8
171               zserver-threads ${toString opts.threads}
172               effective-user ${opts.user}
174               pid-filename ${opts.clientHome}/${opts.name}/pid
175               lock-filename ${opts.clientHome}/${opts.name}/lock
176               python-check-interval 1000
177               enable-product-installation off
179               <environment>
180                 zope_i18n_compile_mo_files false
181               </environment>
183               <eventlog>
184               level INFO
185               <logfile>
186                   path /var/log/zope2/${name}.log
187                   level INFO
188               </logfile>
189               </eventlog>
191               <logger access>
192               level WARN
193               <logfile>
194                   path /var/log/zope2/${name}-Z2.log
195                   format %(message)s
196               </logfile>
197               </logger>
199               <http-server>
200               address ${opts.http_address}
201               </http-server>
203               <zodb_db temporary>
204               <temporarystorage>
205                   name temporary storage for sessioning
206               </temporarystorage>
207               mount-point /temp_folder
208               container-class Products.TemporaryFolder.TemporaryContainer
209               </zodb_db>
211               ${opts.extra}
212               '';
213             ctlScript = pkgs.writeScript "zope2-${name}-ctl-script"
214               ''
215               #!${env}/bin/python
217               import sys
218               import plone.recipe.zope2instance.ctl
220               if __name__ == '__main__':
221                   sys.exit(plone.recipe.zope2instance.ctl.main(
222                       ["-C", "${conf}"]
223                       + sys.argv[1:]))
224               '';
226             ctl = pkgs.writeScript "zope2-${name}-ctl"
227               ''
228               #!${pkgs.bash}/bin/bash -e
229               export PYTHONHOME=${env}
230               exec ${ctlScript} "$@"
231               '';
232           in {
233             #description = "${name} instance";
234             after = [ "network.target" ];  # with RelStorage also add "postgresql.service"
235             wantedBy = [ "multi-user.target" ];
236             path = opts.packages;
237             preStart =
238               ''
239               mkdir -p /var/log/zope2/
240               touch /var/log/zope2/${name}.log
241               touch /var/log/zope2/${name}-Z2.log
242               chown ${opts.user} /var/log/zope2/${name}.log
243               chown ${opts.user} /var/log/zope2/${name}-Z2.log
245               mkdir -p ${opts.clientHome}/filestorage ${opts.clientHome}/blobstorage
246               mkdir -p ${opts.clientHome}/${opts.name}
247               chown ${opts.user} ${opts.clientHome} -R
249               ${ctl} adduser admin admin
250               '';
252             serviceConfig.Type = "forking";
253             serviceConfig.ExecStart = "${ctl} start";
254             serviceConfig.ExecStop = "${ctl} stop";
255             serviceConfig.ExecReload = "${ctl} restart";
256           };
258       in listToAttrs (map (name: { name = "zope2-${name}"; value = createZope2Instance (builtins.getAttr name cfg.instances) name; }) (builtins.attrNames cfg.instances));
260   };