services: postgresql: Wrap long lines.
[jackhill/guix/guix.git] / gnu / services / databases.scm
CommitLineData
105369a4
DT
1;;; GNU Guix --- Functional package management for GNU
2;;; Copyright © 2015 David Thompson <davet@gnu.org>
9b1cee97 3;;; Copyright © 2015, 2016 Ludovic Courtès <ludo@gnu.org>
8823ed4e 4;;; Copyright © 2016 Leo Famulari <leo@famulari.name>
67cadaca 5;;; Copyright © 2017 Christopher Baines <mail@cbaines.net>
5ee4cd69 6;;; Copyright © 2018 Clément Lassieur <clement@lassieur.org>
0d57a50a 7;;; Copyright © 2018 Julien Lepiller <julien@lepiller.eu>
334a2f4d 8;;; Copyright © 2019 Robert Vollmert <rob@vllmrt.net>
e20388ad 9;;; Copyright © 2020 Marius Bakke <marius@gnu.org>
105369a4
DT
10;;;
11;;; This file is part of GNU Guix.
12;;;
13;;; GNU Guix is free software; you can redistribute it and/or modify it
14;;; under the terms of the GNU General Public License as published by
15;;; the Free Software Foundation; either version 3 of the License, or (at
16;;; your option) any later version.
17;;;
18;;; GNU Guix is distributed in the hope that it will be useful, but
19;;; WITHOUT ANY WARRANTY; without even the implied warranty of
20;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21;;; GNU General Public License for more details.
22;;;
23;;; You should have received a copy of the GNU General Public License
24;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
25
26(define-module (gnu services databases)
27 #:use-module (gnu services)
0190c1c0 28 #:use-module (gnu services shepherd)
105369a4
DT
29 #:use-module (gnu system shadow)
30 #:use-module (gnu packages admin)
31 #:use-module (gnu packages databases)
0d57a50a
JL
32 #:use-module (guix build-system trivial)
33 #:use-module (guix build union)
a698df72 34 #:use-module (guix deprecation)
119fdd0d 35 #:use-module (guix modules)
0d57a50a 36 #:use-module (guix packages)
105369a4 37 #:use-module (guix records)
105369a4 38 #:use-module (guix gexp)
936e7a52 39 #:use-module (srfi srfi-1)
0adfe95a 40 #:use-module (ice-9 match)
383c51ca 41 #:export (postgresql-config-file
936e7a52
CB
42 postgresql-config-file?
43 postgresql-config-file-log-destination
44 postgresql-config-file-hba-file
45 postgresql-config-file-ident-file
6c067921 46 postgresql-config-file-socket-directory
936e7a52
CB
47 postgresql-config-file-extra-config
48
488ea71e 49 postgresql-configuration
24e96431 50 postgresql-configuration?
488ea71e
CB
51 postgresql-configuration-postgresql
52 postgresql-configuration-port
53 postgresql-configuration-locale
54 postgresql-configuration-file
fe4b8823 55 postgresql-configuration-log-directory
488ea71e
CB
56 postgresql-configuration-data-directory
57
24e96431
58 postgresql-service
59 postgresql-service-type
60
119fdd0d 61 memcached-service-type
119fdd0d
CB
62 memcached-configuration
63 memcached-configuration?
64 memcached-configuration-memecached
65 memcached-configuration-interfaces
66 memcached-configuration-tcp-port
67 memcached-configuration-udp-port
68 memcached-configuration-additional-options
69
5266ff71
CB
70 mongodb-configuration
71 mongodb-configuration?
72 mongodb-configuration-mongodb
73 mongodb-configuration-config-file
74 mongodb-configuration-data-directory
75 mongodb-service-type
76
6575183b 77 mysql-service
24e96431
78 mysql-service-type
79 mysql-configuration
67cadaca
CB
80 mysql-configuration?
81
82 redis-configuration
83 redis-configuration?
84 redis-service-type))
105369a4
DT
85
86;;; Commentary:
87;;;
88;;; Database services.
89;;;
90;;; Code:
91
936e7a52
CB
92(define %default-postgres-hba
93 (plain-file "pg_hba.conf"
94 "
334a2f4d
RV
95local all all peer
96host all all 127.0.0.1/32 md5
97host all all ::1/128 md5"))
936e7a52
CB
98
99(define %default-postgres-ident
100 (plain-file "pg_ident.conf"
101 "# MAPNAME SYSTEM-USERNAME PG-USERNAME"))
102
103(define-record-type* <postgresql-config-file>
104 postgresql-config-file make-postgresql-config-file
105 postgresql-config-file?
6c067921
MO
106 (log-destination postgresql-config-file-log-destination
107 (default "syslog"))
108 (hba-file postgresql-config-file-hba-file
109 (default %default-postgres-hba))
110 (ident-file postgresql-config-file-ident-file
111 (default %default-postgres-ident))
112 (socket-directory postgresql-config-file-socket-directory
113 (default "/var/run/postgresql"))
114 (extra-config postgresql-config-file-extra-config
115 (default '())))
936e7a52
CB
116
117(define-gexp-compiler (postgresql-config-file-compiler
118 (file <postgresql-config-file>) system target)
119 (match file
120 (($ <postgresql-config-file> log-destination hba-file
6c067921
MO
121 ident-file socket-directory
122 extra-config)
a38d0b01
MO
123 ;; See: https://www.postgresql.org/docs/current/config-setting.html.
124 (define (format-value value)
125 (cond
126 ((boolean? value)
127 (list (if value "on" "off")))
128 ((number? value)
129 (list (number->string value)))
130 (else
131 (list "'" value "'"))))
132
133 (define contents
134 (append-map
135 (match-lambda
136 ((key) '())
137 ((key . #f) '())
138 ((key values ...)
139 `(,key " = " ,@(append-map format-value values) "\n")))
140
141 `(("log_destination" ,log-destination)
142 ("hba_file" ,hba-file)
143 ("ident_file" ,ident-file)
6c067921
MO
144 ,@(if socket-directory
145 `(("unix_socket_directories" ,socket-directory))
146 '())
a38d0b01 147 ,@extra-config)))
936e7a52
CB
148
149 (gexp->derivation
150 "postgresql.conf"
151 #~(call-with-output-file (ungexp output "out")
152 (lambda (port)
153 (display
154 (string-append #$@contents)
155 port)))
156 #:local-build? #t))))
157
0adfe95a
LC
158(define-record-type* <postgresql-configuration>
159 postgresql-configuration make-postgresql-configuration
160 postgresql-configuration?
bdcf4d88 161 (postgresql postgresql-configuration-postgresql) ;<package>
0d57a50a
JL
162 (port postgresql-configuration-port
163 (default 5432))
164 (locale postgresql-configuration-locale
165 (default "en_US.utf8"))
166 (config-file postgresql-configuration-file
167 (default (postgresql-config-file)))
fe4b8823
MO
168 (log-directory postgresql-configuration-log-directory
169 (default "/var/log/postgresql"))
0d57a50a
JL
170 (data-directory postgresql-configuration-data-directory
171 (default "/var/lib/postgresql/data"))
172 (extension-packages postgresql-configuration-extension-packages
173 (default '())))
0adfe95a 174
0adfe95a
LC
175(define %postgresql-accounts
176 (list (user-group (name "postgres") (system? #t))
177 (user-account
178 (name "postgres")
179 (group "postgres")
180 (system? #t)
181 (comment "PostgreSQL server user")
182 (home-directory "/var/empty")
9e41130b 183 (shell (file-append shadow "/sbin/nologin")))))
0adfe95a 184
0d57a50a
JL
185(define (final-postgresql postgresql extension-packages)
186 (if (null? extension-packages)
187 postgresql
188 (package
189 (inherit postgresql)
190 (source #f)
191 (build-system trivial-build-system)
192 (arguments
193 `(#:modules ((guix build utils) (guix build union))
194 #:builder
195 (begin
196 (use-modules (guix build utils) (guix build union) (srfi srfi-26))
33687aa3
MO
197 (union-build (assoc-ref %outputs "out")
198 (map (lambda (input) (cdr input))
199 %build-inputs))
0d57a50a
JL
200 #t)))
201 (inputs
202 `(("postgresql" ,postgresql)
203 ,@(map (lambda (extension) (list "extension" extension))
204 extension-packages))))))
205
0adfe95a
LC
206(define postgresql-activation
207 (match-lambda
fe4b8823
MO
208 (($ <postgresql-configuration> postgresql port locale config-file
209 log-directory data-directory
210 extension-packages)
0adfe95a
LC
211 #~(begin
212 (use-modules (guix build utils)
213 (ice-9 match))
214
215 (let ((user (getpwnam "postgres"))
fe4b8823
MO
216 (initdb (string-append
217 #$(final-postgresql postgresql
218 extension-packages)
219 "/bin/initdb"))
e05b780a
CB
220 (initdb-args
221 (append
222 (if #$locale
223 (list (string-append "--locale=" #$locale))
224 '()))))
0adfe95a
LC
225 ;; Create db state directory.
226 (mkdir-p #$data-directory)
227 (chown #$data-directory (passwd:uid user) (passwd:gid user))
228
6c067921
MO
229 ;; Create the socket directory.
230 (let ((socket-directory
231 #$(postgresql-config-file-socket-directory config-file)))
232 (when (string? socket-directory)
233 (mkdir-p socket-directory)
234 (chown socket-directory (passwd:uid user) (passwd:gid user))))
235
fe4b8823
MO
236 ;; Create the log directory.
237 (when (string? #$log-directory)
238 (mkdir-p #$log-directory)
239 (chown #$log-directory (passwd:uid user) (passwd:gid user)))
240
0adfe95a
LC
241 ;; Drop privileges and init state directory in a new
242 ;; process. Wait for it to finish before proceeding.
243 (match (primitive-fork)
244 (0
245 ;; Exit with a non-zero status code if an exception is thrown.
246 (dynamic-wind
247 (const #t)
248 (lambda ()
249 (setgid (passwd:gid user))
250 (setuid (passwd:uid user))
e05b780a
CB
251 (primitive-exit
252 (apply system*
253 initdb
254 "-D"
255 #$data-directory
256 initdb-args)))
0adfe95a
LC
257 (lambda ()
258 (primitive-exit 1))))
259 (pid (waitpid pid))))))))
260
d4053c71 261(define postgresql-shepherd-service
0adfe95a 262 (match-lambda
fe4b8823
MO
263 (($ <postgresql-configuration> postgresql port locale config-file
264 log-directory data-directory
265 extension-packages)
5ee4cd69
CL
266 (let* ((pg_ctl-wrapper
267 ;; Wrapper script that switches to the 'postgres' user before
268 ;; launching daemon.
269 (program-file
270 "pg_ctl-wrapper"
271 #~(begin
272 (use-modules (ice-9 match)
273 (ice-9 format))
274 (match (command-line)
275 ((_ mode)
276 (let ((user (getpwnam "postgres"))
fe4b8823
MO
277 (pg_ctl #$(file-append
278 (final-postgresql postgresql
279 extension-packages)
0d57a50a 280 "/bin/pg_ctl"))
5ee4cd69
CL
281 (options (format #f "--config-file=~a -p ~d"
282 #$config-file #$port)))
283 (setgid (passwd:gid user))
284 (setuid (passwd:uid user))
fe4b8823
MO
285 (execl pg_ctl pg_ctl "-D" #$data-directory
286 #$@(if (string? log-directory)
287 (list "-l"
288 (string-append log-directory
289 "/pg_ctl.log"))
290 '())
291 "-o" options
5ee4cd69 292 mode)))))))
ef2dda8e 293 (pid-file (in-vicinity data-directory "postmaster.pid"))
5ee4cd69
CL
294 (action (lambda args
295 #~(lambda _
ef2dda8e
CL
296 (invoke #$pg_ctl-wrapper #$@args)
297 (match '#$args
298 (("start")
299 (call-with-input-file #$pid-file read))
300 (_ #t))))))
d4053c71 301 (list (shepherd-service
0adfe95a
LC
302 (provision '(postgres))
303 (documentation "Run the PostgreSQL daemon.")
9b1cee97 304 (requirement '(user-processes loopback syslogd))
ef2dda8e
CL
305 (modules `((ice-9 match)
306 ,@%default-modules))
5ee4cd69
CL
307 (start (action "start"))
308 (stop (action "stop"))))))))
0adfe95a
LC
309
310(define postgresql-service-type
33687aa3
MO
311 (service-type
312 (name 'postgresql)
313 (extensions
314 (list (service-extension shepherd-root-service-type
315 postgresql-shepherd-service)
316 (service-extension activation-service-type
317 postgresql-activation)
318 (service-extension account-service-type
319 (const %postgresql-accounts))
320 (service-extension
321 profile-service-type
322 (compose list postgresql-configuration-postgresql))))))
0adfe95a 323
a698df72
CB
324(define-deprecated (postgresql-service #:key (postgresql postgresql)
325 (port 5432)
326 (locale "en_US.utf8")
327 (config-file (postgresql-config-file))
33687aa3
MO
328 (data-directory
329 "/var/lib/postgresql/data")
a698df72
CB
330 (extension-packages '()))
331 postgresql-service-type
33687aa3
MO
332 "Return a service that runs @var{postgresql}, the PostgreSQL database
333server.
105369a4
DT
334
335The PostgreSQL daemon loads its runtime configuration from @var{config-file}
336and stores the database cluster in @var{data-directory}."
0adfe95a
LC
337 (service postgresql-service-type
338 (postgresql-configuration
339 (postgresql postgresql)
2d3d5cc5 340 (port port)
e05b780a 341 (locale locale)
0adfe95a 342 (config-file config-file)
0d57a50a
JL
343 (data-directory data-directory)
344 (extension-packages extension-packages))))
6575183b
SB
345
346\f
119fdd0d
CB
347;;;
348;;; Memcached
349;;;
350
351(define-record-type* <memcached-configuration>
352 memcached-configuration make-memcached-configuration
353 memcached-configuration?
354 (memcached memcached-configuration-memcached ;<package>
355 (default memcached))
356 (interfaces memcached-configuration-interfaces
357 (default '("0.0.0.0")))
358 (tcp-port memcached-configuration-tcp-port
359 (default 11211))
360 (udp-port memcached-configuration-udp-port
361 (default 11211))
362 (additional-options memcached-configuration-additional-options
363 (default '())))
364
365(define %memcached-accounts
366 (list (user-group (name "memcached") (system? #t))
367 (user-account
368 (name "memcached")
369 (group "memcached")
370 (system? #t)
371 (comment "Memcached server user")
372 (home-directory "/var/empty")
373 (shell (file-append shadow "/sbin/nologin")))))
374
6230e155
CB
375(define memcached-activation
376 #~(begin
377 (use-modules (guix build utils))
378 (let ((user (getpwnam "memcached")))
379 (mkdir-p "/var/run/memcached")
380 (chown "/var/run/memcached"
381 (passwd:uid user) (passwd:gid user)))))
382
119fdd0d
CB
383(define memcached-shepherd-service
384 (match-lambda
385 (($ <memcached-configuration> memcached interfaces tcp-port udp-port
386 additional-options)
387 (with-imported-modules (source-module-closure
388 '((gnu build shepherd)))
389 (list (shepherd-service
390 (provision '(memcached))
391 (documentation "Run the Memcached daemon.")
392 (requirement '(user-processes loopback))
393 (modules '((gnu build shepherd)))
394 (start #~(make-forkexec-constructor
395 `(#$(file-append memcached "/bin/memcached")
396 "-l" #$(string-join interfaces ",")
397 "-p" #$(number->string tcp-port)
398 "-U" #$(number->string udp-port)
399 "--daemon"
6230e155
CB
400 ;; Memcached changes to the memcached user prior to
401 ;; writing the pid file, so write it to a directory
402 ;; that memcached owns.
403 "-P" "/var/run/memcached/pid"
119fdd0d
CB
404 "-u" "memcached"
405 ,#$@additional-options)
406 #:log-file "/var/log/memcached"
6230e155 407 #:pid-file "/var/run/memcached/pid"))
119fdd0d
CB
408 (stop #~(make-kill-destructor))))))))
409
410(define memcached-service-type
411 (service-type (name 'memcached)
412 (extensions
413 (list (service-extension shepherd-root-service-type
414 memcached-shepherd-service)
6230e155
CB
415 (service-extension activation-service-type
416 (const memcached-activation))
119fdd0d
CB
417 (service-extension account-service-type
418 (const %memcached-accounts))))
419 (default-value (memcached-configuration))))
420
421\f
5266ff71
CB
422;;;
423;;; MongoDB
424;;;
425
426(define %default-mongodb-configuration-file
427 (plain-file
428 "mongodb.yaml"
429 "# GNU Guix: MongoDB default configuration file
430processManagement:
431 pidFilePath: /var/run/mongodb/pid
432storage:
433 dbPath: /var/lib/mongodb
434"))
435
436
437(define-record-type* <mongodb-configuration>
438 mongodb-configuration make-mongodb-configuration
439 mongodb-configuration?
440 (mongodb mongodb-configuration-mongodb
441 (default mongodb))
442 (config-file mongodb-configuration-config-file
443 (default %default-mongodb-configuration-file))
444 (data-directory mongodb-configuration-data-directory
445 (default "/var/lib/mongodb")))
446
447(define %mongodb-accounts
448 (list (user-group (name "mongodb") (system? #t))
449 (user-account
450 (name "mongodb")
451 (group "mongodb")
452 (system? #t)
453 (comment "Mongodb server user")
454 (home-directory "/var/lib/mongodb")
455 (shell (file-append shadow "/sbin/nologin")))))
456
457(define mongodb-activation
458 (match-lambda
459 (($ <mongodb-configuration> mongodb config-file data-directory)
460 #~(begin
461 (use-modules (guix build utils))
462 (let ((user (getpwnam "mongodb")))
463 (for-each
464 (lambda (directory)
465 (mkdir-p directory)
466 (chown directory
467 (passwd:uid user) (passwd:gid user)))
468 '("/var/run/mongodb" #$data-directory)))))))
469
470(define mongodb-shepherd-service
471 (match-lambda
472 (($ <mongodb-configuration> mongodb config-file data-directory)
473 (shepherd-service
474 (provision '(mongodb))
475 (documentation "Run the Mongodb daemon.")
476 (requirement '(user-processes loopback))
477 (start #~(make-forkexec-constructor
478 `(,(string-append #$mongodb "/bin/mongod")
479 "--config"
480 ,#$config-file)
481 #:user "mongodb"
482 #:group "mongodb"
483 #:pid-file "/var/run/mongodb/pid"
484 #:log-file "/var/log/mongodb.log"))
485 (stop #~(make-kill-destructor))))))
486
487(define mongodb-service-type
488 (service-type
489 (name 'mongodb)
490 (description "Run the MongoDB document database server.")
491 (extensions
492 (list (service-extension shepherd-root-service-type
493 (compose list
494 mongodb-shepherd-service))
495 (service-extension activation-service-type
496 mongodb-activation)
497 (service-extension account-service-type
498 (const %mongodb-accounts))))
499 (default-value
500 (mongodb-configuration))))
501
502\f
6575183b
SB
503;;;
504;;; MySQL.
505;;;
506
507(define-record-type* <mysql-configuration>
508 mysql-configuration make-mysql-configuration
509 mysql-configuration?
4b41febf 510 (mysql mysql-configuration-mysql (default mariadb))
27d7cdbf 511 (bind-address mysql-configuration-bind-address (default "127.0.0.1"))
33ed8296 512 (port mysql-configuration-port (default 3306))
927bf98e 513 (socket mysql-configuration-socket (default "/run/mysqld/mysqld.sock"))
e20388ad
MB
514 (extra-content mysql-configuration-extra-content (default ""))
515 (auto-upgrade? mysql-configuration-auto-upgrade? (default #t)))
6575183b
SB
516
517(define %mysql-accounts
518 (list (user-group
519 (name "mysql")
520 (system? #t))
521 (user-account
522 (name "mysql")
523 (group "mysql")
524 (system? #t)
525 (home-directory "/var/empty")
9e41130b 526 (shell (file-append shadow "/sbin/nologin")))))
6575183b
SB
527
528(define mysql-configuration-file
529 (match-lambda
927bf98e 530 (($ <mysql-configuration> mysql bind-address port socket extra-content)
4b41febf 531 (mixed-text-file "my.cnf" "[mysqld]
6575183b 532datadir=/var/lib/mysql
927bf98e 533socket=" socket "
27d7cdbf 534bind-address=" bind-address "
4b41febf 535port=" (number->string port) "
33ed8296 536" extra-content "
6575183b
SB
537"))))
538
539(define (%mysql-activation config)
540 "Return an activation gexp for the MySQL or MariaDB database server."
541 (let ((mysql (mysql-configuration-mysql config))
542 (my.cnf (mysql-configuration-file config)))
543 #~(begin
544 (use-modules (ice-9 popen)
545 (guix build utils))
546 (let* ((mysqld (string-append #$mysql "/bin/mysqld"))
547 (user (getpwnam "mysql"))
548 (uid (passwd:uid user))
549 (gid (passwd:gid user))
550 (datadir "/var/lib/mysql")
551 (rundir "/run/mysqld"))
552 (mkdir-p datadir)
553 (chown datadir uid gid)
554 (mkdir-p rundir)
555 (chown rundir uid gid)
556 ;; Initialize the database when it doesn't exist.
557 (when (not (file-exists? (string-append datadir "/mysql")))
558 (if (string-prefix? "mysql-" (strip-store-file-name #$mysql))
559 ;; For MySQL.
560 (system* mysqld
561 (string-append "--defaults-file=" #$my.cnf)
562 "--initialize"
563 "--user=mysql")
564 ;; For MariaDB.
565 ;; XXX: The 'mysql_install_db' script doesn't work directly
566 ;; due to missing 'mkdir' in PATH.
567 (let ((p (open-pipe* OPEN_WRITE mysqld
568 (string-append
569 "--defaults-file=" #$my.cnf)
570 "--bootstrap"
571 "--user=mysql")))
572 ;; Create the system database, as does by 'mysql_install_db'.
573 (display "create database mysql;\n" p)
574 (display "use mysql;\n" p)
575 (for-each
576 (lambda (sql)
577 (call-with-input-file
5c3d77c3 578 (string-append #$mysql:lib "/share/mysql/" sql)
6575183b
SB
579 (lambda (in) (dump-port in p))))
580 '("mysql_system_tables.sql"
581 "mysql_performance_tables.sql"
582 "mysql_system_tables_data.sql"
583 "fill_help_tables.sql"))
584 ;; Remove the anonymous user and disable root access from
585 ;; remote machines, as does by 'mysql_secure_installation'.
586 (display "
587DELETE FROM user WHERE User='';
588DELETE FROM user WHERE User='root' AND
589 Host NOT IN ('localhost', '127.0.0.1', '::1');
590FLUSH PRIVILEGES;
591" p)
592 (close-pipe p))))))))
593
594(define (mysql-shepherd-service config)
595 (list (shepherd-service
596 (provision '(mysql))
597 (documentation "Run the MySQL server.")
598 (start (let ((mysql (mysql-configuration-mysql config))
599 (my.cnf (mysql-configuration-file config)))
600 #~(make-forkexec-constructor
601 (list (string-append #$mysql "/bin/mysqld")
602 (string-append "--defaults-file=" #$my.cnf))
603 #:user "mysql" #:group "mysql")))
604 (stop #~(make-kill-destructor)))))
605
e20388ad
MB
606(define (mysql-upgrade-wrapper mysql socket-file)
607 ;; The MySQL socket and PID file may appear before the server is ready to
608 ;; accept connections. Ensure the socket is responsive before attempting
609 ;; to run the upgrade script.
610 (program-file
611 "mysql-upgrade-wrapper"
612 #~(begin
613 (let ((mysql-upgrade #$(file-append mysql "/bin/mysql_upgrade"))
614 (timeout 10))
615 (begin
616 (let loop ((i 0))
617 (catch 'system-error
618 (lambda ()
619 (let ((sock (socket PF_UNIX SOCK_STREAM 0)))
620 (connect sock AF_UNIX #$socket-file)
621 (close-port sock)
622 ;; The socket is ready!
623 (execl mysql-upgrade mysql-upgrade
624 (string-append "--socket=" #$socket-file))))
3cf19b83
MB
625 (lambda args
626 (if (< i timeout)
627 (begin
628 (sleep 1)
629 (loop (+ 1 i)))
630 ;; No luck, give up.
631 (throw 'timeout-error
632 "MySQL server did not appear in time!"))))))))))
e20388ad
MB
633
634(define (mysql-upgrade-shepherd-service config)
635 (list (shepherd-service
636 (provision '(mysql-upgrade))
637 (requirement '(mysql))
638 (one-shot? #t)
639 (documentation "Upgrade MySQL database schemas.")
640 (start (let ((mysql (mysql-configuration-mysql config))
641 (socket (mysql-configuration-socket config)))
642 #~(make-forkexec-constructor
643 (list #$(mysql-upgrade-wrapper mysql socket))
644 #:user "mysql" #:group "mysql"))))))
645
646(define (mysql-shepherd-services config)
647 (if (mysql-configuration-auto-upgrade? config)
648 (append (mysql-shepherd-service config)
649 (mysql-upgrade-shepherd-service config))
650 (mysql-shepherd-service config)))
651
6575183b
SB
652(define mysql-service-type
653 (service-type
654 (name 'mysql)
655 (extensions
656 (list (service-extension account-service-type
657 (const %mysql-accounts))
658 (service-extension activation-service-type
659 %mysql-activation)
660 (service-extension shepherd-root-service-type
e20388ad 661 mysql-shepherd-services)))
e903738f 662 (default-value (mysql-configuration))))
6575183b 663
89b704a4
MB
664(define-deprecated (mysql-service #:key (config (mysql-configuration)))
665 mysql-service-type
6575183b 666 (service mysql-service-type config))
67cadaca
CB
667
668\f
669;;;
670;;; Redis
671;;;
672
673(define-record-type* <redis-configuration>
674 redis-configuration make-redis-configuration
675 redis-configuration?
676 (redis redis-configuration-redis ;<package>
677 (default redis))
678 (bind redis-configuration-bind
679 (default "127.0.0.1"))
680 (port redis-configuration-port
681 (default 6379))
682 (working-directory redis-configuration-working-directory
683 (default "/var/lib/redis"))
684 (config-file redis-configuration-config-file
685 (default #f)))
686
687(define (default-redis.conf bind port working-directory)
688 (mixed-text-file "redis.conf"
689 "bind " bind "\n"
690 "port " (number->string port) "\n"
691 "dir " working-directory "\n"
692 "daemonize no\n"))
693
694(define %redis-accounts
695 (list (user-group (name "redis") (system? #t))
696 (user-account
697 (name "redis")
698 (group "redis")
699 (system? #t)
700 (comment "Redis server user")
701 (home-directory "/var/empty")
702 (shell (file-append shadow "/sbin/nologin")))))
703
704(define redis-activation
705 (match-lambda
706 (($ <redis-configuration> redis bind port working-directory config-file)
707 #~(begin
708 (use-modules (guix build utils)
709 (ice-9 match))
710
711 (let ((user (getpwnam "redis")))
712 (mkdir-p #$working-directory)
713 (chown #$working-directory (passwd:uid user) (passwd:gid user)))))))
714
715(define redis-shepherd-service
716 (match-lambda
717 (($ <redis-configuration> redis bind port working-directory config-file)
718 (let ((config-file
719 (or config-file
720 (default-redis.conf bind port working-directory))))
721 (list (shepherd-service
722 (provision '(redis))
723 (documentation "Run the Redis daemon.")
724 (requirement '(user-processes syslogd))
725 (start #~(make-forkexec-constructor
726 '(#$(file-append redis "/bin/redis-server")
727 #$config-file)
728 #:user "redis"
729 #:group "redis"))
730 (stop #~(make-kill-destructor))))))))
731
732(define redis-service-type
733 (service-type (name 'redis)
734 (extensions
735 (list (service-extension shepherd-root-service-type
736 redis-shepherd-service)
737 (service-extension activation-service-type
738 redis-activation)
739 (service-extension account-service-type
bc037c1b
CB
740 (const %redis-accounts))))
741 (default-value (redis-configuration))))