1 ;;; GNU Guix --- Functional package management for GNU
2 ;;; Copyright © 2015 David Thompson <davet@gnu.org>
4 ;;; This file is part of GNU Guix.
6 ;;; GNU Guix is free software; you can redistribute it and/or modify it
7 ;;; under the terms of the GNU General Public License as published by
8 ;;; the Free Software Foundation; either version 3 of the License, or (at
9 ;;; your option) any later version.
11 ;;; GNU Guix is distributed in the hope that it will be useful, but
12 ;;; WITHOUT ANY WARRANTY; without even the implied warranty of
13 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 ;;; GNU General Public License for more details.
16 ;;; You should have received a copy of the GNU General Public License
17 ;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
19 (define-module (gnu services databases)
20 #:use-module (gnu services)
21 #:use-module (gnu system shadow)
22 #:use-module (gnu packages admin)
23 #:use-module (gnu packages databases)
24 #:use-module (guix records)
25 #:use-module (guix monads)
26 #:use-module (guix store)
27 #:use-module (guix gexp)
28 #:export (postgresql-service))
32 ;;; Database services.
36 (define %default-postgres-hba
37 (text-file "pg_hba.conf"
40 host all all 127.0.0.1/32 trust
41 host all all ::1/128 trust"))
43 (define %default-postgres-ident
44 (text-file "pg_ident.conf"
45 "# MAPNAME SYSTEM-USERNAME PG-USERNAME"))
47 (define %default-postgres-config
48 (mlet %store-monad ((hba %default-postgres-hba)
49 (ident %default-postgres-ident))
50 (text-file* "postgresql.conf"
51 ;; The daemon will not start without these.
52 "hba_file = '" hba "'\n"
53 "ident_file = '" ident "'\n")))
55 (define* (postgresql-service #:key (postgresql postgresql)
56 (config-file %default-postgres-config)
57 (data-directory "/var/lib/postgresql/data"))
58 "Return a service that runs @var{postgresql}, the PostgreSQL database server.
60 The PostgreSQL daemon loads its runtime configuration from @var{config-file}
61 and stores the database cluster in @var{data-directory}."
62 ;; Wrapper script that switches to the 'postgres' user before launching
65 (mlet %store-monad ((config-file config-file))
66 (gexp->script "start-postgres"
67 #~(let ((user (getpwnam "postgres"))
68 (postgres (string-append #$postgresql
70 (setgid (passwd:gid user))
71 (setuid (passwd:uid user))
73 (string-append "--config-file=" #$config-file)
74 "-D" #$data-directory)))))
78 (use-modules (guix build utils)
81 (let ((user (getpwnam "postgres"))
82 (initdb (string-append #$postgresql "/bin/initdb")))
83 ;; Create db state directory.
84 (mkdir-p #$data-directory)
85 (chown #$data-directory (passwd:uid user) (passwd:gid user))
87 ;; Drop privileges and init state directory in a new
88 ;; process. Wait for it to finish before proceeding.
89 (match (primitive-fork)
91 ;; Exit with a non-zero status code if an exception is thrown.
95 (setgid (passwd:gid user))
96 (setuid (passwd:uid user))
97 (primitive-exit (system* initdb "-D" #$data-directory)))
100 (pid (waitpid pid))))))
102 (mlet %store-monad ((start-script start-script))
105 (provision '(postgres))
106 (documentation "Run the PostgreSQL daemon.")
107 (requirement '(user-processes loopback))
108 (start #~(make-forkexec-constructor #$start-script))
109 (stop #~(make-kill-destructor))
111 (user-groups (list (user-group
114 (user-accounts (list (user-account
118 (comment "PostgreSQL server user")
119 (home-directory "/var/empty")
121 #~(string-append #$shadow "/sbin/nologin")))))))))