aboutsummaryrefslogtreecommitdiff
path: root/gnu/services/mcron.scm
blob: 0e0d07d2523bf332cbe862f8afed6126ce6dccf2 (about) (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2016-2020, 2023 Ludovic Courtès <ludo@gnu.org>
;;; Copyright © 2022 Maxim Cournoyer <maxim.cournoyer@gmail.com>
;;; Copyright © 2023 Bruno Victal <mirai@makinata.eu>
;;;
;;; 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 <http://www.gnu.org/licenses/>.

(define-module (gnu services mcron)
  #:use-module (gnu services)
  #:use-module (gnu services shepherd)
  #:use-module (gnu packages guile-xyz)
  #:use-module (guix records)
  #:use-module (guix gexp)
  #:use-module (srfi srfi-1)
  #:use-module (ice-9 match)
  #:use-module (ice-9 vlist)
  #:export (mcron-configuration
            mcron-configuration?
            mcron-configuration-mcron
            mcron-configuration-jobs
            mcron-configuration-log?
            mcron-configuration-log-file
            mcron-configuration-log-format
            mcron-configuration-date-format
            mcron-configuration-home-service?

            mcron-service-type))

;;; Commentary:
;;;
;;; This module implements a service that to run instances of GNU mcron, a
;;; periodic job execution daemon.  Example of a service:
;;
;;  (service mcron-service-type
;;           (mcron-configuration
;;            (jobs (list #~(job next-second-from
;;                               (lambda ()
;;                                 (call-with-output-file "/dev/console"
;;                                   (lambda (port)
;;                                     (display "hello!\n" port)))))))))
;;;
;;; Code:

