@@ -170,6 +170,11 @@ GUILE_MODULE_AVAILABLE([have_guile_avahi], [(avahi)])
AM_CONDITIONAL([HAVE_GUILE_AVAHI],
[test "x$have_guile_avahi" = "xyes"])
+dnl Check for Guile-eris.
+GUILE_MODULE_AVAILABLE([have_guile_eris], [(eris)])
+AM_CONDITIONAL([HAVE_GUILE_ERIS],
+ [test "x$have_guile_eris" = "xyes"])
+
dnl Guile-newt is used by the graphical installer.
GUILE_MODULE_AVAILABLE([have_guile_newt], [(newt)])
@@ -404,6 +404,7 @@ (define code
("guile-zstd" ,guile-zstd)
("guile-ssh" ,guile-ssh)
("guile-git" ,guile-git)
+ ("guile-eris" ,guile-eris)
;; XXX: Keep the development inputs here even though
;; they're unnecessary, just so that 'guix environment
@@ -45,6 +45,8 @@ (define-module (guix narinfo)
narinfo-file-sizes
narinfo-hash
narinfo-size
+ narinfo-eris-format
+ narinfo-eris-urn
narinfo-references
narinfo-deriver
narinfo-system
@@ -68,8 +70,8 @@ (define-module (guix narinfo)
(define-record-type <narinfo>
(%make-narinfo path uri-base uris compressions file-sizes file-hashes
- nar-hash nar-size references deriver system
- signature contents)
+ nar-hash nar-size eris-format eris-urn references deriver
+ system signature contents)
narinfo?
(path narinfo-path)
(uri-base narinfo-uri-base) ;URI of the cache it originates from
@@ -79,6 +81,8 @@ (define-record-type <narinfo>
(file-hashes narinfo-file-hashes)
(nar-hash narinfo-hash)
(nar-size narinfo-size)
+ (eris-format narinfo-eris-format)
+ (eris-urn narinfo-eris-urn)
(references narinfo-references)
(deriver narinfo-deriver)
(system narinfo-system)
@@ -135,7 +139,7 @@ (define (narinfo-maker str cache-url)
"Return a narinfo constructor for narinfos originating from CACHE-URL. STR
must contain the original contents of a narinfo file."
(lambda (path urls compressions file-hashes file-sizes
- nar-hash nar-size references deriver system
+ nar-hash nar-size eris-format eris-urn references deriver system
signature)
"Return a new <narinfo> object."
(define len (length urls))
@@ -157,6 +161,8 @@ (define len (length urls))
((lst ...) (map string->number lst)))
nar-hash
(and=> nar-size string->number)
+ eris-format
+ (if eris-urn (string->uri eris-urn) #f)
(string-tokenize references)
(match deriver
((or #f "") #f)
@@ -184,7 +190,7 @@ (define* (read-narinfo port #:optional url
(narinfo-maker str url)
'("StorePath" "URL" "Compression"
"FileHash" "FileSize" "NarHash" "NarSize"
- "References" "Deriver" "System"
+ "ERISFormat" "ERIS" "References" "Deriver" "System"
"Signature")
'("URL" "Compression" "FileSize" "FileHash"))))
@@ -58,6 +58,7 @@ (define-module (guix scripts publish)
#:use-module (guix workers)
#:use-module (guix store)
#:use-module ((guix serialization) #:select (write-file))
+ #:use-module (eris)
#:use-module (zlib)
#:autoload (lzlib) (call-with-lzip-output-port
make-lzip-output-port)
@@ -146,6 +147,9 @@ (define %default-gzip-compression
;; Since we compress on the fly, default to fast compression.
(compression 'gzip 3))
+(define %eris-zstd-compression
+ (compression 'zstd 19))
+
(define (default-compression type)
(compression type 3))
@@ -324,7 +328,8 @@ (define* (store-item->recutils store-item
(define* (narinfo-string store store-path
#:key (compressions (list %no-compression))
- (nar-path "nar") (file-sizes '()))
+ (nar-path "nar") (file-sizes '())
+ eris-urn)
"Generate a narinfo key/value string for STORE-PATH; an exception is raised
if STORE-PATH is invalid. Produce a URL that corresponds to COMPRESSION. The
narinfo is signed with KEY. NAR-PATH specifies the prefix for nar URLs.
@@ -347,7 +352,7 @@ (define* (narinfo-string store store-path
StorePath: ~a
~{~a~}\
NarHash: sha256:~a
-NarSize: ~d
+NarSize: ~d~@[~%ERISFormat: application/x-nix-archive+zstd-19~%ERIS: ~a~]
References: ~a~%"
store-path
(map (lambda (compression)
@@ -359,7 +364,7 @@ (define* (narinfo-string store store-path
#:compression
compression)))
compressions)
- hash size references))
+ hash size eris-urn references))
;; Do not render a "Deriver" line if we are rendering info for a
;; derivation. Also do not render a "System" line that would be
;; expensive to compute and is currently unused.
@@ -632,6 +637,16 @@ (define (compressed-nar-size compression)
(and stat
(cons compression (stat:size stat)))))
+ (define (eris-encode-nar compressions)
+ (and (member %eris-zstd-compression compressions)
+ (let* ((nar (nar-cache-file cache item
+ #:compression %eris-zstd-compression))
+ (stat (stat nar #f)))
+ (and stat
+ (call-with-input-file nar
+ (cut eris-encode->string <>
+ #:block-size %eris-block-size-large))))))
+
(let ((compression (actual-compressions item compressions)))
(for-each (cut compress-nar cache item <>) compressions)
@@ -650,7 +665,8 @@ (define (compressed-nar-size compression)
(display (narinfo-string store item
#:nar-path nar-path
#:compressions compressions
- #:file-sizes sizes)
+ #:file-sizes sizes
+ #:eris-urn (eris-encode-nar compression))
port)))
;; Make the cached narinfo world-readable, contrary to what