diff options
author | Ludovic Courtès <ludo@gnu.org> | 2015-05-18 09:47:29 +0200 |
---|---|---|
committer | Ludovic Courtès <ludo@gnu.org> | 2015-05-18 09:47:29 +0200 |
commit | 113c17a0c969e600023698ae3a34994a796d0046 (patch) | |
tree | 6a1102219aa229f3b4ac08d59806b21aa8acbb23 | |
parent | 01dbc7e01a576bf388914dfe99fa473e87728462 (diff) | |
download | guix-113c17a0c969e600023698ae3a34994a796d0046.tar.gz |
profiles: Gracefully deal with packages containing an etc/ symlink.
This fixes a bug whereby 'guix package -i gcc-toolchain' would fail in 'build-profile'. This is because in 'gcc-toolchain', etc/ is a symlink, and so the 'scandir' call in 'unsymlink' would return #f instead of returning a list. Reported by Andreas Enge <andreas.enge@inria.fr>. * guix/build/profiles.scm (ensure-writable-directory)[unsymlink]: Append "/" to TARGET before calling 'scandir'. * tests/profiles.scm ("etc/profile when etc/ is a symlink"): New test.
-rw-r--r-- | guix/build/profiles.scm | 4 | ||||
-rw-r--r-- | tests/profiles.scm | 28 |
2 files changed, 31 insertions, 1 deletions
diff --git a/guix/build/profiles.scm b/guix/build/profiles.scm index 525d59b979..2becc6b9af 100644 --- a/guix/build/profiles.scm +++ b/guix/build/profiles.scm @@ -94,7 +94,9 @@ symlink (to a read-only directory in the store), then delete the symlink and instead make DIRECTORY a \"real\" directory containing symlinks." (define (unsymlink link) (let* ((target (readlink link)) - (files (scandir target + ;; TARGET might itself be a symlink, so append "/" to make sure + ;; 'scandir' enters it. + (files (scandir (string-append target "/") (negate (cut member <> '("." "..")))))) (delete-file link) (mkdir link) diff --git a/tests/profiles.scm b/tests/profiles.scm index ac7f28bf53..cc9a822cee 100644 --- a/tests/profiles.scm +++ b/tests/profiles.scm @@ -277,6 +277,34 @@ get-string-all) "foo!")))))) +(test-assertm "etc/profile when etc/ is a symlink" + ;; When etc/ is a symlink, the unsymlink code in 0.8.2 would fail + ;; gracelessly because 'scandir' would return #f. + (mlet* %store-monad + ((thing -> (dummy-package "dummy" + (build-system trivial-build-system) + (arguments + `(#:guile ,%bootstrap-guile + #:builder + (let ((out (assoc-ref %outputs "out"))) + (mkdir out) + (mkdir (string-append out "/foo")) + (symlink "foo" (string-append out "/etc")) + (call-with-output-file (string-append out "/etc/bar") + (lambda (port) + (display "foo!" port)))))))) + (entry -> (package->manifest-entry thing)) + (drv (profile-derivation (manifest (list entry)) + #:hooks '())) + (profile -> (derivation->output-path drv))) + (mbegin %store-monad + (built-derivations (list drv)) + (return (and (file-exists? (string-append profile "/etc/profile")) + (string=? (call-with-input-file + (string-append profile "/etc/bar") + get-string-all) + "foo!")))))) + (test-end "profiles") |