;; Configuration of mcron.
;; XXX: 'define-configuration' cannot be used here due to the need for
;; 'thunked' and 'innate' fields as well as 'this-mcron-configuration'.
(define-record-type* <mcron-configuration> mcron-configuration
  make-mcron-configuration
  mcron-configuration?
  this-mcron-configuration

  (mcron       mcron-configuration-mcron          ;file-like
               (default mcron))
  (jobs        mcron-configuration-jobs           ;list of gexps
               (default '()))
  (log?        mcron-configuration-log?           ;Boolean
               (default #t))
  (log-file    mcron-configuration-log-file       ;string | gexp
               (thunked)
               (default
                 (if (mcron-configuration-home-service?
                      this-mcron-configuration)
                     #~(string-append %user-log-dir "/mcron.log")
                     "/var/log/mcron.log")))
  (log-format  mcron-configuration-log-format     ;string
               (default "~1@*~a ~a: ~a~%"))
  (date-format mcron-configuration-date-format    ;string | #f
               (default #f))

  (home-service? mcron-configuration-home-service?
                 (default for-home?) (innate)))

(define (job-files mcron jobs)
  "Return a list of file-like object for JOBS, a list of gexps."
  (define (validated-file job)
    ;; This procedure behaves like 'scheme-file' but it runs 'mcron
    ;; --schedule' to detect any error in JOB.
    (computed-file "mcron-job"
                   (with-imported-modules '((guix build utils))
                     #~(begin
                         (use-modules (guix build utils))

                         (call-with-output-file "prologue"
                           (lambda (port)
                             ;; This prologue allows 'mcron --schedule' to
                             ;; proceed no matter what #:user option is passed
                             ;; to 'job'.
                             (write '(set! getpw
                                       (const (getpwuid (getuid))))
                                    port)))

                         (call-with-output-file "job"
                           (lambda (port)
                             (write '#$job port)))

                         (invoke #+(file-append mcron "/bin/mcron")
                                 "--schedule=20" "prologue" "job")
                         (copy-file "job" #$output)))
                   #:options '(#:env-vars (("COLUMNS" . "150")))))

  (map validated-file jobs))

(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 a race with 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 config)
  (match-record config <mcron-configuration>
    (mcron jobs log? log-file log-format date-format home-service?)
    (if (eq? jobs '())
        '()                             ;nothing to do
        (let ((files (job-files mcron jobs)))
          (list (shepherd-service
                 (provision '(mcron))
                 (requirement (if home-service?
                                  '()
                                  '(user-processes)))
                 (modules `((srfi srfi-1)
                            (srfi srfi-26)
                            (ice-9 popen) ;for the 'schedule' action
                            (ice-9 rdelim)
                            (ice-9 match)
                            ((shepherd support) #:hide (mkdir-p)) ;for '%user-log-dir'
                            ,@%default-modules))
                 (start #~(make-forkexec-constructor
                           (list #$(file-append mcron "/bin/mcron")
                                 #$@(if log?
                                        `("--log" "--log-format" ,log-format
                                          ,@(if date-format
                                                (list "--date-format"
                                                      date-format)
                                                '()))
                                        '())
                                 #$@files)

                           ;; Disable auto-compilation of the job files and
                           ;; set a sane value for 'PATH'.
                           #:environment-variables
                           (cons* "GUILE_AUTO_COMPILE=0"
                                  #$(if home-service?
                                        '(environ)
                                        '(cons*
                                          "PATH=/run/current-system/profile/bin"
                                          (remove (cut string-prefix? "PATH=" <>)
                                                  (environ)))))

                           #:log-file #$log-file))
                 (stop #~(make-kill-destructor))
                 (actions
                  (list (shepherd-schedule-action mcron files)))))))))

(define mcron-service-type
  (service-type (name 'mcron)
                (description
                 "Run the mcron job scheduling daemon.")
                (extensions
                 (list (service-extension shepherd-root-service-type
                                          mcron-shepherd-services)
                       (service-extension profile-service-type
                                          (compose list
                                                   mcron-configuration-mcron))))
                (compose concatenate)
                (extend (lambda (config jobs)
                          (mcron-configuration
                           (inherit config)
                           (home-service?
                            (mcron-configuration-home-service? config))
                           (jobs (append (mcron-configuration-jobs config)
                                         jobs)))))
                (default-value (mcron-configuration)))) ;empty job list

;;; mcron.scm ends here
d from … * gnu/packages/xml.scm (libxml2, opensp)[native-search-paths]: … here. Refer to the variables from (guix search-paths) respectively. * gnu/packages/perl.scm (perl-app-xml-docbook-builder)[native-search-paths]: Use $XML_CATALOG_FILES. * doc/guix.texi (Search Paths): Update documentation to reflect changes. Signed-off-by: Maxim Cournoyer <maxim.cournoyer@gmail.com> 2024-08-31gnu: git: Install zsh completions and git-prompt.Liliana Marie Prikler * gnu/packages/version-control.scm (git)[#:phases]<install-shell-completion>: Also install git-prompt and zsh _git site function. Signed-off-by: Maxim Cournoyer <maxim.cournoyer@gmail.com> Change-Id: I76c45e117715a13db96ef0dda4ad6ea9af3a1882 2024-08-31gnu: git-minimal: Add coreutils and sed to PATH.Maxim Cournoyer Fixes <https://issues.guix.gnu.org/65924>. * gnu/packages/version-control.scm (git-minimal) [arguments] <imported-modules>: New field. <modules>: Augment with (ice-9 match), (ice-9 textual-ports) and (guix search-paths). <phases>: Add patch-commands phase. [inputs]: Add coreutils-minimal and sed. Reviewed-by: Liliana Marie Prikler <liliana.prikler@gmail.com> Change-Id: I8e3dbbd24ef7f8fa98a392a36617b07fe632cd15 2024-08-31gnu: git: Invert inheritance relationship.Maxim Cournoyer It's simpler to add features on top of a minimal variant than to remove them, and helps avoiding mistakenly changing git-minimal, which has many dependents. * gnu/packages/version-control.scm (git-minimal): Move above git and severe inheritance. Remove input label. Repatriate most fields from... (git): ... here. Define as package/inherit to inherit from git-minimal. Extend minimal values instead of overriding them whole. Reviewed-by: Liliana Marie Prikler <liliana.prikler@gmail.com> Change-Id: Ia0ef0e7e4f007c2fafad3550344638b6661a408b 2024-08-31gnu: git: Remove labels and use gexps.Maxim Cournoyer * gnu/packages/version-control.scm (git) [native-inputs, inputs]: Remove labels. [arguments]: Use gexps. Use gexp variables input searching procedures where it makes sense. Reviewed-by: Liliana Marie Prikler <liliana.prikler@gmail.com> Change-Id: I1c5d0bb5eb9639342c11af94dca2ae2174496459 2024-08-31gnu: socat: Update to 1.7.4.4.Bruno Victal * gnu/packages/networking.scm (socat): Update to 1.7.4.4. [inputs]: Add readline for READLINE support. Signed-off-by: Maxim Cournoyer <maxim.cournoyer@gmail.com> 2024-08-31gnu: perl-xml-xpath: Update to 1.48.Bruno Victal * gnu/packages/xml.scm (perl-xml-xpath): Update to 1.48. [native-inputs]: Add perl-test-leaktrace. Signed-off-by: Maxim Cournoyer <maxim.cournoyer@gmail.com> 2024-08-31gnu: perl-xml-xpath: Wrap xpath command.Bruno Victal * gnu/packages/xml.scm (perl-xml-xpath)[arguments]: Wrap xpath. Add test for wrapped xpath. [description]: Document xpath command presence. Signed-off-by: Maxim Cournoyer <maxim.cournoyer@gmail.com> 2024-08-31gnu: %objc++-search-paths: Express using $LIBRARY_PATH.Maxim Cournoyer * gnu/packages/gcc.scm (%objc++-search-paths): Express using $LIBRARY_PATH. 2024-08-31gnu: gccgo-4.9: Express search paths via (guix search-paths) variables.Maxim Cournoyer * gnu/packages/gcc.scm (gccgo-4.9) [native-search-paths]: Express search paths via (guix search-paths) variables. 2024-08-31gnu: gcc-2.95: Express search paths via (guix search-paths) variables.Maxim Cournoyer * gnu/packages/gcc.scm (gcc-2.95) [native-search-paths]: Express search paths via (guix search-paths) variables. 2024-08-31gnu: gcc-4.7: Use %gcc-search-paths for native-search-paths.Maxim Cournoyer * gnu/packages/gcc.scm (gcc-4.7) [native-search-paths]: Use %gcc-search-paths. Change-Id: Ia9acc98c2f7c7bc101ac43a4288ee4368c2b3dfa 2024-08-31gnu: gawk: Update to 5.2.2.Efraim Flashner * gnu/packages/gawk.scm (gawk): Update to 5.2.2. 2024-08-31gnu: gzip: Update to 1.13.Efraim Flashner * gnu/packages/compression.scm (gzip): Update to 1.13. 2024-08-31gnu: libgccjit: Track the default GCC version.Efraim Flashner * gnu/packages/gcc.scm (libgccjit): Rewrite to use the default gcc version. 2024-08-31gnu: doxygen: Update to 1.9.8.Maxim Cournoyer * gnu/packages/documentation.scm (doxygen): Update to 1.9.8. 2024-08-31gnu: glibc: Add $TZDIR native search path.Maxim Cournoyer * gnu/packages/base.scm (glibc) [native-search-paths]: Add $TZDIR. 2024-08-31gnu: pcsc-lite: Update to 2.0.0.Arjan Adriaanse * gnu/packages/security-token.scm (pcsc-lite): Update to 2.0.0. Signed-off-by: Maxim Cournoyer <maxim.cournoyer@gmail.com> 2024-08-31gnu: docbook-dsssl: Switch to copy-build-system.Bruno Victal * gnu/packages/docbook.scm (docbook-dsssl)[build-system]: Switch to copy-build-system. [arguments]: Add phase to install documentation as separate output. (docbook-dsssl-doc)[build-system]: Switch to copy-build-system. [arguments]: Adapt to new build-system. Signed-off-by: Maxim Cournoyer <maxim.cournoyer@gmail.com> 2024-08-31gnu: docbook: Refactor dblatex packages.Bruno Victal * gnu/packages/docbook.scm (dblatex): Rewrite using G-Expressions. (dblatex/stable): Use modify-inputs. Signed-off-by: Maxim Cournoyer <maxim.cournoyer@gmail.com> Modified-by: Maxim Cournoyer <maxim.cournoyer@gmail.com> Change-Id: Ic4c974c60a80871c5bf4764b88b913c871208b3f 2024-08-31gnu: docbook: Refactor docbook-sgml packages.Bruno Victal * gnu/packages/docbook.scm (docbook-sgml)[build-system]: Switch to copy-build-system. [arguments]: Replace #:builder with #:install-plan. Add phases 'fix-permission and 'patch-iso-entities. [sources]: Use url-fetch/zipbomb. (docbook-sgml-4.1, docbook-sgml-3.1)[sources]: Ditto. (iso-8879-entities)[source]: Ditto. [build-system]: Switch to copy-build-system. [native-inputs]: Restyle. Signed-off-by: Maxim Cournoyer <maxim.cournoyer@gmail.com> 2024-08-31gnu: docbook-utils: Refactor package.Bruno Victal * gnu/packages/docbook.scm (docbook-utils)[description]: Fix description. [source]: Patch source in snippet. [arguments]: Remove. Signed-off-by: Maxim Cournoyer <maxim.cournoyer@gmail.com> 2024-08-31gnu: docbook-xsl-1.79.1: Refactor package.Bruno Victal * gnu/packages/docbook.scm (docbook-xsl-1.79.1)[source]: Remove bundled binary files. [arguments]: Use #:install-plan. Patch catalog.xml using xmlcatalog. Add phase 'install-doc. [native-inputs]: Add libxml2. Signed-off-by: Maxim Cournoyer <maxim.cournoyer@gmail.com> 2024-08-31gnu: docbook-xsl: Refactor package.Bruno Victal * gnu/packages/docbook.scm (docbook-xsl)[source]: Patch in snippet. [arguments]: Use sxml representation for xmlc file. Use xmlcatalog to manipulate catalog.xml instead of substitute*. Use #:install-plan instead of replacing 'install phase. [native-inputs]: Add docbook-xml-4.4 and libxml2, required for tests. Signed-off-by: Maxim Cournoyer <maxim.cournoyer@gmail.com> 2024-08-31gnu: wget: Update to 1.21.4.Andreas Enge * gnu/packages/wget.scm (wget): Update to 1.21.4. 2024-08-31gnu: psutils: Stop installing broken scripts.Tobias Geerinckx-Rice * gnu/packages/ghostscript.scm (psutils)[inputs]: Add perl-ipc-run3. [arguments]: Add a new 'wrap-scripts phase. 2024-08-31gnu: libinput: Add missing file-name.From: Hilton Chain * gnu/packages/freedesktop.scm (libinput)[source]: Use GIT-FILE-NAME. Signed-off-by: Tobias Geerinckx-Rice <me@tobias.gr> 2024-08-31gnu: libinput: Update to 1.23.0.Hilton Chain * gnu/packages/freedesktop.scm (libinput): Update to 1.23.0. [native-inputs]: Add python-minimal-wrapper and python-pytest. Signed-off-by: Tobias Geerinckx-Rice <me@tobias.gr> Change-Id: I207898dc6971e9fa7be24b7ba9c8fc1887ec930e