Message ID | 871r66umqx.fsf@trop.in |
---|---|
State | Accepted |
Headers | show |
Series | [bug#50332,v2] home-services: Add Shepherd. | expand |
Context | Check | Description |
---|---|---|
cbaines/applying patch | fail | View Laminar job |
cbaines/issue | success | View issue |
Andrew Tropin <andrew@trop.in> writes: >>> * 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 +++++++++++++++++++++++++++++++++ Added to gnu/local.mk. Pushed to wip-guix-home.
On Fri, Sep 03 2021, Andrew Tropin wrote: > 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. Using ‘match-lambda’ would keep line line length shorter :-) (match-lambda (($ <home-shepherd-configuration> shepherd) (list shepherd)))
On 2021-09-03 16:31, Xinglu Chen wrote: > On Fri, Sep 03 2021, Andrew Tropin wrote: > >> 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. > > Using ‘match-lambda’ would keep line line length shorter :-) > > (match-lambda > (($ <home-shepherd-configuration> shepherd) > (list shepherd))) Good idea, maybe will use it next time)
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