Subject: [bug#30701] [PATCH 2/4] services: Use a external pid file for PostgreSQL.

From: Christopher Baines <[email-masked]>
Date: Sun, 4 Mar 2018 19:16:31 +0000

* gnu/services/databases.scm (postgresql-pid-file-for-version): New procedure.
  (<postgresql-config-file>): Add a new external-pid-file field.
  (postgresql-config-file-compiler): Add support for the external-pid-file.
  (postgresql-activation): Create the directory for the pid file.
  (postgresql-shepherd-service): Use the pid-file when starting the service.
---
 gnu/services/databases.scm | 48 ++++++++++++++++++++++++++++++++++------------
 1 file changed, 36 insertions(+), 12 deletions(-)

diff --git a/gnu/services/databases.scm b/gnu/services/databases.scm
index 9ffb6a5e9..4090277a7 100644
--- a/gnu/services/databases.scm
+++ b/gnu/services/databases.scm
@@ -26,10 +26,12 @@
   #:use-module (gnu system shadow)
   #:use-module (gnu packages admin)
   #:use-module (gnu packages databases)
+  #:use-module (guix packages)
   #:use-module (guix store)
   #:use-module (guix modules)
   #:use-module (guix records)
   #:use-module (guix gexp)
+  #:use-module (guix utils)
   #:use-module (srfi srfi-1)
   #:use-module (ice-9 match)
   #:export (<postgresql-config-file>
@@ -38,6 +40,7 @@
             postgresql-config-file-log-destination
             postgresql-config-file-hba-file
             postgresql-config-file-ident-file
+            postgresql-config-file-external-pid-file
             postgresql-config-file-extra-config
 
             postgresql-configuration?
@@ -88,23 +91,32 @@ host	all	all	::1/128 	trust"))
   (plain-file "pg_ident.conf"
               "# MAPNAME       SYSTEM-USERNAME         PG-USERNAME"))
 
+(define (postgresql-pid-file-for-version version)
+  (string-append "/var/run/postgresql/"
+                 (version-major+minor version)
+                 "-main.pid"))
+
 (define-record-type* <postgresql-config-file>
   postgresql-config-file make-postgresql-config-file
   postgresql-config-file?
-  (log-destination postgresql-config-file-log-destination
-                   (default "syslog"))
-  (hba-file        postgresql-config-file-hba-file
-                   (default %default-postgres-hba))
-  (ident-file      postgresql-config-file-ident-file
-                   (default %default-postgres-ident))
-  (extra-config    postgresql-config-file-extra-config
-                   (default '())))
+  (log-destination   postgresql-config-file-log-destination
+                     (default "syslog"))
+  (hba-file          postgresql-config-file-hba-file
+                     (default %default-postgres-hba))
+  (ident-file        postgresql-config-file-ident-file
+                     (default %default-postgres-ident))
+  (external-pid-file postgresql-config-file-external-pid-file
+                     (default (postgresql-pid-file-for-version
+                               (package-version postgresql))))
+  (extra-config      postgresql-config-file-extra-config
+                     (default '())))
 
 (define-gexp-compiler (postgresql-config-file-compiler
                        (file <postgresql-config-file>) system target)
   (match file
     (($ <postgresql-config-file> log-destination hba-file
-                                 ident-file extra-config)
+                                 ident-file external-pid-file
+                                 extra-config)
      (define (quote string)
        (if string
            (list "'" string "'")
@@ -120,6 +132,7 @@ host	all	all	::1/128 	trust"))
         `(("log_destination" ,@(quote log-destination))
           ("hba_file" ,@(quote hba-file))
           ("ident_file" ,@(quote ident-file))
+          ("external_pid_file" ,@(quote external-pid-file))
           ,@extra-config)))
 
      (gexp->derivation
@@ -140,6 +153,9 @@ host	all	all	::1/128 	trust"))
                   (default 5432))
   (locale         postgresql-configuration-locale
                   (default "en_US.utf8"))
+  (pid-file       postgresql-configuration-pid-file
+                  (default (postgresql-pid-file-for-version
+                               (package-version postgresql))))
   (config-file    postgresql-configuration-file
                   (default (postgresql-config-file)))
   (data-directory postgresql-configuration-data-directory
@@ -157,7 +173,8 @@ host	all	all	::1/128 	trust"))
 
 (define postgresql-activation
   (match-lambda
-    (($ <postgresql-configuration> postgresql port locale config-file data-directory)
+    (($ <postgresql-configuration> postgresql port locale pid-file
+                                   config-file data-directory)
      #~(begin
          (use-modules (guix build utils)
                       (ice-9 match))
@@ -173,6 +190,10 @@ host	all	all	::1/128 	trust"))
            (mkdir-p #$data-directory)
            (chown #$data-directory (passwd:uid user) (passwd:gid user))
 
+           ;; Create a directory for the pid file
+           (mkdir-p #$(dirname pid-file))
+           (chown #$(dirname pid-file) (passwd:uid user) (passwd:gid user))
+
            ;; Drop privileges and init state directory in a new
            ;; process.  Wait for it to finish before proceeding.
            (match (primitive-fork)
@@ -195,7 +216,8 @@ host	all	all	::1/128 	trust"))
 
 (define postgresql-shepherd-service
   (match-lambda
-    (($ <postgresql-configuration> postgresql port locale config-file data-directory)
+    (($ <postgresql-configuration> postgresql port locale pid-file
+                                   config-file data-directory)
      (let* ((pg_ctl-wrapper
              ;; Wrapper script that switches to the 'postgres' user before
              ;; launching daemon.
@@ -221,7 +243,9 @@ host	all	all	::1/128 	trust"))
               (provision '(postgres))
               (documentation "Run the PostgreSQL daemon.")
               (requirement '(user-processes loopback syslogd))
-              (start (action "start"))
+              (start #~(make-forkexec-constructor
+                        '(#$pg_ctl-wrapper "start")
+                        #:pid-file #$pid-file))
               (stop (action "stop"))))))))
 
 (define postgresql-service-type
-- 
2.16.0