summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLudovic Courtès <ludo@gnu.org>2015-10-28 10:11:43 +0100
committerLudovic Courtès <ludo@gnu.org>2015-10-28 12:04:03 +0100
commit55b2fc18772a512a2227757423e55dc6c7523113 (patch)
treec7b6919e49385a60b470203196a7cb9cca8075e5
parenta89dde1ed89a53f33556ab12ec73bafe495a796c (diff)
substitute: Honor all the specified server URLs.
* guix/scripts/substitute.scm (lookup-narinfos/diverse): New procedure. (lookup-narinfo): Use it. (process-query): Change #:cache-url to #:cache-urls. [valid?]: Remove 'narinfo?' check, which is no longer necessary. Use 'lookup-narinfos/diverse' instead of 'lookup-narinfos'. (process-substitution): Change #:cache-url to #:cache-urls. (%cache-url): Rename to... (%cache-urls): ... this. Turn into a list. (guix-substitute): Remove 'getaddrinfo' test with early exit. Adjust calls to 'process-query' and 'process-substitution'. * tests/substitute.scm: Change '%cache-url' to '%cache-urls'.
-rwxr-xr-xguix/scripts/substitute.scm83
-rw-r--r--tests/substitute.scm4
2 files changed, 46 insertions, 41 deletions
diff --git a/guix/scripts/substitute.scm b/guix/scripts/substitute.scm
index 34fee5863f2..964df9422cf 100755
--- a/guix/scripts/substitute.scm
+++ b/guix/scripts/substitute.scm
@@ -72,6 +72,7 @@
72 assert-valid-narinfo 72 assert-valid-narinfo
73 73
74 lookup-narinfos 74 lookup-narinfos
75 lookup-narinfos/diverse
75 read-narinfo 76 read-narinfo
76 write-narinfo 77 write-narinfo
77 guix-substitute)) 78 guix-substitute))
@@ -610,11 +611,32 @@ information is available locally."
610 (let ((missing (fetch-narinfos cache missing))) 611 (let ((missing (fetch-narinfos cache missing)))
611 (append cached (or missing '())))))) 612 (append cached (or missing '()))))))
612 613
613(define (lookup-narinfo cache path) 614(define (lookup-narinfos/diverse caches paths)
614 "Return the narinfo for PATH in CACHE, or #f when no substitute for PATH was 615 "Look up narinfos for PATHS on all of CACHES, a list of URLS, in that order.
615found." 616That is, when a cache lacks a narinfo, look it up in the next cache, and so
616 (match (lookup-narinfos cache (list path)) 617on. Return a list of narinfos for PATHS or a subset thereof."
617 ((answer) answer))) 618 (let loop ((caches caches)
619 (paths paths)
620 (result '()))
621 (match paths
622 (() ;we're done
623 result)
624 (_
625 (match caches
626 ((cache rest ...)
627 (let* ((narinfos (lookup-narinfos cache paths))
628 (hits (map narinfo-path narinfos))
629 (missing (lset-difference string=? paths hits))) ;XXX: perf
630 (loop rest missing (append narinfos result))))
631 (() ;that's it
632 result))))))
633
634(define (lookup-narinfo caches path)
635 "Return the narinfo for PATH in CACHES, or #f when no substitute for PATH
636was found."
637 (match (lookup-narinfos/diverse caches (list path))
638 ((answer) answer)
639 (_ #f)))
618 640
619(define (remove-expired-cached-narinfos directory) 641(define (remove-expired-cached-narinfos directory)
620 "Remove expired narinfo entries from DIRECTORY. The sole purpose of this 642 "Remove expired narinfo entries from DIRECTORY. The sole purpose of this
@@ -756,34 +778,34 @@ expected by the daemon."
756 (or (narinfo-size narinfo) 0))) 778 (or (narinfo-size narinfo) 0)))
757 779
758(define* (process-query command 780(define* (process-query command
759 #:key cache-url acl) 781 #:key cache-urls acl)
760 "Reply to COMMAND, a query as written by the daemon to this process's 782 "Reply to COMMAND, a query as written by the daemon to this process's
761standard input. Use ACL as the access-control list against which to check 783standard input. Use ACL as the access-control list against which to check
762authorized substitutes." 784authorized substitutes."
763 (define (valid? obj) 785 (define (valid? obj)
764 (and (narinfo? obj) (valid-narinfo? obj acl))) 786 (valid-narinfo? obj acl))
765 787
766 (match (string-tokenize command) 788 (match (string-tokenize command)
767 (("have" paths ..1) 789 (("have" paths ..1)
768 ;; Return the subset of PATHS available in CACHE-URL. 790 ;; Return the subset of PATHS available in CACHE-URLS.
769 (let ((substitutable (lookup-narinfos cache-url paths))) 791 (let ((substitutable (lookup-narinfos/diverse cache-urls paths)))
770 (for-each (lambda (narinfo) 792 (for-each (lambda (narinfo)
771 (format #t "~a~%" (narinfo-path narinfo))) 793 (format #t "~a~%" (narinfo-path narinfo)))
772 (filter valid? substitutable)) 794 (filter valid? substitutable))
773 (newline))) 795 (newline)))
774 (("info" paths ..1) 796 (("info" paths ..1)
775 ;; Reply info about PATHS if it's in CACHE-URL. 797 ;; Reply info about PATHS if it's in CACHE-URLS.
776 (let ((substitutable (lookup-narinfos cache-url paths))) 798 (let ((substitutable (lookup-narinfos/diverse cache-urls paths)))
777 (for-each display-narinfo-data (filter valid? substitutable)) 799 (for-each display-narinfo-data (filter valid? substitutable))
778 (newline))) 800 (newline)))
779 (wtf 801 (wtf
780 (error "unknown `--query' command" wtf)))) 802 (error "unknown `--query' command" wtf))))
781 803
782(define* (process-substitution store-item destination 804(define* (process-substitution store-item destination
783 #:key cache-url acl) 805 #:key cache-urls acl)
784 "Substitute STORE-ITEM (a store file name) from CACHE-URL, and write it to 806 "Substitute STORE-ITEM (a store file name) from CACHE-URLS, and write it to
785DESTINATION as a nar file. Verify the substitute against ACL." 807DESTINATION as a nar file. Verify the substitute against ACL."
786 (let* ((narinfo (lookup-narinfo cache-url store-item)) 808 (let* ((narinfo (lookup-narinfo cache-urls store-item))
787 (uri (narinfo-uri narinfo))) 809 (uri (narinfo-uri narinfo)))
788 ;; Make sure it is signed and everything. 810 ;; Make sure it is signed and everything.
789 (assert-valid-narinfo narinfo acl) 811 (assert-valid-narinfo narinfo acl)
@@ -880,21 +902,16 @@ found."
880 b 902 b
881 first))) 903 first)))
882 904
883(define %cache-url 905(define %cache-urls
884 (match (and=> (or* (find-daemon-option "untrusted-substitute-urls") ;client 906 (match (and=> (or* (find-daemon-option "untrusted-substitute-urls") ;client
885 (find-daemon-option "substitute-urls")) ;admin 907 (find-daemon-option "substitute-urls")) ;admin
886 string-tokenize) 908 string-tokenize)
887 ((url) 909 ((urls ...)
888 url) 910 urls)
889 ((head tail ..1)
890 ;; Currently we don't handle multiple substitute URLs.
891 (warning (_ "these substitute URLs will not be used:~{ ~a~}~%")
892 tail)
893 head)
894 (#f 911 (#f
895 ;; This can only happen when this script is not invoked by the 912 ;; This can only happen when this script is not invoked by the
896 ;; daemon. 913 ;; daemon.
897 "http://hydra.gnu.org"))) 914 '("http://hydra.gnu.org"))))
898 915
899(define (guix-substitute . args) 916(define (guix-substitute . args)
900 "Implement the build daemon's substituter protocol." 917 "Implement the build daemon's substituter protocol."
@@ -905,20 +922,8 @@ found."
905 ;; Starting from commit 22144afa in Nix, we are allowed to bail out directly 922 ;; Starting from commit 22144afa in Nix, we are allowed to bail out directly
906 ;; when we know we cannot substitute, but we must emit a newline on stdout 923 ;; when we know we cannot substitute, but we must emit a newline on stdout
907 ;; when everything is alright. 924 ;; when everything is alright.
908 (let ((uri (string->uri %cache-url))) 925 (when (null? %cache-urls)
909 (case (uri-scheme uri) 926 (exit 0))
910 ((http)
911 ;; Exit gracefully if there's no network access.
912 (let ((host (uri-host uri)))
913 (catch 'getaddrinfo-error
914 (lambda ()
915 (getaddrinfo host))
916 (lambda (key error)
917 (warning (_ "failed to look up host '~a' (~a), \
918substituter disabled~%")
919 host (gai-strerror error))
920 (exit 0)))))
921 (else #t)))
922 927
923 ;; Say hello (see above.) 928 ;; Say hello (see above.)
924 (newline) 929 (newline)
@@ -933,13 +938,13 @@ substituter disabled~%")
933 (or (eof-object? command) 938 (or (eof-object? command)
934 (begin 939 (begin
935 (process-query command 940 (process-query command
936 #:cache-url %cache-url 941 #:cache-urls %cache-urls
937 #:acl acl) 942 #:acl acl)
938 (loop (read-line))))))) 943 (loop (read-line)))))))
939 (("--substitute" store-path destination) 944 (("--substitute" store-path destination)
940 ;; Download STORE-PATH and add store it as a Nar in file DESTINATION. 945 ;; Download STORE-PATH and add store it as a Nar in file DESTINATION.
941 (process-substitution store-path destination 946 (process-substitution store-path destination
942 #:cache-url %cache-url 947 #:cache-urls %cache-urls
943 #:acl (current-acl))) 948 #:acl (current-acl)))
944 (("--version") 949 (("--version")
945 (show-version-and-exit "guix substitute")) 950 (show-version-and-exit "guix substitute"))
diff --git a/tests/substitute.scm b/tests/substitute.scm
index 85698127fac..9d907e7abf0 100644
--- a/tests/substitute.scm
+++ b/tests/substitute.scm
@@ -167,8 +167,8 @@ a file for NARINFO."
167 (call-with-narinfo narinfo (lambda () body ...))) 167 (call-with-narinfo narinfo (lambda () body ...)))
168 168
169;; Transmit these options to 'guix substitute'. 169;; Transmit these options to 'guix substitute'.
170(set! (@@ (guix scripts substitute) %cache-url) 170(set! (@@ (guix scripts substitute) %cache-urls)
171 (getenv "GUIX_BINARY_SUBSTITUTE_URL")) 171 (list (getenv "GUIX_BINARY_SUBSTITUTE_URL")))
172 172
173(test-equal "query narinfo without signature" 173(test-equal "query narinfo without signature"
174 "" ; not substitutable 174 "" ; not substitutable