unofficial mirror of guix-patches@gnu.org 
 help / color / mirror / code / Atom feed
* [bug#43921] [Shepherd PATCH 0/2]  Add User Service example.
@ 2020-10-11  9:40 Jan Nieuwenhuizen
  2020-10-11  9:43 ` [bug#43921] [Shepherd PATCH 1/2] Use XDG_CACHE_HOME/shepherd for unprivileged users' log directory Jan (janneke) Nieuwenhuizen
                   ` (2 more replies)
  0 siblings, 3 replies; 10+ messages in thread
From: Jan Nieuwenhuizen @ 2020-10-11  9:40 UTC (permalink / raw)
  To: 43921; +Cc: Efraim Flashner

Hi!

Ever since Efraim's excellent blog post
(https://guix.gnu.org/en/blog/2020/gnu-shepherd-user-services/) I have been
willing to try Shepherd's User Services (actually I wanted to try it for much
longer but it felt too daunting to dive in), and thanks to a nice discussion
on IRC this morning I finally gave it a go.

We were wondering it if would be feasible to add

--8<---------------cut here---------------start------------->8---
if [[ ! -S /run/user/$UID/shepherd/socket ]]; then  
    shepherd  
fi  
--8<---------------cut here---------------end--------------->8---

to /etc/skel/.bash_profile, and maybe even add
/etc/skel/.config/shepherd/init.scm:

--8<---------------cut here---------------start------------->8---
(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)
--8<---------------cut here---------------end--------------->8---

that I got from Efraim's blog post.  For starters, I have put this
in the Shepherd manual.  WDYT?

Greetings,
Janneke

Jan (janneke) Nieuwenhuizen (2):
  Use XDG_CACHE_HOME/shepherd for unprivileged users' log directory.
  Add User Service example.

 doc/shepherd.texi            | 75 +++++++++++++++++++++++++++++++++---
 modules/shepherd/support.scm | 15 +++++++-
 2 files changed, 83 insertions(+), 7 deletions(-)

-- 
Jan Nieuwenhuizen <janneke@gnu.org> | GNU LilyPond http://lilypond.org
Freelance IT http://JoyofSource.com | Avatar® http://AvatarAcademy.com




^ permalink raw reply	[flat|nested] 10+ messages in thread

* [bug#43921] [Shepherd PATCH 1/2] Use XDG_CACHE_HOME/shepherd for unprivileged users' log directory.
  2020-10-11  9:40 [bug#43921] [Shepherd PATCH 0/2] Add User Service example Jan Nieuwenhuizen
@ 2020-10-11  9:43 ` Jan (janneke) Nieuwenhuizen
  2020-10-11  9:43   ` [bug#43921] [Shepherd PATCH 2/2] Add User Service example Jan (janneke) Nieuwenhuizen
  2020-10-11 12:10 ` [bug#43921] [Shepherd PATCH v2 " Jan (janneke) Nieuwenhuizen
  2020-10-12  5:15 ` [bug#43921] [PATCH v3 " Jan (janneke) Nieuwenhuizen
  2 siblings, 1 reply; 10+ messages in thread
From: Jan (janneke) Nieuwenhuizen @ 2020-10-11  9:43 UTC (permalink / raw)
  To: 43921

* modules/shepherd/support.scm (%user-cache-dir): New variable.
(user-default-log-file): Use it.
* doc/shepherd.texi (Invoking shepherd): Document it.
---
 doc/shepherd.texi            |  4 +++-
 modules/shepherd/support.scm | 11 +++++++++--
 2 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/doc/shepherd.texi b/doc/shepherd.texi
index 696477e..7c9a739 100644
--- a/doc/shepherd.texi
+++ b/doc/shepherd.texi
@@ -417,7 +417,9 @@ permissions are not as expected.
 Log output into @var{file}.
 
 For unprivileged users, the default log file is
-@file{$XDG_CONFIG_HOME/shepherd/shepherd.log}.
+@file{$XDG_CACHE_HOME/shepherd/shepherd.log}.  If the
+@code{XDG_CACHE_HOME} environment variable is not defined,
+@code{$HOME/.cache/shepherd/shepherd.log} is used instead.
 
 @cindex syslog
 When running as root, the default behavior is to connect to
diff --git a/modules/shepherd/support.scm b/modules/shepherd/support.scm
index cdb7b35..fe64a05 100644
--- a/modules/shepherd/support.scm
+++ b/modules/shepherd/support.scm
@@ -4,6 +4,7 @@
 ;; Copyright (C) 2002, 2003 Wolfgang Jährling <wolfgang@pro-linux.de>
 ;; Copyright (C) 2016 Mathieu Lirzin <mthl@gnu.org>
 ;; Copyright (C) 2018 Danny Milosavljevic <dannym@scratchpost.org>
+;; Copyright (C) 2020 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 ;;
 ;; This file is part of the GNU Shepherd.
 ;;
@@ -265,6 +266,12 @@ There is NO WARRANTY, to the extent permitted by law.")))
       (false-if-exception (passwd:dir (getpwuid (getuid))))
       "/"))
 
+(define %user-cache-dir
+  ;; Default cache directory if shepherd is run as a normal user.
+  (string-append (or (getenv "XDG_CACHE_HOME")
+                     (string-append user-homedir "/.cache"))
+                 "/shepherd"))
+
 (define %user-config-dir
   ;; Default config directory if shepherd is run as a normal user.
   (string-append (or (getenv "XDG_CONFIG_HOME")
@@ -302,8 +309,8 @@ TARGET should be a string representing a filepath + name."
 ;; Logging.
 (define (user-default-log-file)
   "Return the file name of the user's default log file."
-  (mkdir-p %user-config-dir #o700)
-  (string-append %user-config-dir "/shepherd.log"))
+  (mkdir-p %user-cache-dir #o700)
+  (string-append %user-cache-dir "/shepherd.log"))
 
 (define default-logfile-date-format
   ;; 'strftime' format string to prefix each entry in the log.
-- 
Jan Nieuwenhuizen <janneke@gnu.org> | GNU LilyPond http://lilypond.org
Freelance IT http://JoyofSource.com | Avatar® http://AvatarAcademy.com





^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [bug#43921] [Shepherd PATCH 2/2] Add User Service example.
  2020-10-11  9:43 ` [bug#43921] [Shepherd PATCH 1/2] Use XDG_CACHE_HOME/shepherd for unprivileged users' log directory Jan (janneke) Nieuwenhuizen
@ 2020-10-11  9:43   ` Jan (janneke) Nieuwenhuizen
  2020-10-11 10:38     ` Jan Nieuwenhuizen
  0 siblings, 1 reply; 10+ messages in thread
From: Jan (janneke) Nieuwenhuizen @ 2020-10-11  9:43 UTC (permalink / raw)
  To: 43921; +Cc: Efraim Flashner

* 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            | 71 ++++++++++++++++++++++++++++++++++--
 modules/shepherd/support.scm |  4 ++
 2 files changed, 71 insertions(+), 4 deletions(-)

diff --git a/doc/shepherd.texi b/doc/shepherd.texi
index 7c9a739..41cc651 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 @ref{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,67 @@ 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
+(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=/run/user/$UID/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))
+              (unless (file-exists? log-dir)
+                (mkdir-p log-dir))
+              (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)
-- 
Jan Nieuwenhuizen <janneke@gnu.org> | GNU LilyPond http://lilypond.org
Freelance IT http://JoyofSource.com | Avatar® http://AvatarAcademy.com





^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [bug#43921] [Shepherd PATCH 2/2] Add User Service example.
  2020-10-11  9:43   ` [bug#43921] [Shepherd PATCH 2/2] Add User Service example Jan (janneke) Nieuwenhuizen
@ 2020-10-11 10:38     ` Jan Nieuwenhuizen
  0 siblings, 0 replies; 10+ messages in thread
From: Jan Nieuwenhuizen @ 2020-10-11 10:38 UTC (permalink / raw)
  To: 43921; +Cc: Efraim Flashner

Jan (janneke) Nieuwenhuizen writes:

Oops...

> diff --git a/doc/shepherd.texi b/doc/shepherd.texi
> index 7c9a739..41cc651 100644
> --- a/doc/shepherd.texi
> +++ b/doc/shepherd.texi

[..]

> @@ -1025,6 +1027,67 @@ also specifies some more initial values for the slots:
>                     (restart (...)))))
[..]

> +(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))

...this log-dir bit:

> +              (unless (file-exists? log-dir)
> +                (mkdir-p log-dir))

is an obsolete leftover.

Janneke


-- 
Jan Nieuwenhuizen <janneke@gnu.org> | GNU LilyPond http://lilypond.org
Freelance IT http://JoyofSource.com | Avatar® http://AvatarAcademy.com




^ permalink raw reply	[flat|nested] 10+ messages in thread

* [bug#43921] [Shepherd PATCH v2 2/2] Add User Service example.
  2020-10-11  9:40 [bug#43921] [Shepherd PATCH 0/2] Add User Service example Jan Nieuwenhuizen
  2020-10-11  9:43 ` [bug#43921] [Shepherd PATCH 1/2] Use XDG_CACHE_HOME/shepherd for unprivileged users' log directory Jan (janneke) Nieuwenhuizen
@ 2020-10-11 12:10 ` Jan (janneke) Nieuwenhuizen
  2020-10-12  5:15 ` [bug#43921] [PATCH v3 " Jan (janneke) Nieuwenhuizen
  2 siblings, 0 replies; 10+ messages in thread
From: Jan (janneke) Nieuwenhuizen @ 2020-10-11 12:10 UTC (permalink / raw)
  To: 43921; +Cc: Efraim Flashner

* 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(-)

diff --git a/doc/shepherd.texi b/doc/shepherd.texi
index 7c9a739..e6207b3 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_RUN_HOME-$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_RUN_HOME-$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)
-- 
Jan Nieuwenhuizen <janneke@gnu.org> | GNU LilyPond http://lilypond.org
Freelance IT http://JoyofSource.com | Avatar® http://AvatarAcademy.com





^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [bug#43921] [PATCH v3 2/2] Add User Service example.
  2020-10-11  9:40 [bug#43921] [Shepherd PATCH 0/2] Add User Service example Jan Nieuwenhuizen
  2020-10-11  9:43 ` [bug#43921] [Shepherd PATCH 1/2] Use XDG_CACHE_HOME/shepherd for unprivileged users' log directory Jan (janneke) Nieuwenhuizen
  2020-10-11 12:10 ` [bug#43921] [Shepherd PATCH v2 " Jan (janneke) Nieuwenhuizen
@ 2020-10-12  5:15 ` Jan (janneke) Nieuwenhuizen
  2020-10-23 13:31   ` Ludovic Courtès
  2 siblings, 1 reply; 10+ messages in thread
From: Jan (janneke) Nieuwenhuizen @ 2020-10-12  5:15 UTC (permalink / raw)
  To: 43921; +Cc: Efraim Flashner

* 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(-)

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)
-- 
Jan Nieuwenhuizen <janneke@gnu.org> | GNU LilyPond http://lilypond.org
Freelance IT http://JoyofSource.com | Avatar® http://AvatarAcademy.com





^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [bug#43921] [PATCH v3 2/2] Add User Service example.
  2020-10-12  5:15 ` [bug#43921] [PATCH v3 " Jan (janneke) Nieuwenhuizen
@ 2020-10-23 13:31   ` Ludovic Courtès
  2020-10-23 16:37     ` Jan Nieuwenhuizen
  0 siblings, 1 reply; 10+ messages in thread
From: Ludovic Courtès @ 2020-10-23 13:31 UTC (permalink / raw)
  To: Jan (janneke) Nieuwenhuizen; +Cc: 43921, Efraim Flashner

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’.




^ permalink raw reply	[flat|nested] 10+ messages in thread

* [bug#43921] [PATCH v3 2/2] Add User Service example.
  2020-10-23 13:31   ` Ludovic Courtès
@ 2020-10-23 16:37     ` Jan Nieuwenhuizen
  2020-11-18 21:37       ` bug#43921: " Ludovic Courtès
  0 siblings, 1 reply; 10+ messages in thread
From: Jan Nieuwenhuizen @ 2020-10-23 16:37 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: 43921, Efraim Flashner

[-- Attachment #1: Type: text/plain, Size: 3363 bytes --]

Ludovic Courtès writes:

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”?

Sure.

> 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?

Yes, nice.  I changed the opening to

The Shepherd can be used to manage services for an unprivileged user.
First, 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{~/.bash_profile} (@pxref{Bash Startup Files,,, bash, The GNU Bash
Reference Manual}):

>> +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}:”

Nice.

>> +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
[..]
>> +    #: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.

Oops; that's probably $HOME for me, because it worked...

> I’d write:
>
>   #:start (lambda ()
>             ;; make socket dir
>             (fork+exec-command … #:log-file …))

Great; changed that too.

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

Interesting...makes me wonder: maybe we could ship init.scm together
with a couple of popular user service descriptions like ssh-agent.scm,
znc.scm, ...gpg-agent.scm (?) in an examples directory?  That would make
it even easier for people to migrate away from the old

> I run it as:
>   eval `gpg-agent --daemon --enable-ssh-support`
>
> … from ~/.xsession.)

It would have helped me to move away from my `eval ssh-agent` thingy ;-)

New version attached (included 0001 patch for completeness but which
can probably be merged into / obsoleted by #43920).

Greetings,
Janneke


[-- Attachment #2: v3-0001-Use-XDG_CACHE_HOME-shepherd-for-unprivileged-user.patch --]
[-- Type: text/x-patch, Size: 2903 bytes --]

From f0deaa24ad57d2db921bf1b092350988c50558a7 Mon Sep 17 00:00:00 2001
From: "Jan (janneke) Nieuwenhuizen" <janneke@gnu.org>
Date: Sun, 11 Oct 2020 10:54:26 +0200
Subject: [PATCH v3 1/2] Use XDG_CACHE_HOME/shepherd for unprivileged users'
 log directory.
Content-Transfer-Encoding: 8bit
Content-Type: text/plain; charset=UTF-8

* modules/shepherd/support.scm (%user-cache-dir): New variable.
(user-default-log-file): Use it.
* doc/shepherd.texi (Invoking shepherd): Document it.
---
 doc/shepherd.texi            |  4 +++-
 modules/shepherd/support.scm | 11 +++++++++--
 2 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/doc/shepherd.texi b/doc/shepherd.texi
index 696477e..7c9a739 100644
--- a/doc/shepherd.texi
+++ b/doc/shepherd.texi
@@ -417,7 +417,9 @@ permissions are not as expected.
 Log output into @var{file}.
 
 For unprivileged users, the default log file is
-@file{$XDG_CONFIG_HOME/shepherd/shepherd.log}.
+@file{$XDG_CACHE_HOME/shepherd/shepherd.log}.  If the
+@code{XDG_CACHE_HOME} environment variable is not defined,
+@code{$HOME/.cache/shepherd/shepherd.log} is used instead.
 
 @cindex syslog
 When running as root, the default behavior is to connect to
diff --git a/modules/shepherd/support.scm b/modules/shepherd/support.scm
index cdb7b35..fe64a05 100644
--- a/modules/shepherd/support.scm
+++ b/modules/shepherd/support.scm
@@ -4,6 +4,7 @@
 ;; Copyright (C) 2002, 2003 Wolfgang Jährling <wolfgang@pro-linux.de>
 ;; Copyright (C) 2016 Mathieu Lirzin <mthl@gnu.org>
 ;; Copyright (C) 2018 Danny Milosavljevic <dannym@scratchpost.org>
+;; Copyright (C) 2020 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 ;;
 ;; This file is part of the GNU Shepherd.
 ;;
@@ -265,6 +266,12 @@ There is NO WARRANTY, to the extent permitted by law.")))
       (false-if-exception (passwd:dir (getpwuid (getuid))))
       "/"))
 
+(define %user-cache-dir
+  ;; Default cache directory if shepherd is run as a normal user.
+  (string-append (or (getenv "XDG_CACHE_HOME")
+                     (string-append user-homedir "/.cache"))
+                 "/shepherd"))
+
 (define %user-config-dir
   ;; Default config directory if shepherd is run as a normal user.
   (string-append (or (getenv "XDG_CONFIG_HOME")
@@ -302,8 +309,8 @@ TARGET should be a string representing a filepath + name."
 ;; Logging.
 (define (user-default-log-file)
   "Return the file name of the user's default log file."
-  (mkdir-p %user-config-dir #o700)
-  (string-append %user-config-dir "/shepherd.log"))
+  (mkdir-p %user-cache-dir #o700)
+  (string-append %user-cache-dir "/shepherd.log"))
 
 (define default-logfile-date-format
   ;; 'strftime' format string to prefix each entry in the log.
-- 
Jan Nieuwenhuizen <janneke@gnu.org> | GNU LilyPond http://lilypond.org
Freelance IT http://JoyofSource.com | Avatar® http://AvatarAcademy.com


[-- Attachment #3: v3-0002-doc-Add-Managing-User-Services.patch --]
[-- Type: text/x-patch, Size: 5837 bytes --]

From ae64ec3bfa7a0e4e877f06161f2d6aacb5804960 Mon Sep 17 00:00:00 2001
From: "Jan (janneke) Nieuwenhuizen" <janneke@gnu.org>
Date: Sun, 11 Oct 2020 10:59:04 +0200
Subject: [PATCH v3 2/2] doc: Add "Managing User Services".
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Content-Transfer-Encoding: 8bit
Content-Type: text/plain; charset=UTF-8

* modules/shepherd/support.scm: Export %user-cache-dir, %user-config-dir,
%user-runtime-dir.
* doc/shepherd.texi (Managing User Services): Use them in new section with
example.

Co-authored-by: Efraim Flashner <efraim@flashner.co.il>
Co-authored-by: Ludovic Courtès <ludo@gnu.org>
---
 doc/shepherd.texi            | 81 ++++++++++++++++++++++++++++++++++--
 modules/shepherd/support.scm |  4 ++
 2 files changed, 81 insertions(+), 4 deletions(-)

diff --git a/doc/shepherd.texi b/doc/shepherd.texi
index 7c9a739..ea3edf0 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{Managing
+User Services }).  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
@@ -591,6 +593,7 @@ defined in the @code{(shepherd service)} module.
 * Service De- and Constructors:: Commonly used ways of starting and
                                    stopping services.
 * Service Examples::             Examples that show how services are used.
+* Managing User Services::       Running the Shepherd as a user.
 * The root and unknown services:: Special services in the Shepherd.
 @end menu
 
@@ -1025,6 +1028,76 @@ also specifies some more initial values for the slots:
                    (restart (...)))))
 @end lisp
 
+@node Managing User Services
+@section Managing User Services
+
+The Shepherd can be used to manage services for an unprivileged user.
+First, 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{~/.bash_profile} (@pxref{Bash Startup Files,,, bash, The GNU Bash
+Reference Manual}):
+
+@verbatim
+if [[ ! -S ${XDG_RUNTIME_DIR-$HOME/.cache}/shepherd/socket ]]; then
+    shepherd
+fi
+@end verbatim
+
+Then, 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
+(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 @command{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 (lambda ()
+              (let ((socket-dir (string-append %user-runtime-dir "/ssh-agent")))
+                (unless (file-exists? socket-dir)
+                  (mkdir-p socket-dir)
+                  (chmod socket-dir #o700))
+                (fork+exec-command
+                 `("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)
-- 
Jan Nieuwenhuizen <janneke@gnu.org> | GNU LilyPond http://lilypond.org
Freelance IT http://JoyofSource.com | Avatar® http://AvatarAcademy.com


[-- Attachment #4: Type: text/plain, Size: 152 bytes --]


-- 
Jan Nieuwenhuizen <janneke@gnu.org> | GNU LilyPond http://lilypond.org
Freelance IT http://JoyofSource.com | Avatar® http://AvatarAcademy.com

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* bug#43921: [PATCH v3 2/2] Add User Service example.
  2020-10-23 16:37     ` Jan Nieuwenhuizen
@ 2020-11-18 21:37       ` Ludovic Courtès
  2020-11-19  6:00         ` [bug#43921] " Jan Nieuwenhuizen
  0 siblings, 1 reply; 10+ messages in thread
From: Ludovic Courtès @ 2020-11-18 21:37 UTC (permalink / raw)
  To: Jan Nieuwenhuizen; +Cc: 43921-done, Efraim Flashner

Hi,

Jan Nieuwenhuizen <janneke@gnu.org> skribis:

>>From ae64ec3bfa7a0e4e877f06161f2d6aacb5804960 Mon Sep 17 00:00:00 2001
> From: "Jan (janneke) Nieuwenhuizen" <janneke@gnu.org>
> Date: Sun, 11 Oct 2020 10:59:04 +0200
> Subject: [PATCH v3 2/2] doc: Add "Managing User Services".
> MIME-Version: 1.0
> Content-Type: text/plain; charset=UTF-8
> Content-Transfer-Encoding: 8bit
> Content-Transfer-Encoding: 8bit
> Content-Type: text/plain; charset=UTF-8
>
> * modules/shepherd/support.scm: Export %user-cache-dir, %user-config-dir,
> %user-runtime-dir.
> * doc/shepherd.texi (Managing User Services): Use them in new section with
> example.
>
> Co-authored-by: Efraim Flashner <efraim@flashner.co.il>
> Co-authored-by: Ludovic Courtès <ludo@gnu.org>

Finally pushed; I changed ‘%user-cache-dir’ references to
‘%user-log-dir’:

  https://git.savannah.gnu.org/cgit/shepherd.git/commit/?id=4c5176f5a7a5a1e7d7f258f585e8ed127a21b99a

Thanks!

Ludo’.




^ permalink raw reply	[flat|nested] 10+ messages in thread

* [bug#43921] [PATCH v3 2/2] Add User Service example.
  2020-11-18 21:37       ` bug#43921: " Ludovic Courtès
@ 2020-11-19  6:00         ` Jan Nieuwenhuizen
  0 siblings, 0 replies; 10+ messages in thread
From: Jan Nieuwenhuizen @ 2020-11-19  6:00 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: 43921-done, Efraim Flashner

Ludovic Courtès writes:

Hello,

> Jan Nieuwenhuizen <janneke@gnu.org> skribis:
>
>>>From ae64ec3bfa7a0e4e877f06161f2d6aacb5804960 Mon Sep 17 00:00:00 2001
>> From: "Jan (janneke) Nieuwenhuizen" <janneke@gnu.org>
>> Date: Sun, 11 Oct 2020 10:59:04 +0200
>> Subject: [PATCH v3 2/2] doc: Add "Managing User Services".
[..]
> Finally pushed; I changed ‘%user-cache-dir’ references to
> ‘%user-log-dir’:
>
>   https://git.savannah.gnu.org/cgit/shepherd.git/commit/?id=4c5176f5a7a5a1e7d7f258f585e8ed127a21b99a

Nice, thanks!

Janneke

-- 
Jan Nieuwenhuizen <janneke@gnu.org> | GNU LilyPond http://lilypond.org
Freelance IT http://JoyofSource.com | Avatar® http://AvatarAcademy.com




^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2020-11-19  6:02 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-10-11  9:40 [bug#43921] [Shepherd PATCH 0/2] Add User Service example Jan Nieuwenhuizen
2020-10-11  9:43 ` [bug#43921] [Shepherd PATCH 1/2] Use XDG_CACHE_HOME/shepherd for unprivileged users' log directory Jan (janneke) Nieuwenhuizen
2020-10-11  9:43   ` [bug#43921] [Shepherd PATCH 2/2] Add User Service example Jan (janneke) Nieuwenhuizen
2020-10-11 10:38     ` Jan Nieuwenhuizen
2020-10-11 12:10 ` [bug#43921] [Shepherd PATCH v2 " Jan (janneke) Nieuwenhuizen
2020-10-12  5:15 ` [bug#43921] [PATCH v3 " Jan (janneke) Nieuwenhuizen
2020-10-23 13:31   ` Ludovic Courtès
2020-10-23 16:37     ` Jan Nieuwenhuizen
2020-11-18 21:37       ` bug#43921: " Ludovic Courtès
2020-11-19  6:00         ` [bug#43921] " Jan Nieuwenhuizen

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).