nixos/fcgiwrap: add option migration instruction errors

This adds migration instructions for the removed global shared instance
configuration of fcgiwrap.

Adding those explicit messages to the previous options requires moving
the newly defined options from `services.fcgiwrap.*` to
`services.fcgiwrap.instances.*` due to an option namespace clash.

`mkRenamedOptionModule` was not used because the previous options do
not directly map to the new ones. In particular, `user` and `group`
were described as setting the socket's permission, but were actually
setting the process' running user.

Co-authored-by: Minijackson <minijackson@riseup.net>
This commit is contained in:
euxane 2024-07-06 01:49:10 +02:00 committed by Herwig Hochleitner
parent c3392ad349
commit 4f2da6c9c1
6 changed files with 27 additions and 13 deletions

View File

@ -107,7 +107,7 @@
The option `services.fgciwrap` now takes an attribute set of the The option `services.fgciwrap` now takes an attribute set of the
configuration of each individual instance. configuration of each individual instance.
This requires migrating any previous configuration keys from This requires migrating any previous configuration keys from
`services.fcgiwrap.*` to `services.fcgiwrap.some-instance.*`. `services.fcgiwrap.*` to `services.fcgiwrap.instances.some-instance.*`.
The ownership and mode of the UNIX sockets created by this service are now The ownership and mode of the UNIX sockets created by this service are now
configurable and private by default. configurable and private by default.
Processes also now run as a dynamically allocated user by default instead of Processes also now run as a dynamically allocated user by default instead of

View File

@ -202,7 +202,7 @@ in {
]; ];
services = { services = {
fcgiwrap.zoneminder = lib.mkIf useNginx { fcgiwrap.instances.zoneminder = lib.mkIf useNginx {
process.prefork = cfg.cameras; process.prefork = cfg.cameras;
process.user = user; process.user = user;
process.group = group; process.group = group;
@ -255,7 +255,7 @@ in {
fastcgi_param HTTP_PROXY ""; fastcgi_param HTTP_PROXY "";
fastcgi_intercept_errors on; fastcgi_intercept_errors on;
fastcgi_pass unix:${config.services.fcgiwrap.zoneminder.socket.address}; fastcgi_pass unix:${config.services.fcgiwrap.instances.zoneminder.socket.address};
} }
location /cache/ { location /cache/ {

View File

@ -32,7 +32,7 @@ let
fastcgi_split_path_info ^(${regexLocation cfg})(/.+)$; fastcgi_split_path_info ^(${regexLocation cfg})(/.+)$;
fastcgi_param PATH_INFO $fastcgi_path_info; fastcgi_param PATH_INFO $fastcgi_path_info;
'' ''
}fastcgi_pass unix:${config.services.fcgiwrap."cgit-${name}".socket.address}; }fastcgi_pass unix:${config.services.fcgiwrap.instances."cgit-${name}".socket.address};
''; '';
cgitrcLine = name: value: "${name}=${ cgitrcLine = name: value: "${name}=${
@ -171,7 +171,7 @@ in
groups.${cfg.group} = { }; groups.${cfg.group} = { };
})); }));
services.fcgiwrap = flip mapAttrs' cfgs (name: cfg: services.fcgiwrap.instances = flip mapAttrs' cfgs (name: cfg:
nameValuePair "cgit-${name}" { nameValuePair "cgit-${name}" {
process = { inherit (cfg) user group; }; process = { inherit (cfg) user group; };
socket = { inherit (config.services.nginx) user group; }; socket = { inherit (config.services.nginx) user group; };

View File

@ -337,7 +337,7 @@ in
}; };
# use nginx to serve the smokeping web service # use nginx to serve the smokeping web service
services.fcgiwrap.smokeping = mkIf cfg.webService { services.fcgiwrap.instances.smokeping = mkIf cfg.webService {
process.user = cfg.user; process.user = cfg.user;
process.group = cfg.user; process.group = cfg.user;
socket = { inherit (config.services.nginx) user group; }; socket = { inherit (config.services.nginx) user group; };
@ -353,7 +353,7 @@ in
locations."/smokeping.fcgi" = { locations."/smokeping.fcgi" = {
extraConfig = '' extraConfig = ''
include ${config.services.nginx.package}/conf/fastcgi_params; include ${config.services.nginx.package}/conf/fastcgi_params;
fastcgi_pass unix:${config.services.fcgiwrap.smokeping.socket.address}; fastcgi_pass unix:${config.services.fcgiwrap.instances.smokeping.socket.address};
fastcgi_param SCRIPT_FILENAME ${smokepingHome}/smokeping.fcgi; fastcgi_param SCRIPT_FILENAME ${smokepingHome}/smokeping.fcgi;
fastcgi_param DOCUMENT_ROOT ${smokepingHome}; fastcgi_param DOCUMENT_ROOT ${smokepingHome};
''; '';

View File

@ -3,12 +3,26 @@
with lib; with lib;
let let
forEachInstance = f: flip mapAttrs' config.services.fcgiwrap (name: cfg: forEachInstance = f: flip mapAttrs' config.services.fcgiwrap.instances (
nameValuePair "fcgiwrap-${name}" (f cfg) name: cfg: nameValuePair "fcgiwrap-${name}" (f cfg)
); );
in { in {
options.services.fcgiwrap = mkOption { imports = forEach [
"enable"
"user"
"group"
"socketType"
"socketAddress"
"preforkProcesses"
] (attr: mkRemovedOptionModule [ "services" "fcgiwrap" attr ] ''
The global shared fcgiwrap instance is no longer supported due to
security issues.
Isolated instances should instead be configured through
`services.fcgiwrap.instances.*'.
'');
options.services.fcgiwrap.instances = mkOption {
description = "Configuration for fcgiwrap instances."; description = "Configuration for fcgiwrap instances.";
default = { }; default = { };
type = types.attrsOf (types.submodule ({ config, ... }: { options = { type = types.attrsOf (types.submodule ({ config, ... }: { options = {
@ -95,7 +109,7 @@ in {
assertion = cfg.socket.mode != null -> cfg.socket.type == "unix"; assertion = cfg.socket.mode != null -> cfg.socket.type == "unix";
message = "Socket mode can only be set for the UNIX socket type."; message = "Socket mode can only be set for the UNIX socket type.";
} }
]) config.services.fcgiwrap); ]) config.services.fcgiwrap.instances);
systemd.services = forEachInstance (cfg: { systemd.services = forEachInstance (cfg: {
after = [ "nss-user-lookup.target" ]; after = [ "nss-user-lookup.target" ];

View File

@ -24,7 +24,7 @@ import ./make-test-python.nix (
{ {
networking.firewall.allowedTCPPorts = [ 80 ]; networking.firewall.allowedTCPPorts = [ 80 ];
services.fcgiwrap.gitolite = { services.fcgiwrap.instances.gitolite = {
process.user = "gitolite"; process.user = "gitolite";
process.group = "gitolite"; process.group = "gitolite";
socket = { inherit (config.services.nginx) user group; }; socket = { inherit (config.services.nginx) user group; };
@ -64,7 +64,7 @@ import ./make-test-python.nix (
fastcgi_param SCRIPT_FILENAME ${pkgs.gitolite}/bin/gitolite-shell; fastcgi_param SCRIPT_FILENAME ${pkgs.gitolite}/bin/gitolite-shell;
# use Unix domain socket or inet socket # use Unix domain socket or inet socket
fastcgi_pass unix:${config.services.fcgiwrap.gitolite.socket.address}; fastcgi_pass unix:${config.services.fcgiwrap.instances.gitolite.socket.address};
''; '';
}; };