shell, inferior: Store GC roots under /var/guix/profiles.

Fixes guix/guix#2410.

Until now, ‘guix shell’ and ‘guix time-machine’ would store GC roots under
~/.cache/guix.  However, this directory is unreadable to guix-daemon when it’s
running without root privileges.  This commit changes ‘guix shell’ and ‘guix
time-machine’ so they store GC roots under /var/guix/profiles/per-user/$USER,
in a world-readable directory.

An added benefit is that, in cluster setups, user homes no longer need to be
mounted on the head node for GC to work (assuming ‘guix build -r’ and similar
are not used).

* guix/inferior.scm (%inferior-cache-directory): Change default value to be
under ‘%profile-directory’.
(%legacy-inferior-cache-directory): New variable.
(cached-channel-instance): Add ‘maybe-remove-expired-cache-entries’ call.
* guix/scripts/environment.scm (launch-environment/container)[nesting-mappings]:
Add /inferiors and /profiles sub-directories of ‘%profile-directory’.  Call
‘mkdir-p’ for these two directories.
* guix/scripts/shell.scm (%profile-cache-directory): Change default value to
be under ‘%profile-directory’.
(%legacy-cache-directory): New variable.
(guix-shell): Add call to ‘maybe-remove-expired-cache-entries’.

Change-Id: Ie7d6c16a55b35c7beb18078c967d6fc902bf68d0
Signed-off-by: Ludovic Courtès <ludo@gnu.org>
This commit is contained in:
Ludovic Courtès 2025-09-02 09:57:19 +02:00
parent 5b218cd2b9
commit d12c4452a4
No known key found for this signature in database
GPG key ID: 090B11993D9AEBB5
3 changed files with 45 additions and 10 deletions

View file

@ -1,5 +1,5 @@
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2018-2024 Ludovic Courtès <ludo@gnu.org>
;;; Copyright © 2018-2025 Ludovic Courtès <ludo@gnu.org>
;;;
;;; This file is part of GNU Guix.
;;;
@ -860,9 +860,13 @@ failing when GUIX is too old and lacks the 'guix repl' command."
;;;
(define %inferior-cache-directory
;; Directory for cached inferiors (GC roots).
(make-parameter (string-append (cache-directory #:ensure? #f)
"/inferiors")))
;; Directory for cached inferiors (GC roots). It must be world-readable so
;; the daemon can traverse it.
(make-parameter (string-append %profile-directory "/inferiors")))
(define %legacy-inferior-cache-directory
;; Former directory for cached inferiors, by default under $HOME/.cache.
(string-append (cache-directory #:ensure? #f) "/inferiors"))
(define* (channel-full-commit channel #:key (verify-certificate? #t))
"Return the commit designated by CHANNEL as quickly as possible. If
@ -950,6 +954,14 @@ X.509 host certificate; otherwise, warn about the problem and keep going."
#:entry-expiration
(file-expiration-time ttl))
;; Clean the legacy cache directory as well. Remove this call once at least
;; one year has passed.
(maybe-remove-expired-cache-entries %legacy-inferior-cache-directory
cache-entries
#:entry-expiration
(file-expiration-time ttl))
(if (file-exists? cached)
cached
(run-with-store store

View file

@ -793,11 +793,24 @@ WHILE-LIST."
(define (nesting-mappings)
;; Files shared with the host when enabling nesting.
;; Make sure these two directories exist so they can be shared.
(mkdir-p (string-append %profile-directory "/profiles"))
(mkdir-p (string-append %profile-directory "/inferiors"))
(cons* (file-system-mapping
(source (%store-prefix))
(target source))
(file-system-mapping
(source (cache-directory))
(source (cache-directory)) ;~/.cache/guix/checkouts etc.
(target source)
(writable? #t))
(file-system-mapping ;'guix shell' cached GC roots
(source (string-append %profile-directory "/profiles"))
(target source)
(writable? #t))
(file-system-mapping ;'guix time-machine' cached GC roots
(source (string-append %profile-directory "/inferiors"))
(target source)
(writable? #t))
(let ((uri (string->uri (%daemon-socket-uri))))

View file

@ -1,5 +1,5 @@
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2021-2024 Ludovic Courtès <ludo@gnu.org>
;;; Copyright © 2021-2025 Ludovic Courtès <ludo@gnu.org>
;;; Copyright © 2023 Janneke Nieuwenhuizen <janneke@gnu.org>
;;;
;;; This file is part of GNU Guix.
@ -327,10 +327,13 @@ echo ~a >> ~a
;;;
(define %profile-cache-directory
;; Directory where profiles created by 'guix shell' alone (without extra
;; options) are cached.
(make-parameter (string-append (cache-directory #:ensure? #f)
"/profiles")))
;; Directory where profiles (GC roots) created by 'guix shell' are cached.
;; It must be world-readable so the daemon can traverse it.
(make-parameter (string-append %profile-directory "/profiles")))
(define %legacy-cache-directory
;; Former cache directory, by default under $HOME/.cache.
(string-append (cache-directory #:ensure? #f) "/profiles"))
(define (profile-cache-primary-key)
"Return the \"primary key\" used when computing keys for the profile cache.
@ -592,6 +595,13 @@ to make sure your shell does not clobber environment variables."))) )
(maybe-remove-expired-cache-entries
(%profile-cache-directory)
cache-entries
#:entry-expiration entry-expiration)
;; Clean the legacy cache directory as well. Remove this
;; call once at least one year has passed.
(maybe-remove-expired-cache-entries
%legacy-cache-directory
cache-entries
#:entry-expiration entry-expiration)))
(if (assoc-ref opts 'export-manifest?)