Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions nixos/doc/manual/release-notes/rl-1903.xml
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,18 @@
reset to the default value (<literal>false</literal>).
</para>
</listitem>
<listitem>
<para>
The <literal>services.fcgiwrap</literal> module has been converted to use
socket activation with <literal>systemd</literal>. You can now
configure the owner, group and mode of a unix socket. The service
won't be started as <literal>root</literal> anymore by default and the option
<literal>services.fcgiwrap.socketType</literal> was removed because
<literal>services.fcgiwrap.socketAddress</literal> now takes
addresses as defined in
<citerefentry><refentrytitle>systemd.socket</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
</para>
</listitem>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should there also be a note about socket restarts in here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, yeah. you're right. Adding socking restart support is kind of a bugfix though. I'll add a paragraph.

</itemizedlist>
</section>

Expand Down
1 change: 1 addition & 0 deletions nixos/modules/rename.nix
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,7 @@ with lib;
(mkRemovedOptionModule [ "virtualisation" "xen" "qemu" ] "You don't need this option anymore, it will work without it.")
(mkRemovedOptionModule [ "services" "logstash" "enableWeb" ] "The web interface was removed from logstash")
(mkRemovedOptionModule [ "boot" "zfs" "enableLegacyCrypto" ] "The corresponding package was removed from nixpkgs.")
(mkRemovedOptionModule [ "services" "fcgiwrap" "socketType" ] "Use services.fcgiwrap.socketAddress to specify the socket type instead.")

# ZSH
(mkRenamedOptionModule [ "programs" "zsh" "enableSyntaxHighlighting" ] [ "programs" "zsh" "syntaxHighlighting" "enable" ])
Expand Down
60 changes: 37 additions & 23 deletions nixos/modules/services/web-servers/fcgiwrap.nix
Original file line number Diff line number Diff line change
Expand Up @@ -20,28 +20,44 @@ in {
description = "Number of processes to prefork.";
};

socketType = mkOption {
type = types.enum [ "unix" "tcp" "tcp6" ];
default = "unix";
description = "Socket type: 'unix', 'tcp' or 'tcp6'.";
};

socketAddress = mkOption {
type = types.str;
default = "/run/fcgiwrap.sock";
example = "1.2.3.4:5678";
description = "Socket address. In case of a UNIX socket, this should be its filesystem path.";
description = ''
Socket address as defined in
<citerefentry><refentrytitle>systemd.socket</refentrytitle><manvolnum>5</manvolnum></citerefentry>
for <literal>ListemStream</literal>.
'';
};

socketUser = mkOption {
type = types.str;
default = "root";
description = "Owner of the socket if it is defined as a Unix socket.";
};

socketGroup = mkOption {
type = types.str;
default = "root";
description = "Group of the socket if it is defined as a Unix socket.";
};

socketMode = mkOption {
type = types.str;
default = "0660";
description = "File mode of the socket if it is defined as a Unix socket.";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest we don't bikeshed this PR on this discussion, but…

Would it maybe make sense to make a socket type which contains all these options, since it may well be used in multiple places? It doesn't seem that nice to have these settings which are essentially aliases for systemd.sockets.fcgiwrap.socketConfig.*.

};

user = mkOption {
type = types.nullOr types.str;
default = null;
type = types.str;
default = "nobody";
description = "User permissions for the socket.";
};

group = mkOption {
type = types.nullOr types.str;
default = null;
type = types.str;
default = "nogroup";
description = "Group permissions for the socket.";
};
};
Expand All @@ -50,23 +66,21 @@ in {
config = mkIf cfg.enable {
systemd.services.fcgiwrap = {
after = [ "nss-user-lookup.target" ];
wantedBy = optional (cfg.socketType != "unix") "multi-user.target";

serviceConfig = {
ExecStart = "${pkgs.fcgiwrap}/sbin/fcgiwrap -c ${builtins.toString cfg.preforkProcesses} ${
if (cfg.socketType != "unix") then "-s ${cfg.socketType}:${cfg.socketAddress}" else ""
}";
} // (if cfg.user != null && cfg.group != null then {
ExecStart = "${pkgs.fcgiwrap}/sbin/fcgiwrap -c ${toString cfg.preforkProcesses}";
User = cfg.user;
Group = cfg.group;
} else { } );
};
};

