services: Add Shepherd 'configuration' action to various services.
[jackhill/guix/guix.git] / gnu / services / dict.scm
CommitLineData
c3d38b2b
SB
1;;; GNU Guix --- Functional package management for GNU
2;;; Copyright © 2016 Sou Bunnbu <iyzsong@gmail.com>
002bcb7e 3;;; Copyright © 2016, 2017, 2018, 2020, 2022 Ludovic Courtès <ludo@gnu.org>
9af7ecd9 4;;; Copyright © 2017 Huang Ying <huang.ying.caritas@gmail.com>
c3d38b2b
SB
5;;;
6;;; This file is part of GNU Guix.
7;;;
8;;; GNU Guix is free software; you can redistribute it and/or modify it
9;;; under the terms of the GNU General Public License as published by
10;;; the Free Software Foundation; either version 3 of the License, or (at
11;;; your option) any later version.
12;;;
13;;; GNU Guix is distributed in the hope that it will be useful, but
14;;; WITHOUT ANY WARRANTY; without even the implied warranty of
15;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16;;; GNU General Public License for more details.
17;;;
18;;; You should have received a copy of the GNU General Public License
19;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
20
21(define-module (gnu services dict)
22 #:use-module (guix gexp)
23 #:use-module (guix records)
9e549ad1 24 #:use-module (guix modules)
002bcb7e 25 #:use-module (guix least-authority)
c3d38b2b
SB
26 #:use-module (gnu services)
27 #:use-module (gnu services shepherd)
28 #:use-module (gnu system shadow)
29 #:use-module ((gnu packages admin) #:select (shadow))
30 #:use-module (gnu packages dico)
31 #:use-module (gnu packages dictionaries)
002bcb7e
LC
32 #:autoload (gnu build linux-container) (%namespaces)
33 #:autoload (gnu system file-systems) (file-system-mapping)
c3d38b2b
SB
34 #:use-module (srfi srfi-1)
35 #:use-module (srfi srfi-26)
36 #:use-module (ice-9 match)
37 #:export (dicod-service
24e96431 38 dicod-service-type
c3d38b2b 39 dicod-configuration
9af7ecd9 40 dicod-handler
c3d38b2b
SB
41 dicod-database
42 %dicod-database:gcide))
43
44\f
45;;;
46;;; GNU Dico.
47;;;
48
49(define-record-type* <dicod-configuration>
50 dicod-configuration make-dicod-configuration
51 dicod-configuration?
52 (dico dicod-configuration-dico (default dico))
a1b48465
LC
53 (interfaces dicod-configuration-interfaces ;list of strings
54 (default '("localhost")))
9af7ecd9
HY
55 (handlers dicod-configuration-handlers ;list of <dicod-handler>
56 (default '()))
57 (databases dicod-configuration-databases ;list of <dicod-database>
c3d38b2b
SB
58 (default (list %dicod-database:gcide))))
59
9af7ecd9
HY
60(define-record-type* <dicod-handler>
61 dicod-handler make-dicod-handler
62 dicod-handler?
63 (name dicod-handler-name)
64 (module dicod-handler-module (default #f))
65 (options dicod-handler-options (default '())))
66
c3d38b2b
SB
67(define-record-type* <dicod-database>
68 dicod-database make-dicod-database
69 dicod-database?
70 (name dicod-database-name)
9af7ecd9
HY
71 (handler dicod-database-handler)
72 (complex? dicod-database-complex? (default #f))
c3d38b2b
SB
73 (options dicod-database-options (default '())))
74
75(define %dicod-database:gcide
76 (dicod-database
77 (name "gcide")
9af7ecd9 78 (handler "gcide")
c3d38b2b
SB
79 (options (list #~(string-append "dbdir=" #$gcide "/share/gcide")
80 "idxdir=/var/run/dicod"))))
81
82(define %dicod-accounts
83 (list (user-group
84 (name "dicod")
85 (system? #t))
86 (user-account
87 (name "dicod")
88 (group "dicod")
89 (system? #t)
90 (home-directory "/var/empty")
9e41130b 91 (shell (file-append shadow "/sbin/nologin")))))
c3d38b2b
SB
92
93(define (dicod-configuration-file config)
9af7ecd9
HY
94 (define handler->text
95 (match-lambda
96 (($ <dicod-handler> name #f '())
97 `("
98load-module " ,name ";"))
99 (($ <dicod-handler> name #f options)
100 (handler->text (dicod-handler
101 (name name)
102 (module name)
103 (options options))))
104 (($ <dicod-handler> name module options)
105 `("
106load-module " ,name " {
107 command \"" ,module (string-join (list ,@options) " " 'prefix) "\";
108}\n"))))
109
a1b48465 110 (define database->text
c3d38b2b 111 (match-lambda
9af7ecd9
HY
112 (($ <dicod-database> name handler #f options)
113 (append
114 (handler->text (dicod-handler
115 (name handler)))
116 (database->text (dicod-database
117 (name name)
118 (handler handler)
119 (complex? #t)
120 (options options)))))
121 (($ <dicod-database> name handler complex? options)
a1b48465 122 `("
c3d38b2b
SB
123database {
124 name \"" ,name "\";
9af7ecd9 125 handler \"" ,handler
c3d38b2b 126 (string-join (list ,@options) " " 'prefix) "\";
a1b48465
LC
127}\n"))))
128
129 (define configuration->text
130 (match-lambda
9af7ecd9 131 (($ <dicod-configuration> dico (interfaces ...) handlers databases)
a1b48465
LC
132 (append `("listen ("
133 ,(string-join interfaces ", ") ");\n")
9af7ecd9 134 (append-map handler->text handlers)
a1b48465
LC
135 (append-map database->text databases)))))
136
137 (apply mixed-text-file "dicod.conf" (configuration->text config)))
c3d38b2b
SB
138
139(define %dicod-activation
140 #~(begin
141 (use-modules (guix build utils))
142 (let ((user (getpwnam "dicod"))
143 (rundir "/var/run/dicod"))
144 (mkdir-p rundir)
145 (chown rundir (passwd:uid user) (passwd:gid user)))))
146
147(define (dicod-shepherd-service config)
002bcb7e 148 (let* ((dicod.conf (dicod-configuration-file config))
fd57ce26 149 (interfaces (dicod-configuration-interfaces config))
002bcb7e
LC
150 (dicod (least-authority-wrapper
151 (file-append (dicod-configuration-dico config)
152 "/bin/dicod")
153 #:name "dicod"
154 #:mappings (list (file-system-mapping
155 (source "/var/run/dicod")
156 (target source)
157 (writable? #t))
158 (file-system-mapping
159 (source "/dev/log")
160 (target source))
161 (file-system-mapping
162 (source dicod.conf)
163 (target source)))
164 #:namespaces (delq 'net %namespaces))))
165 (list (shepherd-service
166 (provision '(dicod))
167 (requirement '(user-processes))
168 (documentation "Run the dicod daemon.")
fd57ce26
LC
169 (start #~(if (and (defined? 'make-inetd-constructor)
170 #$(= 1 (length interfaces))) ;XXX
171 (make-inetd-constructor
172 (list #$dicod "--inetd" "--foreground"
173 (string-append "--config=" #$dicod.conf))
174 (addrinfo:addr
175 (car (getaddrinfo #$(first interfaces) "dict")))
176 #:user "dicod" #:group "dicod"
177 #:service-name-stem "dicod")
178 (make-forkexec-constructor
179 (list #$dicod "--foreground"
180 (string-append "--config=" #$dicod.conf))
181 #:user "dicod" #:group "dicod")))
2a37f174
LC
182 (stop #~(if (and (defined? 'make-inetd-destructor)
183 #$(= 1 (length interfaces))) ;XXX
184 (make-inetd-destructor)
8d9647d8
LC
185 (make-kill-destructor)))
186 (actions (list (shepherd-configuration-action dicod.conf)))))))
c3d38b2b
SB
187
188(define dicod-service-type
189 (service-type
190 (name 'dict)
191 (extensions
192 (list (service-extension account-service-type
193 (const %dicod-accounts))
194 (service-extension activation-service-type
195 (const %dicod-activation))
196 (service-extension shepherd-root-service-type
3d3c5650 197 dicod-shepherd-service)))
dd0804c6
LC
198 (default-value (dicod-configuration))
199 (description
200 "Run @command{dicod}, the dictionary server of
201@uref{https://www.gnu.org/software/dico, GNU Dico}. @command{dicod}
202implements the standard DICT protocol supported by clients such as
203@command{dico} and GNOME Dictionary.")))
c3d38b2b
SB
204
205(define* (dicod-service #:key (config (dicod-configuration)))
206 "Return a service that runs the @command{dicod} daemon, an implementation
207of DICT server (@pxref{Dicod,,, dico, GNU Dico Manual}).
208
209The optional @var{config} argument specifies the configuration for
210@command{dicod}, which should be a @code{<dicod-configuration>} object, by
b864ddb6 211default it serves the GNU Collaborative International Dictionary of English.
c3d38b2b
SB
212
213You can add @command{open localhost} to your @file{~/.dico} file to make
214@code{localhost} the default server for @command{dico}
215client (@pxref{Initialization File,,, dico, GNU Dico Manual})."
216 (service dicod-service-type config))