From: Maxim Cournoyer <maxim.cournoyer@gmail.com>
To: Ricardo Wurmus <rekado@elephly.net>
Cc: 36875@debbugs.gnu.org
Subject: [bug#36875] [PATCH] doc: Document the use of `program-file' for mcron jobs.
Date: Fri, 02 Aug 2019 09:03:54 +0900 [thread overview]
Message-ID: <87wofwa0wl.fsf@gmail.com> (raw)
In-Reply-To: <87h872t2me.fsf@elephly.net> (Ricardo Wurmus's message of "Wed, 31 Jul 2019 21:39:37 +0200")
[-- Attachment #1.1: Type: text/plain, Size: 3954 bytes --]
Hello Ricardo!
Ricardo Wurmus <rekado@elephly.net> writes:
> Hi Maxim,
>
>> This follows up to my second post under the thread at
>> (https://lists.gnu.org/archive/html/help-guix/2019-07/msg00180.html).
>>
>> It aims to shed some light on (more) complex mcron job Guile scripting
>> with the aid of Guix features (such as program-file).
>
> I wonder if this can be worked around some other way, e.g. by adding
> srfi-26 to the “with-imported-modules” clause.
No; srfi-26 is already present in the Guile load
path. `with-imported-modules' is used to import non-builtin Guile
modules into the generated script load paths. In the current example,
passing (srfi srfi-26) to (with-imported-modules ...) doesn't change the
hash of the compiled gexps (because it is already included).
> I don’t fully understand the problem as described in the addition to the
> manual. What does “imported syntax definitions wouldn't work correctly”
> mean?
That any macro imported with (use-modules ...) in a mcron job defined
using a lambda would not be expanded correctly.
> It would be useful to state that this is something to do with srfi-26.
It is not just about srfi-26; but about any syntax definitions (macros) that a
user might want to use in a mcron script, such as `guard' from
srfi-34. Consider the mcron job defined as below:
--8<---------------cut here---------------start------------->8---
(define %macros-in-a-mcron-lambda-job-dont-work
(with-imported-modules (source-module-closure
'((guix build utils)))
#~(job
'(next-minute (range 0 60 1))
(lambda _
(use-modules (guix build utils)
(srfi srfi-34))
(guard (c ((invoke-error? c))
(format #t "Guard worked as expected."))
(invoke "false"))))))
--8<---------------cut here---------------end--------------->8---
Then upon running, it would fail with the following backtrace:
--8<---------------cut here---------------start------------->8---
Backtrace:
9 (apply-smob/1 #<catch-closure 19e7300>)
In ice-9/boot-9.scm:
829:9 8 (catch _ _ #<procedure 7f858dc5ed38 at mcron/scripts/m?> ?)
In mcron/scripts/mcron.scm:
99:7 7 (_)
In mcron/base.scm:
234:12 6 (_ #<continuation 19d3020>)
In srfi/srfi-1.scm:
640:9 5 (for-each #<procedure run-job (job)> (#<<job> user: #(?>))
In mcron/base.scm:
186:10 4 (run-job _)
In ice-9/eval.scm:
159:9 3 (_ #(#(#<directory (mcron scripts mcron) 1ac1c80>) ()))
182:19 2 (proc #(#(#<directory (mcron scripts mcron) 1ac1c80>) #))
142:16 1 (compile-top-call _ (7 . c) ((10 (10 (13 15 . #) #)) #))
In unknown file:
0 (%resolve-variable (7 . c) #<directory (mcron scripts m?>)
ERROR: In procedure %resolve-variable:
Unbound variable: c
--8<---------------cut here---------------end--------------->8---
Which I found quite puzzling, and can easily imagine other mcron users
stumbling onto. The solution (to use the program-file Gexp facility) is
not an obvious one, so is worth being documented, in my opinion. I've
attempted to clarify the text is the revised patch (attached).
> About the patch:
>
> - please replace tabs with spaces.
Done.
> - “Beep the system when the battery reaches %MIN-LEVEL or less battery
> percent.” sounds odd. How about “Beep when the battery percentage
> falls below %MIN-LEVEL.”?
Done (and modified the logic to match it).
)
> - Can the example be simplified further? Is (setenv "LC_ALL" "C")
> really needed here?
It's to ensure that the output of the 'acpi' command is in English,
which the script depends on (setting the locale of the system to
something else could affect this, if acpi is internationalized (I don't
know, but I'm protecting against it, in case)).
> - instead of let* and when I’d probably use and-let*.
Done.
Reworked patch is attached.
Thanks for the feedback! :-)
Maxim
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1.2: 0001-doc-Document-the-use-of-program-file-for-mcron-jobs.patch --]
[-- Type: text/x-patch, Size: 2584 bytes --]
From 0fffed46b4899bf0485926399d3971a4b5e94408 Mon Sep 17 00:00:00 2001
From: Maxim Cournoyer <maxim.cournoyer@gmail.com>
Date: Thu, 1 Aug 2019 07:34:17 +0900
Subject: [PATCH] doc: Document the use of `program-file' for mcron jobs.
* doc/guix.texi (Scheduled Job Execution): Explain why using `program-file'
for an mcron job can be necessary. Add an example.
---
doc/guix.texi | 35 +++++++++++++++++++++++++++++++++++
1 file changed, 35 insertions(+)
diff --git a/doc/guix.texi b/doc/guix.texi
index e6047a4909..dd06efa9c2 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -12444,6 +12444,41 @@ gexps to introduce job definitions that are passed to mcron
%base-services)))
@end lisp
+For more complex jobs defined in Scheme, it is safer to pass the job as a
+script to mcron; otherwise, macros defined or imported with @code{use-modules}
+wouldn't expand correctly, as Guile requires macros to be strictly defined or
+imported at the top level of a Guile module. This can be achieved using the
+@code{program-file} procedure from the @code{(guix gexp)} module, as shown in
+the example below.
+
+@lisp
+(define %battery-alert-job
+ ;; Beep when the battery percentage falls below %MIN-LEVEL.
+ #~(job
+ '(next-minute (range 0 60 1))
+ #$(program-file
+ "battery-alert.scm"
+ (with-imported-modules (source-module-closure
+ '((guix build utils)))
+ #~(begin
+ (define %min-level 20)
+ (use-modules (guix build utils)
+ (ice-9 popen)
+ (ice-9 regex)
+ (ice-9 textual-ports)
+ (srfi srfi-2))
+ (setenv "LC_ALL" "C")
+ (and-let* ((input-pipe (open-pipe*
+ OPEN_READ
+ #$(file-append acpi "/bin/acpi")))
+ (output (get-string-all input-pipe))
+ (m (string-match "Discharging, ([0-9]+)%" output))
+ (level (string->number (match:substring m 1)))
+ ((< level %min-level)))
+ (format #t "warning: Battery level is low (~a%)~%" level)
+ (invoke #$(file-append beep "/bin/beep") "-r5")))))))
+@end lisp
+
@xref{Guile Syntax, mcron job specifications,, mcron, GNU@tie{}mcron},
for more information on mcron job specifications. Below is the
reference of the mcron service.
--
2.21.0
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 832 bytes --]
next prev parent reply other threads:[~2019-08-01 15:05 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-08-01 0:27 [bug#36875] [PATCH] doc: Document the use of `program-file' for mcron jobs Maxim Cournoyer
2019-07-31 19:39 ` Ricardo Wurmus
2019-08-02 0:03 ` Maxim Cournoyer [this message]
2019-08-17 20:06 ` Ludovic Courtès
2019-08-25 22:54 ` bug#36875: " Maxim Cournoyer
2019-08-26 8:30 ` [bug#36875] " Ludovic Courtès
2019-08-27 10:59 ` Maxim Cournoyer
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87wofwa0wl.fsf@gmail.com \
--to=maxim.cournoyer@gmail.com \
--cc=36875@debbugs.gnu.org \
--cc=rekado@elephly.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this external index
https://git.savannah.gnu.org/cgit/guix.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.