From d12c4452a49b355369636de1dfc766b5bad6437b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20Court=C3=A8s?= Date: Tue, 2 Sep 2025 09:57:19 +0200 Subject: [PATCH] shell, inferior: Store GC roots under /var/guix/profiles. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- guix/inferior.scm | 20 ++++++++++++++++---- guix/scripts/environment.scm | 15 ++++++++++++++- guix/scripts/shell.scm | 20 +++++++++++++++----- 3 files changed, 45 insertions(+), 10 deletions(-) diff --git a/guix/inferior.scm b/guix/inferior.scm index 680fe6a805b503c206fa42c64b427bdcc51c4ca3..1440c684ccdf7876f3b2b6fba1e14b29871eddca 100644 --- a/guix/inferior.scm +++ b/guix/inferior.scm @@ -1,5 +1,5 @@ ;;; GNU Guix --- Functional package management for GNU -;;; Copyright © 2018-2024 Ludovic Courtès +;;; Copyright © 2018-2025 Ludovic Courtès ;;; ;;; 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 diff --git a/guix/scripts/environment.scm b/guix/scripts/environment.scm index 41353e33053a780b6a6282b0d786b4209893ee92..15b84afb7fd218480ff6b8f2a04a3cb0d2365011 100644 --- a/guix/scripts/environment.scm +++ b/guix/scripts/environment.scm @@ -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)))) diff --git a/guix/scripts/shell.scm b/guix/scripts/shell.scm index d23362a15d5a7d787fea08c573c503fb4bf679d5..80251606a321d5140a101c345a890ecfeed5d8a9 100644 --- a/guix/scripts/shell.scm +++ b/guix/scripts/shell.scm @@ -1,5 +1,5 @@ ;;; GNU Guix --- Functional package management for GNU -;;; Copyright © 2021-2024 Ludovic Courtès +;;; Copyright © 2021-2025 Ludovic Courtès ;;; Copyright © 2023 Janneke Nieuwenhuizen ;;; ;;; 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?)