--- a/doc/guix.texi +++ b/doc/guix.texi @@ -233,6 +233,16 @@ The @code{guix-daemon} program may then be run as @code{root} with: # guix-daemon --build-users-group=guix-builder @end example +In such a multi-user setup, @dfn{user profiles}---i.e., the set of +user-installed packages as seen by @command{guix-package} +(@pxref{Invoking guix-package})---must be stored in a place registered +as a @dfn{garbage-collector root}. That directory is normally +@code{@var{localstatedir}/profiles/per-user/@var{user}}, where +@var{localstatedir} is the value passed to @code{configure} as +@code{--localstatedir}, and @var{user} is the user name. This directory +must be created by @code{root}, with @var{user} as the owner. When it +does not exist, @command{guix-package} emits an error about it. + Guix may also be used in a single-user setup, with @command{guix-daemon} running as a unprivileged user. However, to maximize non-interference of build processes, the daemon still needs to perform certain operations diff --git a/guix-package.in b/guix-package.in index 450d09e..ec09cc4 100644 --- a/guix-package.in +++ b/guix-package.in @@ -36,6 +36,7 @@ exec ${GUILE-@GUILE@} -L "@guilemoduledir@" -l "$0" \ #:use-module (guix packages) #:use-module (guix utils) #:use-module (guix config) + #:use-module ((guix build utils) #:select (directory-exists?)) #:use-module (ice-9 ftw) #:use-module (ice-9 format) #:use-module (ice-9 match) @@ -465,6 +466,25 @@ Install, remove, or upgrade PACKAGES in a single transaction.\n")) (not (file-exists? %user-environment-directory))) (symlink %current-profile %user-environment-directory)) + ;; Attempt to create /…/profiles/per-user/$USER if needed. + (unless (or (not (equal? (assoc-ref opts 'profile) %current-profile)) + (directory-exists? %profile-directory)) + (catch 'system-error + (lambda () + (mkdir %profile-directory)) + (lambda args + ;; Often, we cannot create %PROFILE-DIRECTORY because its + ;; parent directory is root-owned and we're running + ;; unprivileged. + (format (current-error-port) + (_ "error: while creating directory `~a': ~a~%") + %profile-directory + (strerror (system-error-errno args))) + (format (current-error-port) + (_ "Please create the `~a' directory, with you as the owner.~%") + %profile-directory) + (exit 1)))) + (with-error-handling (or (process-query opts) (parameterize ((%guile-for-build