diff mbox series

[bug#69781] services: Add the Guix Home Service

Message ID 05fd930c91838ce9640720ce68e3379f10154590.1710355300.git.richard@freakingpenguin.com
State New
Headers show
Series [bug#69781] services: Add the Guix Home Service | expand

Commit Message

Richard Sent March 13, 2024, 6:41 p.m. UTC
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.

[1] https://git.sr.ht/~abcdw/rde/tree/master/item/src/gnu/services/home.scm
[2] https://lists.sr.ht/~abcdw/rde-discuss/%3C87h6j0rqmi.fsf%40freakingpenguin.com%3E

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


base-commit: 447e9c96259e8fa15a828de9b2dd3400e2ffafe6
diff mbox series

Patch

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