* Defining shepherd user services -- feedback desired
@ 2018-02-04 1:13 Alex ter Weele
2018-02-05 11:03 ` Ludovic Courtès
0 siblings, 1 reply; 3+ messages in thread
From: Alex ter Weele @ 2018-02-04 1:13 UTC (permalink / raw)
To: guix-devel
[-- Attachment #1: Type: text/plain, Size: 985 bytes --]
Attached is a manifest file which allows a user to write a
shepherd-service like the following:
(define redshift-service
(shepherd-service
(provision '(redshift))
(modules `((gnu packages xdisorg)
,@%default-modules))
(start #~(make-forkexec-constructor
(list (string-append #$redshift "/bin/redshift")
"-l" "50:4")))))
And transform it into a package:
(services->package (list redshift-service))
This allows it to be included in a user's profile. This unites the
definition of a service with its dependencies (redshift, in the example
above). A user would not have to install a package just to use it as a
service, nor would they have to hand-write a Shepherd configuration
file.
It may be desired to add services->package and my edited version of
shepherd-configuration-file to Guix. I have not written a patch, though,
because I am unsure where it should go and some FIXMEs remain. Feedback
would be much appreciated!
[-- Attachment #2: user-services.scm --]
[-- Type: application/octet-stream, Size: 5217 bytes --]
(use-modules (srfi srfi-1)
(gnu packages)
(gnu packages emacs)
(gnu packages xdisorg)
(gnu services shepherd)
(guix build-system trivial)
(guix gexp)
(guix monads)
(guix packages)
(guix store)
(guix profiles))
;; a user writes services like this
(define emacs-service
(shepherd-service
(provision '(emacs))
(modules `((gnu packages emacs)
,@%default-modules))
(start #~(make-forkexec-constructor
(list (string-append #$emacs "/bin/emacs")
;;#;"--daemon"
;; Why not --daemon? That causes emacs to fork and
;; exit, so shepherd tries to restart it.
"--eval" "(server-start)"
;; also doesn't work. spawns a window.
)))))
;; Based on Mathieu's service
(define redshift-service
(shepherd-service
(provision '(redshift))
(modules `((gnu packages xdisorg)
,@%default-modules))
;; Why doesn't a with-imported-modules work here?
(start #~(make-forkexec-constructor
(list (string-append #$redshift "/bin/redshift")
"-l" "50:4")))))
;; the next two are copied from (gnu services shepherd) because:
;; * (gnu services shepherd)'s version of shepherd-configuration-file
;; is for the pid1 shepherd and has some stuff like fallback-to-REPL
;; that is not necessary for user services.
;; * (gnu services shepherd) doesn't export
;; shepherd-configuration-file.
(define (shepherd-service-file service)
"Return a file defining SERVICE."
(scheme-file
"shepherd-service.scm"
(with-imported-modules
'((guix build utils)
(guix build syscalls))
#~(begin
(use-modules #$@(shepherd-service-modules service))
(make <service>
#:docstring '#$(shepherd-service-documentation service)
#:provides '#$(shepherd-service-provision service)
#:requires '#$(shepherd-service-requirement service)
#:respawn? '#$(shepherd-service-respawn? service)
#:start #$(shepherd-service-start service)
#:stop #$(shepherd-service-stop service))))))
(define (shepherd-configuration-file services)
"Return the shepherd configuration file for SERVICES."
;; also not exported. Don't make a circular dependency.
;;(assert-valid-graph services)
(define files (map shepherd-service-file services))
(define config
#~(begin
(use-modules (srfi srfi-34))
(apply register-services (map primitive-load '#$files))
(for-each (lambda (service)
;; In the Shepherd 0.3 the 'start' method can raise
;; '&action-runtime-error' if it fails, so protect
;; against it. (XXX: 'action-runtime-error?' is not
;; exported is 0.3, hence 'service-error?'.)
(guard (c ((service-error? c)
(format (current-error-port)
"failed to start service '~a'~%"
service)))
(start service)))
'#$(append-map shepherd-service-provision
(filter shepherd-service-auto-start?
services)))))
(scheme-file "shepherd.conf" config))
(define (services->package services)
"Yield a package for SERVICES by making them into a shepherd
configuration file via scheme-file."
(package
(name "shepherd-services")
(version "0")
(source (shepherd-configuration-file services))
(build-system trivial-build-system)
(arguments
`(#:modules ((guix build utils))
#:builder
(begin
(use-modules (guix build utils))
(let ((install-directory (string-append %output "/etc/shepherd/")))
(mkdir-p install-directory)
(copy-file (assoc-ref %build-inputs "source")
(string-append install-directory "init.scm"))))))
(synopsis "Package closing over Shepherd services.")
(description (format #f "Contains services ~a"
(map shepherd-service-provision services)))
(license #f
;; FIXME: should the licenses be the union of the services
;; closed over? What's the liccense of auto-generated code
;; anyway?
)
(home-page #f)))
(define manifest
(packages->manifest
(cons*
(services->package (list redshift-service))
(map
specification->package
'("emacs" ; emacs and supporting
; packages
"magit"
"emacs-guix"
"emacs-debbugs"
"emacs-evil"
"geiser"
"emacs-paredit"
"emacs-erc-hl-nicks"
"emacs-helm"
"emacs-elfeed"
"emacs-auctex"
"emacs-pdf-tools"
"emacs-tuareg"
"emacs-org"
"font-inconsolata" ; preferred monospace font
;; other development
"git"
"openssh" ; for the client
"stow"
"icecat")))))
manifest
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: Defining shepherd user services -- feedback desired
2018-02-04 1:13 Defining shepherd user services -- feedback desired Alex ter Weele
@ 2018-02-05 11:03 ` Ludovic Courtès
2018-02-11 1:29 ` Chris Marusich
0 siblings, 1 reply; 3+ messages in thread
From: Ludovic Courtès @ 2018-02-05 11:03 UTC (permalink / raw)
To: Alex ter Weele; +Cc: guix-devel
Hey Alex,
Alex ter Weele <alex.ter.weele@gmail.com> skribis:
> Attached is a manifest file which allows a user to write a
> shepherd-service like the following:
>
> (define redshift-service
> (shepherd-service
> (provision '(redshift))
> (modules `((gnu packages xdisorg)
> ,@%default-modules))
> (start #~(make-forkexec-constructor
> (list (string-append #$redshift "/bin/redshift")
> "-l" "50:4")))))
>
> And transform it into a package:
>
> (services->package (list redshift-service))
>
> This allows it to be included in a user's profile. This unites the
> definition of a service with its dependencies (redshift, in the example
> above). A user would not have to install a package just to use it as a
> service, nor would they have to hand-write a Shepherd configuration
> file.
Indeed, that’s a neat hack! And it ties software and service
deployment, which is great.
> ;; the next two are copied from (gnu services shepherd) because:
>
> ;; * (gnu services shepherd)'s version of shepherd-configuration-file
> ;; is for the pid1 shepherd and has some stuff like fallback-to-REPL
> ;; that is not necessary for user services.
>
> ;; * (gnu services shepherd) doesn't export
> ;; shepherd-configuration-file.
That we can fix. :-) Would it be enough for you?
I don’t think the first item is a showstopper, is it?
> (define (services->package services)
> "Yield a package for SERVICES by making them into a shepherd
> configuration file via scheme-file."
This makes me think that perhaps we should generalize profile, and allow
non-package objects in there—it doesn’t feel right to define a <package>
for something that’s conceptually not a package at all.
But then that leads to issues, like what should ‘guix package -u’ do?
How should ~/.guix-profile/manifest represent these non-package things?
Should we add ‘guix package --install-service’ or similar? (Well, that
may be overboard…)
It would be nice to think about whether/how we could make this part of
Guix proper.
Thanks!
Ludo’.
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: Defining shepherd user services -- feedback desired
2018-02-05 11:03 ` Ludovic Courtès
@ 2018-02-11 1:29 ` Chris Marusich
0 siblings, 0 replies; 3+ messages in thread
From: Chris Marusich @ 2018-02-11 1:29 UTC (permalink / raw)
To: Ludovic Courtès; +Cc: guix-devel, Alex ter Weele
[-- Attachment #1: Type: text/plain, Size: 1963 bytes --]
ludo@gnu.org (Ludovic Courtès) writes:
>> (define (services->package services)
>> "Yield a package for SERVICES by making them into a shepherd
>> configuration file via scheme-file."
>
> This makes me think that perhaps we should generalize profile, and allow
> non-package objects in there—it doesn’t feel right to define a <package>
> for something that’s conceptually not a package at all.
>
> But then that leads to issues, like what should ‘guix package -u’ do?
> How should ~/.guix-profile/manifest represent these non-package things?
> Should we add ‘guix package --install-service’ or similar? (Well, that
> may be overboard…)
Profiles are our mechanism for "activating" simple software like GNU
Hello. Software that does not need to be started, stopped, or otherwise
managed by a system like Shepherd.
What is a good mechanism for "activating" more complex software that
needs this sort of management? Perhaps we can make a "guix service"
command which performs upgrades like we do in
'upgrade-shepherd-services' (from guix/scripts/system.scm), but arranges
to execute those commands against a user-specific Shepherd, not the root
user's Shepherd? Perhaps a user profile should also have a "user
services activation script", like how an operating system declaration
has operating-system-activation-script (in gnu/system.scm)?
I personally wouldn't mind if this stuff (e.g., the service activation
script) wound up in a user's profile, but I can see what you're saying
about how it might make using manifests difficult. So, I also wouldn't
mind if the user service activation stuff was stored somewhere else, for
example in ~/.guix-services". Maybe we could we stash the activation
script into a place like ~/.guix-profile/boot, similar to how we store
an activation script for the entire system in /run/current-system/boot?
There must be a way to do this that makes sense...
--
Chris
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 832 bytes --]
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2018-02-11 1:29 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-02-04 1:13 Defining shepherd user services -- feedback desired Alex ter Weele
2018-02-05 11:03 ` Ludovic Courtès
2018-02-11 1:29 ` Chris Marusich
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/guix.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).