summary refs log tree commit diff
path: root/gnu/system
diff options
context:
space:
mode:
authorLudovic Courtès <ludo@gnu.org>2017-02-01 12:16:39 +0100
committerLudovic Courtès <ludo@gnu.org>2017-02-01 12:36:41 +0100
commitae763b5b0b7d5e7316a3d0efe991fe8ab2261031 (patch)
treeffe951fbfe0387c43b7352f1bd3d2e0571b1d154 /gnu/system
parent524ee6c9e5a2510f6e15ab23c75a26f61b6a0d81 (diff)
downloadguix-ae763b5b0b7d5e7316a3d0efe991fe8ab2261031.tar.gz
system: Create home directories once 'file-systems' is up.
Fixes <http://bugs.gnu.org/21108>.
Reported by Andy Patterson <ajpatter@uwaterloo.ca>
and Leo Famulari <leo@famulari.name>.

* gnu/build/activation.scm (activate-users+groups)[activate-user]: Pass
  #:create-home? #t iff CREATE-HOME? and SYSTEM?.
(activate-user-home): New procedure.
* gnu/system/shadow.scm (account-shepherd-service): New procedure.
(account-service-type)[extensions]: Add SHEPHERD-ROOT-SERVICE-TYPE
extension.
* gnu/tests/base.scm (run-basic-test)["home"]
["skeletons in home directories"]: New tests.
* gnu/tests/install.scm (%separate-home-os, %separate-home-os-source)
(%test-separate-home-os): New variables.
Diffstat (limited to 'gnu/system')
-rw-r--r--gnu/system/shadow.scm34
1 files changed, 34 insertions, 0 deletions
diff --git a/gnu/system/shadow.scm b/gnu/system/shadow.scm
index cfdcf5e136..ee9d55c157 100644
--- a/gnu/system/shadow.scm
+++ b/gnu/system/shadow.scm
@@ -21,9 +21,11 @@
   #:use-module (guix records)
   #:use-module (guix gexp)
   #:use-module (guix store)
+  #:use-module (guix modules)
   #:use-module (guix sets)
   #:use-module (guix ui)
   #:use-module (gnu services)
+  #:use-module (gnu services shepherd)
   #:use-module ((gnu system file-systems)
                 #:select (%tty-gid))
   #:use-module ((gnu packages admin)
@@ -43,6 +45,7 @@
             user-account-supplementary-groups
             user-account-comment
             user-account-home-directory
+            user-account-create-home-directory?
             user-account-shell
             user-account-system?
 
@@ -288,6 +291,35 @@ group."
       (activate-users+groups (list #$@user-specs)
                              (list #$@group-specs))))
 
+(define (account-shepherd-service accounts+groups)
+  "Return a Shepherd service that creates the home directories for the user
+accounts among ACCOUNTS+GROUPS."
+  (define accounts
+    (filter user-account? accounts+groups))
+
+  ;; Create home directories only once 'file-systems' is up.  This makes sure
+  ;; they are created in the right place if /home lives on a separate
+  ;; partition.
+  ;;
+  ;; XXX: We arrange for this service to stop right after it's done its job so
+  ;; that 'guix system reconfigure' knows that it can reload it fearlessly
+  ;; (and thus create new home directories).  The cost of this hack is that
+  ;; there's a small window during which first-time logins could happen before
+  ;; the home directory has been created.
+  (list (shepherd-service
+         (requirement '(file-systems))
+         (provision '(user-homes))
+         (modules '((gnu build activation)))
+         (start (with-imported-modules (source-module-closure
+                                        '((gnu build activation)))
+                  #~(lambda ()
+                      (activate-user-home
+                       (list #$@(map user-account->gexp accounts)))
+                      #f)))                       ;stop
+         (stop #~(const #f))
+         (respawn? #f)
+         (documentation "Create user home directories."))))
+
 (define (shells-file shells)
   "Return a file-like object that builds a shell list for use as /etc/shells
 based on SHELLS.  /etc/shells is used by xterm, polkit, and other programs."
@@ -327,6 +359,8 @@ the /etc/skel directory for those."
                 (extensions
                  (list (service-extension activation-service-type
                                           account-activation)
+                       (service-extension shepherd-root-service-type
+                                          account-shepherd-service)
                        (service-extension etc-service-type
                                           etc-files)))))