guix-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[bug#50332] [PATCH v2] home-services: Add Shepherd.


From: Andrew Tropin
Subject: [bug#50332] [PATCH v2] home-services: Add Shepherd.
Date: Fri, 03 Sep 2021 10:44:22 +0300

On 2021-09-02 16:59, Xinglu Chen wrote:

> On Thu, Sep 02 2021, Andrew Tropin wrote:
>
>> * gnu/home-services/shepherd.scm: New file.
>> * doc/guix.texi: Add documentation about Shepherd Home Service.
>> ---
>>  doc/guix.texi                  |  31 +++++++-
>>  gnu/home-services/shepherd.scm | 133 +++++++++++++++++++++++++++++++++
>>  2 files changed, 163 insertions(+), 1 deletion(-)
>>  create mode 100644 gnu/home-services/shepherd.scm
>>
>> diff --git a/doc/guix.texi b/doc/guix.texi
>> index 622a973bdf..51a317e8a7 100644
>> --- a/doc/guix.texi
>> +++ b/doc/guix.texi
>> @@ -35538,7 +35538,36 @@ mcron info here
>>  
>>  @node Shepherd Home Service
>>  @subsection Managing User's Daemons
>> -shepherd info here
>> +
>> +@cindex shepherd services
>> +
>> +@defvr {Scheme Variable} shepherd-home-service-type
>> +The service type for the userland Shepherd, which allows to manage
>
> “allows one to manage”
>
>> +long-running process or one-shot tasks.  Almost all the information
>
> s/process/processes/
>
>> +described in (@pxref{Shepherd Services}) is applicable here too.
>
> What is not applicable?
>

Clarified.

>
>> +This is the service type that extensions target when they want to create
>> +shepherd services (@pxref{Service Types and Services}, for an example).
>> +Each extension must pass a list of @code{<shepherd-service>}.  Its
>> +value must be a @code{shepherd-configuration}, as described below.
>> +@end defvr
>> +
>> +@deftp {Data Type} shepherd-configuration
>> +This data type represents the Shepherd's configuration.
>> +
>> +@table @code
>> +@item shepherd (default: @code{shepherd})
>> +The Shepherd package to use.
>> +
>> +@item auto-start? (default: @code{#t})
>> +Wether or not to start Shepherd on first login.
>
> s/Wether/Whether/
>
>> +@item services (default: @code{'()})
>> +A list of @code{<shepherd-service>} to start.
>> +You should probably use the service extension
>> +mechanism instead (@pxref{Shepherd Services}).
>> +@end table
>> +@end deftp
>>  
>>  @node Invoking guix home
>>  @section Invoking @code{guix home}
>> diff --git a/gnu/home-services/shepherd.scm b/gnu/home-services/shepherd.scm
>> new file mode 100644
>> index 0000000000..158b50bdb6
>> --- /dev/null
>> +++ b/gnu/home-services/shepherd.scm
>> @@ -0,0 +1,133 @@
>> +;;; GNU Guix --- Functional package management for GNU
>> +;;; Copyright © 2021 Andrew Tropin <andrew@trop.in>
>> +;;; Copyright © 2021 Xinglu Chen <public@yoctocell.xyz>
>> +;;;
>> +;;; This file is part of GNU Guix.
>> +;;;
>> +;;; GNU Guix is free software; you can redistribute it and/or modify it
>> +;;; under the terms of the GNU General Public License as published by
>> +;;; the Free Software Foundation; either version 3 of the License, or (at
>> +;;; your option) any later version.
>> +;;;
>> +;;; GNU Guix is distributed in the hope that it will be useful, but
>> +;;; WITHOUT ANY WARRANTY; without even the implied warranty of
>> +;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>> +;;; GNU General Public License for more details.
>> +;;;
>> +;;; You should have received a copy of the GNU General Public License
>> +;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.
>> +
>> +(define-module (gnu home-services shepherd)
>> +  #:use-module (gnu home-services)
>> +  #:use-module (gnu packages admin)
>> +  #:use-module (gnu services shepherd)
>> +  #:use-module (guix sets)
>> +  #:use-module (guix gexp)
>> +  #:use-module (guix i18n)
>> +  #:use-module (guix records)
>> +
>> +  #:use-module (srfi srfi-1)
>> +
>> +  #:re-export (shepherd-service
>> +               shepherd-action))
>> +
>> +(define-record-type* <home-shepherd-configuration>
>> +  home-shepherd-configuration make-home-shepherd-configuration
>> +  home-shepherd-configuration?
>> +  (shepherd home-shepherd-configuration-shepherd
>> +            (default shepherd)) ; package
>> +  (auto-start? home-shepherd-configuration-auto-start?
>> +               (default #t))
>> +  (services home-shepherd-configuration-services
>> +            (default '())))
>> +
>> +(define (home-shepherd-configuration-file services shepherd)
>> +  "Return the shepherd configuration file for SERVICES.  SHEPHERD is used
>> +as shepherd package."
>> +  (assert-valid-graph services)
>> +
>> +  (let ((files (map shepherd-service-file services))
>> +        ;; TODO: Add compilation of services, it can improve start
>> +        ;; time.
>> +        ;; (scm->go (cute scm->go <> shepherd))
>> +        )
>> +    (define config
>> +      #~(begin
>> +          (use-modules (srfi srfi-34)
>> +                       (system repl error-handling))
>> +          (apply
>> +           register-services
>> +           (map
>> +            (lambda (file) (load file))
>> +            '#$files))
>> +          (action 'root 'daemonize)
>> +          (format #t "Starting services...~%")
>
> Maybe (G_ ...) should be used to make strings translatable?
>
>
>> +          (for-each
>> +           (lambda (service) (start service))
>> +           '#$(append-map shepherd-service-provision
>> +                          (filter shepherd-service-auto-start?
>> +                                  services)))
>> +          (newline)))
>
> Is ‘newline’ necessary?
>

Not necessary, but nice to have for better separation of different
processes launched during activation.  It could newline at the beginning
of each activation subscript, but it is what it is)

>
>> +    (scheme-file "shepherd.conf" config)))
>> +
>> +(define (launch-shepherd-gexp config)
>> +  (let* ((shepherd (home-shepherd-configuration-shepherd config))
>> +         (services (home-shepherd-configuration-services config)))
>> +    (if (home-shepherd-configuration-auto-start? config)
>> +        (with-imported-modules '((guix build utils))
>> +          #~(let ((log-dir (or (getenv "XDG_LOG_HOME")
>> +                               (format #f "~a/.local/var/log" (getenv 
>> "HOME")))))
>> +              ((@ (guix build utils) mkdir-p) log-dir)
>> +              (system*
>> +               #$(file-append shepherd "/bin/shepherd")
>> +               "--logfile"
>> +               (string-append
>> +                log-dir
>> +                "/shepherd.log")
>> +               "--config"
>> +               #$(home-shepherd-configuration-file services shepherd))))
>> +        #~"")))
>> +
>> +(define (reload-configuration-gexp config)
>> +  (let* ((shepherd (home-shepherd-configuration-shepherd config))
>> +         (services (home-shepherd-configuration-services config)))
>> +    #~(system*
>> +       #$(file-append shepherd "/bin/herd")
>> +       "load" "root"
>> +       #$(home-shepherd-configuration-file services shepherd))))
>> +
>> +(define (ensure-shepherd-gexp config)
>> +  #~(if (file-exists?
>> +         (string-append
>> +          (or (getenv "XDG_RUNTIME_DIR")
>> +              (format #f "/run/user/~a" (getuid)))
>> +          "/shepherd/socket"))
>> +        #$(reload-configuration-gexp config)
>> +        #$(launch-shepherd-gexp config)))
>> +
>> +(define-public home-shepherd-service-type
>> +  (service-type (name 'home-shepherd)
>> +                (extensions
>> +                 (list (service-extension
>> +                        home-run-on-first-login-service-type
>> +                        launch-shepherd-gexp)
>> +                       (service-extension
>> +                        home-activation-service-type
>> +                        ensure-shepherd-gexp)
>> +                       (service-extension
>> +                        home-profile-service-type
>> +                        (lambda (config)
>> +                          `(,(home-shepherd-configuration-shepherd 
>> config))))))
>
> Nit: I would use ‘list’ instead of quasiquoting and unquoting.
>

It's probably done this way to keep the line under 80 characters long,
but I agree, using list would be a little more cleaner.

>
>> +                (compose concatenate)
>> +                (extend
>> +                 (lambda (config extra-services)
>> +                   (home-shepherd-configuration
>> +                    (inherit config)
>> +                    (services
>> +                     (append (home-shepherd-configuration-services config)
>> +                             extra-services)))))
>> +                (default-value (home-shepherd-configuration))
>> +                (description "Configure and install userland Shepherd.")))
>> +
>> +
>> -- 
>> 2.33.0

Replied or addressed all the comments.

From c12b51bdbc86fa995c88f331b5d04b0b963087cf Mon Sep 17 00:00:00 2001
From: Andrew Tropin <andrew@trop.in>
Date: Thu, 2 Sep 2021 12:33:36 +0300
Subject: [PATCH v2] home-services: Add Shepherd.

* gnu/home-services/shepherd.scm: New file.
* doc/guix.texi: Add documentation about Shepherd Home Service.
---
 doc/guix.texi                  |  32 +++++++-
 gnu/home-services/shepherd.scm | 133 +++++++++++++++++++++++++++++++++
 2 files changed, 164 insertions(+), 1 deletion(-)
 create mode 100644 gnu/home-services/shepherd.scm

diff --git a/doc/guix.texi b/doc/guix.texi
index 622a973bdf..0591848f7e 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -35538,7 +35538,37 @@ mcron info here
 
 @node Shepherd Home Service
 @subsection Managing User's Daemons
-shepherd info here
+
+@cindex shepherd services
+
+@defvr {Scheme Variable} home-shepherd-service-type
+The service type for the userland Shepherd, which allows one to manage
+long-running processes or one-shot tasks.  User's Shepherd is not an
+init process (PID 1), but almost all other information described in
+(@pxref{Shepherd Services}) is applicable here too.
+
+This is the service type that extensions target when they want to create
+shepherd services (@pxref{Service Types and Services}, for an example).
+Each extension must pass a list of @code{<shepherd-service>}.  Its
+value must be a @code{shepherd-configuration}, as described below.
+@end defvr
+
+@deftp {Data Type} shepherd-configuration
+This data type represents the Shepherd's configuration.
+
+@table @code
+@item shepherd (default: @code{shepherd})
+The Shepherd package to use.
+
+@item auto-start? (default: @code{#t})
+Whether or not to start Shepherd on first login.
+
+@item services (default: @code{'()})
+A list of @code{<shepherd-service>} to start.
+You should probably use the service extension
+mechanism instead (@pxref{Shepherd Services}).
+@end table
+@end deftp
 
 @node Invoking guix home
 @section Invoking @code{guix home}
diff --git a/gnu/home-services/shepherd.scm b/gnu/home-services/shepherd.scm
new file mode 100644
index 0000000000..04366f4b81
--- /dev/null
+++ b/gnu/home-services/shepherd.scm
@@ -0,0 +1,133 @@
+;;; GNU Guix --- Functional package management for GNU
+;;; Copyright © 2021 Andrew Tropin <andrew@trop.in>
+;;; Copyright © 2021 Xinglu Chen <public@yoctocell.xyz>
+;;;
+;;; This file is part of GNU Guix.
+;;;
+;;; GNU Guix is free software; you can redistribute it and/or modify it
+;;; under the terms of the GNU General Public License as published by
+;;; the Free Software Foundation; either version 3 of the License, or (at
+;;; your option) any later version.
+;;;
+;;; GNU Guix is distributed in the hope that it will be useful, but
+;;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;;; GNU General Public License for more details.
+;;;
+;;; You should have received a copy of the GNU General Public License
+;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.
+
+(define-module (gnu home-services shepherd)
+  #:use-module (gnu home-services)
+  #:use-module (gnu packages admin)
+  #:use-module (gnu services shepherd)
+  #:use-module (guix sets)
+  #:use-module (guix gexp)
+  #:use-module (guix i18n)
+  #:use-module (guix records)
+
+  #:use-module (srfi srfi-1)
+
+  #:re-export (shepherd-service
+               shepherd-action))
+
+(define-record-type* <home-shepherd-configuration>
+  home-shepherd-configuration make-home-shepherd-configuration
+  home-shepherd-configuration?
+  (shepherd home-shepherd-configuration-shepherd
+            (default shepherd)) ; package
+  (auto-start? home-shepherd-configuration-auto-start?
+               (default #t))
+  (services home-shepherd-configuration-services
+            (default '())))
+
+(define (home-shepherd-configuration-file services shepherd)
+  "Return the shepherd configuration file for SERVICES.  SHEPHERD is used
+as shepherd package."
+  (assert-valid-graph services)
+
+  (let ((files (map shepherd-service-file services))
+        ;; TODO: Add compilation of services, it can improve start
+        ;; time.
+        ;; (scm->go (cute scm->go <> shepherd))
+        )
+    (define config
+      #~(begin
+          (use-modules (srfi srfi-34)
+                       (system repl error-handling))
+          (apply
+           register-services
+           (map
+            (lambda (file) (load file))
+            '#$files))
+          (action 'root 'daemonize)
+          (format #t (G_ "Starting services...~%"))
+          (for-each
+           (lambda (service) (start service))
+           '#$(append-map shepherd-service-provision
+                          (filter shepherd-service-auto-start?
+                                  services)))
+          (newline)))
+
+    (scheme-file "shepherd.conf" config)))
+
+(define (launch-shepherd-gexp config)
+  (let* ((shepherd (home-shepherd-configuration-shepherd config))
+         (services (home-shepherd-configuration-services config)))
+    (if (home-shepherd-configuration-auto-start? config)
+        (with-imported-modules '((guix build utils))
+          #~(let ((log-dir (or (getenv "XDG_LOG_HOME")
+                               (format #f "~a/.local/var/log" (getenv 
"HOME")))))
+              ((@ (guix build utils) mkdir-p) log-dir)
+              (system*
+               #$(file-append shepherd "/bin/shepherd")
+               "--logfile"
+               (string-append
+                log-dir
+                "/shepherd.log")
+               "--config"
+               #$(home-shepherd-configuration-file services shepherd))))
+        #~"")))
+
+(define (reload-configuration-gexp config)
+  (let* ((shepherd (home-shepherd-configuration-shepherd config))
+         (services (home-shepherd-configuration-services config)))
+    #~(system*
+       #$(file-append shepherd "/bin/herd")
+       "load" "root"
+       #$(home-shepherd-configuration-file services shepherd))))
+
+(define (ensure-shepherd-gexp config)
+  #~(if (file-exists?
+         (string-append
+          (or (getenv "XDG_RUNTIME_DIR")
+              (format #f "/run/user/~a" (getuid)))
+          "/shepherd/socket"))
+        #$(reload-configuration-gexp config)
+        #$(launch-shepherd-gexp config)))
+
+(define-public home-shepherd-service-type
+  (service-type (name 'home-shepherd)
+                (extensions
+                 (list (service-extension
+                        home-run-on-first-login-service-type
+                        launch-shepherd-gexp)
+                       (service-extension
+                        home-activation-service-type
+                        ensure-shepherd-gexp)
+                       (service-extension
+                        home-profile-service-type
+                        (lambda (config)
+                          `(,(home-shepherd-configuration-shepherd config))))))
+                (compose concatenate)
+                (extend
+                 (lambda (config extra-services)
+                   (home-shepherd-configuration
+                    (inherit config)
+                    (services
+                     (append (home-shepherd-configuration-services config)
+                             extra-services)))))
+                (default-value (home-shepherd-configuration))
+                (description "Configure and install userland Shepherd.")))
+
+
-- 
2.33.0

Attachment: signature.asc
Description: PGP signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]