at 17.09-beta 7.9 kB view raw
1{ config, lib, pkgs, ... }: 2 3with lib; 4 5let 6 7 cfg = config.services.zope2; 8 9 zope2Opts = { name, config, ... }: { 10 options = { 11 12 name = mkOption { 13 default = "${name}"; 14 type = types.string; 15 description = "The name of the zope2 instance. If undefined, the name of the attribute set will be used."; 16 }; 17 18 threads = mkOption { 19 default = 2; 20 type = types.int; 21 description = "Specify the number of threads that Zope's ZServer web server will use to service requests. "; 22 }; 23 24 http_address = mkOption { 25 default = "localhost:8080"; 26 type = types.string; 27 description = "Give a port and address for the HTTP server."; 28 }; 29 30 user = mkOption { 31 default = "zope2"; 32 type = types.string; 33 description = "The name of the effective user for the Zope process."; 34 }; 35 36 clientHome = mkOption { 37 default = "/var/lib/zope2/${name}"; 38 type = types.string; 39 description = "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.string; 56 description = "Extra zope.conf"; 57 }; 58 59 packages = mkOption { 60 type = types.listOf types.package; 61 description = "The list of packages you want to make available to the zope2 instance."; 62 }; 63 64 }; 65 }; 66 67in 68 69{ 70 71 ###### interface 72 73 options = { 74 75 services.zope2.instances = mkOption { 76 default = {}; 77 type = with types; attrsOf (submodule zope2Opts); 78 example = literalExample '' 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 = "zope2 instances to be created automaticaly by the system."; 99 }; 100 }; 101 102 ###### implementation 103 104 config = mkIf (cfg.instances != {}) { 105 106 users.extraUsers.zope2.uid = config.ids.uids.zope2; 107 108 systemd.services = 109 let 110 111 createZope2Instance = opts: name: 112 let 113 interpreter = pkgs.writeScript "interpreter" 114 '' 115 import sys 116 117 _interactive = True 118 if len(sys.argv) > 1: 119 _options, _args = __import__("getopt").getopt(sys.argv[1:], 'ic:m:') 120 _interactive = False 121 for (_opt, _val) in _options: 122 if _opt == '-i': 123 _interactive = True 124 elif _opt == '-c': 125 exec _val 126 elif _opt == '-m': 127 sys.argv[1:] = _args 128 _args = [] 129 __import__("runpy").run_module( 130 _val, {}, "__main__", alter_sys=True) 131 132 if _args: 133 sys.argv[:] = _args 134 __file__ = _args[0] 135 del _options, _args 136 execfile(__file__) 137 138 if _interactive: 139 del _interactive 140 __import__("code").interact(banner="", local=globals()) 141 ''; 142 env = pkgs.buildEnv { 143 name = "zope2-${name}-env"; 144 paths = [ 145 pkgs.python27 146 pkgs.python27Packages.recursivePthLoader 147 pkgs.python27Packages."plone.recipe.zope2instance" 148 ] ++ attrValues pkgs.python27.modules 149 ++ opts.packages; 150 postBuild = 151 '' 152 echo "#!$out/bin/python" > $out/bin/interpreter 153 cat ${interpreter} >> $out/bin/interpreter 154 ''; 155 }; 156 conf = pkgs.writeText "zope2-${name}-conf" 157 '' 158 %define INSTANCEHOME ${env} 159 instancehome $INSTANCEHOME 160 %define CLIENTHOME ${opts.clientHome}/${opts.name} 161 clienthome $CLIENTHOME 162 163 debug-mode off 164 security-policy-implementation C 165 verbose-security off 166 default-zpublisher-encoding utf-8 167 zserver-threads ${toString opts.threads} 168 effective-user ${opts.user} 169 170 pid-filename ${opts.clientHome}/${opts.name}/pid 171 lock-filename ${opts.clientHome}/${opts.name}/lock 172 python-check-interval 1000 173 enable-product-installation off 174 175 <environment> 176 zope_i18n_compile_mo_files false 177 </environment> 178 179 <eventlog> 180 level INFO 181 <logfile> 182 path /var/log/zope2/${name}.log 183 level INFO 184 </logfile> 185 </eventlog> 186 187 <logger access> 188 level WARN 189 <logfile> 190 path /var/log/zope2/${name}-Z2.log 191 format %(message)s 192 </logfile> 193 </logger> 194 195 <http-server> 196 address ${opts.http_address} 197 </http-server> 198 199 <zodb_db temporary> 200 <temporarystorage> 201 name temporary storage for sessioning 202 </temporarystorage> 203 mount-point /temp_folder 204 container-class Products.TemporaryFolder.TemporaryContainer 205 </zodb_db> 206 207 ${opts.extra} 208 ''; 209 ctlScript = pkgs.writeScript "zope2-${name}-ctl-script" 210 '' 211 #!${env}/bin/python 212 213 import sys 214 import plone.recipe.zope2instance.ctl 215 216 if __name__ == '__main__': 217 sys.exit(plone.recipe.zope2instance.ctl.main( 218 ["-C", "${conf}"] 219 + sys.argv[1:])) 220 ''; 221 222 ctl = pkgs.writeScript "zope2-${name}-ctl" 223 '' 224 #!${pkgs.bash}/bin/bash -e 225 export PYTHONHOME=${env} 226 exec ${ctlScript} "$@" 227 ''; 228 in { 229 #description = "${name} instance"; 230 after = [ "network.target" ]; # with RelStorage also add "postgresql.service" 231 wantedBy = [ "multi-user.target" ]; 232 path = opts.packages; 233 preStart = 234 '' 235 mkdir -p /var/log/zope2/ 236 touch /var/log/zope2/${name}.log 237 touch /var/log/zope2/${name}-Z2.log 238 chown ${opts.user} /var/log/zope2/${name}.log 239 chown ${opts.user} /var/log/zope2/${name}-Z2.log 240 241 mkdir -p ${opts.clientHome}/filestorage ${opts.clientHome}/blobstorage 242 mkdir -p ${opts.clientHome}/${opts.name} 243 chown ${opts.user} ${opts.clientHome} -R 244 245 ${ctl} adduser admin admin 246 ''; 247 248 serviceConfig.Type = "forking"; 249 serviceConfig.ExecStart = "${ctl} start"; 250 serviceConfig.ExecStop = "${ctl} stop"; 251 serviceConfig.ExecReload = "${ctl} restart"; 252 }; 253 254 in listToAttrs (map (name: { name = "zope2-${name}"; value = createZope2Instance (builtins.getAttr name cfg.instances) name; }) (builtins.attrNames cfg.instances)); 255 256 }; 257 258}