(define-module (atlas utils services)
#:use-module (gnu services)
#:use-module (ice-9 control)
#:use-module (ice-9 ftw)
#:use-module (srfi srfi-171)
#:export (&s +s))
(define (name->typename ctx name)
(datum->syntax ctx (symbol-append
(syntax->datum name)
'-service-type)))
(define (name->configname ctx name)
(datum->syntax ctx (symbol-append
(syntax->datum name)
'-configuration)))
(define-syntax &s
(lambda (x)
"Takes a name and
configuration body and yields a valid
guix service expression:
@lisp
(&s hurd-vm
(disk-size 20)
(memory-size 2048))
@end lisp
transforms into
@lisp
(service hurd-vm-service-type
(hurd-vm-configuration
(disk-size 20)
(memory-size 2048)))
@end lisp
if you with to pass the body as-is, then
pass #:config before it:
@lisp
(&s pam-limits #:config
(list (pam-limits-entry \"*\" 'both 'nofile 524288)))
@end lisp
simple outputs
@lisp
(service pam-limits-service-type
(list (pam-limits-entry \"*\" 'both 'nofile 524288)))
@end lisp"
(syntax-case x ()
[(_ name)
(with-syntax ([service-type (name->typename x #'name)])
#'(service service-type))]
[(_ name #:config config)
(with-syntax
([service-type (name->typename x #'name)])
#'(service service-type
config))]
[(_ name config ...)
(with-syntax
([service-type (name->typename x #'name)]
[configuration (name->configname x #'name)])
#'(service service-type
(configuration
config ...)))])))
(define-syntax +s
(lambda (x)
"Similar to &s,
but doesn't wrap in a configuration struct,
and declares a simple-service:
@lisp
(+s hosts example-host
(list (host \"127.10.1.0\" \"example.local\")))
@end lisp
expands to
@lisp
(simple-service 'example-host hosts-service-type
(list (host \"127.10.1.0\" \"example.local\")))
@end lisp"
(syntax-case x ()
[(_ name extension-name config)
(with-syntax ([service-type (name->typename x #'name)])
#'(simple-service 'extension-name
service-type
config))])))