systemd.sockets = if (cfg.socketType == "unix") then {
fcgiwrap = {
wantedBy = [ "sockets.target" ];
socketConfig.ListenStream = cfg.socketAddress;
systemd.sockets.fcgiwrap = {
wantedBy = [ "sockets.target" ];
socketConfig = {
ListenStream = cfg.socketAddress;
SocketUser = cfg.socketUser;
SocketGroup = cfg.socketGroup;
SocketMode = cfg.socketMode;
};
} else { };
};
};
}
12 changes: 11 additions & 1 deletion nixos/modules/system/activation/switch-to-configuration.pl
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,17 @@ sub fingerprintUnit {
# Reload the changed mount unit to force a remount.
$unitsToReload{$unit} = 1;
recordUnit($reloadListFile, $unit);
} elsif ($unit =~ /\.socket$/ || $unit =~ /\.path$/ || $unit =~ /\.slice$/) {
} elsif ($unit =~ /\.socket$/) {
my $unitInfo = parseUnit($newUnitFile);
# If a socket unit has been changed, the corresponding
# service unit has to be stopped before the socket can
# be restarted.
my $serviceUnit = $unitInfo->{'Unit'} // "$baseName.service";
$unitsToStop{$serviceUnit} = 1;
$unitsToStop{$unit} = 1;
$unitsToStart{$unit} = 1;
recordUnit($startListFile, $unit);
} elsif ($unit =~ /\.path$/ || $unit =~ /\.slice$/) {
# FIXME: do something?
} else {
my $unitInfo = parseUnit($newUnitFile);
Expand Down
1 change: 1 addition & 0 deletions nixos/tests/all-tests.nix
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ in
elk = handleTestOn ["x86_64-linux"] ./elk.nix {};
env = handleTest ./env.nix {};
etcd = handleTestOn ["x86_64-linux"] ./etcd.nix {};
fcgiwrap = handleTest ./fcgiwrap.nix {};
ferm = handleTest ./ferm.nix {};
firefox = handleTest ./firefox.nix {};
firewall = handleTest ./firewall.nix {};
Expand Down
54 changes: 54 additions & 0 deletions nixos/tests/fcgiwrap.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import ./make-test.nix ({ pkgs, lib, ... }:

let
helloScript = pkgs.writeShellScriptBin "hello" ''
echo "Status: 200 OK"
echo
echo "$out says: Hello World!"
'';

mkServer = extraConfig: { ... }:
lib.mkMerge [
{ services.fcgiwrap.enable = true;
services.nginx.enable = true;
services.nginx.commonHttpConfig = ''
error_log syslog:server=unix:/dev/log;
access_log syslog:server=unix:/dev/log;
'';
services.nginx.virtualHosts."_".locations."/".extraConfig = ''
fastcgi_param SCRIPT_FILENAME ${helloScript}/bin/hello;
fastcgi_pass unix:/run/fcgiwrap.sock;
'';
}
extraConfig
];

in

{ name = "fcgiwrap";
meta = with pkgs.stdenv.lib.maintainers;
{ maintainers = [ fpletz ]; };

nodes = {
working = mkServer {
services.fcgiwrap.socketGroup = "nginx";
};

permissionfail = mkServer {
services.fcgiwrap.socketGroup = "root";
};
};

testScript = { nodes, ... }: let
permissionfail = nodes.permissionfail.config.system.build.toplevel;
in ''
$working->start;

$working->waitForUnit("nginx");
$working->waitForOpenPort("80");
$working->succeed("curl http://localhost/ | tee /dev/stderr | grep 'Hello World!'");

$working->succeed("${permissionfail}/bin/switch-to-configuration test");
$working->fail("curl -f http://localhost/");
'';
})
11 changes: 10 additions & 1 deletion pkgs/servers/fcgiwrap/default.nix
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{ stdenv, fetchurl, systemd, fcgi, autoreconfHook, pkgconfig }:
{ stdenv, fetchurl, fetchpatch, systemd, fcgi, autoreconfHook, pkgconfig }:

stdenv.mkDerivation rec {
name = "fcgiwrap-${version}";
Expand All @@ -9,6 +9,15 @@ stdenv.mkDerivation rec {
sha256 = "07y6s4mm86cv7p1ljz94sxnqa89y9amn3vzwsnbq5hrl4vdy0zac";
};

patches = [
# Support for custom working dir with the FCGI_CHDIR environment variable.
# https://github.com/gnosek/fcgiwrap/pull/21
(fetchpatch {
url = "https://github.com/gnosek/fcgiwrap/commit/caf1f5c7b3e9cf5b777139c0419d47fa933ff510.patch";
sha256 = "0npdicjvkhpjvd39parrc3wjwd0871d3vz34nwr7p2mk6x9q5dwi";
})
];

NIX_CFLAGS_COMPILE = "-Wno-error=implicit-fallthrough";
configureFlags = [ "--with-systemd" "--with-systemdsystemunitdir=$(out)/etc/systemd/system" ];

Expand Down