diff options
| -rwxr-xr-x | guix/scripts/substitute.scm | 31 | ||||
| -rw-r--r-- | guix/serialization.scm | 8 | ||||
| -rw-r--r-- | nix/libstore/build.cc | 13 |
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 |
| 1050 | DESTINATION as a nar file. Verify the substitute against ACL, and verify its | 1052 | DESTINATION as a nar file. Verify the substitute against ACL, and verify its |
| 1051 | hash against what appears in the narinfo. Print a status line on the current | 1053 | hash against what appears in the narinfo. When DEDUPLICATE? is true, and if |
| 1052 | output port." | 1054 | DESTINATION is in the store, deduplicate its files. Print a status line on |
| 1055 | the 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 | |||
| 464 | This 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; |
