diff mbox series

[bug#43921,v3,2/2] Add User Service example.

Message ID 20201012051536.1609-1-janneke@gnu.org
State Accepted
Headers show
Series None | expand

Checks

Context Check Description
cbaines/applying patch fail View Laminar job

Commit Message

Janneke Nieuwenhuizen Oct. 12, 2020, 5:15 a.m. UTC
* modules/shepherd/support.scm: Export %user-cache-dir, %user-config-dir,
%user-runtime-dir.
* doc/shepherd.texi (User Service examples): Use them in new subsection with
example.

Co-authored-by: Efraim Flashner <efraim@flashner.co.il>
---
 doc/shepherd.texi            | 79 ++++++++++++++++++++++++++++++++++--
 modules/shepherd/support.scm |  4 ++
 2 files changed, 79 insertions(+), 4 deletions(-)

Comments

Ludovic Courtès Oct. 23, 2020, 1:31 p.m. UTC | #1
Hello!

"Jan (janneke) Nieuwenhuizen" <janneke@gnu.org> skribis:

> * modules/shepherd/support.scm: Export %user-cache-dir, %user-config-dir,
> %user-runtime-dir.
> * doc/shepherd.texi (User Service examples): Use them in new subsection with
> example.
>
> Co-authored-by: Efraim Flashner <efraim@flashner.co.il>

Good idea!

> +@menu
> +* User Service examples::
> +@end menu
> +
> +@node User Service examples
> +@subsection User Service examples

The subsection looks lonely.  :-)  How about making it a section, at the
same level as “Service Examples”?

Also, since “user services” are no different than “non-user” services,
perhaps the focus should be on using the Shepherd as an unprivileged
user.  Thus, I’d suggest calling the section “Managing User Services”,
or “Running the Shepherd as a User”, which do not imply that “user
services” are a new concept.

WDYT?

> +For starters, use a toplevel @code{$XDG_CONFIG_HOME/shepherd/init.scm}
> +that looks like this:

Maybe: “… we suggest the following top-level
@file{$XDG_CONFIG_HOME/shepherd/init.scm} file, which will automatically
load individual service definitions from
@file{~/.config/shepherd/init.d}:”

> +@lisp
> +;;; Commentary:
> +;;;
> +;;; Add to your ~/.bash_profile:
> +;;;
> +;;; if [[ ! -S ${XDG_RUNTIME_DIR-$HOME/.cache}/shepherd/socket ]]; then
> +;;;     shepherd
> +;;; fi

Maybe make it a paragraph in the text, above the ‘init.scm’ example:

  First, to use the Shepherd as an unprivileged user, you may want to
  ensure it is up and running every time you log in.  One way to
  accomplish that is by adding the following lines to @file{~/.bashrc}
  (@pxref{Bash Startup Files,,, bash, The GNU Bash Reference Manual}):

  …

> +Then, individual user services can be put in
> +@code{$XDG_CONFIG_HOME/shepherd/init.d/}, e.g., for ssh-agent

@command{ssh-agent} and period.  :-)

