civodul pushed a commit to branch master
in repository guix.

commit e9cd72875e9bd07656c7926865310e6562f0b466
Author: Rutherther <ruthert...@ditigal.xyz>
AuthorDate: Mon Apr 28 10:07:53 2025 +0200

    services: guix: Fix case when /etc/guix/acl is a dangling symlink.
    
    One possible solution for an issue when /etc/guix/acl file exists, but 
points
    to a non-existent location. This can for example happen if one is
    reinitializing the system, and remove only /gnu/store and /var/guix, keep 
the
    rest okay. This is a major advantage of guix as compared to other distros 
that
    usually need you to reinitialize the whole root partition. But this will 
leave
    the user with acl file pointing to non-existent location. The file-exists?
    procedure will return #f for broken symbolic links.
    
    I think that another reason one would get this issue is, if one was booted 
in
    a live iso, chrooted, fixing their system. They would switch generations to
    one with different acl file, delete other generations gc rooting the 
original
    acl file and then gc. One could do this approach for example when recovering
    from file corruptions in the store, to get rid of the unsubstitutable paths
    that can't be repaired with guix gc --verify.
    
    This fixes the issue by looking for type of a file through lstat, instead of
    relying on file-exists?. If the symlink is a broken symlink, it is
    removed. Other than that the old behavior is kept:
    - If regular file, back it up
    - If symlink pointing to the store, remove it
    - If symlink not pointing to the store, back it up
    
    * gnu/services/base.scm (substitute-key-authorization): Check if acl file 
is a
    possibly-dangling symbolic link.
    
    Change-Id: I2f8170606b2f4afeea48f04acfd738b04cafc7cf
    Signed-off-by: Ludovic Courtès <l...@gnu.org>
    Modified-by: Ludovic Courtès <l...@gnu.org>
---
 gnu/services/base.scm | 19 ++++++++++++-------
 1 file changed, 12 insertions(+), 7 deletions(-)

diff --git a/gnu/services/base.scm b/gnu/services/base.scm
index 650121be8f..dfb96b1f0c 100644
--- a/gnu/services/base.scm
+++ b/gnu/services/base.scm
@@ -1843,17 +1843,22 @@ archive' public keys, with GUIX."
 
   (with-imported-modules '((guix build utils))
     #~(begin
-        (use-modules (guix build utils))
+        (use-modules (guix build utils)
+                     (ice-9 match))
         (define acl-file #$%acl-file)
         ;; If the ACL already exists, move it out of the way.  Create a backup
         ;; if it's a regular file: it's likely that the user manually updated
         ;; it with 'guix archive --authorize'.
-        (if (file-exists? acl-file)
-            (if (and (symbolic-link? acl-file)
-                     (store-file-name? (readlink acl-file)))
-                (delete-file acl-file)
-                (rename-file acl-file (string-append acl-file ".bak")))
-            (mkdir-p (dirname acl-file)))
+        (match (and=> (false-if-exception (lstat acl-file)) stat:type)
+          (#f #f) ;file doesn't exist
+          ('symlink ;delete symlink pointing to store, backup otherwise.
+           (if (or (store-file-name? (readlink acl-file)) ;store symlink
+                   (not (file-exists? acl-file)))         ;dangling symlink
+               (delete-file acl-file)
+               (rename-file acl-file (string-append acl-file ".bak"))))
+          (_ ;backup
+           (rename-file acl-file (string-append acl-file ".bak"))))
+        (mkdir-p (dirname acl-file))
 
         ;; Installed the declared ACL.
         (symlink #+default-acl acl-file))))

Reply via email to