projects/guix·blob javascript-team · refs

325 lines · 13.4 KiB

1;;; GNU Guix --- Functional package management for GNU
2;;; Copyright © 2016 Sou Bunnbu <[email protected]>
3;;; Copyright © 2016, 2017, 2018, 2020, 2022, 2023, 2026 Ludovic Courtès <[email protected]>
4;;; Copyright © 2017 Huang Ying <[email protected]>
5;;; Copyright © 2024 Runciter <[email protected]>
6;;;
7;;; This file is part of GNU Guix.
8;;;
9;;; GNU Guix is free software; you can redistribute it and/or modify it
10;;; under the terms of the GNU General Public License as published by
11;;; the Free Software Foundation; either version 3 of the License, or (at
12;;; your option) any later version.
13;;;
14;;; GNU Guix is distributed in the hope that it will be useful, but
15;;; WITHOUT ANY WARRANTY; without even the implied warranty of
16;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17;;; GNU General Public License for more details.
18;;;
19;;; You should have received a copy of the GNU General Public License
20;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
21
22(define-module (gnu services dict)
23 #:use-module (guix deprecation)
24 #:use-module (guix gexp)
25 #:use-module (guix records)
26 #:use-module (guix modules)
27 #:use-module (guix least-authority)
28 #:use-module (gnu services)
29 #:use-module (gnu services shepherd)
30 #:use-module (gnu system shadow)
31 #:use-module ((gnu packages admin) #:select (shadow))
32 #:use-module (gnu packages dictionaries)
33 #:autoload (gnu build linux-container) (%namespaces)
34 #:autoload (gnu system file-systems) (file-system-mapping)
35 #:use-module (srfi srfi-1)
36 #:use-module (srfi srfi-26)
37 #:use-module (ice-9 match)
38 #:export (dicod-service ; deprecated
39 dicod-service-type
40 dicod-configuration
41 dicod-handler
42 dicod-database
43 %dicod-database:gcide
44 dicod-freedict-database
45 %dicod-databases:freedict))
46
47
48;;;
49;;; GNU Dico.
50;;;
51
52(define-record-type* <dicod-configuration>
53 dicod-configuration make-dicod-configuration
54 dicod-configuration?
55 (dico dicod-configuration-dico (default dico))
56 (interfaces dicod-configuration-interfaces ;list of strings
57 (default '("localhost")))
58 (handlers dicod-configuration-handlers ;list of <dicod-handler>
59 (default '()))
60 (databases dicod-configuration-databases ;list of <dicod-database>
61 (default (list %dicod-database:gcide)))
62 (home-service? dicod-configuration-home-service? ;boolean
63 (default for-home?) (innate)))
64
65(define-record-type* <dicod-handler>
66 dicod-handler make-dicod-handler
67 dicod-handler?
68 (name dicod-handler-name)
69 (module dicod-handler-module (default #f))
70 (options dicod-handler-options (default '())))
71
72(define-record-type* <dicod-database>
73 dicod-database make-dicod-database
74 dicod-database?
75 (name dicod-database-name)
76 (handler dicod-database-handler)
77 (complex? dicod-database-complex? (default #f))
78 (options dicod-database-options (default '())))
79
80(define %dicod-gcide-index
81 ;; The GCIDE pre-built index. The Dico 'gcide' module can build it lazily;
82 ;; do it upfront so there's no need for a writable directory at run-time.
83 (computed-file "dicod-gcide-index"
84 (with-imported-modules '((guix build utils))
85 #~(begin
86 (use-modules (guix build utils))
87 (mkdir #$output)
88 (invoke #+(file-append dico "/libexec/idxgcide")
89 #+(file-append gcide "/share/gcide")
90 #$output)))))
91
92(define %dicod-database:gcide
93 (dicod-database
94 (name "gcide")
95 (handler "gcide")
96 (options (list #~(string-append "dbdir=" #$gcide "/share/gcide")
97 #~(string-append "idxdir=" #$%dicod-gcide-index)))))
98
99(define (dicod-freedict-database dictionary-name)
100 "Returns a record of type @code{dicod-database} for purpose of configuring a
101database for the FreeDict multilingual dictionary named by the string
102@var{dictionary-name} into a service of type @code{dicod-service-type}."
103 (dicod-database (name (string-append "freedict-"
104 dictionary-name))
105 (handler "dictorg")
106 (options (list #~(string-append "database="
107 #$freedict-dictionaries
108 "/share/dictd/"
109 #$dictionary-name)))))
110
111(define %dicod-databases:freedict
112 (map dicod-freedict-database (list "afr-deu"
113 "afr-eng"
114 "ara-eng"
115 "bre-fra"
116 "ces-eng"
117 "ckb-kmr"
118 "cym-eng"
119 "dan-eng"
120 "deu-ita"
121 "deu-kur"
122 "deu-nld"
123 "deu-por"
124 "deu-tur"
125 "eng-afr"
126 "eng-ara"
127 "eng-ces"
128 "eng-cym"
129 "eng-dan"
130 "eng-ell"
131 "eng-fra"
132 "eng-gle"
133 "eng-hin"
134 "eng-hrv"
135 "eng-hun"
136 "eng-ita"
137 "eng-lat"
138 "eng-lit"
139 "eng-nld"
140 "eng-pol"
141 "eng-por"
142 "eng-rom"
143 "eng-rus"
144 "eng-spa"
145 "eng-srp"
146 "eng-swh"
147 "eng-tur"
148 "fra-bre"
149 "fra-eng"
150 "fra-nld"
151 "gla-deu"
152 "gle-eng"
153 "gle-pol"
154 "hrv-eng"
155 "hun-eng"
156 "isl-eng"
157 "ita-deu"
158 "ita-eng"
159 "jpn-deu"
160 "jpn-eng"
161 "jpn-fra"
162 "jpn-rus"
163 "kha-deu"
164 "kha-eng"
165 "kur-deu"
166 "kur-eng"
167 "kur-tur"
168 "lat-deu"
169 "lat-eng"
170 "lit-eng"
171 "mkd-bul"
172 "nld-deu"
173 "nld-eng"
174 "nld-fra"
175 "nno-nob"
176 "oci-cat"
177 "pol-gle"
178 "por-deu"
179 "por-eng"
180 "san-deu"
181 "slk-eng"
182 "slv-eng"
183 "spa-ast"
184 "spa-eng"
185 "spa-por"
186 "srp-eng"
187 "swe-eng"
188 "swh-eng"
189 "swh-pol"
190 "tur-deu"
191 "tur-eng"
192 "wol-fra")))
193
194(define %dicod-accounts
195 (list (user-group
196 (name "dicod")
197 (system? #t))
198 (user-account
199 (name "dicod")
200 (group "dicod")
201 (system? #t)
202 (home-directory "/var/empty")
203 (shell (file-append shadow "/sbin/nologin")))))
204
205(define (dicod-configuration-file config)
206 (define handler->text
207 (match-lambda
208 (($ <dicod-handler> name #f '())
209 `("
210load-module " ,name ";"))
211 (($ <dicod-handler> name #f options)
212 (handler->text (dicod-handler
213 (name name)
214 (module name)
215 (options options))))
216 (($ <dicod-handler> name module options)
217 `("
218load-module " ,name " {
219 command \"" ,module (string-join (list ,@options) " " 'prefix) "\";
220}\n"))))
221
222 (define database->text
223 (match-lambda
224 (($ <dicod-database> name handler #f options)
225 (append
226 (handler->text (dicod-handler
227 (name handler)))
228 (database->text (dicod-database
229 (name name)
230 (handler handler)
231 (complex? #t)
232 (options options)))))
233 (($ <dicod-database> name handler complex? options)
234 `("
235database {
236 name \"" ,name "\";
237 handler \"" ,handler
238 (string-join (list ,@options) " " 'prefix) "\";
239}\n"))))
240
241 (define configuration->text
242 (match-lambda
243 (($ <dicod-configuration> dico (interfaces ...) handlers databases)
244 (append `("listen ("
245 ,(string-join interfaces ", ") ");\n")
246 (append-map handler->text handlers)
247 (append-map database->text databases)))))
248
249 (apply mixed-text-file "dicod.conf" (configuration->text config)))
250
251(define (dicod-shepherd-service config)
252 (define dict-port
253 ;; The default 'dict' port. This is normally specified in /etc/services
254 ;; but provide it here in case /etc/services is missing as is the case in
255 ;; a build environment where we'd run 'shepherd --dry-run'.
256 2628)
257
258 (let* ((dicod.conf (dicod-configuration-file config))
259 (interfaces (dicod-configuration-interfaces config))
260 (home-service? (dicod-configuration-home-service? config))
261 (mappings `(,@(if home-service?
262 '()
263 (list (file-system-mapping
264 (source "/dev/log")
265 (target source))))
266 ,(file-system-mapping
267 (source dicod.conf)
268 (target source))))
269 (dicod (least-authority-wrapper
270 (file-append (dicod-configuration-dico config)
271 "/bin/dicod")
272 #:name "dicod"
273 #:mappings mappings
274 #:namespaces (delq 'net %namespaces))))
275 (list (shepherd-service
276 (provision '(dicod))
277 (requirement (if home-service?
278 '()
279 '(user-processes)))
280 (documentation "Run the dicod daemon.")
281 (start #~(make-inetd-constructor
282 (list #$dicod "--inetd" "--foreground"
283 (string-append "--config=" #$dicod.conf))
284 (map (lambda (interface)
285 (endpoint
286 (addrinfo:addr
287 (car (getaddrinfo interface
288 #$(number->string dict-port)
289 AI_NUMERICSERV)))))
290 '#$interfaces)
291 #:requirements '#$requirement
292 #:user #$(and (not home-service?) "dicod")
293 #:group #$(and (not home-service?) "dicod")
294 #:service-name-stem "dicod"))
295 (stop #~(make-inetd-destructor))
296 (actions (list (shepherd-configuration-action dicod.conf)))))))
297
298(define dicod-service-type
299 (service-type
300 (name 'dict)
301 (extensions
302 (list (service-extension account-service-type
303 (const %dicod-accounts))
304 (service-extension shepherd-root-service-type
305 dicod-shepherd-service)))
306 (default-value (dicod-configuration))
307 (description
308 "Run @command{dicod}, the dictionary server of
309@uref{https://www.gnu.org/software/dico, GNU Dico}. @command{dicod}
310implements the standard DICT protocol supported by clients such as
311@command{dico} and GNOME Dictionary.")))
312
313(define-deprecated (dicod-service #:key (config (dicod-configuration)))
314 dicod-service-type
315 "Return a service that runs the @command{dicod} daemon, an implementation
316of DICT server (@pxref{Dicod,,, dico, GNU Dico Manual}).
317
318The optional @var{config} argument specifies the configuration for
319@command{dicod}, which should be a @code{<dicod-configuration>} object, by
320default it serves the GNU Collaborative International Dictionary of English.
321
322You can add @command{open localhost} to your @file{~/.dico} file to make
323@code{localhost} the default server for @command{dico}
324client (@pxref{Initialization File,,, dico, GNU Dico Manual})."
325 (service dicod-service-type config))