gnu: Add GeoClue desktop service.
[jackhill/guix/guix.git] / gnu / services / databases.scm
1 ;;; GNU Guix --- Functional package management for GNU
2 ;;; Copyright © 2015 David Thompson <davet@gnu.org>
3 ;;;
4 ;;; This file is part of GNU Guix.
5 ;;;
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.
10 ;;;
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.
15 ;;;
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/>.
18
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))
29
30 ;;; Commentary:
31 ;;;
32 ;;; Database services.
33 ;;;
34 ;;; Code:
35
36 (define %default-postgres-hba
37 (text-file "pg_hba.conf"
38 "
39 local all all trust
40 host all all 127.0.0.1/32 trust
41 host all all ::1/128 trust"))
42
43 (define %default-postgres-ident
44 (text-file "pg_ident.conf"
45 "# MAPNAME SYSTEM-USERNAME PG-USERNAME"))
46
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")))
54
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.
59
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
63 ;; daemon.
64 (define start-script
65 (mlet %store-monad ((config-file config-file))
66 (gexp->script "start-postgres"
67 #~(let ((user (getpwnam "postgres"))
68 (postgres (string-append #$postgresql
69 "/bin/postgres")))
70 (setgid (passwd:gid user))
71 (setuid (passwd:uid user))
72 (system* postgres
73 (string-append "--config-file=" #$config-file)
74 "-D" #$data-directory)))))
75
76 (define activate
77 #~(begin
78 (use-modules (guix build utils)
79 (ice-9 match))
80
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))
86
87 ;; Drop privileges and init state directory in a new
88 ;; process. Wait for it to finish before proceeding.
89 (match (primitive-fork)
90 (0
91 ;; Exit with a non-zero status code if an exception is thrown.
92 (dynamic-wind
93 (const #t)
94 (lambda ()
95 (setgid (passwd:gid user))
96 (setuid (passwd:uid user))
97 (primitive-exit (system* initdb "-D" #$data-directory)))
98 (lambda ()
99 (primitive-exit 1))))
100 (pid (waitpid pid))))))
101
102 (mlet %store-monad ((start-script start-script))
103 (return
104 (service
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))
110 (activate activate)
111 (user-groups (list (user-group
112 (name "postgres")
113 (system? #t))))
114 (user-accounts (list (user-account
115 (name "postgres")
116 (group "postgres")
117 (system? #t)
118 (comment "PostgreSQL server user")
119 (home-directory "/var/empty")
120 (shell
121 #~(string-append #$shadow "/sbin/nologin")))))))))