diff options
| -rwxr-xr-x | guix/scripts/substitute.scm | 61 | ||||
| -rw-r--r-- | tests/substitute.scm | 20 |
2 files changed, 69 insertions, 12 deletions
diff --git a/guix/scripts/substitute.scm b/guix/scripts/substitute.scm index 49f5389fe27..383661511e2 100755 --- a/guix/scripts/substitute.scm +++ b/guix/scripts/substitute.scm | |||
| @@ -44,7 +44,7 @@ | |||
| 44 | . guix:open-connection-for-uri))) | 44 | . guix:open-connection-for-uri))) |
| 45 | #:use-module (guix progress) | 45 | #:use-module (guix progress) |
| 46 | #:use-module ((guix build syscalls) | 46 | #:use-module ((guix build syscalls) |
| 47 | #:select (set-thread-name)) | 47 | #:select (set-thread-name mkdtemp!)) |
| 48 | #:use-module (ice-9 rdelim) | 48 | #:use-module (ice-9 rdelim) |
| 49 | #:use-module (ice-9 match) | 49 | #:use-module (ice-9 match) |
| 50 | #:use-module (ice-9 format) | 50 | #:use-module (ice-9 format) |
| @@ -630,6 +630,26 @@ default value." | |||
| 630 | ;; use the current output port instead. | 630 | ;; use the current output port instead. |
| 631 | (make-parameter 4)) | 631 | (make-parameter 4)) |
| 632 | 632 | ||
| 633 | ;; XXX: copied from (guix utils) | ||
| 634 | (define (call-with-temporary-directory-in directory proc) | ||
| 635 | "Call PROC with a name of a temporary directory; close the directory and | ||
| 636 | delete it when leaving the dynamic extent of this call." | ||
| 637 | (let* ((template (string-append directory "/guix-directory-" | ||
| 638 | ;; In case the temporary directory may be | ||
| 639 | ;; garbage collected, including our pid | ||
| 640 | ;; ensures that no live process can mistake | ||
| 641 | ;; our freshly-created instance for their | ||
| 642 | ;; old deleted one. | ||
| 643 | (number->string (getpid)) | ||
| 644 | ".XXXXXX")) | ||
| 645 | (tmp-dir (mkdtemp! template))) | ||
| 646 | (dynamic-wind | ||
| 647 | (const #t) | ||
| 648 | (lambda () | ||
| 649 | (proc tmp-dir)) | ||
| 650 | (lambda () | ||
| 651 | (false-if-exception (delete-file-recursively tmp-dir)))))) | ||
| 652 | |||
| 633 | (define-command (guix-substitute . args) | 653 | (define-command (guix-substitute . args) |
| 634 | (category internal) | 654 | (category internal) |
| 635 | (synopsis "implement the build daemon's substituter protocol") | 655 | (synopsis "implement the build daemon's substituter protocol") |
| @@ -712,15 +732,35 @@ default value." | |||
| 712 | actual-hash | 732 | actual-hash |
| 713 | cpu-usage | 733 | cpu-usage |
| 714 | (with-cpu-usage-monitoring | 734 | (with-cpu-usage-monitoring |
| 715 | (process-substitution | 735 | ;; Restore inside a temporary directory until the hash |
| 716 | store-path destination | 736 | ;; can be verified so that no dangling references a |
| 717 | #:cache-urls (substitute-urls) | 737 | ;; user may have laying around will point to |
| 718 | #:acl (current-acl) | 738 | ;; attacker-controlled content in the meantime. |
| 719 | #:deduplicate? deduplicate? | 739 | (call-with-temporary-directory-in (dirname destination) |
| 720 | #:print-build-trace? | 740 | (lambda (temp-directory) |
| 721 | print-build-trace? | 741 | (let* ((temp-destination |
| 722 | #:fast-decompression? | 742 | (string-append temp-directory "/restored")) |
| 723 | fast-decompression?)))) | 743 | (narinfo |
| 744 | expected-hash | ||
| 745 | actual-hash | ||
| 746 | (process-substitution | ||
| 747 | store-path temp-destination | ||
| 748 | #:cache-urls (substitute-urls) | ||
| 749 | #:acl (current-acl) | ||
| 750 | #:deduplicate? deduplicate? | ||
| 751 | #:print-build-trace? | ||
| 752 | print-build-trace? | ||
| 753 | #:fast-decompression? | ||
| 754 | fast-decompression?))) | ||
| 755 | (when (and expected-hash actual-hash | ||
| 756 | (bytevector=? actual-hash | ||
| 757 | expected-hash)) | ||
| 758 | (catch 'system-error | ||
| 759 | (lambda () | ||
| 760 | (delete-file-recursively destination)) | ||
| 761 | (const #f)) | ||
| 762 | (rename-file temp-destination destination)) | ||
| 763 | (values narinfo expected-hash actual-hash))))))) | ||
| 724 | 764 | ||
| 725 | (if expected-hash | 765 | (if expected-hash |
| 726 | (begin | 766 | (begin |
| @@ -777,6 +817,7 @@ default value." | |||
| 777 | 817 | ||
| 778 | ;;; Local Variables: | 818 | ;;; Local Variables: |
| 779 | ;;; eval: (put 'with-redirected-error-port 'scheme-indent-function 0) | 819 | ;;; eval: (put 'with-redirected-error-port 'scheme-indent-function 0) |
| 820 | ;;; eval: (put 'call-with-temporary-directory-in 'scheme-indent-function 1) | ||
| 780 | ;;; End: | 821 | ;;; End: |
| 781 | 822 | ||
| 782 | ;;; substitute.scm ends here | 823 | ;;; substitute.scm ends here |
diff --git a/tests/substitute.scm b/tests/substitute.scm index 10b74db084e..086bd588358 100644 --- a/tests/substitute.scm +++ b/tests/substitute.scm | |||
| @@ -39,6 +39,7 @@ | |||
| 39 | #:use-module (rnrs io ports) | 39 | #:use-module (rnrs io ports) |
| 40 | #:use-module (web uri) | 40 | #:use-module (web uri) |
| 41 | #:use-module (ice-9 regex) | 41 | #:use-module (ice-9 regex) |
| 42 | #:use-module (ice-9 binary-ports) | ||
| 42 | #:use-module (srfi srfi-11) | 43 | #:use-module (srfi srfi-11) |
| 43 | #:use-module (srfi srfi-26) | 44 | #:use-module (srfi srfi-26) |
| 44 | #:use-module (srfi srfi-34) | 45 | #:use-module (srfi srfi-34) |
| @@ -142,6 +143,21 @@ version identifier.." | |||
| 142 | ;; <https://www.rfc-editor.org/rfc/rfc5737>. | 143 | ;; <https://www.rfc-editor.org/rfc/rfc5737>. |
| 143 | "http://203.0.113.1") | 144 | "http://203.0.113.1") |
| 144 | 145 | ||
| 146 | (define (plain-file-nar-sha256 string) | ||
| 147 | (sha256 (call-with-output-bytevector | ||
| 148 | (lambda (port) | ||
| 149 | (let ((bv (string->utf8 string))) | ||
| 150 | (call-with-input-bytevector | ||
| 151 | bv | ||
| 152 | (lambda (contents) | ||
| 153 | (write-file-tree #t port | ||
| 154 | #:file-type+size | ||
| 155 | (lambda (_) | ||
| 156 | (values 'regular | ||
| 157 | (bytevector-length | ||
| 158 | bv))) | ||
| 159 | #:file-port | ||
| 160 | (const contents))))))))) | ||
| 145 | 161 | ||
| 146 | (define %narinfo | 162 | (define %narinfo |
| 147 | ;; Skeleton of the narinfo used below. | 163 | ;; Skeleton of the narinfo used below. |
| @@ -150,7 +166,7 @@ version identifier.." | |||
| 150 | URL: example.nar | 166 | URL: example.nar |
| 151 | Compression: none | 167 | Compression: none |
| 152 | NarHash: sha256:" (bytevector->nix-base32-string | 168 | NarHash: sha256:" (bytevector->nix-base32-string |
| 153 | (sha256 (string->utf8 "Substitutable data."))) " | 169 | (plain-file-nar-sha256 "Substitutable data.")) " |
| 154 | NarSize: 42 | 170 | NarSize: 42 |
| 155 | References: bar baz | 171 | References: bar baz |
| 156 | Deriver: " (%store-prefix) "/foo.drv | 172 | Deriver: " (%store-prefix) "/foo.drv |
| @@ -819,7 +835,7 @@ Compression: lzip | |||
| 819 | URL: example.nar | 835 | URL: example.nar |
| 820 | Compression: none | 836 | Compression: none |
| 821 | NarHash: sha256:" (bytevector->nix-base32-string | 837 | NarHash: sha256:" (bytevector->nix-base32-string |
| 822 | (sha256 (string->utf8 "Substitutable data."))) " | 838 | (plain-file-nar-sha256 "Substitutable data.")) " |
| 823 | NarSize: 42 | 839 | NarSize: 42 |
| 824 | References: bar baz | 840 | References: bar baz |
| 825 | Deriver: " (%store-prefix) "/foo.drv | 841 | Deriver: " (%store-prefix) "/foo.drv |
