From b31e63c3668e5163eba40f7815ccae19cb2af236 Mon Sep 17 00:00:00 2001 From: Eric Bavier Date: Mon, 24 Feb 2020 23:47:02 -0600 Subject: [PATCH] guix: pack: Only wrap executable files. * guix/scripts/pack.scm (wrapped-package): Build wrappers for executable files and symlink others. * tests/guix-pack-relocatable.sh: Test relocatable example of mixed executable and non-executable files. --- guix/scripts/pack.scm | 31 ++++++++++++++++++++++--------- tests/guix-pack-relocatable.sh | 31 +++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 9 deletions(-) diff --git a/guix/scripts/pack.scm b/guix/scripts/pack.scm index 5fb6aaae0c..1b9609753d 100644 --- a/guix/scripts/pack.scm +++ b/guix/scripts/pack.scm @@ -5,6 +5,7 @@ ;;; Copyright © 2018 Chris Marusich ;;; Copyright © 2018 Efraim Flashner ;;; Copyright © 2020 Tobias Geerinckx-Rice +;;; Copyright © 2020 Eric Bavier ;;; ;;; This file is part of GNU Guix. ;;; @@ -747,11 +748,12 @@ last resort for relocation." (guix elf))) #~(begin (use-modules (guix build utils) - ((guix build union) #:select (relative-file-name)) + ((guix build union) #:select (symlink-relative)) (guix elf) (ice-9 binary-ports) (ice-9 ftw) (ice-9 match) + (ice-9 receive) (srfi srfi-1) (rnrs bytevectors)) @@ -847,16 +849,27 @@ last resort for relocation." (mkdir target) (for-each (lambda (file) (unless (member file '("." ".." "bin" "sbin" "libexec")) - (let ((file* (string-append input "/" file))) - (symlink (relative-file-name target file*) - (string-append target "/" file))))) + (symlink-relative (string-append input "/" file) + (string-append target "/" file)))) (scandir input)) - (for-each build-wrapper - ;; Note: Trailing slash in case these are symlinks. - (append (find-files (string-append input "/bin/")) - (find-files (string-append input "/sbin/")) - (find-files (string-append input "/libexec/"))))))) + (receive (executables others) + (partition executable-file? + ;; Note: Trailing slash in case these are symlinks. + (append (find-files (string-append input "/bin/")) + (find-files (string-append input "/sbin/")) + (find-files (string-append input "/libexec/")))) + ;; Wrap only executables, since the wrapper will eventually need + ;; to execve them. E.g. git's "libexec" directory contains many + ;; shell scripts that are source'd from elsewhere, which fails if + ;; they are wrapped. + (for-each build-wrapper executables) + ;; Link any other non-executable files + (for-each (lambda (old) + (let ((new (string-append target (strip-store-prefix old)))) + (mkdir-p (dirname new)) + (symlink-relative old new))) + others))))) (computed-file (string-append (cond ((package? package) diff --git a/tests/guix-pack-relocatable.sh b/tests/guix-pack-relocatable.sh index 52d7212594..2ed497027d 100644 --- a/tests/guix-pack-relocatable.sh +++ b/tests/guix-pack-relocatable.sh @@ -1,5 +1,6 @@ # GNU Guix --- Functional package management for GNU # Copyright © 2018, 2019, 2020 Ludovic Courtès +# Copyright © 2020 Eric Bavier # # This file is part of GNU Guix. # @@ -99,6 +100,7 @@ case "`uname -m`" in GUIX_EXECUTION_ENGINE="fakechroot" "$test_directory/Bin/sed" --version > "$test_directory/output" grep 'GNU sed' "$test_directory/output" + unset GUIX_EXECUTION_ENGINE chmod -Rf +w "$test_directory"; rm -rf "$test_directory"/* ;; @@ -111,8 +113,37 @@ esac tarball="`guix pack -R -S /share=share groff:doc`" (cd "$test_directory"; tar xvf "$tarball") test -d "$test_directory/share/doc/groff/html" +chmod -Rf +w "$test_directory"; rm -rf "$test_directory"/* # Ensure '-R' applies to propagated inputs. Failing to do that, it would fail # with a profile collision error in this case because 'python-scipy' # propagates 'python-numpy'. See . guix pack -RR python-numpy python-scipy --no-grafts -n + +# Check that packages that mix executable and support files (e.g. git) in the +# "binary" directories still work after wrapped. +cat >"$test_directory/manifest.scm" <<'EOF' +(use-modules (guix) (guix profiles) + (gnu packages bootstrap)) +(manifest + (list (manifest-entry + (name "test") (version "0") + (item (file-union "test" + `(("bin/hello" + ,(program-file + "hello" + #~(format #t "~d~%" (load "../libexec/msg")) + #:guile %bootstrap-guile)) + ("libexec/msg" + ,(plain-file "msg" "42")))))))) +EOF +tarball="`guix pack $relocatable_option -S /opt= -m $test_directory/manifest.scm`" +(cd "$test_directory"; tar xvf "$tarball") +do_test='"$test_directory/opt/bin/hello" >"$test_directory/output"' +if unshare -r true # Are user namespaces supported? +then + unshare -mrf sh -c 'mount -t tmpfs none "$STORE_PARENT"; '"$do_test" +else + ( $do_test ) +fi +test "`cat $test_directory/output`" = "42" -- 2.27.0