> +@lisp
> +;;; Commentary:
> +;;;
> +;;; Add to your ~/.bash_profile:
> +;;;
> +;;; SSH_AUTH_SOCK=${XDG_RUNTIME_DIR-$HOME/.cache}/ssh-agent/socket
> +;;; export SSH_AUTH_SOCK
> +;;;
> +;;; Code:
> +
> +(use-modules (shepherd support))
> +
> +(define ssh-agent
> +  (make <service>
> +    #:provides '(ssh-agent)
> +    #:docstring "Run `ssh-agent'"
> +    #:start (let ((socket-dir (string-append %user-runtime-dir "/ssh-agent")))
> +              (unless (file-exists? socket-dir)
> +                (mkdir-p socket-dir)
> +                (chmod socket-dir #o700))
> +              (make-forkexec-constructor
> +               `("ssh-agent" "-D" "-a" ,(string-append socket-dir "/socket"))
> +               #:log-file (string-append %user-cache-dir "/ssh-agent.log")))

This is misleading because the code to create the socket directory runs
from the top-level, i.e., when shepherd starts.  I’d write:

  #:start (lambda ()
            ;; make socket dir
            (fork+exec-command … #:log-file …))

(BTW, I use ‘gnupg-agent’, which I think is pretty nice because it’s
integrated with pinentry and all.  I run it as:

  eval `gpg-agent --daemon --enable-ssh-support`

… from ~/.xsession.)

Thanks,
Ludo’.
diff mbox series

Patch

diff --git a/doc/shepherd.texi b/doc/shepherd.texi
index 7c9a739..15d00f1 100644
--- a/doc/shepherd.texi
+++ b/doc/shepherd.texi
@@ -13,6 +13,7 @@  Copyright @copyright{} @value{OLD-YEARS} Wolfgang J@"ahrling@*
 Copyright @copyright{} @value{NEW-YEARS} Ludovic Courtès@*
 Copyright @copyright{} 2020 Brice Waegeneire@*
 Copyright @copyright{} 2020 Oleg Pykhalov
+Copyright @copyright{} 2020 Jan (janneke) Nieuwenhuizen@*
 
 Permission is granted to copy, distribute and/or modify this document
 under the terms of the GNU Free Documentation License, Version 1.3 or
@@ -146,10 +147,11 @@  configuration file.  When it is started with superuser privileges, it
 tries to use @code{/etc/shepherd.scm}.  When started as normal user, it
 looks for a file called @code{$XDG_CONFIG_HOME/shepherd/init.scm}.  If
 the @code{XDG_CONFIG_HOME} environment variable is not defined,
-@code{$HOME/.config/shepherd/init.scm} is used instead.  With the option
-@code{--config} (or, for short, @code{-c}), you can specify where to
-look instead.  So if you want to start @command{shepherd} with an
-alternative file, use one of the following commands:
+@code{$HOME/.config/shepherd/init.scm} is used instead (@pxref{User
+Service examples}).  With the option @code{--config} (or, for short,
+@code{-c}), you can specify where to look instead.  So if you want to
+start @command{shepherd} with an alternative file, use one of the
+following commands:
 
 @example
 shepherd --config=/etc/shepherd.scm.old
@@ -1025,6 +1027,75 @@  also specifies some more initial values for the slots:
                    (restart (...)))))
 @end lisp
 
+@menu
+* User Service examples::
+@end menu
+
+@node User Service examples
+@subsection User Service examples
+
+For starters, use a toplevel @code{$XDG_CONFIG_HOME/shepherd/init.scm}
+that looks like this:
+
+@lisp
+;;; Commentary:
+;;;
+;;; Add to your ~/.bash_profile:
+;;;
+;;; if [[ ! -S ${XDG_RUNTIME_DIR-$HOME/.cache}/shepherd/socket ]]; then
+;;;     shepherd
+;;; fi
+;;;
+;;; Code:
+
+(use-modules (shepherd service)
+             ((ice-9 ftw) #:select (scandir)))
+
+;; Load all the files in the directory 'init.d' with a suffix '.scm'.
+(for-each
+  (lambda (file)
+    (load (string-append "init.d/" file)))
+  (scandir (string-append (dirname (current-filename)) "/init.d")
+           (lambda (file)
+             (string-suffix? ".scm" file))))
+
+;; Send shepherd into the background
+(action 'shepherd 'daemonize)
+@end lisp
+
+Then, individual user services can be put in
+@code{$XDG_CONFIG_HOME/shepherd/init.d/}, e.g., for ssh-agent
+
+@lisp
+;;; Commentary:
+;;;
+;;; Add to your ~/.bash_profile:
+;;;
+;;; SSH_AUTH_SOCK=${XDG_RUNTIME_DIR-$HOME/.cache}/ssh-agent/socket
+;;; export SSH_AUTH_SOCK
+;;;
+;;; Code:
+
+(use-modules (shepherd support))
+
+(define ssh-agent
+  (make <service>
+    #:provides '(ssh-agent)
+    #:docstring "Run `ssh-agent'"
+    #:start (let ((socket-dir (string-append %user-runtime-dir "/ssh-agent")))
+              (unless (file-exists? socket-dir)
+                (mkdir-p socket-dir)
+                (chmod socket-dir #o700))
+              (make-forkexec-constructor
+               `("ssh-agent" "-D" "-a" ,(string-append socket-dir "/socket"))
+               #:log-file (string-append %user-cache-dir "/ssh-agent.log")))
+    #:stop (make-kill-destructor)
+    #:respawn? #t))
+(register-services ssh-agent)
+
+(start ssh-agent)
+@end lisp
+
 @c @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
 
 @node The root and unknown services
diff --git a/modules/shepherd/support.scm b/modules/shepherd/support.scm
index fe64a05..bf34ada 100644
--- a/modules/shepherd/support.scm
+++ b/modules/shepherd/support.scm
@@ -61,6 +61,10 @@ 
             persistency
             persistency-state-file
 
+            %user-cache-dir
+            %user-config-dir
+            %user-runtime-dir
+
             verify-dir))
 
 (define-syntax-rule (if-2.0 subsequent alternate)