[PATCH] services: Add the Guix Home Service

  • Done
  • quality assurance status badge
Details
2 participants
  • Ludovic Courtès
  • Richard Sent
Owner
unassigned
Submitted by
Richard Sent
Severity
normal

Debbugs page

R
R
Richard Sent wrote on 13 Mar 11:41 -0700
(address . guix-patches@gnu.org)
05fd930c91838ce9640720ce68e3379f10154590.1710355300.git.richard@freakingpenguin.com
This patch adds a Guix Home Service, which allows for configuring/deploying an
operating-system declaration with an associated home-environment.

* gnu/services/guix.scm: Add guix-home-service and guix-home-shepherd-service
* gnu/home/services/shepherd.scm: Don't attempt to launch user shepherd when
the system shepherd runs guix-home-<user>
* doc/guix.texi: Add documentation for guix-home-service

Change-Id: Ifbcc0878d934aa4abe34bb2123b5081fb432aa8e
---

Hi Guix. This patch adds support for activating a home configuration
as part of a Guix System configuration. It does this by creating a
one-shot shepherd service that runs the home environment activation
script.

This patch is based on code from Andrew Tropin [1], used with permission.
[2]. Given that fact I'm not 100% sure I handled the copyright headers
correctly; let me know if they need changed.

There was an issue where the activation script would attempt to also
launch the user-level shepherd, which would fail as /run/user/<uid>
would not usually exist. It was a benign issue (symlinks would still
be set up), but I decided an environment variable would be the best
way to avoid printing spurious warnings to the shepherd log file.

I also changed the rde code from relying on term-tty1 to
user-processes. I've not observed any failed activations with this
change and it also allows the operating-system to run in a container,
unlike term-tty1.


doc/guix.texi | 32 ++++++++++++++++++++++++++++
gnu/home/services/shepherd.scm | 7 +++++-
gnu/services/guix.scm | 39 ++++++++++++++++++++++++++++++++++
3 files changed, 77 insertions(+), 1 deletion(-)

