summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristopher Baines <mail@cbaines.net>2017-06-24 14:19:46 +0100
committerChristopher Baines <mail@cbaines.net>2017-07-29 12:45:03 +0100
commit730ed6ec8b69a0f908a8aadbbe0555dd45de227c (patch)
tree68448b94cc257c8b034a668ca6b45f4712e7b86b
parentb5244fcb49804922e34fffb18d71908dac37b303 (diff)
gnu: services: admin: Add tailon.
* gnu/services/admin.scm (<tailon-configuration>, <tailon-configuration-file>): New record types. (tailon-configuration-files-string, tailon-shepherd-service): New procedures. (%tailon-accounts, tailon-service-type: New variables. * doc/guix.texi (Monitoring Services: Document the Tailon service. * gnu/local.mk (GNU_SYSTEM_MODULES): Add gnu/tests/admin.scm. * gnu/tests/admin.scm: New file.
-rw-r--r--doc/guix.texi90
-rw-r--r--gnu/local.mk1
-rw-r--r--gnu/services/admin.scm151
-rw-r--r--gnu/tests/admin.scm128
4 files changed, 369 insertions, 1 deletions
diff --git a/doc/guix.texi b/doc/guix.texi
index e8c4e0eaf3a..34528503168 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -219,6 +219,7 @@ Services
219* Database Services:: SQL databases. 219* Database Services:: SQL databases.
220* Mail Services:: IMAP, POP3, SMTP, and all that. 220* Mail Services:: IMAP, POP3, SMTP, and all that.
221* Messaging Services:: Messaging services. 221* Messaging Services:: Messaging services.
222* Monitoring Services:: Monitoring services.
222* Kerberos Services:: Kerberos services. 223* Kerberos Services:: Kerberos services.
223* Web Services:: Web servers. 224* Web Services:: Web servers.
224* DNS Services:: DNS daemons. 225* DNS Services:: DNS daemons.
@@ -9011,6 +9012,7 @@ declaration.
9011* Database Services:: SQL databases. 9012* Database Services:: SQL databases.
9012* Mail Services:: IMAP, POP3, SMTP, and all that. 9013* Mail Services:: IMAP, POP3, SMTP, and all that.
9013* Messaging Services:: Messaging services. 9014* Messaging Services:: Messaging services.
9015* Monitoring Services:: Monitoring services.
9014* Kerberos Services:: Kerberos services. 9016* Kerberos Services:: Kerberos services.
9015* Web Services:: Web servers. 9017* Web Services:: Web servers.
9016* DNS Services:: DNS daemons. 9018* DNS Services:: DNS daemons.
@@ -13599,6 +13601,94 @@ string, you could instantiate a prosody service like this:
13599 (prosody.cfg.lua ""))) 13601 (prosody.cfg.lua "")))
13600@end example 13602@end example
13601 13603
13604@node Monitoring Services
13605@subsubsection Monitoring Services
13606
13607@subsubheading Tailon Service
13608
13609@uref{https://tailon.readthedocs.io/, Tailon} is a web application for
13610viewing and searching log files.
13611
13612The following example will configure the service with default values.
13613By default, Tailon can be accessed on port 8080 (@code{http://localhost:8080}).
13614
13615@example
13616(service tailon-service-type)
13617@end example
13618
13619The following example customises more of the Tailon configuration,
13620adding @command{sed} to the list of allowed commands.
13621
13622@example
13623(service tailon-service-type
13624 (tailon-configuration
13625 (config-file
13626 (tailon-configuration-file
13627 (allowed-commands '("tail" "grep" "awk" "sed"))))))
13628@end example
13629
13630
13631@deftp {Data Type} tailon-configuration
13632Data type representing the configuration of Tailon.
13633This type has the following parameters:
13634
13635@table @asis
13636@item @code{config-file} (default: @code{(tailon-configuration-file)})
13637The configuration file to use for Tailon. This can be set to a
13638@dfn{tailon-configuration-file} record value, or any gexp
13639(@pxref{G-Expressions}).
13640
13641For example, to instead use a local file, the @code{local-file} function
13642can be used:
13643
13644@example
13645(service tailon-service-type
13646 (tailon-configuration
13647 (config-file (local-file "./my-tailon.conf"))))
13648@end example
13649
13650@item @code{package} (default: @code{tailon})
13651The tailon package to use.
13652
13653@end table
13654@end deftp
13655
13656@deftp {Data Type} tailon-configuration-file
13657Data type representing the configuration options for Tailon.
13658This type has the following parameters:
13659
13660@table @asis
13661@item @code{files} (default: @code{(list "/var/log")})
13662List of files to display. The list can include strings for a single file
13663or directory, or a list, where the first item is the name of a
13664subsection, and the remaining items are the files or directories in that
13665subsection.
13666
13667@item @code{bind} (default: @code{"localhost:8080"})
13668Address and port to which Tailon should bind on.
13669
13670@item @code{relative-root} (default: @code{#f})
13671URL path to use for Tailon, set to @code{#f} to not use a path.
13672
13673@item @code{allow-transfers?} (default: @code{#t})
13674Allow downloading the log files in the web interface.
13675
13676@item @code{follow-names?} (default: @code{#t})
13677Allow tailing of not-yet existent files.
13678
13679@item @code{tail-lines} (default: @code{200})
13680Number of lines to read initially from each file.
13681
13682@item @code{allowed-commands} (default: @code{(list "tail" "grep" "awk")})
13683Commands to allow running. By default, @code{sed} is disabled.
13684
13685@item @code{debug?} (default: @code{#f})
13686Set @code{debug?} to @code{#t} to show debug messages.
13687
13688@end table
13689@end deftp
13690
13691
13602@node Kerberos Services 13692@node Kerberos Services
13603@subsubsection Kerberos Services 13693@subsubsection Kerberos Services
13604@cindex Kerberos 13694@cindex Kerberos
diff --git a/gnu/local.mk b/gnu/local.mk
index 724c6b6758c..29dee73c464 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -478,6 +478,7 @@ GNU_SYSTEM_MODULES = \
478 %D%/build/vm.scm \ 478 %D%/build/vm.scm \
479 \ 479 \
480 %D%/tests.scm \ 480 %D%/tests.scm \
481 %D%/tests/admin.scm \
481 %D%/tests/base.scm \ 482 %D%/tests/base.scm \
482 %D%/tests/dict.scm \ 483 %D%/tests/dict.scm \
483 %D%/tests/nfs.scm \ 484 %D%/tests/nfs.scm \
diff --git a/gnu/services/admin.scm b/gnu/services/admin.scm
index b9e3fa70a45..1044833fef0 100644
--- a/gnu/services/admin.scm
+++ b/gnu/services/admin.scm
@@ -20,14 +20,19 @@
20(define-module (gnu services admin) 20(define-module (gnu services admin)
21 #:use-module (gnu packages admin) 21 #:use-module (gnu packages admin)
22 #:use-module (gnu packages base) 22 #:use-module (gnu packages base)
23 #:use-module (gnu packages logging)
23 #:use-module (gnu services) 24 #:use-module (gnu services)
24 #:use-module (gnu services mcron) 25 #:use-module (gnu services mcron)
25 #:use-module (gnu services shepherd) 26 #:use-module (gnu services shepherd)
27 #:use-module (gnu services web)
28 #:use-module (gnu system shadow)
26 #:use-module (guix gexp) 29 #:use-module (guix gexp)
30 #:use-module (guix store)
27 #:use-module (guix packages) 31 #:use-module (guix packages)
28 #:use-module (guix records) 32 #:use-module (guix records)
29 #:use-module (srfi srfi-1) 33 #:use-module (srfi srfi-1)
30 #:use-module (ice-9 vlist) 34 #:use-module (ice-9 vlist)
35 #:use-module (ice-9 match)
31 #:export (%default-rotations 36 #:export (%default-rotations
32 %rotated-files 37 %rotated-files
33 38
@@ -41,7 +46,27 @@
41 rottlog-configuration 46 rottlog-configuration
42 rottlog-configuration? 47 rottlog-configuration?
43 rottlog-service 48 rottlog-service
44 rottlog-service-type)) 49 rottlog-service-type
50
51 <tailon-configuration-file>
52 tailon-configuration-file
53 tailon-configuration-file?
54 tailon-configuration-file-files
55 tailon-configuration-file-bind
56 tailon-configuration-file-relative-root
57 tailon-configuration-file-allow-transfers?
58 tailon-configuration-file-follow-names?
59 tailon-configuration-file-tail-lines
60 tailon-configuration-file-allowed-commands
61 tailon-configuration-file-debug?
62
63 <tailon-configuration>
64 tailon-configuration
65 tailon-configuration?
66 tailon-configuration-config-file
67 tailon-configuration-package
68
69 tailon-service-type))
45 70
46;;; Commentary: 71;;; Commentary:
47;;; 72;;;
@@ -172,4 +197,128 @@ for ROTATION."
172 rotations))))) 197 rotations)))))
173 (default-value (rottlog-configuration)))) 198 (default-value (rottlog-configuration))))
174 199
200
201;;;
202;;; Tailon
203;;;
204
205(define-record-type* <tailon-configuration-file>
206 tailon-configuration-file make-tailon-configuration-file
207 tailon-configuration-file?
208 (files tailon-configuration-file-files
209 (default '("/var/log")))
210 (bind tailon-configuration-file-bind
211 (default "localhost:8080"))
212 (relative-root tailon-configuration-file-relative-root
213 (default #f))
214 (allow-transfers? tailon-configuration-file-allow-transfers?
215 (default #t))
216 (follow-names? tailon-configuration-file-follow-names?
217 (default #t))
218 (tail-lines tailon-configuration-file-tail-lines
219 (default 200))
220 (allowed-commands tailon-configuration-file-allowed-commands
221 (default '("tail" "grep" "awk")))
222 (debug? tailon-configuration-file-debug?
223 (default #f)))
224
225(define (tailon-configuration-files-string files)
226 (string-append
227 "\n"
228 (string-join
229 (map
230 (lambda (x)
231 (string-append
232 " - "
233 (cond
234 ((string? x)
235 (simple-format #f "'~A'" x))
236 ((list? x)
237 (string-join
238 (cons (simple-format #f "'~A':" (car x))
239 (map
240 (lambda (x) (simple-format #f " - '~A'" x))
241 (cdr x)))
242 "\n"))
243 (else (error x)))))
244 files)
245 "\n")))
246
247(define-gexp-compiler (tailon-configuration-file-compiler
248 (file <tailon-configuration-file>) system target)
249 (match file
250 (($ <tailon-configuration-file> files bind relative-root
251 allow-transfers? follow-names?
252 tail-lines allowed-commands debug?)
253 (text-file
254 "tailon-config.yaml"
255 (string-concatenate
256 (filter-map
257 (match-lambda
258 ((key . #f) #f)
259 ((key . value) (string-append key ": " value "\n")))
260
261 `(("files" . ,(tailon-configuration-files-string files))
262 ("bind" . ,bind)
263 ("relative-root" . ,relative-root)
264 ("allow-transfers" . ,(if allow-transfers? "true" "false"))
265 ("follow-names" . ,(if follow-names? "true" "false"))
266 ("tail-lines" . ,(number->string tail-lines))
267 ("commands" . ,(string-append "["
268 (string-join allowed-commands ", ")
269 "]"))
270 ,@(if debug? '(("debug" . "true")) '()))))))))
271
272(define-record-type* <tailon-configuration>
273 tailon-configuration make-tailon-configuration
274 tailon-configuration?
275 (config-file tailon-configuration-config-file
276 (default (tailon-configuration-file)))
277 (package tailon-configuration-package
278 (default tailon)))
279
280(define tailon-shepherd-service
281 (match-lambda
282 (($ <tailon-configuration> config-file package)
283 (list (shepherd-service
284 (provision '(tailon))
285 (documentation "Run the tailon daemon.")
286 (start #~(make-forkexec-constructor
287 `(,(string-append #$package "/bin/tailon")
288 "-c" ,#$config-file)
289 #:user "tailon"
290 #:group "tailon"))
291 (stop #~(make-kill-destructor)))))))
292
293(define %tailon-accounts
294 (list (user-group (name "tailon") (system? #t))
295 (user-account
296 (name "tailon")
297 (group "tailon")
298 (system? #t)
299 (comment "tailon")
300 (home-directory "/var/empty")
301 (shell (file-append shadow "/sbin/nologin")))))
302
303(define tailon-service-type
304 (service-type
305 (name 'tailon)
306 (extensions
307 (list (service-extension shepherd-root-service-type
308 tailon-shepherd-service)
309 (service-extension account-service-type
310 (const %tailon-accounts))))
311 (compose concatenate)
312 (extend (lambda (parameter files)
313 (tailon-configuration
314 (inherit parameter)
315 (config-file
316 (let ((old-config-file
317 (tailon-configuration-config-file parameter)))
318 (tailon-configuration-file
319 (inherit old-config-file)
320 (files (append (tailon-configuration-file-files old-config-file)
321 files))))))))
322 (default-value (tailon-configuration))))
323
175;;; admin.scm ends here 324;;; admin.scm ends here
diff --git a/gnu/tests/admin.scm b/gnu/tests/admin.scm
new file mode 100644
index 00000000000..3c7deb54268
--- /dev/null
+++ b/gnu/tests/admin.scm
@@ -0,0 +1,128 @@
1;;; GNU Guix --- Functional package management for GNU
2;;; Copyright © 2017 Christopher Baines <mail@cbaines.net>
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 tests admin)
20 #:use-module (gnu tests)
21 #:use-module (gnu system)
22 #:use-module (gnu system file-systems)
23 #:use-module (gnu system shadow)
24 #:use-module (gnu system vm)
25 #:use-module (gnu services)
26 #:use-module (gnu services admin)
27 #:use-module (gnu services networking)
28 #:use-module (guix gexp)
29 #:use-module (guix store)
30 #:use-module (guix monads)
31 #:export (%test-tailon))
32
33(define %tailon-os
34 ;; Operating system under test.
35 (simple-operating-system
36 (dhcp-client-service)
37 (service tailon-service-type
38 (tailon-configuration
39 (config-file
40 (tailon-configuration-file
41 (bind "0.0.0.0:8080")))))))
42
43(define* (run-tailon-test #:optional (http-port 8081))
44 "Run tests in %TAILON-OS, which has tailon running and listening on
45HTTP-PORT."
46 (define os
47 (marionette-operating-system
48 %tailon-os
49 #:imported-modules '((gnu services herd)
50 (guix combinators))))
51
52 (define vm
53 (virtual-machine
54 (operating-system os)
55 (port-forwardings `((,http-port . 8080)))))
56
57 (define test
58 (with-imported-modules '((gnu build marionette))
59 #~(begin
60 (use-modules (srfi srfi-11) (srfi srfi-64)
61 (ice-9 match)
62 (gnu build marionette)
63 (web uri)
64 (web client)
65 (web response))
66
67 (define marionette
68 ;; Forward the guest's HTTP-PORT, where tailon is listening, to
69 ;; port 8080 in the host.
70 (make-marionette (list #$vm)))
71
72 (mkdir #$output)
73 (chdir #$output)
74
75 (test-begin "tailon")
76
77 (test-eq "service running"
78 'running!
79 (marionette-eval
80 '(begin
81 (use-modules (gnu services herd))
82 (start-service 'tailon)
83 'running!)
84 marionette))
85
86 (define* (retry-on-error f #:key times delay)
87 (let loop ((attempt 1))
88 (match (catch
89 #t
90 (lambda ()
91 (cons #t
92 (f)))
93 (lambda args
94 (cons #f
95 args)))
96 ((#t . return-value)
97 return-value)
98 ((#f . error-args)
99 (if (>= attempt times)
100 error-args
101 (begin
102 (sleep delay)
103 (loop (+ 1 attempt))))))))
104
105 (test-equal "http-get"
106 200
107 (retry-on-error
108 (lambda ()
109 (let-values (((response text)
110 (http-get #$(format
111 #f
112 "http://localhost:~A/"
113 http-port)
114 #:decode-body? #t)))
115 (response-code response)))
116 #:times 10
117 #:delay 5))
118
119 (test-end)
120 (exit (= (test-runner-fail-count (test-runner-current)) 0)))))
121
122 (gexp->derivation "tailon-test" test))
123
124(define %test-tailon
125 (system-test
126 (name "tailon")
127 (description "Connect to a running Tailon server.")
128 (value (run-tailon-test))))