(zilch magic): add helper to turn a store path into its FOD equivalent

This commit is contained in:
puck 2025-05-11 22:21:07 +00:00
parent 9d72e8a246
commit ec41674598

View file

@ -5,9 +5,10 @@
(import
(scheme base) (scheme file)
(zilch lib hash) (zilch nix daemon) (zilch nix drv) (zilch nix path)
(zilch nix hash)
(zilch planner step)
(zilch zexpr)
(srfi 128) (srfi 132) (srfi 146) (srfi 152)
(srfi 128) (srfi 132) (srfi 146) (srfi 152) (srfi 207)
(chicken base) (chicken format) socket)
(export
@ -24,16 +25,61 @@
zilch-magic-counters)
(begin
(define (daemon-connect)
(define conn
(parameterize
((socket-send-buffer-size 4096) (socket-send-size 4096) (socket-receive-timeout 60000) (socket-send-timeout 5000))
(let ((unix-socket (socket af/unix sock/stream)))
(socket-connect unix-socket (unix-address "/nix/var/nix/daemon-socket/socket"))
(let-values (((in-port out-port) (socket-i/o-ports unix-socket)))
(make-daemon-link in-port out-port)))))
(daemon-wop-handshake conn)
conn)
(define (daemon-close conn)
(close-input-port (daemon-link-in-port conn))
(close-output-port (daemon-link-out-port conn)))
;; The daemon connection used by `(zilch magic)`.
(define *daemon*
(make-parameter
(parameterize
((socket-send-buffer-size 4096) (socket-send-size 4096) (socket-receive-timeout 60000) (socket-send-timeout 5000))
(let ((unix-socket (socket af/unix sock/stream)))
(socket-connect unix-socket (unix-address "/nix/var/nix/daemon-socket/socket"))
(let-values (((in-port out-port) (socket-i/o-ports unix-socket)))
(make-daemon-link in-port out-port))))))
(daemon-wop-handshake (*daemon*))
(make-parameter (daemon-connect)))
; Create a CA store path from the store path being passed in.
(define (store-path-to-fod conn path)
(define data (daemon-wop-query-path-info conn path))
(define nar-size (valid-path-info-nar-size data))
(define hash (valid-path-info-nar-hash data))
(define references (valid-path-info-references data))
(define references-filtered (list-copy references))
(define self-references (member path references-filtered string=?))
(when self-references
(if (null? (cdr self-references))
(set! references-filtered '())
(begin
; Cheaply remove this item from the list.
; (self-references . (foo . (bar . baz)))
; -> (foo . (bar . baz)
(set-car! self-references (cadr self-references))
(set-cdr! self-references (cddr self-references)))))
(define name (string-copy path (+ (string-length (%store-dir)) 1 32 1)))
(define ca-store-path (make-fixed-output-with-references hash name references-filtered self-references))
(unless (daemon-wop-query-path-info conn ca-store-path)
(daemon-wop-add-to-store-nar conn ca-store-path (valid-path-info-deriver data) (hex hash) references nar-size (string-append "fixed:r:sha256:" (as-base32 hash))
(lambda (write-blob)
(define new-conn (daemon-connect))
(daemon-wop-nar-from-path new-conn path)
(define blob (make-bytevector 4096))
(do ((i 0))
((= i nar-size) (daemon-close new-conn))
(let* ((chunk-size (min 4096 (- nar-size i)))
(bytes-read (read-bytevector! blob (daemon-link-in-port new-conn) 0 chunk-size)))
(when (eof-object? bytes-read)
(error "unexpected EOF"))
(set! i (+ i bytes-read))
(write-blob blob 0 bytes-read))))))
(values name hash nar-size ca-store-path))
;; If set to `#f`, `store-path-for-ca-drv*` will not generate
;; content-addressed derivations.