1 { config, lib, pkgs, ... }:
6 forEachInstance = f: flip mapAttrs' config.services.fcgiwrap.instances (
7 name: cfg: nameValuePair "fcgiwrap-${name}" (f cfg)
18 ] (attr: mkRemovedOptionModule [ "services" "fcgiwrap" attr ] ''
19 The global shared fcgiwrap instance is no longer supported due to
21 Isolated instances should instead be configured through
22 `services.fcgiwrap.instances.*'.
25 options.services.fcgiwrap.instances = mkOption {
26 description = "Configuration for fcgiwrap instances.";
28 type = types.attrsOf (types.submodule ({ config, ... }: { options = {
29 process.prefork = mkOption {
30 type = types.ints.positive;
32 description = "Number of processes to prefork.";
35 process.user = mkOption {
36 type = types.nullOr types.str;
39 User as which this instance of fcgiwrap will be run.
40 Set to `null` (the default) to use a dynamically allocated user.
44 process.group = mkOption {
45 type = types.nullOr types.str;
47 description = "Group as which this instance of fcgiwrap will be run.";
50 socket.type = mkOption {
51 type = types.enum [ "unix" "tcp" "tcp6" ];
53 description = "Socket type: 'unix', 'tcp' or 'tcp6'.";
56 socket.address = mkOption {
58 default = "/run/fcgiwrap-${config._module.args.name}.sock";
59 example = "1.2.3.4:5678";
62 In case of a UNIX socket, this should be its filesystem path.
66 socket.user = mkOption {
67 type = types.nullOr types.str;
70 User to be set as owner of the UNIX socket.
74 socket.group = mkOption {
75 type = types.nullOr types.str;
78 Group to be set as owner of the UNIX socket.
82 socket.mode = mkOption {
83 type = types.nullOr types.str;
84 default = if config.socket.type == "unix" then "0600" else null;
85 defaultText = literalExpression ''
86 if config.socket.type == "unix" then "0600" else null
89 Mode to be set on the UNIX socket.
90 Defaults to private to the socket's owner.
97 assertions = concatLists (mapAttrsToList (name: cfg: [
99 assertion = cfg.socket.type == "unix" -> cfg.socket.user != null;
100 message = "Socket owner is required for the UNIX socket type.";
103 assertion = cfg.socket.type == "unix" -> cfg.socket.group != null;
104 message = "Socket owner is required for the UNIX socket type.";
107 assertion = cfg.socket.user != null -> cfg.socket.type == "unix";
108 message = "Socket owner can only be set for the UNIX socket type.";
111 assertion = cfg.socket.group != null -> cfg.socket.type == "unix";
112 message = "Socket owner can only be set for the UNIX socket type.";
115 assertion = cfg.socket.mode != null -> cfg.socket.type == "unix";
116 message = "Socket mode can only be set for the UNIX socket type.";
118 ]) config.services.fcgiwrap.instances);
120 systemd.services = forEachInstance (cfg: {
121 after = [ "nss-user-lookup.target" ];
122 wantedBy = optional (cfg.socket.type != "unix") "multi-user.target";
126 ${pkgs.fcgiwrap}/sbin/fcgiwrap ${cli.toGNUCommandLineShell {} ({
127 c = cfg.process.prefork;
128 } // (optionalAttrs (cfg.socket.type != "unix") {
129 s = "${cfg.socket.type}:${cfg.socket.address}";
132 } // (if cfg.process.user != null then {
133 User = cfg.process.user;
134 Group = cfg.process.group;
140 systemd.sockets = forEachInstance (cfg: mkIf (cfg.socket.type == "unix") {
141 wantedBy = [ "sockets.target" ];
143 ListenStream = cfg.socket.address;
144 SocketUser = cfg.socket.user;
145 SocketGroup = cfg.socket.group;
146 SocketMode = cfg.socket.mode;