29027fd1e1
Using pkgs.lib on the spine of module evaluation is problematic because the pkgs argument depends on the result of module evaluation. To prevent an infinite recursion, pkgs and some of the modules are evaluated twice, which is inefficient. Using ‘with lib’ prevents this problem.
258 lines
7.7 KiB
Nix
258 lines
7.7 KiB
Nix
{ config, lib, pkgs, ... }:
|
|
|
|
with lib;
|
|
|
|
let
|
|
|
|
cfg = config.services.zope2;
|
|
|
|
zope2Opts = { name, config, ... }: {
|
|
options = {
|
|
|
|
name = mkOption {
|
|
default = "${name}";
|
|
type = types.string;
|
|
description = "The name of the zope2 instance. If undefined, the name of the attribute set will be used.";
|
|
};
|
|
|
|
threads = mkOption {
|
|
default = 2;
|
|
type = types.int;
|
|
description = "Specify the number of threads that Zope's ZServer web server will use to service requests. ";
|
|
};
|
|
|
|
http_address = mkOption {
|
|
default = "localhost:8080";
|
|
type = types.string;
|
|
description = "Give a port and adress for the HTTP server.";
|
|
};
|
|
|
|
user = mkOption {
|
|
default = "zope2";
|
|
type = types.string;
|
|
description = "The name of the effective user for the Zope process.";
|
|
};
|
|
|
|
clientHome = mkOption {
|
|
default = "/var/lib/zope2/${name}";
|
|
type = types.string;
|
|
description = "Home directory of zope2 instance.";
|
|
};
|
|
extra = mkOption {
|
|
default =
|
|
''
|
|
<zodb_db main>
|
|
mount-point /
|
|
cache-size 30000
|
|
<blobstorage>
|
|
blob-dir /var/lib/zope2/${name}/blobstorage
|
|
<filestorage>
|
|
path /var/lib/zope2/${name}/filestorage/Data.fs
|
|
</filestorage>
|
|
</blobstorage>
|
|
</zodb_db>
|
|
'';
|
|
type = types.string;
|
|
description = "Extra zope.conf";
|
|
};
|
|
|
|
packages = mkOption {
|
|
type = types.listOf types.package;
|
|
description = "The list of packages you want to make available to the zope2 instance.";
|
|
};
|
|
|
|
};
|
|
};
|
|
|
|
in
|
|
|
|
{
|
|
|
|
###### interface
|
|
|
|
options = {
|
|
|
|
services.zope2.instances = mkOption {
|
|
default = {};
|
|
type = types.loaOf types.optionSet;
|
|
example = {
|
|
plone01 = {
|
|
http_address = "127.0.0.1:8080";
|
|
extra =
|
|
''
|
|
<zodb_db main>
|
|
mount-point /
|
|
cache-size 30000
|
|
<blobstorage>
|
|
blob-dir /var/lib/zope2/plone01/blobstorage
|
|
<filestorage>
|
|
path /var/lib/zope2/plone01/filestorage/Data.fs
|
|
</filestorage>
|
|
</blobstorage>
|
|
</zodb_db>
|
|
'';
|
|
|
|
};
|
|
};
|
|
description = "zope2 instances to be created automaticaly by the system.";
|
|
options = [ zope2Opts ];
|
|
};
|
|
};
|
|
|
|
###### implementation
|
|
|
|
config = mkIf (cfg.instances != {}) {
|
|
|
|
users.extraUsers.zope2.uid = config.ids.uids.zope2;
|
|
|
|
systemd.services =
|
|
let
|
|
|
|
createZope2Instance = opts: name:
|
|
let
|
|
interpreter = pkgs.writeScript "interpreter"
|
|
''
|
|
import sys
|
|
|
|
_interactive = True
|
|
if len(sys.argv) > 1:
|
|
_options, _args = __import__("getopt").getopt(sys.argv[1:], 'ic:m:')
|
|
_interactive = False
|
|
for (_opt, _val) in _options:
|
|
if _opt == '-i':
|
|
_interactive = True
|
|
elif _opt == '-c':
|
|
exec _val
|
|
elif _opt == '-m':
|
|
sys.argv[1:] = _args
|
|
_args = []
|
|
__import__("runpy").run_module(
|
|
_val, {}, "__main__", alter_sys=True)
|
|
|
|
if _args:
|
|
sys.argv[:] = _args
|
|
__file__ = _args[0]
|
|
del _options, _args
|
|
execfile(__file__)
|
|
|
|
if _interactive:
|
|
del _interactive
|
|
__import__("code").interact(banner="", local=globals())
|
|
'';
|
|
env = pkgs.buildEnv {
|
|
name = "zope2-${name}-env";
|
|
paths = [
|
|
pkgs.python27
|
|
pkgs.python27Packages.recursivePthLoader
|
|
pkgs.python27Packages."plone.recipe.zope2instance"
|
|
] ++ attrValues pkgs.python27.modules
|
|
++ opts.packages;
|
|
postBuild =
|
|
''
|
|
echo "#!$out/bin/python" > $out/bin/interpreter
|
|
cat ${interpreter} >> $out/bin/interpreter
|
|
'';
|
|
};
|
|
conf = pkgs.writeText "zope2-${name}-conf"
|
|
''
|
|
%define INSTANCEHOME ${env}
|
|
instancehome $INSTANCEHOME
|
|
%define CLIENTHOME ${opts.clientHome}/${opts.name}
|
|
clienthome $CLIENTHOME
|
|
|
|
debug-mode off
|
|
security-policy-implementation C
|
|
verbose-security off
|
|
default-zpublisher-encoding utf-8
|
|
zserver-threads ${toString opts.threads}
|
|
effective-user ${opts.user}
|
|
|
|
pid-filename ${opts.clientHome}/${opts.name}/pid
|
|
lock-filename ${opts.clientHome}/${opts.name}/lock
|
|
python-check-interval 1000
|
|
enable-product-installation off
|
|
|
|
<environment>
|
|
zope_i18n_compile_mo_files false
|
|
</environment>
|
|
|
|
<eventlog>
|
|
level INFO
|
|
<logfile>
|
|
path /var/log/zope2/${name}.log
|
|
level INFO
|
|
</logfile>
|
|
</eventlog>
|
|
|
|
<logger access>
|
|
level WARN
|
|
<logfile>
|
|
path /var/log/zope2/${name}-Z2.log
|
|
format %(message)s
|
|
</logfile>
|
|
</logger>
|
|
|
|
<http-server>
|
|
address ${opts.http_address}
|
|
</http-server>
|
|
|
|
<zodb_db temporary>
|
|
<temporarystorage>
|
|
name temporary storage for sessioning
|
|
</temporarystorage>
|
|
mount-point /temp_folder
|
|
container-class Products.TemporaryFolder.TemporaryContainer
|
|
</zodb_db>
|
|
|
|
${opts.extra}
|
|
'';
|
|
ctlScript = pkgs.writeScript "zope2-${name}-ctl-script"
|
|
''
|
|
#!${env}/bin/python
|
|
|
|
import sys
|
|
import plone.recipe.zope2instance.ctl
|
|
|
|
if __name__ == '__main__':
|
|
sys.exit(plone.recipe.zope2instance.ctl.main(
|
|
["-C", "${conf}"]
|
|
+ sys.argv[1:]))
|
|
'';
|
|
|
|
ctl = pkgs.writeScript "zope2-${name}-ctl"
|
|
''
|
|
#!${pkgs.bash}/bin/bash -e
|
|
export PYTHONHOME=${env}
|
|
exec ${ctlScript} "$@"
|
|
'';
|
|
in {
|
|
#description = "${name} instance";
|
|
after = [ "network.target" ]; # with RelStorage also add "postgresql.service"
|
|
wantedBy = [ "multi-user.target" ];
|
|
path = opts.packages;
|
|
preStart =
|
|
''
|
|
mkdir -p /var/log/zope2/
|
|
touch /var/log/zope2/${name}.log
|
|
touch /var/log/zope2/${name}-Z2.log
|
|
chown ${opts.user} /var/log/zope2/${name}.log
|
|
chown ${opts.user} /var/log/zope2/${name}-Z2.log
|
|
|
|
mkdir -p ${opts.clientHome}/filestorage ${opts.clientHome}/blobstorage
|
|
mkdir -p ${opts.clientHome}/${opts.name}
|
|
chown ${opts.user} ${opts.clientHome} -R
|
|
|
|
${ctl} adduser admin admin
|
|
'';
|
|
|
|
serviceConfig.Type = "forking";
|
|
serviceConfig.ExecStart = "${ctl} start";
|
|
serviceConfig.ExecStop = "${ctl} stop";
|
|
serviceConfig.ExecReload = "${ctl} restart";
|
|
};
|
|
|
|
in listToAttrs (map (name: { name = "zope2-${name}"; value = createZope2Instance (builtins.getAttr name cfg.instances) name; }) (builtins.attrNames cfg.instances));
|
|
|
|
};
|
|
|
|
}
|