From 3c78f5b5c341aa741a39417e6007dbaf369438f8 Mon Sep 17 00:00:00 2001 From: Ludovic Courtès Date: Tue, 3 Jul 2018 15:29:37 +0200 Subject: tests: basic: Wait for /var/run/shepherd/socket to be ready. * gnu/tests/base.scm (run-basic-test)["shepherd socket ready"]: New test. --- gnu/tests/base.scm | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'gnu/tests') diff --git a/gnu/tests/base.scm b/gnu/tests/base.scm index 4c24cf57f67..0efb4a6e55a 100644 --- a/gnu/tests/base.scm +++ b/gnu/tests/base.scm @@ -100,6 +100,23 @@ initialization step, such as entering a LUKS passphrase." version) (string-prefix? architecture %host-type))))) + ;; Shepherd reads the config file *before* binding its control + ;; socket, so /var/run/shepherd/socket might not exist yet when the + ;; 'marionette' service is started. + (test-assert "shepherd socket ready" + (marionette-eval + `(begin + (use-modules (gnu services herd)) + (let loop ((i 10)) + (cond ((file-exists? (%shepherd-socket-file)) + #t) + ((> i 0) + (sleep 1) + (loop (- i 1))) + (else + #f)))) + marionette)) + (test-assert "shell and user commands" ;; Is everything in $PATH? (zero? (marionette-eval '(system " -- cgit v1.3 From a33652ee336ae9a5d2ab5fd54bf2397caec42a0e Mon Sep 17 00:00:00 2001 From: Gábor Boskovits Date: Mon, 18 Jun 2018 12:43:42 +0200 Subject: services: Add prometheus-node-exporter-service-type. * gnu/services/monitoring.scm (prometheus-node-exporter-service-type): New variable. (): New record type. (prometheus-node-exporter-shepherd-service): New procedure. * gnu/doc/guix.texi (Monitoring Services): Document it. * gnu/tests/monitoring.scm: New file. * gnu/local.mk (GNU_SYSTEM_MODULES): Add test module. --- doc/guix.texi | 36 ++++++++++++++++- gnu/local.mk | 3 +- gnu/packages/monitoring.scm | 1 + gnu/services/monitoring.scm | 38 +++++++++++++++++- gnu/tests/monitoring.scm | 97 +++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 172 insertions(+), 3 deletions(-) create mode 100644 gnu/tests/monitoring.scm (limited to 'gnu/tests') diff --git a/doc/guix.texi b/doc/guix.texi index a458c7c8dd7..3f0eedd0d90 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -48,7 +48,8 @@ Copyright @copyright{} 2017 nee@* Copyright @copyright{} 2018 Rutger Helling@* Copyright @copyright{} 2018 Oleg Pykhalov@* Copyright @copyright{} 2018 Mike Gerwitz@* -Copyright @copyright{} 2018 Pierre-Antoine Rouby +Copyright @copyright{} 2018 Pierre-Antoine Rouby@* +Copyright @copyright{} 2018 Gábor Boskovits@* Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or @@ -15649,6 +15650,39 @@ Specify the path of the base URL. This can be useful if @end table @end deftp +@subsubheading Prometheus Node Exporter Service + +@cindex prometheus-node-exporter +The Prometheus ``node exporter'' makes hardware and operating system statistics +provided by the Linux kernel available for the Prometheus monitoring system. +This service should be deployed on all physical nodes and virtual machines, +where monitoring these statistics is desirable. + +@defvr {Scheme variable} prometheus-node-exporter-service-type +This is the service type for the +@uref{https://github.com/prometheus/node_exporter/, prometheus-node-exporter} +service, its value must be a @code{prometheus-node-exporter-configuration} +record as in this example: + +@example +(service prometheus-node-exporter-service-type + (prometheus-node-exporter-configuration + (web-listen-address ":9100"))) +@end example +@end defvar + +@deftp {Data Type} prometheus-node-exporter-configuration +Data type representing the configuration of @command{node_exporter}. + +@table @asis +@item @code{package} (default: @code{go-github-com-prometheus-node-exporter}) +The prometheus-node-exporter package to use. + +@item @code{web-listen-address} (default: @code{":9100"}) +Bind the web interface to the specified address. + +@end table +@end deftp @node Kerberos Services @subsubsection Kerberos Services diff --git a/gnu/local.mk b/gnu/local.mk index dad664ca152..eb245e32687 100644 --- a/gnu/local.mk +++ b/gnu/local.mk @@ -15,7 +15,7 @@ # Copyright © 2017 Tobias Geerinckx-Rice # Copyright © 2017, 2018 Clément Lassieur # Copyright © 2017 Mathieu Othacehe -# Copyright © 2017 Gábor Boskovits +# Copyright © 2017, 2018 Gábor Boskovits # Copyright © 2018 Amirouche Boubekki # Copyright © 2018 Oleg Pykhalov # @@ -530,6 +530,7 @@ GNU_SYSTEM_MODULES = \ %D%/tests/databases.scm \ %D%/tests/desktop.scm \ %D%/tests/dict.scm \ + %D%/tests/monitoring.scm \ %D%/tests/nfs.scm \ %D%/tests/install.scm \ %D%/tests/mail.scm \ diff --git a/gnu/packages/monitoring.scm b/gnu/packages/monitoring.scm index db6c22a69cb..fae62d5493e 100644 --- a/gnu/packages/monitoring.scm +++ b/gnu/packages/monitoring.scm @@ -3,6 +3,7 @@ ;;; Copyright © 2018 Sou Bunnbu ;;; Copyright © 2017, 2018 Ricardo Wurmus ;;; Copyright © 2018 Tobias Geerinckx-Rice +;;; Copyright © 2018 Gábor Boskovits ;;; ;;; This file is part of GNU Guix. ;;; diff --git a/gnu/services/monitoring.scm b/gnu/services/monitoring.scm index 49a65db4b53..aa3b63a0e4e 100644 --- a/gnu/services/monitoring.scm +++ b/gnu/services/monitoring.scm @@ -1,5 +1,6 @@ ;;; GNU Guix --- Functional package management for GNU ;;; Copyright © 2018 Sou Bunnbu +;;; Copyright © 2018 Gábor Boskovits ;;; ;;; This file is part of GNU Guix. ;;; @@ -26,7 +27,9 @@ #:use-module (guix records) #:use-module (ice-9 match) #:export (darkstat-configuration - darkstat-service-type)) + prometheus-node-exporter-configuration + darkstat-service-type + prometheus-node-exporter-service-type)) ;;; @@ -89,3 +92,36 @@ HTTP.") (const %darkstat-accounts)) (service-extension shepherd-root-service-type (compose list darkstat-shepherd-service)))))) + +(define-record-type* + prometheus-node-exporter-configuration + make-prometheus-node-exporter-configuration + prometheus-node-exporter-configuration? + (package prometheus-node-exporter-configuration-package + (default go-github-com-prometheus-node-exporter)) + (web-listen-address prometheus-node-exporter-web-listen-address + (default ":9100"))) + +(define prometheus-node-exporter-shepherd-service + (match-lambda + (( $ + package web-listen-address) + (shepherd-service + (documentation "Prometheus node exporter.") + (provision '(prometheus-node-exporter)) + (requirement '(networking)) + (start #~(make-forkexec-constructor + (list #$(file-append package "/bin/node_exporter") + "--web.listen-address" #$web-listen-address))) + (stop #~(make-kill-destructor)))))) + +(define prometheus-node-exporter-service-type + (service-type + (name 'prometheus-node-exporter) + (description + "Run @command{node_exporter} to serve hardware and OS metrics to +prometheus.") + (extensions + (list (service-extension + shepherd-root-service-type + (compose list prometheus-node-exporter-shepherd-service)))))) diff --git a/gnu/tests/monitoring.scm b/gnu/tests/monitoring.scm new file mode 100644 index 00000000000..67899987cef --- /dev/null +++ b/gnu/tests/monitoring.scm @@ -0,0 +1,97 @@ +;;; GNU Guix --- Functional package management for GNU +;;; Copyright © 2018 Gábor Boskovits +;;; +;;; This file is part of GNU Guix. +;;; +;;; GNU Guix is free software; you can redistribute it and/or modify it +;;; under the terms of the GNU General Public License as published by +;;; the Free Software Foundation; either version 3 of the License, or (at +;;; your option) any later version. +;;; +;;; GNU Guix is distributed in the hope that it will be useful, but +;;; WITHOUT ANY WARRANTY; without even the implied warranty of +;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;;; GNU General Public License for more details. +;;; +;;; You should have received a copy of the GNU General Public License +;;; along with GNU Guix. If not, see . + +(define-module (gnu tests monitoring) + #:use-module (gnu services) + #:use-module (gnu services monitoring) + #:use-module (gnu services networking) + #:use-module (gnu system vm) + #:use-module (gnu tests) + #:use-module (guix gexp) + #:export (%test-prometheus-node-exporter)) + + +;;; +;;; Prometheus Node Exporter +;;; + +(define* (run-prometheus-node-exporter-server-test name test-os) + "Run tests in %PROMETHEUS-NODE-EXPORTER-OS, which has prometheus-node-exporter running." + (define os + (marionette-operating-system + test-os + #:imported-modules '((gnu services herd)))) + + (define vm + (virtual-machine + (operating-system os) + (port-forwardings '((8080 . 9100))))) + + (define test + (with-imported-modules '((gnu build marionette)) + #~(begin + (use-modules (srfi srfi-11) + (srfi srfi-64) + (gnu build marionette) + (web client) + (web response)) + + (define marionette + (make-marionette (list #$vm))) + + (mkdir #$output) + (chdir #$output) + + (test-begin #$name) + + (test-assert "prometheus-node-exporter running" + (marionette-eval + '(begin + (use-modules (gnu services herd)) + (match (start-service 'prometheus-node-exporter) + (#f #f) + (('service response-parts ...) + (match (assq-ref response-parts 'running) + ((pid) (number? pid)))))) + marionette)) + + (test-equal "http-get" + 200 + (begin + (wait-for-tcp-port 9100 marionette) + (let-values (((response text) + (http-get "http://localhost:8080"))) + (response-code response)))) + + (test-end) + (exit (= (test-runner-fail-count (test-runner-current)) 0))))) + + (gexp->derivation (string-append name "-test") test)) + +(define %prometheus-node-exporter-os + (simple-operating-system + (dhcp-client-service) + (service prometheus-node-exporter-service-type + (prometheus-node-exporter-configuration)))) + +(define %test-prometheus-node-exporter + (system-test + (name "prometheus-node-exporter") + (description "Connect to a running prometheus-node-exporter server.") + (value (run-prometheus-node-exporter-server-test + name %prometheus-node-exporter-os)))) -- cgit v1.3 From 147c5aa5d4e3bd21ee4c4cae70dff8da0bcf94b7 Mon Sep 17 00:00:00 2001 From: Ludovic Courtès Date: Wed, 11 Jul 2018 23:40:57 +0200 Subject: services: mcron: Add 'schedule' action. Inspired by . * gnu/services/mcron.scm (shepherd-schedule-action): New procedure. (mcron-shepherd-services): Add 'actions' field. * gnu/tests/base.scm (run-mcron-test)["schedule action"]: New test. * doc/guix.texi (Scheduled Job Execution): Mention 'herd schedule'. --- doc/guix.texi | 15 ++++++++++ gnu/services/herd.scm | 3 ++ gnu/services/mcron.scm | 76 +++++++++++++++++++++++++++++++++++++++----------- gnu/tests/base.scm | 7 +++++ 4 files changed, 84 insertions(+), 17 deletions(-) (limited to 'gnu/tests') diff --git a/doc/guix.texi b/doc/guix.texi index 34012a357b6..eaec4c422be 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -10850,6 +10850,21 @@ gexps to introduce job definitions that are passed to mcron for more information on mcron job specifications. Below is the reference of the mcron service. +On a running system, you can use the @code{schedule} action of the service to +visualize the mcron jobs that will be executed next: + +@example +# herd schedule mcron +@end example + +@noindent +The example above lists the next five tasks that will be executed, but you can +also specify the number of tasks to display: + +@example +# herd schedule mcron 10 +@end example + @deffn {Scheme Procedure} mcron-service @var{jobs} [#:mcron @var{mcron}] Return an mcron service running @var{mcron} that schedules @var{jobs}, a list of gexps denoting mcron job specifications. diff --git a/gnu/services/herd.scm b/gnu/services/herd.scm index d882c232cf3..8c96b70731e 100644 --- a/gnu/services/herd.scm +++ b/gnu/services/herd.scm @@ -45,6 +45,7 @@ live-service-requirement live-service-running + with-shepherd-action current-services unload-services unload-service @@ -168,6 +169,8 @@ return #f." (define-syntax-rule (with-shepherd-action service (action args ...) result body ...) + "Invoke ACTION on SERVICE with the given ARGS, and evaluate BODY with RESULT +bound to the action's result." (invoke-action service action (list args ...) (lambda (result) body ...))) diff --git a/gnu/services/mcron.scm b/gnu/services/mcron.scm index 5bee02a5872..5757bf8cf69 100644 --- a/gnu/services/mcron.scm +++ b/gnu/services/mcron.scm @@ -60,29 +60,71 @@ (define (job-file job) (scheme-file "mcron-job" job)) +(define (shepherd-schedule-action mcron files) + "Return a Shepherd action that runs MCRON with '--schedule' for the given +files." + (shepherd-action + (name 'schedule) + (documentation + "Display jobs that are going to be scheduled.") + (procedure + #~(lambda* (_ #:optional (n "5")) + ;; XXX: This is a global side effect. + (setenv "GUILE_AUTO_COMPILE" "0") + + ;; Run 'mcron' in a pipe so we can explicitly redirect its output to + ;; 'current-output-port', which at this stage is bound to the client + ;; connection. + (let ((pipe (open-pipe* OPEN_READ + #$(file-append mcron "/bin/mcron") + (string-append "--schedule=" n) + #$@files))) + (let loop () + (match (read-line pipe 'concat) + ((? eof-object?) + (catch 'system-error + (lambda () + (zero? (close-pipe pipe))) + (lambda args + ;; There's with race between the SIGCHLD handler, which + ;; could call 'waitpid' before 'close-pipe' above does. If + ;; we get ECHILD, that means we lost the race, but that's + ;; fine. + (or (= ECHILD (system-error-errno args)) + (apply throw args))))) + (line + (display line) + (loop))))))))) + (define mcron-shepherd-services (match-lambda (($ mcron ()) ;nothing to do! '()) (($ mcron jobs) - (list (shepherd-service - (provision '(mcron)) - (requirement '(user-processes)) - (modules `((srfi srfi-1) - (srfi srfi-26) - ,@%default-modules)) - (start #~(make-forkexec-constructor - (list (string-append #$mcron "/bin/mcron") - #$@(map job-file jobs)) + (let ((files (map job-file jobs))) + (list (shepherd-service + (provision '(mcron)) + (requirement '(user-processes)) + (modules `((srfi srfi-1) + (srfi srfi-26) + (ice-9 popen) ;for the 'schedule' action + (ice-9 rdelim) + (ice-9 match) + ,@%default-modules)) + (start #~(make-forkexec-constructor + (list (string-append #$mcron "/bin/mcron") #$@files) + + ;; Disable auto-compilation of the job files and set a + ;; sane value for 'PATH'. + #:environment-variables + (cons* "GUILE_AUTO_COMPILE=0" + "PATH=/run/current-system/profile/bin" + (remove (cut string-prefix? "PATH=" <>) + (environ))))) + (stop #~(make-kill-destructor)) - ;; Disable auto-compilation of the job files and set a - ;; sane value for 'PATH'. - #:environment-variables - (cons* "GUILE_AUTO_COMPILE=0" - "PATH=/run/current-system/profile/bin" - (remove (cut string-prefix? "PATH=" <>) - (environ))))) - (stop #~(make-kill-destructor))))))) + (actions + (list (shepherd-schedule-action mcron files))))))))) (define mcron-service-type (service-type (name 'mcron) diff --git a/gnu/tests/base.scm b/gnu/tests/base.scm index 0efb4a6e55a..f27064af857 100644 --- a/gnu/tests/base.scm +++ b/gnu/tests/base.scm @@ -632,6 +632,13 @@ non-ASCII names from /tmp.") (wait-for-file "/root/witness-touch" marionette #:read '(@ (ice-9 rdelim) read-string))) + ;; Make sure the 'schedule' action is accepted. + (test-equal "schedule action" + '(#t) ;one value, #t + (marionette-eval '(with-shepherd-action 'mcron ('schedule) result + result) + marionette)) + (test-end) (exit (= (test-runner-fail-count (test-runner-current)) 0))))) -- cgit v1.3