summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xguix/scripts/substitute.scm31
-rw-r--r--guix/serialization.scm8
-rw-r--r--nix/libstore/build.cc13
3 files changed, 40 insertions, 12 deletions
diff --git a/guix/scripts/substitute.scm b/guix/scripts/substitute.scm
index 17d0002b9f9..38702d0c4b0 100755
--- a/guix/scripts/substitute.scm
+++ b/guix/scripts/substitute.scm
@@ -28,7 +28,8 @@
28 #:use-module (guix records) 28 #:use-module (guix records)
29 #:use-module (guix diagnostics) 29 #:use-module (guix diagnostics)
30 #:use-module (guix i18n) 30 #:use-module (guix i18n)
31 #:use-module ((guix serialization) #:select (restore-file)) 31 #:use-module ((guix serialization) #:select (restore-file dump-file))
32 #:autoload (guix store deduplication) (dump-file/deduplicate)
32 #:autoload (guix scripts discover) (read-substitute-urls) 33 #:autoload (guix scripts discover) (read-substitute-urls)
33 #:use-module (gcrypt hash) 34 #:use-module (gcrypt hash)
34 #:use-module (guix base32) 35 #:use-module (guix base32)
@@ -1045,15 +1046,27 @@ one. Return #f if URI's scheme is 'file' or #f."
1045 (call-with-cached-connection uri (lambda (port) exp ...))) 1046 (call-with-cached-connection uri (lambda (port) exp ...)))
1046 1047
1047(define* (process-substitution store-item destination 1048(define* (process-substitution store-item destination
1048 #:key cache-urls acl print-build-trace?) 1049 #:key cache-urls acl
1050 deduplicate? print-build-trace?)
1049 "Substitute STORE-ITEM (a store file name) from CACHE-URLS, and write it to 1051 "Substitute STORE-ITEM (a store file name) from CACHE-URLS, and write it to
1050DESTINATION as a nar file. Verify the substitute against ACL, and verify its 1052DESTINATION as a nar file. Verify the substitute against ACL, and verify its
1051hash against what appears in the narinfo. Print a status line on the current 1053hash against what appears in the narinfo. When DEDUPLICATE? is true, and if
1052output port." 1054DESTINATION is in the store, deduplicate its files. Print a status line on
1055the current output port."
1053 (define narinfo 1056 (define narinfo
1054 (lookup-narinfo cache-urls store-item 1057 (lookup-narinfo cache-urls store-item
1055 (cut valid-narinfo? <> acl))) 1058 (cut valid-narinfo? <> acl)))
1056 1059
1060 (define destination-in-store?
1061 (string-prefix? (string-append (%store-prefix) "/")
1062 destination))
1063
1064 (define (dump-file/deduplicate* . args)
1065 ;; Make sure deduplication looks at the right store (necessary in test
1066 ;; environments).
1067 (apply dump-file/deduplicate
1068 (append args (list #:store (%store-prefix)))))
1069
1057 (unless narinfo 1070 (unless narinfo
1058 (leave (G_ "no valid substitute for '~a'~%") 1071 (leave (G_ "no valid substitute for '~a'~%")
1059 store-item)) 1072 store-item))
@@ -1100,7 +1113,11 @@ output port."
1100 ((hashed get-hash) 1113 ((hashed get-hash)
1101 (open-hash-input-port algorithm input))) 1114 (open-hash-input-port algorithm input)))
1102 ;; Unpack the Nar at INPUT into DESTINATION. 1115 ;; Unpack the Nar at INPUT into DESTINATION.
1103 (restore-file hashed destination) 1116 (restore-file hashed destination
1117 #:dump-file (if (and destination-in-store?
1118 deduplicate?)
1119 dump-file/deduplicate*
1120 dump-file))
1104 (close-port hashed) 1121 (close-port hashed)
1105 (close-port input) 1122 (close-port input)
1106 1123
@@ -1248,6 +1265,9 @@ default value."
1248 ((= string->number number) (> number 0)) 1265 ((= string->number number) (> number 0))
1249 (_ #f))) 1266 (_ #f)))
1250 1267
1268 (define deduplicate?
1269 (find-daemon-option "deduplicate"))
1270
1251 ;; The daemon's agent code opens file descriptor 4 for us and this is where 1271 ;; The daemon's agent code opens file descriptor 4 for us and this is where
1252 ;; stderr should go. 1272 ;; stderr should go.
1253 (parameterize ((current-error-port (if (%error-to-file-descriptor-4?) 1273 (parameterize ((current-error-port (if (%error-to-file-descriptor-4?)
@@ -1307,6 +1327,7 @@ default value."
1307 (process-substitution store-path destination 1327 (process-substitution store-path destination
1308 #:cache-urls (substitute-urls) 1328 #:cache-urls (substitute-urls)
1309 #:acl (current-acl) 1329 #:acl (current-acl)
1330 #:deduplicate? deduplicate?
1310 #:print-build-trace? 1331 #:print-build-trace?
1311 print-build-trace?) 1332 print-build-trace?)
1312 (loop)))))) 1333 (loop))))))
diff --git a/guix/serialization.scm b/guix/serialization.scm
index 9e2dce8bb0e..59cd93fb189 100644
--- a/guix/serialization.scm
+++ b/guix/serialization.scm
@@ -51,7 +51,8 @@
51 write-file 51 write-file
52 write-file-tree 52 write-file-tree
53 fold-archive 53 fold-archive
54 restore-file)) 54 restore-file
55 dump-file))
55 56
56;;; Comment: 57;;; Comment:
57;;; 58;;;
@@ -458,7 +459,10 @@ depends on TYPE."
458 (&nar-read-error (port port) (file file) (token x))))))))) 459 (&nar-read-error (port port) (file file) (token x)))))))))
459 460
460(define (dump-file file input size type) 461(define (dump-file file input size type)
461 "Dump SIZE bytes from INPUT to FILE." 462 "Dump SIZE bytes from INPUT to FILE.
463
464This procedure is suitable for use as the #:dump-file argument to
465'restore-file'."
462 (call-with-output-file file 466 (call-with-output-file file
463 (lambda (output) 467 (lambda (output)
464 (dump input output size)))) 468 (dump input output size))))
diff --git a/nix/libstore/build.cc b/nix/libstore/build.cc
index ea809c6971c..20d83fea4a8 100644
--- a/nix/libstore/build.cc
+++ b/nix/libstore/build.cc
@@ -2984,7 +2984,12 @@ void SubstitutionGoal::tryToRun()
2984 2984
2985 if (!worker.substituter) { 2985 if (!worker.substituter) {
2986 const Strings args = { "substitute", "--substitute" }; 2986 const Strings args = { "substitute", "--substitute" };
2987 const std::map<string, string> env = { { "_NIX_OPTIONS", settings.pack() } }; 2987 const std::map<string, string> env = {
2988 { "_NIX_OPTIONS",
2989 settings.pack() + "deduplicate="
2990 + (settings.autoOptimiseStore ? "yes" : "no")
2991 }
2992 };
2988 worker.substituter = std::make_shared<Agent>(settings.guixProgram, args, env); 2993 worker.substituter = std::make_shared<Agent>(settings.guixProgram, args, env);
2989 } 2994 }
2990 2995
@@ -3085,10 +3090,8 @@ void SubstitutionGoal::finished()
3085 3090
3086 if (repair) replaceValidPath(storePath, destPath); 3091 if (repair) replaceValidPath(storePath, destPath);
3087 3092
3088 /* Note: 'guix substitute' takes care of resetting timestamps and 3093 /* Note: 'guix substitute' takes care of resetting timestamps and of
3089 permissions on 'destPath', so no need to do it here. */ 3094 deduplicating 'destPath', so no need to do it here. */
3090
3091 worker.store.optimisePath(storePath); // FIXME: combine with hashPath()
3092 3095
3093 ValidPathInfo info2; 3096 ValidPathInfo info2;
3094 info2.path = storePath; 3097 info2.path = storePath;