Subject: add fcgiwrap service

From: Andy Wingo <[email-masked]>
Date: Thu, 27 Apr 2017 22:13:40 +0200

Attached patch adds fcgiwrap service.

>From 09369d54d54764dfcdae481c61e789f1755c7748 Mon Sep 17 00:00:00 2001
From: Andy Wingo <[email-masked]>
Date: Thu, 27 Apr 2017 10:08:36 +0200
Subject: [PATCH 3/5] gnu: Add fcgiwrap service.

* doc/guix.texi (Web Services): Add documentation.
* gnu/services/web.scm (<fcgiwrap-configuration>): New record type.
(fcgiwrap-accounts, fcgiwrap-shepherd-service): New service extensions.
(fcgiwrap-service-type): New service type.
---
 doc/guix.texi        | 53 ++++++++++++++++++++++++++++++++++++++++++++++-
 gnu/services/web.scm | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 109 insertions(+), 2 deletions(-)

diff --git a/doc/guix.texi b/doc/guix.texi
index 21b6d7d88..eeacf8833 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -13295,7 +13295,8 @@ Local accounts with lower values will silently fail to authenticate.
 @cindex web
 @cindex www
 @cindex HTTP
-The @code{(gnu services web)} module provides the following service:
+The @code{(gnu services web)} module provides the nginx web server and
+also a fastcgi wrapper daemon.
 
 @deffn {Scheme Procedure} nginx-service [#:nginx nginx] @
        [#:log-directory ``/var/log/nginx''] @
@@ -13381,6 +13382,56 @@ Whether the server should add its configuration to response.
 @end table
 @end deftp
 
+@cindex fastcgi
+@cindex fcgiwrap
+FastCGI is an interface between the front-end and the back-end of a web
+service.  It is a somewhat legacy facility; new web services should
+generally just talk HTTP between the front-end and the back-end.
+However there are a number of back-end services such as PHP or the
+optimized HTTP Git repository access that use FastCGI, so we have
+support for it in Guix.
+
+To use FastCGI, you configure the front-end web server (e.g., nginx) to
+dispatch some subset of its requests to the fastcgi backend, which
+listens on a local TCP or UNIX socket.  There is an intermediary
+@code{fcgiwrap} program that sits between the actual backend process and
+the web server.  The front-end indicates which backend program to run,
+passing that information to the @code{fcgiwrap} process.
+
+@defvr {Scheme Variable} fcgiwrap-service-type
+A service type for the @code{fcgiwrap} FastCGI proxy.
+@end defvr
+
+@deftp {Data Type} fcgiwrap-configuration
+Data type representing the configuration of the @code{fcgiwrap} serice.
+This type has the following parameters:
+@table @asis
+@item @code{package} (default: @code{fcgiwrap})
+The fcgiwrap package to use.
+
+@item @code{socket} (default: @code{tcp:127.0.0.1:9000})
+The socket on which the @code{fcgiwrap} process should listen, as a
+string.  Valid @var{socket} values include
+@code{unix:@var{/path/to/unix/socket}},
+@code{tcp:@var{dot.ted.qu.ad}:@var{port}} and
+@code{tcp6:[@var{ipv6_addr}]:port}.
+
+@item @code{user} (default: @code{fcgiwrap})
+@itemx @code{group} (default: @code{fcgiwrap})
+The user and group names, as strings, under which to run the
+@code{fcgiwrap} process.  The @code{fastcgi} service will ensure that if
+the user asks for the specific user or group names @code{fcgiwrap} that
+the corresponding user and/or group is present on the system.
+
+It is possible to configure a FastCGI-backed web service to pass HTTP
+authentication information from the front-end to the back-end, and to
+allow @code{fcgiwrap} to run the back-end process as a corresponding
+local user.  To enable this capability on the back-end., run
+@code{fcgiwrap} as the @code{root} user and group.  Note that this
+capability also has to be configured on the front-end as well.
+@end table
+@end deftp
+
 
 @node Certificate Services
 @subsubsection Certificate Services
diff --git a/gnu/services/web.scm b/gnu/services/web.scm
index e8769522a..e8a287ba4 100644
--- a/gnu/services/web.scm
+++ b/gnu/services/web.scm
@@ -41,7 +41,11 @@
             nginx-named-location-configuration
             nginx-named-location-configuration?
             nginx-service
-            nginx-service-type))
+            nginx-service-type
+
+            fcgiwrap-configuration
+            fcgiwrap-configuration?
+            fcgiwrap-service-type))
 
 ;;; Commentary:
 ;;;
@@ -296,3 +300,55 @@ files in LOG-DIRECTORY, and stores temporary runtime files in RUN-DIRECTORY."
             (server-blocks server-list)
             (upstream-blocks upstream-list)
             (file config-file))))
+
+(define-record-type* <fcgiwrap-configuration> fcgiwrap-configuration
+  make-fcgiwrap-configuration
+  fcgiwrap-configuration?
+  (package       fcgiwrap-configuration-package ;<package>
+                 (default fcgiwrap))
+  (socket        fcgiwrap-configuration-socket
+                 (default "tcp:127.0.0.1:9000"))
+  (user          fcgiwrap-configuration-user
+                 (default "fcgiwrap"))
+  (group         fcgiwrap-configuration-group
+                 (default "fcgiwrap")))
+
+(define fcgiwrap-accounts
+  (match-lambda
+    (($ <fcgiwrap-configuration> package socket user group)
+     (filter identity
+             (list
+              (and (equal? group "fcgiwrap")
+                   (user-group
+                    (name "fcgiwrap")
+                    (system? #t)))
+              (and (equal? user "fcgiwrap")
+                   (user-account
+                    (name "fcgiwrap")
+                    (group group)
+                    (system? #t)
+                    (comment "Fcgiwrap Daemon")
+                    (home-directory "/var/empty")
+                    (shell (file-append shadow "/sbin/nologin")))))))))
+
+(define fcgiwrap-shepherd-service
+  (match-lambda
+    (($ <fcgiwrap-configuration> package socket user group)
+     (list (shepherd-service
+            (provision '(fcgiwrap))
+            (documentation "Run the fcgiwrap daemon.")
+            (requirement '(networking))
+            (start #~(make-forkexec-constructor
+                      '(#$(file-append package "/sbin/fcgiwrap")
+			  "-s" #$socket)
+		      #:user #$user #:group #$group))
+            (stop #~(make-kill-destructor)))))))
+
+(define fcgiwrap-service-type
+  (service-type (name 'fcgiwrap)
+                (extensions
+                 (list (service-extension shepherd-root-service-type
+                                          fcgiwrap-shepherd-service)
+		       (service-extension account-service-type
+                                          fcgiwrap-accounts)))
+                (default-value (fcgiwrap-configuration))))
-- 
2.12.2