diff options
| -rw-r--r-- | guix/build/store-copy.scm | 28 | ||||
| -rw-r--r-- | tests/guix-pack.sh | 2 | ||||
| -rw-r--r-- | tests/pack.scm | 48 |
3 files changed, 65 insertions, 13 deletions
diff --git a/guix/build/store-copy.scm b/guix/build/store-copy.scm index 64ade7885c9..549aa4f28be 100644 --- a/guix/build/store-copy.scm +++ b/guix/build/store-copy.scm | |||
| @@ -168,6 +168,28 @@ REFERENCE-GRAPHS, a list of reference-graph files." | |||
| 168 | 168 | ||
| 169 | (reduce + 0 (map file-size items))) | 169 | (reduce + 0 (map file-size items))) |
| 170 | 170 | ||
| 171 | (define (reset-permissions file) | ||
| 172 | "Reset the permissions on FILE and its sub-directories so that they are all | ||
| 173 | read-only." | ||
| 174 | ;; XXX: This procedure exists just to work around the inability of | ||
| 175 | ;; 'copy-recursively' to preserve permissions. | ||
| 176 | (file-system-fold (const #t) ;enter? | ||
| 177 | (lambda (file stat _) ;leaf | ||
| 178 | (unless (eq? 'symlink (stat:type stat)) | ||
| 179 | (chmod file | ||
| 180 | (if (zero? (logand (stat:mode stat) | ||
| 181 | #o100)) | ||
| 182 | #o444 | ||
| 183 | #o555)))) | ||
| 184 | (const #t) ;down | ||
| 185 | (lambda (directory stat _) ;up | ||
| 186 | (chmod directory #o555)) | ||
| 187 | (const #f) ;skip | ||
| 188 | (const #f) ;error | ||
| 189 | #t | ||
| 190 | file | ||
| 191 | lstat)) | ||
| 192 | |||
| 171 | (define* (populate-store reference-graphs target | 193 | (define* (populate-store reference-graphs target |
| 172 | #:key (log-port (current-error-port))) | 194 | #:key (log-port (current-error-port))) |
| 173 | "Populate the store under directory TARGET with the items specified in | 195 | "Populate the store under directory TARGET with the items specified in |
| @@ -197,7 +219,13 @@ REFERENCE-GRAPHS, a list of reference-graph files." | |||
| 197 | (for-each (lambda (thing) | 219 | (for-each (lambda (thing) |
| 198 | (copy-recursively thing | 220 | (copy-recursively thing |
| 199 | (string-append target thing) | 221 | (string-append target thing) |
| 222 | #:keep-mtime? #t | ||
| 200 | #:log (%make-void-port "w")) | 223 | #:log (%make-void-port "w")) |
| 224 | |||
| 225 | ;; XXX: Since 'copy-recursively' doesn't allow us to | ||
| 226 | ;; preserve permissions, we have to traverse TARGET to | ||
| 227 | ;; make sure everything is read-only. | ||
| 228 | (reset-permissions (string-append target thing)) | ||
| 201 | (report)) | 229 | (report)) |
| 202 | things))))) | 230 | things))))) |
| 203 | 231 | ||
diff --git a/tests/guix-pack.sh b/tests/guix-pack.sh index 8c1f5564263..a43f4d128fa 100644 --- a/tests/guix-pack.sh +++ b/tests/guix-pack.sh | |||
| @@ -49,7 +49,7 @@ the_pack="`guix pack --bootstrap -S /opt/gnu/bin=bin guile-bootstrap`" | |||
| 49 | # exists because /opt/gnu/bin may be an absolute symlink to a store item that | 49 | # exists because /opt/gnu/bin may be an absolute symlink to a store item that |
| 50 | # has been GC'd. | 50 | # has been GC'd. |
| 51 | test_directory="`mktemp -d`" | 51 | test_directory="`mktemp -d`" |
| 52 | trap 'rm -rf "$test_directory"' EXIT | 52 | trap 'chmod -Rf +w "$test_directory"; rm -rf "$test_directory"' EXIT |
| 53 | cd "$test_directory" | 53 | cd "$test_directory" |
| 54 | tar -xf "$the_pack" | 54 | tar -xf "$the_pack" |
| 55 | test -L opt/gnu/bin | 55 | test -L opt/gnu/bin |
diff --git a/tests/pack.scm b/tests/pack.scm index a9bc8948b91..40473a9fe93 100644 --- a/tests/pack.scm +++ b/tests/pack.scm | |||
| @@ -68,18 +68,42 @@ | |||
| 68 | #:archiver %tar-bootstrap)) | 68 | #:archiver %tar-bootstrap)) |
| 69 | (check (gexp->derivation | 69 | (check (gexp->derivation |
| 70 | "check-tarball" | 70 | "check-tarball" |
| 71 | #~(let ((bin (string-append "." #$profile "/bin"))) | 71 | (with-imported-modules '((guix build utils)) |
| 72 | (setenv "PATH" | 72 | #~(begin |
| 73 | (string-append #$%tar-bootstrap "/bin")) | 73 | (use-modules (guix build utils) |
| 74 | (system* "tar" "xvf" #$tarball) | 74 | (srfi srfi-1)) |
| 75 | (mkdir #$output) | 75 | |
| 76 | (exit | 76 | (define store |
| 77 | (and (file-exists? (string-append bin "/guile")) | 77 | ;; The unpacked store. |
| 78 | (string=? (string-append #$%bootstrap-guile "/bin") | 78 | (string-append "." (%store-directory) "/")) |
| 79 | (readlink bin)) | 79 | |
| 80 | (string=? (string-append ".." #$profile | 80 | (define (canonical? file) |
| 81 | "/bin/guile") | 81 | ;; Return #t if FILE is read-only and its mtime is 1. |
| 82 | (readlink "bin/Guile")))))))) | 82 | (let ((st (lstat file))) |
| 83 | (or (not (string-prefix? store file)) | ||
| 84 | (eq? 'symlink (stat:type st)) | ||
| 85 | (and (= 1 (stat:mtime st)) | ||
| 86 | (zero? (logand #o222 | ||
| 87 | (stat:mode st))))))) | ||
| 88 | |||
| 89 | (define bin | ||
| 90 | (string-append "." #$profile "/bin")) | ||
| 91 | |||
| 92 | (setenv "PATH" | ||
| 93 | (string-append #$%tar-bootstrap "/bin")) | ||
| 94 | (system* "tar" "xvf" #$tarball) | ||
| 95 | (mkdir #$output) | ||
| 96 | (exit | ||
| 97 | (and (file-exists? (string-append bin "/guile")) | ||
| 98 | (file-exists? store) | ||
| 99 | (every canonical? | ||
| 100 | (find-files "." (const #t) | ||
| 101 | #:directories? #t)) | ||
| 102 | (string=? (string-append #$%bootstrap-guile "/bin") | ||
| 103 | (readlink bin)) | ||
| 104 | (string=? (string-append ".." #$profile | ||
| 105 | "/bin/guile") | ||
| 106 | (readlink "bin/Guile"))))))))) | ||
| 83 | (built-derivations (list check)))) | 107 | (built-derivations (list check)))) |
| 84 | 108 | ||
| 85 | ;; The following test needs guile-sqlite3, libgcrypt, etc. as a consequence of | 109 | ;; The following test needs guile-sqlite3, libgcrypt, etc. as a consequence of |
