Subject: [PATCH 49/49] gnu: Add postgrest service.

From: Robert Vollmert <[email-masked]>
Date: Fri, 29 Nov 2019 12:37:51 +0100

* gnu/services/databases.scm: Add postgrest service and associated
record type.
---
 gnu/services/databases.scm | 101 ++++++++++++++++++++++++++++++++++++-
 1 file changed, 100 insertions(+), 1 deletion(-)

diff --git a/gnu/services/databases.scm b/gnu/services/databases.scm
index 6b04ae0a0f..3f938689df 100644
--- a/gnu/services/databases.scm
+++ b/gnu/services/databases.scm
@@ -28,6 +28,7 @@
   #:use-module (gnu system shadow)
   #:use-module (gnu packages admin)
   #:use-module (gnu packages databases)
+  #:use-module (gnu packages haskell-apps)
   #:use-module (guix build-system trivial)
   #:use-module (guix build union)
   #:use-module (guix modules)
@@ -81,7 +82,11 @@
 
             redis-configuration
             redis-configuration?
-            redis-service-type))
+            redis-service-type
+
+            postgrest-configuration
+            postgrest-configuration?
+            postgrest-service-type))
 
 ;;; Commentary:
 ;;;
@@ -647,3 +652,97 @@ The optional @var{config} argument specifies the configuration for
                        (service-extension account-service-type
                                           (const %redis-accounts))))
                 (default-value (redis-configuration))))
+
+
+;;;
+;;; PostgREST
+;;;
+
+(define-record-type* <postgrest-configuration>
+  postgrest-configuration make-postgrest-configuration
+  postgrest-configuration?
+  (postgrest     postgrest-configuration-postgrest ;<package>
+                 (default postgrest))
+  (db-uri        postgrest-configuration-db-uri
+                 (default "postgres://postgrest@localhost:5432/postgrestdb"))
+  (db-schema     postgrest-configuration-db-schema
+                 (default "public"))
+  (db-anon-role  postgrest-configuration-db-anon-role
+                 (default "postgrest-anon"))
+  (jwt-secret    postgrest-configuration-jwt-secret
+                 (default #f))
+  (server-host   postgrest-configuration-server-host
+                 (default "127.0.0.1"))
+  (server-port   postgrest-configuration-server-port
+                 (default 3000))
+  (config-file   postgrest-configuration-config-file
+                 (default #f)))
+
+(define (default-postgrest.conf db-uri db-schema db-anon-role jwt-secret server-host server-port)
+  (mixed-text-file "postgrest.conf"
+                   "server-host = \"" server-host "\"\n"
+                   "server-port = " (number->string server-port) "\n"
+                   "db-uri = \"" db-uri "\"\n"
+                   "db-schema = \"" db-schema "\"\n"
+                   "db-anon-role = \"" db-anon-role "\"\n"
+                   (if jwt-secret
+                     (string-append "jwt-secret = \"" jwt-secret "\"\n")
+                     "")))
+
+(define %postgrest-accounts
+  (list (user-group (name "postgrest") (system? #t))
+        (user-account
+         (name "postgrest")
+         (group "postgrest")
+         (system? #t)
+         (comment "PostgREST server user")
+         (home-directory "/var/empty")
+         (shell (file-append shadow "/sbin/nologin")))))
+
+(define* (logger-wrapper name exec . args)
+  "Return a derivation that builds a script to start a process with
+standard output and error redirected to syslog via logger."
+  (define exp
+    #~(begin
+        (use-modules (ice-9 popen))
+        (let* ((pid    (number->string (getpid)))
+               (logger #$(file-append inetutils "/bin/logger"))
+               (args   (list "-t" #$name (string-append "--id=" pid)))
+               (pipe   (apply open-pipe* OPEN_WRITE logger args)))
+          (dup pipe 1)
+          (dup pipe 2)
+          (execl #$exec #$exec #$@args))))
+  (program-file (string-append name "-logger") exp))
+
+(define postgrest-shepherd-service
+  (match-lambda
+    (($ <postgrest-configuration> postgrest db-uri db-schema db-anon-role
+                                  jwt-secret server-port server-host config-file)
+     (let* ((config-file
+             (or config-file
+                 (default-postgrest.conf db-uri db-schema db-anon-role
+                   jwt-secret server-port server-host)))
+            (postgrest-logger
+             (logger-wrapper "postgrest"
+                             (file-append postgrest "/bin/postgrest")
+                             config-file)))
+
+       (list (shepherd-service
+              (provision '(postgrest))
+              (documentation "Run the PostgREST daemon.")
+              (requirement '(user-processes postgres))
+              (start #~(make-forkexec-constructor
+                        '(#$postgrest-logger)
+                        #:user "postgrest"
+                        #:group "postgrest"))
+              (stop #~(make-kill-destructor))))))))
+
+(define postgrest-service-type
+  (service-type
+   (name 'postgrest)
+   (extensions
+    (list (service-extension shepherd-root-service-type
+                             postgrest-shepherd-service)
+          (service-extension account-service-type
+                             (const %postgrest-accounts))))
+   (default-value (postgrest-configuration))))
-- 
2.21.0 (Apple Git-122.2)