summaryrefslogtreecommitdiff
path: root/guix/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'guix/scripts')
-rw-r--r--guix/scripts/archive.scm2
-rw-r--r--guix/scripts/challenge.scm1
-rw-r--r--guix/scripts/discover.scm58
-rw-r--r--guix/scripts/offload.scm12
-rw-r--r--guix/scripts/pack.scm260
-rw-r--r--guix/scripts/publish.scm26
-rwxr-xr-xguix/scripts/substitute.scm70
-rw-r--r--guix/scripts/system.scm66
8 files changed, 261 insertions, 234 deletions
diff --git a/guix/scripts/archive.scm b/guix/scripts/archive.scm
index c04baf9784..1f73fff711 100644
--- a/guix/scripts/archive.scm
+++ b/guix/scripts/archive.scm
@@ -347,6 +347,8 @@ output port."
(match type
('directory
(format #t "D ~a~%" file))
+ ('directory-complete
+ #t)
('symlink
(format #t "S ~a -> ~a~%" file content))
((or 'regular 'executable)
diff --git a/guix/scripts/challenge.scm b/guix/scripts/challenge.scm
index 39bd2c1c0f..d0a456ac1d 100644
--- a/guix/scripts/challenge.scm
+++ b/guix/scripts/challenge.scm
@@ -210,6 +210,7 @@ taken since we do not import the archives."
(cons `(,file ,type ,(port-sha256* port size))
result))))
('directory result)
+ ('directory-complete result)
('symlink
(cons `(,file ,type ,contents) result))))
'()
diff --git a/guix/scripts/discover.scm b/guix/scripts/discover.scm
index 007db0d49d..6aade81ed1 100644
--- a/guix/scripts/discover.scm
+++ b/guix/scripts/discover.scm
@@ -21,6 +21,7 @@
#:use-module (guix config)
#:use-module (guix scripts)
#:use-module (guix ui)
+ #:use-module (guix utils)
#:use-module (guix build syscalls)
#:use-module (guix build utils)
#:use-module (guix scripts publish)
@@ -78,47 +79,27 @@ CACHE-DIRECTORY."
(define* (write-publish-file #:key (file (%publish-file)))
"Dump the content of %PUBLISH-SERVICES hash table into FILE. Use a write
lock on FILE to synchronize with any potential readers."
- (with-file-lock file
- (call-with-output-file file
- (lambda (port)
- (hash-for-each
- (lambda (name service)
- (format port "http://~a:~a~%"
- (avahi-service-address service)
- (avahi-service-port service)))
- %publish-services)))
- (chmod file #o644)))
-
-(define (call-with-read-file-lock file thunk)
- "Call THUNK with a read lock on FILE."
- (let ((port #f))
- (dynamic-wind
- (lambda ()
- (set! port
- (let ((port (open-file file "r0")))
- (fcntl-flock port 'read-lock)
- port)))
- thunk
- (lambda ()
- (when port
- (unlock-file port))))))
-
-(define-syntax-rule (with-read-file-lock file exp ...)
- "Wait to acquire a read lock on FILE and evaluate EXP in that context."
- (call-with-read-file-lock file (lambda () exp ...)))
+ (with-atomic-file-output file
+ (lambda (port)
+ (hash-for-each
+ (lambda (name service)
+ (format port "http://~a:~a~%"
+ (avahi-service-address service)
+ (avahi-service-port service)))
+ %publish-services)))
+ (chmod file #o644))
(define* (read-substitute-urls #:key (file (%publish-file)))
"Read substitute urls list from FILE and return it. Use a read lock on FILE
to synchronize with the writer."
(if (file-exists? file)
- (with-read-file-lock file
- (call-with-input-file file
- (lambda (port)
- (let loop ((url (read-line port))
- (urls '()))
- (if (eof-object? url)
- urls
- (loop (read-line port) (cons url urls)))))))
+ (call-with-input-file file
+ (lambda (port)
+ (let loop ((url (read-line port))
+ (urls '()))
+ (if (eof-object? url)
+ urls
+ (loop (read-line port) (cons url urls))))))
'()))
@@ -156,9 +137,6 @@ to synchronize with the writer."
(publish-file (publish-file cache)))
(parameterize ((%publish-file publish-file))
(mkdir-p (dirname publish-file))
+ (false-if-exception (delete-file publish-file))
(avahi-browse-service-thread service-proc
#:types %services)))))
-
-;;; Local Variables:
-;;; eval: (put 'with-read-file-lock 'scheme-indent-function 1)
-;;; End:
diff --git a/guix/scripts/offload.scm b/guix/scripts/offload.scm
index 6366556647..58ee53e85c 100644
--- a/guix/scripts/offload.scm
+++ b/guix/scripts/offload.scm
@@ -2,6 +2,7 @@
;;; Copyright © 2014, 2015, 2016, 2017, 2018, 2019, 2020 Ludovic Courtès <ludo@gnu.org>
;;; Copyright © 2017 Ricardo Wurmus <rekado@elephly.net>
;;; Copyright © 2020 Maxim Cournoyer <maxim.cournoyer@gmail.com>
+;;; Copyright © 2020 Julien Lepiller <julien@lepiller.eu>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -65,6 +66,7 @@
build-machine-overload-threshold
build-machine-systems
build-machine-features
+ build-machine-location
build-requirements
build-requirements?
@@ -112,11 +114,17 @@
(speed build-machine-speed ; inexact real
(default 1.0))
(features build-machine-features ; list of strings
- (default '())))
+ (default '()))
+ (location build-machine-location
+ (default (and=> (current-source-location)
+ source-properties->location))
+ (innate)))
;;; Deprecated.
(define (build-machine-system machine)
- (warning (G_ "The 'system' field is deprecated, \
+ (warning
+ (build-machine-location machine)
+ (G_ "The 'system' field is deprecated, \
please use 'systems' instead.~%"))
(%build-machine-system machine))
diff --git a/guix/scripts/pack.scm b/guix/scripts/pack.scm
index ba9a6dc1b2..8ecdcb823f 100644
--- a/guix/scripts/pack.scm
+++ b/guix/scripts/pack.scm
@@ -167,8 +167,6 @@ dependencies are registered."
(let ((items (append-map read-closure '#$labels)))
(with-database db-file db
(register-items db items
- #:deduplicate? #f
- #:reset-timestamps? #f
#:registration-time %epoch)))))))
(computed-file "store-database" build
@@ -204,12 +202,19 @@ added to the pack."
#+(file-append glibc-utf8-locales "/lib/locale"))
(setlocale LC_ALL "en_US.utf8"))))
+ (define (import-module? module)
+ ;; Since we don't use deduplication support in 'populate-store', don't
+ ;; import (guix store deduplication) and its dependencies, which includes
+ ;; Guile-Gcrypt. That way we can run tests with '--bootstrap'.
+ (and (not-config? module)
+ (not (equal? '(guix store deduplication) module))))
+
(define build
(with-imported-modules (source-module-closure
`((guix build utils)
(guix build union)
(gnu build install))
- #:select? not-config?)
+ #:select? import-module?)
#~(begin
(use-modules (guix build utils)
((guix build union) #:select (relative-file-name))
@@ -383,138 +388,139 @@ added to the pack."
`(("/bin" -> "bin") ,@symlinks)))
(define build
- (with-imported-modules (source-module-closure
- '((guix build utils)
- (guix build store-copy)
- (guix build union)
- (gnu build install))
- #:select? not-config?)
- #~(begin
- (use-modules (guix build utils)
- (guix build store-copy)
- ((guix build union) #:select (relative-file-name))
- (gnu build install)
- (srfi srfi-1)
- (srfi srfi-26)
- (ice-9 match))
+ (with-extensions (list guile-gcrypt)
+ (with-imported-modules (source-module-closure
+ '((guix build utils)
+ (guix build store-copy)
+ (guix build union)
+ (gnu build install))
+ #:select? not-config?)
+ #~(begin
+ (use-modules (guix build utils)
+ (guix build store-copy)
+ ((guix build union) #:select (relative-file-name))
+ (gnu build install)
+ (srfi srfi-1)
+ (srfi srfi-26)
+ (ice-9 match))
- (define database #+database)
- (define entry-point #$entry-point)
+ (define database #+database)
+ (define entry-point #$entry-point)
- (define (mksquashfs args)
- (apply invoke "mksquashfs"
- `(,@args
+ (define (mksquashfs args)
+ (apply invoke "mksquashfs"
+ `(,@args
- ;; Do not create a "recovery file" when appending to the
- ;; file system since it's useless in this case.
- "-no-recovery"
+ ;; Do not create a "recovery file" when appending to the
+ ;; file system since it's useless in this case.
+ "-no-recovery"
- ;; Do not attempt to store extended attributes.
- ;; See <https://bugs.gnu.org/40043>.
- "-no-xattrs"
+ ;; Do not attempt to store extended attributes.
+ ;; See <https://bugs.gnu.org/40043>.
+ "-no-xattrs"
- ;; Set file times and the file system creation time to
- ;; one second after the Epoch.
- "-all-time" "1" "-mkfs-time" "1"
+ ;; Set file times and the file system creation time to
+ ;; one second after the Epoch.
+ "-all-time" "1" "-mkfs-time" "1"
- ;; Reset all UIDs and GIDs.
- "-force-uid" "0" "-force-gid" "0")))
+ ;; Reset all UIDs and GIDs.
+ "-force-uid" "0" "-force-gid" "0")))
- (setenv "PATH" #+(file-append archiver "/bin"))
+ (setenv "PATH" #+(file-append archiver "/bin"))
- ;; We need an empty file in order to have a valid file argument when
- ;; we reparent the root file system. Read on for why that's
- ;; necessary.
- (with-output-to-file ".empty" (lambda () (display "")))
-
- ;; Create the squashfs image in several steps.
- ;; Add all store items. Unfortunately mksquashfs throws away all
- ;; ancestor directories and only keeps the basename. We fix this
- ;; in the following invocations of mksquashfs.
- (mksquashfs `(,@(map store-info-item
- (call-with-input-file "profile"
- read-reference-graph))
- #$environment
- ,#$output
-
- ;; Do not perform duplicate checking because we
- ;; don't have any dupes.
- "-no-duplicates"
- "-comp"
- ,#+(compressor-name compressor)))
-
- ;; Here we reparent the store items. For each sub-directory of
- ;; the store prefix we need one invocation of "mksquashfs".
- (for-each (lambda (dir)
- (mksquashfs `(".empty"
- ,#$output
- "-root-becomes" ,dir)))
- (reverse (string-tokenize (%store-directory)
- (char-set-complement (char-set #\/)))))
-
- ;; Add symlinks and mount points.
- (mksquashfs
- `(".empty"
- ,#$output
- ;; Create SYMLINKS via pseudo file definitions.
- ,@(append-map
- (match-lambda
- ((source '-> target)
- ;; Create relative symlinks to work around a bug in
- ;; Singularity 2.x:
- ;; https://bugs.gnu.org/34913
- ;; https://github.com/sylabs/singularity/issues/1487
- (let ((target (string-append #$profile "/" target)))
- (list "-p"
- (string-join
- ;; name s mode uid gid symlink
- (list source
- "s" "777" "0" "0"
- (relative-file-name (dirname source)
- target)))))))
- '#$symlinks*)
-
- "-p" "/.singularity.d d 555 0 0"
-
- ;; Create the environment file.
- "-p" "/.singularity.d/env d 555 0 0"
- "-p" ,(string-append
- "/.singularity.d/env/90-environment.sh s 777 0 0 "
- (relative-file-name "/.singularity.d/env"
- #$environment))
-
- ;; Create /.singularity.d/actions, and optionally the 'run'
- ;; script, used by 'singularity run'.
- "-p" "/.singularity.d/actions d 555 0 0"
-
- ,@(if entry-point
- `(;; This one if for Singularity 2.x.
- "-p"
- ,(string-append
- "/.singularity.d/actions/run s 777 0 0 "
- (relative-file-name "/.singularity.d/actions"
- (string-append #$profile "/"
- entry-point)))
-
- ;; This one is for Singularity 3.x.
- "-p"
- ,(string-append
- "/.singularity.d/runscript s 777 0 0 "
- (relative-file-name "/.singularity.d"
- (string-append #$profile "/"
- entry-point))))
- '())
-
- ;; Create empty mount points.
- "-p" "/proc d 555 0 0"
- "-p" "/sys d 555 0 0"
- "-p" "/dev d 555 0 0"
- "-p" "/home d 555 0 0"))
-
- (when database
- ;; Initialize /var/guix.
- (install-database-and-gc-roots "var-etc" database #$profile)
- (mksquashfs `("var-etc" ,#$output))))))
+ ;; We need an empty file in order to have a valid file argument when
+ ;; we reparent the root file system. Read on for why that's
+ ;; necessary.
+ (with-output-to-file ".empty" (lambda () (display "")))
+
+ ;; Create the squashfs image in several steps.
+ ;; Add all store items. Unfortunately mksquashfs throws away all
+ ;; ancestor directories and only keeps the basename. We fix this
+ ;; in the following invocations of mksquashfs.
+ (mksquashfs `(,@(map store-info-item
+ (call-with-input-file "profile"
+ read-reference-graph))
+ #$environment
+ ,#$output
+
+ ;; Do not perform duplicate checking because we
+ ;; don't have any dupes.
+ "-no-duplicates"
+ "-comp"
+ ,#+(compressor-name compressor)))
+
+ ;; Here we reparent the store items. For each sub-directory of
+ ;; the store prefix we need one invocation of "mksquashfs".
+ (for-each (lambda (dir)
+ (mksquashfs `(".empty"
+ ,#$output
+ "-root-becomes" ,dir)))
+ (reverse (string-tokenize (%store-directory)
+ (char-set-complement (char-set #\/)))))
+
+ ;; Add symlinks and mount points.
+ (mksquashfs
+ `(".empty"
+ ,#$output
+ ;; Create SYMLINKS via pseudo file definitions.
+ ,@(append-map
+ (match-lambda
+ ((source '-> target)
+ ;; Create relative symlinks to work around a bug in
+ ;; Singularity 2.x:
+ ;; https://bugs.gnu.org/34913
+ ;; https://github.com/sylabs/singularity/issues/1487
+ (let ((target (string-append #$profile "/" target)))
+ (list "-p"
+ (string-join
+ ;; name s mode uid gid symlink
+ (list source
+ "s" "777" "0" "0"
+ (relative-file-name (dirname source)
+ target)))))))
+ '#$symlinks*)
+
+ "-p" "/.singularity.d d 555 0 0"
+
+ ;; Create the environment file.
+ "-p" "/.singularity.d/env d 555 0 0"
+ "-p" ,(string-append
+ "/.singularity.d/env/90-environment.sh s 777 0 0 "
+ (relative-file-name "/.singularity.d/env"
+ #$environment))
+
+ ;; Create /.singularity.d/actions, and optionally the 'run'
+ ;; script, used by 'singularity run'.
+ "-p" "/.singularity.d/actions d 555 0 0"
+
+ ,@(if entry-point
+ `( ;; This one if for Singularity 2.x.
+ "-p"
+ ,(string-append
+ "/.singularity.d/actions/run s 777 0 0 "
+ (relative-file-name "/.singularity.d/actions"
+ (string-append #$profile "/"
+ entry-point)))
+
+ ;; This one is for Singularity 3.x.
+ "-p"
+ ,(string-append
+ "/.singularity.d/runscript s 777 0 0 "
+ (relative-file-name "/.singularity.d"
+ (string-append #$profile "/"
+ entry-point))))
+ '())
+
+ ;; Create empty mount points.
+ "-p" "/proc d 555 0 0"
+ "-p" "/sys d 555 0 0"
+ "-p" "/dev d 555 0 0"
+ "-p" "/home d 555 0 0"))
+
+ (when database
+ ;; Initialize /var/guix.
+ (install-database-and-gc-roots "var-etc" database #$profile)
+ (mksquashfs `("var-etc" ,#$output)))))))
(gexp->derivation (string-append name
(compressor-extension compressor)
diff --git a/guix/scripts/publish.scm b/guix/scripts/publish.scm
index c31cef3181..5a865c838d 100644
--- a/guix/scripts/publish.scm
+++ b/guix/scripts/publish.scm
@@ -824,32 +824,6 @@ example: \"/foo/bar\" yields '(\"foo\" \"bar\")."
(define %http-write
(@@ (web server http) http-write))
-(match (list (major-version) (minor-version) (micro-version))
- (("2" "2" "5") ;Guile 2.2.5
- (let ()
- (define %read-line (@ (ice-9 rdelim) %read-line))
- (define bad-header (@@ (web http) bad-header))
-
- ;; XXX: Work around <https://bugs.gnu.org/36350> by reverting to the
- ;; definition of 'read-header-line' as found in 2.2.4 and earlier.
- (define (read-header-line port)
- "Read an HTTP header line and return it without its final CRLF or LF.
-Raise a 'bad-header' exception if the line does not end in CRLF or LF,
-or if EOF is reached."
- (match (%read-line port)
- (((? string? line) . #\newline)
- ;; '%read-line' does not consider #\return a delimiter; so if it's
- ;; there, remove it. We are more tolerant than the RFC in that we
- ;; tolerate LF-only endings.
- (if (string-suffix? "\r" line)
- (string-drop-right line 1)
- line))
- ((line . _) ;EOF or missing delimiter
- (bad-header 'read-header-line line))))
-
- (set! (@@ (web http) read-header-line) read-header-line)))
- (_ #t))
-
(define (strip-headers response)
"Return RESPONSE's headers minus 'Content-Length' and our internal headers."
(fold alist-delete
diff --git a/guix/scripts/substitute.scm b/guix/scripts/substitute.scm
index 25075eedff..38702d0c4b 100755
--- a/guix/scripts/substitute.scm
+++ b/guix/scripts/substitute.scm
@@ -26,7 +26,10 @@
#:use-module (guix combinators)
#:use-module (guix config)
#:use-module (guix records)
- #:use-module ((guix serialization) #:select (restore-file))
+ #:use-module (guix diagnostics)
+ #:use-module (guix i18n)
+ #:use-module ((guix serialization) #:select (restore-file dump-file))
+ #:autoload (guix store deduplication) (dump-file/deduplicate)
#:autoload (guix scripts discover) (read-substitute-urls)
#:use-module (gcrypt hash)
#:use-module (guix base32)
@@ -256,6 +259,18 @@ connection (typically PORT) is kept open once data has been fetched from URI."
;; for more information.
(contents narinfo-contents))
+(define (narinfo-hash-algorithm+value narinfo)
+ "Return two values: the hash algorithm used by NARINFO and its value as a
+bytevector."
+ (match (string-tokenize (narinfo-hash narinfo)
+ (char-set-complement (char-set #\:)))
+ ((algorithm base32)
+ (values (lookup-hash-algorithm (string->symbol algorithm))
+ (nix-base32-string->bytevector base32)))
+ (_
+ (raise (formatted-message
+ (G_ "invalid narinfo hash: ~s") (narinfo-hash narinfo))))))
+
(define (narinfo-hash->sha256 hash)
"If the string HASH denotes a sha256 hash, return it as a bytevector.
Otherwise return #f."
@@ -1031,22 +1046,33 @@ one. Return #f if URI's scheme is 'file' or #f."
(call-with-cached-connection uri (lambda (port) exp ...)))
(define* (process-substitution store-item destination
- #:key cache-urls acl print-build-trace?)
+ #:key cache-urls acl
+ deduplicate? print-build-trace?)
"Substitute STORE-ITEM (a store file name) from CACHE-URLS, and write it to
-DESTINATION as a nar file. Verify the substitute against ACL."
+DESTINATION as a nar file. Verify the substitute against ACL, and verify its
+hash against what appears in the narinfo. When DEDUPLICATE? is true, and if
+DESTINATION is in the store, deduplicate its files. Print a status line on
+the current output port."
(define narinfo
(lookup-narinfo cache-urls store-item
(cut valid-narinfo? <> acl)))
+ (define destination-in-store?
+ (string-prefix? (string-append (%store-prefix) "/")
+ destination))
+
+ (define (dump-file/deduplicate* . args)
+ ;; Make sure deduplication looks at the right store (necessary in test
+ ;; environments).
+ (apply dump-file/deduplicate
+ (append args (list #:store (%store-prefix)))))
+
(unless narinfo
(leave (G_ "no valid substitute for '~a'~%")
store-item))
(let-values (((uri compression file-size)
(narinfo-best-uri narinfo)))
- ;; Tell the daemon what the expected hash of the Nar itself is.
- (format #t "~a~%" (narinfo-hash narinfo))
-
(unless print-build-trace?
(format (current-error-port)
(G_ "Downloading ~a...~%") (uri->string uri)))
@@ -1079,9 +1105,20 @@ DESTINATION as a nar file. Verify the substitute against ACL."
;; closed here, while the child process doing the
;; reporting will close it upon exit.
(decompressed-port (string->symbol compression)
- progress)))
+ progress))
+
+ ;; Compute the actual nar hash as we read it.
+ ((algorithm expected)
+ (narinfo-hash-algorithm+value narinfo))
+ ((hashed get-hash)
+ (open-hash-input-port algorithm input)))
;; Unpack the Nar at INPUT into DESTINATION.
- (restore-file input destination)
+ (restore-file hashed destination
+ #:dump-file (if (and destination-in-store?
+ deduplicate?)
+ dump-file/deduplicate*
+ dump-file))
+ (close-port hashed)
(close-port input)
;; Wait for the reporter to finish.
@@ -1091,8 +1128,17 @@ DESTINATION as a nar file. Verify the substitute against ACL."
;; one to visually separate substitutions.
(display "\n\n" (current-error-port))
- ;; Tell the daemon that we're done.
- (display "success\n" (current-output-port)))))
+ ;; Check whether we got the data announced in NARINFO.
+ (let ((actual (get-hash)))
+ (if (bytevector=? actual expected)
+ ;; Tell the daemon that we're done.
+ (format (current-output-port) "success ~a ~a~%"
+ (narinfo-hash narinfo) (narinfo-size narinfo))
+ ;; The actual data has a different hash than that in NARINFO.
+ (format (current-output-port) "hash-mismatch ~a ~a ~a~%"
+ (hash-algorithm-name algorithm)
+ (bytevector->nix-base32-string expected)
+ (bytevector->nix-base32-string actual)))))))
;;;
@@ -1219,6 +1265,9 @@ default value."
((= string->number number) (> number 0))
(_ #f)))
+ (define deduplicate?
+ (find-daemon-option "deduplicate"))
+
;; The daemon's agent code opens file descriptor 4 for us and this is where
;; stderr should go.
(parameterize ((current-error-port (if (%error-to-file-descriptor-4?)
@@ -1278,6 +1327,7 @@ default value."
(process-substitution store-path destination
#:cache-urls (substitute-urls)
#:acl (current-acl)
+ #:deduplicate? deduplicate?
#:print-build-trace?
print-build-trace?)
(loop))))))
diff --git a/guix/scripts/system.scm b/guix/scripts/system.scm
index db80e0be8f..0dcf2b3afe 100644
--- a/guix/scripts/system.scm
+++ b/guix/scripts/system.scm
@@ -29,7 +29,10 @@
#:use-module (guix ui)
#:use-module ((guix status) #:select (with-status-verbosity))
#:use-module (guix store)
- #:autoload (guix store database) (register-path)
+ #:autoload (guix base16) (bytevector->base16-string)
+ #:autoload (guix store database)
+ (sqlite-register store-database-file call-with-database)
+ #:autoload (guix build store-copy) (copy-store-item)
#:use-module (guix describe)
#:use-module (guix grafts)
#:use-module (guix gexp)
@@ -129,12 +132,11 @@ BODY..., and restore them."
(store-lift topologically-sorted))
-(define* (copy-item item references target
+(define* (copy-item item info target db
#:key (log-port (current-error-port)))
- "Copy ITEM to the store under root directory TARGET and register it with
-REFERENCES as its set of references."
- (let ((dest (string-append target item))
- (state (string-append target "/var/guix")))
+ "Copy ITEM to the store under root directory TARGET and populate DB with the
+given INFO, a <path-info> record."
+ (let ((dest (string-append target item)))
(format log-port "copying '~a'...~%" item)
;; Remove DEST if it exists to make sure that (1) we do not fail badly
@@ -147,44 +149,48 @@ REFERENCES as its set of references."
#:directories? #t))
(delete-file-recursively dest))
- (copy-recursively item dest
- #:log (%make-void-port "w"))
+ (copy-store-item item target
+ #:deduplicate? #t)
- ;; Register ITEM; as a side-effect, it resets timestamps, etc.
- ;; Explicitly use "TARGET/var/guix" as the state directory, to avoid
- ;; reproducing the user's current settings; see
- ;; <http://bugs.gnu.org/18049>.
- (unless (register-path item
- #:prefix target
- #:state-directory state
- #:references references)
- (leave (G_ "failed to register '~a' under '~a'~%")
- item target))))
+ (sqlite-register db
+ #:path item
+ #:references (path-info-references info)
+ #:deriver (path-info-deriver info)
+ #:hash (string-append
+ "sha256:"
+ (bytevector->base16-string (path-info-hash info)))
+ #:nar-size (path-info-nar-size info))))
(define* (copy-closure item target
#:key (log-port (current-error-port)))
"Copy ITEM and all its dependencies to the store under root directory
TARGET, and register them."
(mlet* %store-monad ((to-copy (topologically-sorted* (list item)))
- (refs (mapm %store-monad references* to-copy))
- (info (mapm %store-monad query-path-info*
- (delete-duplicates
- (append to-copy (concatenate refs)))))
+ (info (mapm %store-monad query-path-info* to-copy))
(size -> (reduce + 0 (map path-info-nar-size info))))
(define progress-bar
(progress-reporter/bar (length to-copy)
(format #f (G_ "copying to '~a'...")
target)))
+ (define state
+ (string-append target "/var/guix"))
+
(check-available-space size target)
- (call-with-progress-reporter progress-bar
- (lambda (report)
- (let ((void (%make-void-port "w")))
- (for-each (lambda (item refs)
- (copy-item item refs target #:log-port void)
- (report))
- to-copy refs))))
+ ;; Explicitly use "TARGET/var/guix" as the state directory to avoid
+ ;; reproducing the user's current settings; see
+ ;; <http://bugs.gnu.org/18049>.
+ (call-with-database (store-database-file #:prefix target
+ #:state-directory state)
+ (lambda (db)
+ (call-with-progress-reporter progress-bar
+ (lambda (report)
+ (let ((void (%make-void-port "w")))
+ (for-each (lambda (item info)
+ (copy-item item info target db #:log-port void)
+ (report))
+ to-copy info))))))
(return *unspecified*)))
@@ -385,6 +391,7 @@ STORE is an open connection to the store."
(params (first (profile-boot-parameters %system-profile
(list number))))
(locale (boot-parameters-locale params))
+ (store-crypto-devices (boot-parameters-store-crypto-devices params))
(store-directory-prefix
(boot-parameters-store-directory-prefix params))
(old-generations
@@ -400,6 +407,7 @@ STORE is an open connection to the store."
((bootloader-configuration-file-generator bootloader)
bootloader-config entries
#:locale locale
+ #:store-crypto-devices store-crypto-devices
#:store-directory-prefix store-directory-prefix
#:old-entries old-entries)))
(drvs -> (list bootcfg)))