summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLudovic Courtès <ludo@gnu.org>2014-01-06 22:25:29 +0100
committerLudovic Courtès <ludo@gnu.org>2014-01-06 22:25:29 +0100
commit87236aed77bd57ecd143d84acf864fb112842118 (patch)
tree77ebed23b8267ab621a69051ba60e58dfe715689
parentb84612605204d604da84b30e56966994cc03d0a3 (diff)
archive: Add '--missing'.
* guix/scripts/archive.scm (show-help, %options): Add '--missing'. (guix-archive)[lines]: New procedure. Use it to honor '--missing'. * tests/guix-archive.sh: Add tests. * doc/guix.texi (Invoking guix archive): Document '--missing'.
-rw-r--r--doc/guix.texi11
-rw-r--r--guix/scripts/archive.scm21
-rw-r--r--tests/guix-archive.sh20
3 files changed, 51 insertions, 1 deletions
diff --git a/doc/guix.texi b/doc/guix.texi
index d5884008f4c..93d1c2be3b6 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -938,6 +938,12 @@ package to a machine connected over SSH, one would run:
938guix archive --export emacs | ssh the-machine guix archive --import 938guix archive --export emacs | ssh the-machine guix archive --import
939@end example 939@end example
940 940
941@noindent
942However, note that, in this example, all of @code{emacs} and its
943dependencies are transferred, regardless of what is already available in
944the target machine's store. The @code{--missing} option can help figure
945out which items are missing from the target's store.
946
941Archives are stored in the ``Nix archive'' or ``Nar'' format, which is 947Archives are stored in the ``Nix archive'' or ``Nar'' format, which is
942comparable in spirit to `tar'. When exporting, the daemon digitally 948comparable in spirit to `tar'. When exporting, the daemon digitally
943signs the contents of the archive, and that digital signature is 949signs the contents of the archive, and that digital signature is
@@ -959,6 +965,11 @@ therein into the store. Abort if the archive has an invalid digital
959signature, or if it is signed by a public key not among the authorized 965signature, or if it is signed by a public key not among the authorized
960keys (see @code{--authorize} below.) 966keys (see @code{--authorize} below.)
961 967
968@item --missing
969Read a list of store file names from the standard input, one per line,
970and write on the standard output the subset of these files missing from
971the store.
972
962@item --generate-key[=@var{parameters}] 973@item --generate-key[=@var{parameters}]
963@cindex signing, archives 974@cindex signing, archives
964Generate a new key pair for the daemons. This is a prerequisite before 975Generate a new key pair for the daemons. This is a prerequisite before
diff --git a/guix/scripts/archive.scm b/guix/scripts/archive.scm
index 3b778d81513..32690c6b459 100644
--- a/guix/scripts/archive.scm
+++ b/guix/scripts/archive.scm
@@ -27,6 +27,8 @@
27 #:use-module (guix pki) 27 #:use-module (guix pki)
28 #:use-module (guix pk-crypto) 28 #:use-module (guix pk-crypto)
29 #:use-module (ice-9 match) 29 #:use-module (ice-9 match)
30 #:use-module (ice-9 format)
31 #:use-module (ice-9 rdelim)
30 #:use-module (srfi srfi-1) 32 #:use-module (srfi srfi-1)
31 #:use-module (srfi srfi-11) 33 #:use-module (srfi srfi-11)
32 #:use-module (srfi srfi-26) 34 #:use-module (srfi srfi-26)
@@ -55,6 +57,8 @@ Export/import one or more packages from/to the store.\n"))
55 --export export the specified files/packages to stdout")) 57 --export export the specified files/packages to stdout"))
56 (display (_ " 58 (display (_ "
57 --import import from the archive passed on stdin")) 59 --import import from the archive passed on stdin"))
60 (display (_ "
61 --missing print the files from stdin that are missing"))
58 (newline) 62 (newline)
59 (display (_ " 63 (display (_ "
60 --generate-key[=PARAMETERS] 64 --generate-key[=PARAMETERS]
@@ -102,6 +106,9 @@ Export/import one or more packages from/to the store.\n"))
102 (option '("import") #f #f 106 (option '("import") #f #f
103 (lambda (opt name arg result) 107 (lambda (opt name arg result)
104 (alist-cons 'import #t result))) 108 (alist-cons 'import #t result)))
109 (option '("missing") #f #f
110 (lambda (opt name arg result)
111 (alist-cons 'missing #t result)))
105 (option '("generate-key") #f #t 112 (option '("generate-key") #f #t
106 (lambda (opt name arg result) 113 (lambda (opt name arg result)
107 (catch 'gcry-error 114 (catch 'gcry-error
@@ -294,6 +301,15 @@ the input port."
294 (alist-cons 'argument arg result)) 301 (alist-cons 'argument arg result))
295 %default-options)) 302 %default-options))
296 303
304 (define (lines port)
305 ;; Return lines read from PORT.
306 (let loop ((line (read-line port))
307 (result '()))
308 (if (eof-object? line)
309 (reverse result)
310 (loop (read-line port)
311 (cons line result)))))
312
297 (with-error-handling 313 (with-error-handling
298 ;; Ask for absolute file names so that .drv file names passed from the 314 ;; Ask for absolute file names so that .drv file names passed from the
299 ;; user to 'read-derivation' are absolute when it returns. 315 ;; user to 'read-derivation' are absolute when it returns.
@@ -310,6 +326,11 @@ the input port."
310 (export-from-store store opts)) 326 (export-from-store store opts))
311 ((assoc-ref opts 'import) 327 ((assoc-ref opts 'import)
312 (import-paths store (current-input-port))) 328 (import-paths store (current-input-port)))
329 ((assoc-ref opts 'missing)
330 (let* ((files (lines (current-input-port)))
331 (missing (remove (cut valid-path? store <>)
332 files)))
333 (format #t "~{~a~%~}" missing)))
313 (else 334 (else
314 (leave 335 (leave
315 (_ "either '--export' or '--import' \ 336 (_ "either '--export' or '--import' \
diff --git a/tests/guix-archive.sh b/tests/guix-archive.sh
index 3ac618ae33c..0de7395145b 100644
--- a/tests/guix-archive.sh
+++ b/tests/guix-archive.sh
@@ -1,5 +1,5 @@
1# GNU Guix --- Functional package management for GNU 1# GNU Guix --- Functional package management for GNU
2# Copyright © 2013 Ludovic Courtès <ludo@gnu.org> 2# Copyright © 2013, 2014 Ludovic Courtès <ludo@gnu.org>
3# 3#
4# This file is part of GNU Guix. 4# This file is part of GNU Guix.
5# 5#
@@ -44,5 +44,23 @@ guix archive --import < "$archive" 2>&1 | grep "import.*guile-bootstrap"
44if guix archive something-that-does-not-exist 44if guix archive something-that-does-not-exist
45then false; else true; fi 45then false; else true; fi
46 46
47# This one must not be listed as missing.
48guix build guile-bootstrap > "$archive"
49guix archive --missing < "$archive"
50test "`guix archive --missing < "$archive"`" = ""
51
52# Two out of three should be listed as missing.
53echo "$NIX_STORE_DIR/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-foo" >> "$archive"
54echo "$NIX_STORE_DIR/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-bar" >> "$archive"
55guix archive --missing < "$archive" > "$archive_alt"
56echo "$NIX_STORE_DIR/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-foo" > "$archive"
57echo "$NIX_STORE_DIR/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-bar" >> "$archive"
58cmp "$archive" "$archive_alt"
59
60# This is not a valid store file name, so an error.
61echo something invalid > "$archive"
62if guix archive --missing < "$archive"
63then false; else true; fi
64
47if echo foo | guix archive --authorize 65if echo foo | guix archive --authorize
48then false; else true; fi 66then false; else true; fi