Good morning Guix,
I am trying to set up a timer to regularly pull from Git repositories for a Git
mirroring service.
Our old setup used a shell script with templating. Now, I am trying to do
things the idiomatic Guix way.
I currently have this:
--8<---------------cut here---------------start------------->8---
(define %git-mirror-update-gexp
#~(begin
(use-modules (guix build utils)
(ice-9 match))
(define (update-repo repo)
"Update the repository REPO, a list HOST, ORG, NAME, DESCRIPTION, to
the latest remote changes."
(match repo
((hostname org name _)
(with-directory-excursion (string-append "/srv/git/mirrored/" org
"/" name)
(invoke (string-append #$git "/bin/git") "fetch" "-q" "--prune")
(mkdir-p "info/web")
(invoke (string-append #$bash "/bin/bash") "-c"
(string-append #$git
"/bin/git for-each-ref --sort=-committerdate --count=1
--format='%(committerdate:iso8601)' --exclude='refs/pull/*/merge' >
info/web/last-modified"))))))
;; See comment in %git-mirror-activation.
(map update-repo
'#$%mirrored-repos)))
(define %git-mirror-update
(with-imported-modules (source-module-closure '((guix build utils)))
%git-mirror-update-gexp))
(define %git-mirror-update-timer
(shepherd-timer '(git-mirror-update)
"*/5 * * * *"
#~(#$(program-file "git-mirror-update" %git-mirror-update))
#:requirement '(networking user-processes)))
(define %git-mirror-update-service
(simple-service 'git-mirror-update-timer shepherd-root-service-type
(list %git-mirror-update-timer)))
--8<---------------cut here---------------end--------------->8---
%mirrored-repos is a list of four-item lists. I have similar code working for
the service activation (to do the initial clone).
However, despite `with-imported-modules`, the resulting file lacks `guix build
utils`:
--8<---------------cut here---------------start------------->8---
$ sudo /gnu/store/xv8ssfz9cah1ax7x5z24mx21acxy0id8-git-mirror-update
Backtrace:
9 (primitive-load "/gnu/store/xv8ssfz9cah1ax7x5z24mx21acx…")
In ice-9/eval.scm:
721:20 8 (primitive-eval (begin (use-modules (guix build #) #) …))
In ice-9/psyntax.scm:
1229:36 7 (expand-top-sequence (#<syntax:xv8ssfz9cah1ax7x5z24mx…>) …)
1089:25 6 (parse _ (("placeholder" placeholder)) ((top) #(# # …)) …)
1221:19 5 (parse _ (("placeholder" placeholder)) ((top) #(# # …)) …)
259:10 4 (parse _ (("placeholder" placeholder)) (()) _ c&e (eval) …)
In ice-9/boot-9.scm:
3935:20 3 (process-use-modules _)
222:17 2 (map1 (((guix build utils)) ((ice-9 match))))
3936:31 1 (_ ((guix build utils)))
3330:6 0 (resolve-interface (guix build utils) #:select _ #:hide …)
ice-9/boot-9.scm:3330:6: In procedure resolve-interface:
no code for module (guix build utils)
--8<---------------cut here---------------end--------------->8---
Could somebody help me understand why, and point me to the right direction of
writing this?
I've also seen the possibility to write a regular shell script using
`wrap-program` / `wrap-script`, but feel like it is cleaner to do it in Guile.
But maybe I'm doing Shepherd timers wrong?
Thank you very much
Johannes