Toggle diff (135 lines)
diff --git a/doc/guix.texi b/doc/guix.texi
index 858d5751bf..5523d1a174 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -125,6 +125,7 @@
Copyright @copyright{} 2023 Graham James Addis@*
Copyright @copyright{} 2023 Tomas Volf@*
Copyright @copyright{} 2024 Herman Rimm@*
+Copyright @copyright{} 2024 Richard Sent@*
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3 or
@@ -39567,6 +39568,37 @@ Guix Services
@end table
@end deftp
+@subsubheading Guix Home Service
+The Guix Home Service allows for associating Guix @ref{Declaring the
+Home Environment, home-environment} declarations with a Guix
+@ref{operating-system Reference, operating-system}.
+
+@defvar guix-home-service-type
+Service type for the Guix Home Service. Its value must be an
+association list. The key of each pair is a string representing the user
+to deploy the configuration under and the value is a home-environment
+configuration.
+
+@lisp
+(define my-home
+ (home-environment
+ ...))
+
+(operating-system
+ (services (list
+ (service guix-home-service-type
+ `(("alice" ,my-home))))))
+@end lisp
+
+This service can be extended by other services to add additional home
+environments, as in this example:
+
+@lisp
+(simple-service 'my-extra-home home-service-type
+ `(("bob" ,my-extra-home))))
+@end lisp
+@end defvar
+
@subsubheading Nar Herder
The @uref{https://git.cbaines.net/guix/nar-herder/about/,Nar Herder} is
a utility for managing a collection of nars.
diff --git a/gnu/home/services/shepherd.scm b/gnu/home/services/shepherd.scm
index 176f4575cb..e68dea6954 100644
--- a/gnu/home/services/shepherd.scm
+++ b/gnu/home/services/shepherd.scm
@@ -132,7 +132,12 @@ (define (ensure-shepherd-gexp config)
(format #f "/run/user/~a" (getuid)))
"/shepherd/socket"))
#$(reload-configuration-gexp config)
- #$(launch-shepherd-gexp config)))
+ ;; Don't attempt to start user shepherd if the system is running the
+ ;; activation script. /run/user/<uid> may not have been created
+ ;; yet. But do otherwise so if the runtime dir does not exist an error
+ ;; is logged.
+ (unless (getenv "GUIX_SYSTEM_IS_RUNNING_HOME_ACTIVATE")
+ #$(launch-shepherd-gexp config))))
(define (shepherd-xdg-configuration-files config)
`(("shepherd/init.scm" ,(home-shepherd-configuration-file config))))
diff --git a/gnu/services/guix.scm b/gnu/services/guix.scm
index c438da531c..5f649cbb6f 100644
--- a/gnu/services/guix.scm
+++ b/gnu/services/guix.scm
@@ -1,5 +1,6 @@
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2019, 2020, 2021, 2022 Christopher Baines <mail@cbaines.net>
+;;; Copyright © 2024 Andrew Tropin <andrew@trop.in>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -101,6 +102,8 @@ (define-module (gnu services guix)
guix-data-service-type
+ guix-home-service-type
+
nar-herder-service-type
nar-herder-configuration
nar-herder-configuration?
@@ -686,6 +689,42 @@ (define guix-data-service-type
(description
"Run an instance of the Guix Data Service.")))
+
+;;;
+;;; Guix Home Service
+;;;
+
+(define (guix-home-shepherd-service config)
+ (map (lambda (x)
+ (let ((user (car x))
+ (he (cdr x)))
+ (shepherd-service
+ (documentation "Activate Guix Home.")
+ (requirement '(user-processes))
+ (provision (list (symbol-append 'guix-home- (string->symbol user))))
+ (one-shot? #t)
+ (auto-start? #t)
+ (start #~(make-forkexec-constructor
+ '(#$(file-append he "/activate"))
+ #:user #$user
+ #:environment-variables
+ (list (string-append "HOME=" (passwd:dir (getpw #$user)))
+ "GUIX_SYSTEM_IS_RUNNING_HOME_ACTIVATE=t")
+ #:group (group:name (getgrgid (passwd:gid (getpw #$user))))))
+ (stop #~(make-kill-destructor)))))
+ config))
+
+(define guix-home-service-type
+ (service-type
+ (name 'guix-home)
+ (description "Setups home-environments specified in the value.")
+ (extensions (list (service-extension
+ shepherd-root-service-type
+ guix-home-shepherd-service)))
+ (compose concatenate)
+ (extend append)
+ (default-value '())))
+
;;;
;;; Nar Herder

base-commit: 447e9c96259e8fa15a828de9b2dd3400e2ffafe6
--
2.41.0
R
R
Richard Sent wrote on 21 Mar 11:36 -0700
[PATCH v2] services: Add the Guix Home Service
(address . 69781@debbugs.gnu.org)
3394b0b51f6a5a608ebcfb7a63fdc34e52fe928e.1711046203.git.richard@freakingpenguin.com
This patch adds a Guix Home Service, which allows for configuring/deploying an
operating-system declaration with an associated home-environment.

* gnu/services/guix.scm: Add guix-home-service and guix-home-shepherd-service
* gnu/home/services/shepherd.scm: Don't attempt to launch user shepherd when
the system shepherd runs guix-home-<user>
* doc/guix.texi: Add documentation for guix-home-service
* gnu/tests/guix.scm: Add a test to verify guix-home-service-type is able to
activate a home environment

Change-Id: Ifbcc0878d934aa4abe34bb2123b5081fb432aa8e
---

Resubmitting based on feedback on a similar patch that I missed
earlier, https://issues.guix.gnu.org/68589.Not sure how to merge
patches, but figured best to submit V2 to this issue. Sorry!

doc/guix.texi | 32 +++++++++++++++
gnu/home/services/shepherd.scm | 7 +++-
gnu/services/guix.scm | 38 ++++++++++++++++++
gnu/tests/guix.scm | 73 ++++++++++++++++++++++++++++++++++
4 files changed, 149 insertions(+), 1 deletion(-)

Toggle diff (232 lines)
diff --git a/doc/guix.texi b/doc/guix.texi
index 20f007b1c0..3a5f1289fa 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -125,6 +125,7 @@
Copyright @copyright{} 2023 Graham James Addis@*
Copyright @copyright{} 2023 Tomas Volf@*
Copyright @copyright{} 2024 Herman Rimm@*
+Copyright @copyright{} 2024 Richard Sent@*
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3 or
@@ -39576,6 +39577,37 @@ Guix Services
@end table
@end deftp
+@subsubheading Guix Home Service
+The Guix Home Service allows for associating Guix @ref{Declaring the
+Home Environment, home-environment} declarations with a Guix
+@ref{operating-system Reference, operating-system}.
+
+@defvar guix-home-service-type
+Service type for the Guix Home Service. Its value must be a list of
+lists containing user and home environment pairs. The key of each pair
+is a string representing the user to deploy the configuration under and
+the value is a home-environment configuration.
+
+@lisp
+(define my-home
+ (home-environment
+ ...))
+
+(operating-system
+ (services (list
+ (service guix-home-service-type
+ `(("alice" ,my-home))))))
+@end lisp
+
+This service can be extended by other services to add additional home
+environments, as in this example:
+
+@lisp
+(simple-service 'my-extra-home home-service-type
+ `(("bob" ,my-extra-home))))
+@end lisp
+@end defvar
+
@subsubheading Nar Herder
The @uref{https://git.cbaines.net/guix/nar-herder/about/,Nar Herder} is
a utility for managing a collection of nars.
diff --git a/gnu/home/services/shepherd.scm b/gnu/home/services/shepherd.scm
index 176f4575cb..e68dea6954 100644
--- a/gnu/home/services/shepherd.scm
+++ b/gnu/home/services/shepherd.scm
@@ -132,7 +132,12 @@ (define (ensure-shepherd-gexp config)
(format #f "/run/user/~a" (getuid)))
"/shepherd/socket"))
#$(reload-configuration-gexp config)
- #$(launch-shepherd-gexp config)))
+ ;; Don't attempt to start user shepherd if the system is running the
+ ;; activation script. /run/user/<uid> may not have been created
+ ;; yet. But do otherwise so if the runtime dir does not exist an error
+ ;; is logged.
+ (unless (getenv "GUIX_SYSTEM_IS_RUNNING_HOME_ACTIVATE")
+ #$(launch-shepherd-gexp config))))
(define (shepherd-xdg-configuration-files config)
`(("shepherd/init.scm" ,(home-shepherd-configuration-file config))))
diff --git a/gnu/services/guix.scm b/gnu/services/guix.scm
index c438da531c..05ff9f1ba4 100644
--- a/gnu/services/guix.scm
+++ b/gnu/services/guix.scm
@@ -1,5 +1,6 @@
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2019, 2020, 2021, 2022 Christopher Baines <mail@cbaines.net>
+;;; Copyright © 2024 Andrew Tropin <andrew@trop.in>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -101,6 +102,8 @@ (define-module (gnu services guix)
guix-data-service-type
+ guix-home-service-type
+
nar-herder-service-type
nar-herder-configuration
nar-herder-configuration?
@@ -686,6 +689,41 @@ (define guix-data-service-type
(description
"Run an instance of the Guix Data Service.")))
+
+;;;
+;;; Guix Home Service
+;;;
+
+(define (guix-home-shepherd-service config)
+ (map (match-lambda
+ ((user he)
+ (shepherd-service
+ (documentation "Activate Guix Home.")
+ (requirement '(user-processes))
+ (provision (list (symbol-append 'guix-home- (string->symbol user))))
+ (one-shot? #t)
+ (auto-start? #t)
+ (start #~(make-forkexec-constructor
+ '(#$(file-append he "/activate"))
+ #:user #$user
+ #:environment-variables
+ (list (string-append "HOME=" (passwd:dir (getpw #$user)))
+ "GUIX_SYSTEM_IS_RUNNING_HOME_ACTIVATE=t")
+ #:group (group:name (getgrgid (passwd:gid (getpw #$user))))))
+ (stop #~(make-kill-destructor)))))
+ config))
+
+(define guix-home-service-type
+ (service-type
+ (name 'guix-home)
+ (description "Sets up Guix Home for the specified user accounts.")
+ (extensions (list (service-extension
+ shepherd-root-service-type
+ guix-home-shepherd-service)))
+ (compose concatenate)
+ (extend append)
+ (default-value '())))
+
;;;
;;; Nar Herder
diff --git a/gnu/tests/guix.scm b/gnu/tests/guix.scm
index 240ded4825..12ad1bf255 100644
--- a/gnu/tests/guix.scm
+++ b/gnu/tests/guix.scm
@@ -17,6 +17,8 @@
;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
(define-module (gnu tests guix)
+ #:use-module (gnu home)
+ #:use-module (gnu home services)
#:use-module (gnu tests)
#:use-module (gnu system)
#:use-module (gnu system file-systems)
@@ -37,6 +39,7 @@ (define-module (gnu tests guix)
#:use-module (ice-9 match)
#:export (%test-guix-build-coordinator
%test-guix-data-service
+ %test-guix-home-service
%test-nar-herder
%test-bffe))
@@ -251,6 +254,76 @@ (define %test-guix-data-service
(description "Connect to a running Guix Data Service.")
(value (run-guix-data-service-test))))
+
+;;;
+;;; Guix Home
+;;;
+
+(define %guix-home-service-he
+ (home-environment
+ (services
+ (list (simple-service 'guix-home-service-test
+ home-files-service-type
+ `(("guix-home-service-activated"
+ ,(plain-file "guix-home-service-activated"
+ "Guix Home service activated"))))))))
+
+(define %guix-home-service-os
+ (simple-operating-system
+ (service guix-home-service-type
+ `(("alice" ,%guix-home-service-he)))))
+
+(define (run-guix-home-service-test)
+ (define os
+ (marionette-operating-system
+ %guix-home-service-os
+ #:imported-modules '((gnu services herd))))
+
+ (define vm
+ (virtual-machine
+ (operating-system os)
+ (memory-size 1024)))
+
+ (define test
+ (with-imported-modules '((gnu build marionette))
+ #~(begin
+ (use-modules (srfi srfi-64)
+ (gnu build marionette))
+
+ (define marionette
+ (make-marionette (list #$vm)))
+
+ (test-runner-current (system-test-runner #$output))
+ (test-begin "guix-home-service")
+
+ (test-assert "service started"
+ (marionette-eval
+ '(begin
+ (use-modules (gnu services herd))
+ (match (start-service 'guix-home-alice)
+ (#f #f)
+ ;; herd returns (running #f), likely because of one shot,
+ ;; so consider any non-error a success.
+ (('service response-parts ...) #t)))
+ marionette))
+
+ (test-assert "file-exists"
+ (marionette-eval
+ '(begin
+ (sleep 3) ;make sure service has time to symlink files
+ (file-exists? "/home/alice/guix-home-service-activated"))
+ marionette))
+
+ (test-end))))
+
+ (gexp->derivation "guix-home-service-test" test))
+
+(define %test-guix-home-service
+ (system-test
+ (name "guix-home-service")
+ (description "Activate a Guix home environment.")
+ (value (run-guix-home-service-test))))
+
;;;
;;; Nar Herder

base-commit: 9b84b362963770d7a21ceb4e711a5a389db5b02d
--
2.41.0
L
L
Ludovic Courtès wrote on 17 Apr 03:18 -0700
(name . Richard Sent)(address . richard@freakingpenguin.com)
87h6g0i97e.fsf@gnu.org
Hi Richard,

Richard Sent <richard@freakingpenguin.com> skribis:

Toggle quote (12 lines)
> This patch adds a Guix Home Service, which allows for configuring/deploying an
> operating-system declaration with an associated home-environment.
>
> * gnu/services/guix.scm: Add guix-home-service and guix-home-shepherd-service
> * gnu/home/services/shepherd.scm: Don't attempt to launch user shepherd when
> the system shepherd runs guix-home-<user>
> * doc/guix.texi: Add documentation for guix-home-service
> * gnu/tests/guix.scm: Add a test to verify guix-home-service-type is able to
> activate a home environment
>
> Change-Id: Ifbcc0878d934aa4abe34bb2123b5081fb432aa8e

This addresses a longstanding user request, nice!

I followed up with a doc update to make the service more discoverable.

Thank you!

Ludo’.
Closed
L
L
Ludovic Courtès wrote on 29 Apr 03:14 -0700
(name . Richard Sent)(address . richard@freakingpenguin.com)
87jzkgfpbp.fsf@gnu.org
Hi Richard,

Richard Sent <richard@freakingpenguin.com> skribis:

Toggle quote (12 lines)
> This patch adds a Guix Home Service, which allows for configuring/deploying an
> operating-system declaration with an associated home-environment.
>
> * gnu/services/guix.scm: Add guix-home-service and guix-home-shepherd-service
> * gnu/home/services/shepherd.scm: Don't attempt to launch user shepherd when
> the system shepherd runs guix-home-<user>
> * doc/guix.texi: Add documentation for guix-home-service
> * gnu/tests/guix.scm: Add a test to verify guix-home-service-type is able to
> activate a home environment
>
> Change-Id: Ifbcc0878d934aa4abe34bb2123b5081fb432aa8e

I’m using it now, yay!!

I realized there are two issues:

1. ‘guix system reconfigure’ installs ~/.guix-home, but it doesn’t run
activation scripts. So for instance, in my case, ~/.ssh/config
would remain dangling, pointing to that installed by my previous
Home generation, and Shepherd services were not reloaded.

2. ‘guix home describe’ USN’t prepared to deal with that: it returns
information from the last
/var/guix/profiles/per-user/$USER/guix-home-*.

#1 is the most problematic.

Thoughts?

Ludo’.
L
L
Ludovic Courtès wrote on 29 Apr 06:41 -0700
(name . Richard Sent)(address . richard@freakingpenguin.com)
87le4w1e2l.fsf@gnu.org
Ludovic Courtès <ludo@gnu.org> skribis:

Toggle quote (5 lines)
> 1. ‘guix system reconfigure’ installs ~/.guix-home, but it doesn’t run
> activation scripts. So for instance, in my case, ~/.ssh/config
> would remain dangling, pointing to that installed by my previous
> Home generation, and Shepherd services were not reloaded.

Silly me: I was using ‘home-service-type’ instead of
‘guix-home-service-type’. 🤦

(Interestingly, this has no effect at all, but nothing complained,
either.)

Works like a charm after switching to ‘guix-home-service-type’! :-)

Toggle quote (4 lines)
> 2. ‘guix home describe’ isn’t prepared to deal with that: it returns
> information from the last
> /var/guix/profiles/per-user/$USER/guix-home-*.

That issue remains, but it’s less of a problem.

Ludo’.
R
R
Richard Sent wrote on 29 Apr 08:21 -0700
(name . Ludovic Courtès)(address . ludo@gnu.org)
87il00yz1z.fsf@freakingpenguin.com
Hi Ludo!

Ludovic Courtès <ludo@gnu.org> writes:

Toggle quote (10 lines)
> Ludovic Courtès <ludo@gnu.org> skribis:
>
> Silly me: I was using ‘home-service-type’ instead of
> ‘guix-home-service-type’. 🤦
>
> (Interestingly, this has no effect at all, but nothing complained,
> either.)
>
> Works like a charm after switching to ‘guix-home-service-type’! :-)

Thanks for the response! I just started investigating that and was close
to entering the "losing my mind" phase of debugging. Glad to hear it
does in fact work!

Toggle quote (6 lines)
>> 2. ‘guix home describe’ isn’t prepared to deal with that: it returns
>> information from the last
>> /var/guix/profiles/per-user/$USER/guix-home-*.
>
> That issue remains, but it’s less of a problem.

There are definitely some potential issues when running certain 'guix
home ...' commands that operate on generations while using
'guix-home-service. The "correct" behavior may not always be obvious
either. For example:

1. 'guix-home-service' reactivates the same home environment every time
the service is launched. If generations are created, how should that be
reflected if the user has a home environment activated by
'guix-home-service' (generation A), runs 'guix home reconfigure'
(generation B), and reboots? Consider it a silent roll back to A? Should
B be marked a garbage collection candidate? Or should generation C be
created?

2. Users may try 'guix home roll-back' or 'switch-generations', thinking
the change is persistent. Should this be transient? Or should the change
be made persistent somehow? (I'm strongly in favor of "transient", but I
figured I'd raise the point.)

I think this approach is best:

1. Create a new home generation when 'guix system reconfigure' and
'guix-home-service' are used.

2. Make 'guix home reconfigure', 'switch-generations', and 'roll-back'
all warn that the changes are temporary.

3. Disable 'guix home delete-generations' on any system-created home
generations. System-created home generations are deleted when the
corresponding system generation is deleted.

4. Adjust 'guix home list-generations' and 'describe' to indicate if a
home generation came from a particular system generation.

As for how to accomplish this or how feasible it is? No clue.

--
Take it easy,
Richard Sent
Making my computer weirder one commit at a time.
L
L
Ludovic Courtès wrote on 25 May 06:04 -0700
(name . Richard Sent)(address . richard@freakingpenguin.com)
87v83211r9.fsf@gnu.org
Hi!

Richard Sent <richard@freakingpenguin.com> skribis:

Toggle quote (5 lines)
> I think this approach is best:
>
> 1. Create a new home generation when 'guix system reconfigure' and
> 'guix-home-service' are used.

Yes. That would placate ‘guix home describe’.

Toggle quote (3 lines)
> 2. Make 'guix home reconfigure', 'switch-generations', and 'roll-back'
> all warn that the changes are temporary.

How could they know, though?

Toggle quote (4 lines)
> 3. Disable 'guix home delete-generations' on any system-created home
> generations. System-created home generations are deleted when the
> corresponding system generation is deleted.

Same question here.

In short: adding an activation snippet that creates a new Home
generation should be an improvement.

Thanks!

Ludo’.
?
Your comment

This issue is archived.

To comment on this conversation send an email to 69781@patchwise.org

To respond to this issue using the mumi CLI, first switch to it
mumi current 69781
Then, you may apply the latest patchset in this issue (with sign off)
mumi am -- -s
Or, compose a reply to this issue
mumi compose
Or, send patches to this issue
mumi send-email *.patch