diff options
| author | Ludovic Courtès <ludo@gnu.org> | 2014-01-06 22:25:29 +0100 |
|---|---|---|
| committer | Ludovic Courtès <ludo@gnu.org> | 2014-01-06 22:25:29 +0100 |
| commit | 87236aed77bd57ecd143d84acf864fb112842118 (patch) | |
| tree | 77ebed23b8267ab621a69051ba60e58dfe715689 | |
| parent | b84612605204d604da84b30e56966994cc03d0a3 (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.texi | 11 | ||||
| -rw-r--r-- | guix/scripts/archive.scm | 21 | ||||
| -rw-r--r-- | tests/guix-archive.sh | 20 |
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: | |||
| 938 | guix archive --export emacs | ssh the-machine guix archive --import | 938 | guix archive --export emacs | ssh the-machine guix archive --import |
| 939 | @end example | 939 | @end example |
| 940 | 940 | ||
| 941 | @noindent | ||
| 942 | However, note that, in this example, all of @code{emacs} and its | ||
| 943 | dependencies are transferred, regardless of what is already available in | ||
| 944 | the target machine's store. The @code{--missing} option can help figure | ||
| 945 | out which items are missing from the target's store. | ||
| 946 | |||
| 941 | Archives are stored in the ``Nix archive'' or ``Nar'' format, which is | 947 | Archives are stored in the ``Nix archive'' or ``Nar'' format, which is |
| 942 | comparable in spirit to `tar'. When exporting, the daemon digitally | 948 | comparable in spirit to `tar'. When exporting, the daemon digitally |
| 943 | signs the contents of the archive, and that digital signature is | 949 | signs 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 | |||
| 959 | signature, or if it is signed by a public key not among the authorized | 965 | signature, or if it is signed by a public key not among the authorized |
| 960 | keys (see @code{--authorize} below.) | 966 | keys (see @code{--authorize} below.) |
| 961 | 967 | ||
| 968 | @item --missing | ||
| 969 | Read a list of store file names from the standard input, one per line, | ||
| 970 | and write on the standard output the subset of these files missing from | ||
| 971 | the store. | ||
| 972 | |||
| 962 | @item --generate-key[=@var{parameters}] | 973 | @item --generate-key[=@var{parameters}] |
| 963 | @cindex signing, archives | 974 | @cindex signing, archives |
| 964 | Generate a new key pair for the daemons. This is a prerequisite before | 975 | Generate 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" | |||
| 44 | if guix archive something-that-does-not-exist | 44 | if guix archive something-that-does-not-exist |
| 45 | then false; else true; fi | 45 | then false; else true; fi |
| 46 | 46 | ||
| 47 | # This one must not be listed as missing. | ||
| 48 | guix build guile-bootstrap > "$archive" | ||
| 49 | guix archive --missing < "$archive" | ||
| 50 | test "`guix archive --missing < "$archive"`" = "" | ||
| 51 | |||
| 52 | # Two out of three should be listed as missing. | ||
| 53 | echo "$NIX_STORE_DIR/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-foo" >> "$archive" | ||
| 54 | echo "$NIX_STORE_DIR/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-bar" >> "$archive" | ||
| 55 | guix archive --missing < "$archive" > "$archive_alt" | ||
| 56 | echo "$NIX_STORE_DIR/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-foo" > "$archive" | ||
| 57 | echo "$NIX_STORE_DIR/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-bar" >> "$archive" | ||
| 58 | cmp "$archive" "$archive_alt" | ||
| 59 | |||
| 60 | # This is not a valid store file name, so an error. | ||
| 61 | echo something invalid > "$archive" | ||
| 62 | if guix archive --missing < "$archive" | ||
| 63 | then false; else true; fi | ||
| 64 | |||
| 47 | if echo foo | guix archive --authorize | 65 | if echo foo | guix archive --authorize |
| 48 | then false; else true; fi | 66 | then false; else true; fi |
