| 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 | (define-module (gnu services mcron)
|
| 37 | #:use-module (gnu services)
|
| 38 | #:use-module (gnu services shepherd)
|
| 39 | #:use-module (gnu packages guile-xyz)
|
| 40 | #:use-module (guix records)
|
| 41 | #:use-module (guix gexp)
|
| 42 | #:use-module (srfi srfi-1)
|
| 43 | #:use-module (ice-9 match)
|
| 44 | #:use-module (ice-9 vlist)
|
| 45 | #:export (mcron-configuration
|
| 46 | mcron-configuration?
|
| 47 | mcron-configuration-mcron
|
| 48 | mcron-configuration-jobs
|
| 49 | mcron-configuration-log?
|
| 50 | mcron-configuration-log-file
|
| 51 | mcron-configuration-log-format
|
| 52 | mcron-configuration-date-format
|
| 53 | mcron-configuration-home-service?
|
| 54 |
|
| 55 | mcron-service-type))
|
| 56 |
|
| 57 | |
| 58 | |
| 59 | |
| 60 | (define-record-type* <mcron-configuration> mcron-configuration
|
| 61 | make-mcron-configuration
|
| 62 | mcron-configuration?
|
| 63 | this-mcron-configuration
|
| 64 |
|
| 65 | (mcron mcron-configuration-mcron |
| 66 | (default mcron))
|
| 67 | (jobs mcron-configuration-jobs |
| 68 | (default '()))
|
| 69 | (log? mcron-configuration-log? |
| 70 | (default #t))
|
| 71 | (log-file mcron-configuration-log-file |
| 72 | (thunked)
|
| 73 | (default
|
| 74 | (if (mcron-configuration-home-service?
|
| 75 | this-mcron-configuration)
|
| 76 | #~(string-append %user-log-dir "/mcron.log")
|
| 77 | "/var/log/mcron.log")))
|
| 78 | (log-format mcron-configuration-log-format |
| 79 | (default "~1@*~a ~a: ~a~%"))
|
| 80 | (date-format mcron-configuration-date-format |
| 81 | (default #f))
|
| 82 |
|
| 83 | (home-service? mcron-configuration-home-service?
|
| 84 | (default for-home?) (innate)))
|
| 85 |
|
| 86 | (define (job-files mcron jobs)
|
| 87 | "Return a list of file-like object for JOBS, a list of gexps."
|
| 88 | (define (validated-file job)
|
| 89 | |
| 90 | |
| 91 | (computed-file "mcron-job"
|
| 92 | (with-imported-modules '((guix build utils))
|
| 93 | #~(begin
|
| 94 | (use-modules (guix build utils))
|
| 95 |
|
| 96 | (call-with-output-file "prologue"
|
| 97 | (lambda (port)
|
| 98 | |
| 99 | |
| 100 | |
| 101 | (write '(set! getpw
|
| 102 | (const (getpwuid (getuid))))
|
| 103 | port)))
|
| 104 |
|
| 105 | (call-with-output-file "job"
|
| 106 | (lambda (port)
|
| 107 | (write '#$job port)))
|
| 108 |
|
| 109 | (invoke #+(file-append mcron "/bin/mcron")
|
| 110 | "--schedule=20" "prologue" "job")
|
| 111 | (copy-file "job" #$output)))
|
| 112 | #:options '(#:env-vars (("COLUMNS" . "150")))))
|
| 113 |
|
| 114 | (map validated-file jobs))
|
| 115 |
|
| 116 | (define (shepherd-schedule-action mcron files)
|
| 117 | "Return a Shepherd action that runs MCRON with '--schedule' for the given
|
| 118 | files."
|
| 119 | (shepherd-action
|
| 120 | (name 'schedule)
|
| 121 | (documentation
|
| 122 | "Display jobs that are going to be scheduled.")
|
| 123 | (procedure
|
| 124 | #~(lambda* (_ #:optional (n "5"))
|
| 125 | |
| 126 | (setenv "GUILE_AUTO_COMPILE" "0")
|
| 127 |
|
| 128 | |
| 129 | |
| 130 | |
| 131 | (let ((pipe (open-pipe* OPEN_READ
|
| 132 | #$(file-append mcron "/bin/mcron")
|
| 133 | (string-append "--schedule=" n)
|
| 134 | #$@files)))
|
| 135 | (let loop ()
|
| 136 | (match (read-line pipe 'concat)
|
| 137 | ((? eof-object?)
|
| 138 | (catch 'system-error
|
| 139 | (lambda ()
|
| 140 | (zero? (close-pipe pipe)))
|
| 141 | (lambda args
|
| 142 | |
| 143 | |
| 144 | |
| 145 | |
| 146 | (or (= ECHILD (system-error-errno args))
|
| 147 | (apply throw args)))))
|
| 148 | (line
|
| 149 | (display line)
|
| 150 | (loop)))))))))
|
| 151 |
|
| 152 | (define (mcron-shepherd-services config)
|
| 153 | (match-record config <mcron-configuration>
|
| 154 | (mcron jobs log? log-file log-format date-format home-service?)
|
| 155 | (if (eq? jobs '())
|
| 156 | '() |
| 157 | (let ((files (job-files mcron jobs)))
|
| 158 | (list (shepherd-service
|
| 159 | (provision '(mcron))
|
| 160 | (requirement (if home-service?
|
| 161 | '()
|
| 162 | '(user-processes)))
|
| 163 | (modules `((srfi srfi-1)
|
| 164 | (srfi srfi-26)
|
| 165 | (ice-9 popen) |
| 166 | (ice-9 rdelim)
|
| 167 | (ice-9 match)
|
| 168 | ((shepherd support) #:hide (mkdir-p)) |
| 169 | ,@%default-modules))
|
| 170 | (start #~(make-forkexec-constructor
|
| 171 | (list #$(file-append mcron "/bin/mcron")
|
| 172 | #$@(if log?
|
| 173 | `("--log" "--log-format" ,log-format
|
| 174 | ,@(if date-format
|
| 175 | (list "--date-format"
|
| 176 | date-format)
|
| 177 | '()))
|
| 178 | '())
|
| 179 | #$@files)
|
| 180 |
|
| 181 | |
| 182 | |
| 183 | #:environment-variables
|
| 184 | (cons* "GUILE_AUTO_COMPILE=0"
|
| 185 | #$(if home-service?
|
| 186 | '(environ)
|
| 187 | '(cons*
|
| 188 | "PATH=/run/current-system/profile/bin"
|
| 189 | (remove (cut string-prefix? "PATH=" <>)
|
| 190 | (environ)))))
|
| 191 |
|
| 192 | #:log-file #$log-file))
|
| 193 | (stop #~(make-kill-destructor))
|
| 194 | (actions
|
| 195 | (list (shepherd-schedule-action mcron files)))))))))
|
| 196 |
|
| 197 | (define mcron-service-type
|
| 198 | (service-type (name 'mcron)
|
| 199 | (description
|
| 200 | "Run the mcron job scheduling daemon.")
|
| 201 | (extensions
|
| 202 | (list (service-extension shepherd-root-service-type
|
| 203 | mcron-shepherd-services)
|
| 204 | (service-extension profile-service-type
|
| 205 | (compose list
|
| 206 | mcron-configuration-mcron))))
|
| 207 | (compose concatenate)
|
| 208 | (extend (lambda (config jobs)
|
| 209 | (mcron-configuration
|
| 210 | (inherit config)
|
| 211 | (home-service?
|
| 212 | (mcron-configuration-home-service? config))
|
| 213 | (jobs (append (mcron-configuration-jobs config)
|
| 214 | jobs)))))
|
| 215 | (default-value (mcron-configuration)))) |
| 216 |
|
| 217 | |