summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLudovic Courtès <ludo@gnu.org>2018-12-28 18:40:06 +0100
committerLudovic Courtès <ludo@gnu.org>2018-12-28 18:40:06 +0100
commit79b0f72a9ef21a66f3c3cd65b3609f238f9e5c23 (patch)
tree78f134c911155aa0890d39dd28712403fc7a5de9
parent5fdb66f17629c0f08b5976020f185f9285f59a18 (diff)
DRAFT substitute: Add IPFS support.wip-ipfs-substitutes
Missing: - documentation - command-line options - progress report when downloading over IPFS - fallback when we fail to fetch from IPFS * guix/scripts/substitute.scm (<narinfo>)[ipfs]: New field. (read-narinfo): Read "IPFS". (process-substitution/http): New procedure, with code formerly in 'process-substitution'. (process-substitution): Check for IPFS and call 'ipfs:restore-file-tree' when IPFS is true.
-rwxr-xr-xguix/scripts/substitute.scm106
1 files changed, 61 insertions, 45 deletions
diff --git a/guix/scripts/substitute.scm b/guix/scripts/substitute.scm
index 53b17772410..8be15e4f135 100755
--- a/guix/scripts/substitute.scm
+++ b/guix/scripts/substitute.scm
@@ -42,6 +42,7 @@
42 #:use-module (guix progress) 42 #:use-module (guix progress)
43 #:use-module ((guix build syscalls) 43 #:use-module ((guix build syscalls)
44 #:select (set-thread-name)) 44 #:select (set-thread-name))
45 #:use-module ((guix ipfs) #:prefix ipfs:)
45 #:use-module (ice-9 rdelim) 46 #:use-module (ice-9 rdelim)
46 #:use-module (ice-9 regex) 47 #:use-module (ice-9 regex)
47 #:use-module (ice-9 match) 48 #:use-module (ice-9 match)
@@ -281,7 +282,7 @@ failure, return #f and #f."
281 282
282(define-record-type <narinfo> 283(define-record-type <narinfo>
283 (%make-narinfo path uri uri-base compression file-hash file-size nar-hash nar-size 284 (%make-narinfo path uri uri-base compression file-hash file-size nar-hash nar-size
284 references deriver system signature contents) 285 references deriver system ipfs signature contents)
285 narinfo? 286 narinfo?
286 (path narinfo-path) 287 (path narinfo-path)
287 (uri narinfo-uri) 288 (uri narinfo-uri)
@@ -294,6 +295,7 @@ failure, return #f and #f."
294 (references narinfo-references) 295 (references narinfo-references)
295 (deriver narinfo-deriver) 296 (deriver narinfo-deriver)
296 (system narinfo-system) 297 (system narinfo-system)
298 (ipfs narinfo-ipfs)
297 (signature narinfo-signature) ; canonical sexp 299 (signature narinfo-signature) ; canonical sexp
298 ;; The original contents of a narinfo file. This field is needed because we 300 ;; The original contents of a narinfo file. This field is needed because we
299 ;; want to preserve the exact textual representation for verification purposes. 301 ;; want to preserve the exact textual representation for verification purposes.
@@ -335,7 +337,7 @@ s-expression: ~s~%")
335 "Return a narinfo constructor for narinfos originating from CACHE-URL. STR 337 "Return a narinfo constructor for narinfos originating from CACHE-URL. STR
336must contain the original contents of a narinfo file." 338must contain the original contents of a narinfo file."
337 (lambda (path url compression file-hash file-size nar-hash nar-size 339 (lambda (path url compression file-hash file-size nar-hash nar-size
338 references deriver system signature) 340 references deriver system ipfs signature)
339 "Return a new <narinfo> object." 341 "Return a new <narinfo> object."
340 (%make-narinfo path 342 (%make-narinfo path
341 ;; Handle the case where URL is a relative URL. 343 ;; Handle the case where URL is a relative URL.
@@ -352,6 +354,7 @@ must contain the original contents of a narinfo file."
352 ((or #f "") #f) 354 ((or #f "") #f)
353 (_ deriver)) 355 (_ deriver))
354 system 356 system
357 ipfs
355 (false-if-exception 358 (false-if-exception
356 (and=> signature narinfo-signature->canonical-sexp)) 359 (and=> signature narinfo-signature->canonical-sexp))
357 str))) 360 str)))
@@ -386,7 +389,7 @@ No authentication and authorization checks are performed here!"
386 (narinfo-maker str url) 389 (narinfo-maker str url)
387 '("StorePath" "URL" "Compression" 390 '("StorePath" "URL" "Compression"
388 "FileHash" "FileSize" "NarHash" "NarSize" 391 "FileHash" "FileSize" "NarHash" "NarSize"
389 "References" "Deriver" "System" 392 "References" "Deriver" "System" "IPFS"
390 "Signature")))) 393 "Signature"))))
391 394
392(define (narinfo-sha256 narinfo) 395(define (narinfo-sha256 narinfo)
@@ -947,13 +950,58 @@ authorized substitutes."
947 (wtf 950 (wtf
948 (error "unknown `--query' command" wtf)))) 951 (error "unknown `--query' command" wtf))))
949 952
953(define* (process-substitution/http narinfo destination uri
954 #:key print-build-trace?)
955 (unless print-build-trace?
956 (format (current-error-port)
957 (G_ "Downloading ~a...~%") (uri->string uri)))
958
959 (let*-values (((raw download-size)
960 ;; Note that Hydra currently generates Nars on the fly
961 ;; and doesn't specify a Content-Length, so
962 ;; DOWNLOAD-SIZE is #f in practice.
963 (fetch uri #:buffered? #f #:timeout? #f))
964 ((progress)
965 (let* ((comp (narinfo-compression narinfo))
966 (dl-size (or download-size
967 (and (equal? comp "none")
968 (narinfo-size narinfo))))
969 (reporter (if print-build-trace?
970 (progress-reporter/trace
971 destination
972 (uri->string uri) dl-size
973 (current-error-port))
974 (progress-reporter/file
975 (uri->string uri) dl-size
976 (current-error-port)
977 #:abbreviation nar-uri-abbreviation))))
978 (progress-report-port reporter raw)))
979 ((input pids)
980 ;; NOTE: This 'progress' port of current process will be
981 ;; closed here, while the child process doing the
982 ;; reporting will close it upon exit.
983 (decompressed-port (and=> (narinfo-compression narinfo)
984 string->symbol)
985 progress)))
986 ;; Unpack the Nar at INPUT into DESTINATION.
987 (restore-file input destination)
988 (close-port input)
989
990 ;; Wait for the reporter to finish.
991 (every (compose zero? cdr waitpid) pids)
992
993 ;; Skip a line after what 'progress-reporter/file' printed, and another
994 ;; one to visually separate substitutions.
995 (display "\n\n" (current-error-port))))
996
950(define* (process-substitution store-item destination 997(define* (process-substitution store-item destination
951 #:key cache-urls acl print-build-trace?) 998 #:key cache-urls acl print-build-trace?)
952 "Substitute STORE-ITEM (a store file name) from CACHE-URLS, and write it to 999 "Substitute STORE-ITEM (a store file name) from CACHE-URLS, and write it to
953DESTINATION as a nar file. Verify the substitute against ACL." 1000DESTINATION as a nar file. Verify the substitute against ACL."
954 (let* ((narinfo (lookup-narinfo cache-urls store-item 1001 (let* ((narinfo (lookup-narinfo cache-urls store-item
955 (cut valid-narinfo? <> acl))) 1002 (cut valid-narinfo? <> acl)))
956 (uri (and=> narinfo narinfo-uri))) 1003 (uri (and=> narinfo narinfo-uri))
1004 (ipfs (and=> narinfo narinfo-ipfs)))
957 (unless uri 1005 (unless uri
958 (leave (G_ "no valid substitute for '~a'~%") 1006 (leave (G_ "no valid substitute for '~a'~%")
959 store-item)) 1007 store-item))
@@ -961,47 +1009,15 @@ DESTINATION as a nar file. Verify the substitute against ACL."
961 ;; Tell the daemon what the expected hash of the Nar itself is. 1009 ;; Tell the daemon what the expected hash of the Nar itself is.
962 (format #t "~a~%" (narinfo-hash narinfo)) 1010 (format #t "~a~%" (narinfo-hash narinfo))
963 1011
964 (unless print-build-trace? 1012 (if ipfs
965 (format (current-error-port) 1013 (begin
966 (G_ "Downloading ~a...~%") (uri->string uri))) 1014 (unless print-build-trace?
967 1015 (format (current-error-port)
968 (let*-values (((raw download-size) 1016 (G_ "Downloading from IPFS ~s...~%") ipfs))
969 ;; Note that Hydra currently generates Nars on the fly 1017 (ipfs:restore-file-tree ipfs destination))
970 ;; and doesn't specify a Content-Length, so 1018 (process-substitution/http narinfo destination uri
971 ;; DOWNLOAD-SIZE is #f in practice. 1019 #:print-build-trace?
972 (fetch uri #:buffered? #f #:timeout? #f)) 1020 print-build-trace?))))
973 ((progress)
974 (let* ((comp (narinfo-compression narinfo))
975 (dl-size (or download-size
976 (and (equal? comp "none")
977 (narinfo-size narinfo))))
978 (reporter (if print-build-trace?
979 (progress-reporter/trace
980 destination
981 (uri->string uri) dl-size
982 (current-error-port))
983 (progress-reporter/file
984 (uri->string uri) dl-size
985 (current-error-port)
986 #:abbreviation nar-uri-abbreviation))))
987 (progress-report-port reporter raw)))
988 ((input pids)
989 ;; NOTE: This 'progress' port of current process will be
990 ;; closed here, while the child process doing the
991 ;; reporting will close it upon exit.
992 (decompressed-port (and=> (narinfo-compression narinfo)
993 string->symbol)
994 progress)))
995 ;; Unpack the Nar at INPUT into DESTINATION.
996 (restore-file input destination)
997 (close-port input)
998
999 ;; Wait for the reporter to finish.
1000 (every (compose zero? cdr waitpid) pids)
1001
1002 ;; Skip a line after what 'progress-reporter/file' printed, and another
1003 ;; one to visually separate substitutions.
1004 (display "\n\n" (current-error-port)))))
1005 1021
1006 1022
1007;;; 1023;;;