Serve narinfo files for derivations
This commit is contained in:
parent
120af42c24
commit
66e886a6b4
3 changed files with 150 additions and 10 deletions
|
|
@ -322,11 +322,11 @@
|
||||||
(render-narinfos conn filename))
|
(render-narinfos conn filename))
|
||||||
(((or 'GET 'POST) "build-server" _ ...)
|
(((or 'GET 'POST) "build-server" _ ...)
|
||||||
(delegate-to-with-secret-key-base build-server-controller))
|
(delegate-to-with-secret-key-base build-server-controller))
|
||||||
(('GET "nar" _ ...) (delegate-to nar-controller))
|
|
||||||
(('GET "compare" _ ...) (delegate-to compare-controller))
|
(('GET "compare" _ ...) (delegate-to compare-controller))
|
||||||
(('GET "compare-by-datetime" _ ...) (delegate-to compare-controller))
|
(('GET "compare-by-datetime" _ ...) (delegate-to compare-controller))
|
||||||
(('GET "jobs") (delegate-to jobs-controller))
|
(('GET "jobs") (delegate-to jobs-controller))
|
||||||
(('GET "jobs" "queue") (delegate-to jobs-controller))
|
(('GET "jobs" "queue") (delegate-to jobs-controller))
|
||||||
(('GET "job" job-id) (delegate-to jobs-controller))
|
(('GET "job" job-id) (delegate-to jobs-controller))
|
||||||
|
(('GET _ ...) (delegate-to nar-controller))
|
||||||
((method path ...)
|
((method path ...)
|
||||||
(not-found (request-uri request)))))
|
(not-found (request-uri request)))))
|
||||||
|
|
|
||||||
|
|
@ -16,28 +16,95 @@
|
||||||
;;; <http://www.gnu.org/licenses/>.
|
;;; <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
(define-module (guix-data-service web nar controller)
|
(define-module (guix-data-service web nar controller)
|
||||||
|
#:use-module (srfi srfi-1)
|
||||||
#:use-module (ice-9 iconv)
|
#:use-module (ice-9 iconv)
|
||||||
#:use-module (ice-9 match)
|
#:use-module (ice-9 match)
|
||||||
|
#:use-module (ice-9 format)
|
||||||
#:use-module (ice-9 binary-ports)
|
#:use-module (ice-9 binary-ports)
|
||||||
#:use-module (rnrs bytevectors)
|
#:use-module (rnrs bytevectors)
|
||||||
|
#:use-module (gcrypt hash)
|
||||||
|
#:use-module (gcrypt pk-crypto)
|
||||||
|
#:use-module (web uri)
|
||||||
#:use-module (web request)
|
#:use-module (web request)
|
||||||
#:use-module (web response)
|
#:use-module (web response)
|
||||||
|
#:use-module (guix pki)
|
||||||
|
#:use-module (guix base32)
|
||||||
|
#:use-module (guix base64)
|
||||||
#:use-module (guix serialization)
|
#:use-module (guix serialization)
|
||||||
#:use-module (guix-data-service web render)
|
#:use-module (guix-data-service web render)
|
||||||
#:use-module (guix-data-service model derivation)
|
#:use-module (guix-data-service model derivation)
|
||||||
#:export (nar-controller))
|
#:export (nar-controller
|
||||||
|
|
||||||
|
%narinfo-signing-private-key
|
||||||
|
%narinfo-signing-public-key))
|
||||||
|
|
||||||
|
|
||||||
|
(define %narinfo-signing-private-key
|
||||||
|
(make-parameter #f))
|
||||||
|
|
||||||
|
(define %narinfo-signing-public-key
|
||||||
|
(make-parameter #f))
|
||||||
|
|
||||||
(define (nar-controller request
|
(define (nar-controller request
|
||||||
method-and-path-components
|
method-and-path-components
|
||||||
mime-types
|
mime-types
|
||||||
body
|
body
|
||||||
conn)
|
conn)
|
||||||
|
(define (.narinfo-suffix s)
|
||||||
|
(string-suffix? ".narinfo" s))
|
||||||
|
|
||||||
(match method-and-path-components
|
(match method-and-path-components
|
||||||
(('GET "nar" derivation)
|
(('GET "nar" derivation)
|
||||||
(render-nar request
|
(render-nar request
|
||||||
mime-types
|
mime-types
|
||||||
conn
|
conn
|
||||||
(string-append "/gnu/store/" derivation)))
|
(string-append "/gnu/store/" derivation)))
|
||||||
|
(('GET (? .narinfo-suffix path))
|
||||||
|
(let* ((hash (string-drop-right
|
||||||
|
path
|
||||||
|
(string-length ".narinfo")))
|
||||||
|
(derivation (select-derivation-by-file-name-hash
|
||||||
|
conn
|
||||||
|
hash)))
|
||||||
|
(if derivation
|
||||||
|
(list (build-response
|
||||||
|
#:code 200
|
||||||
|
#:headers '((content-type . (application/x-narinfo))))
|
||||||
|
(let* ((derivation-file-name
|
||||||
|
(second derivation))
|
||||||
|
(derivation-text
|
||||||
|
(select-serialized-derivation-by-file-name
|
||||||
|
conn
|
||||||
|
derivation-file-name))
|
||||||
|
(derivation-bytevector
|
||||||
|
(string->bytevector derivation-text
|
||||||
|
"ISO-8859-1"))
|
||||||
|
(derivation-references
|
||||||
|
(select-derivation-references-by-derivation-id
|
||||||
|
conn
|
||||||
|
(first derivation)))
|
||||||
|
(nar-bytevector
|
||||||
|
(call-with-values
|
||||||
|
(lambda ()
|
||||||
|
(open-bytevector-output-port))
|
||||||
|
(lambda (port get-bytevector)
|
||||||
|
(write-file-tree
|
||||||
|
derivation-file-name
|
||||||
|
port
|
||||||
|
#:file-type+size
|
||||||
|
(lambda (file)
|
||||||
|
(values 'regular
|
||||||
|
(bytevector-length derivation-bytevector)))
|
||||||
|
#:file-port
|
||||||
|
(lambda (file)
|
||||||
|
(open-bytevector-input-port derivation-bytevector)))
|
||||||
|
(get-bytevector)))))
|
||||||
|
(lambda (port)
|
||||||
|
(display (narinfo-string derivation-file-name
|
||||||
|
nar-bytevector
|
||||||
|
derivation-references)
|
||||||
|
port))))
|
||||||
|
(not-found (request-uri request)))))
|
||||||
(_ #f)))
|
(_ #f)))
|
||||||
|
|
||||||
(define (render-nar request
|
(define (render-nar request
|
||||||
|
|
@ -68,3 +135,44 @@
|
||||||
(lambda (file)
|
(lambda (file)
|
||||||
(open-bytevector-input-port derivation-bytevector))))))
|
(open-bytevector-input-port derivation-bytevector))))))
|
||||||
(not-found (request-uri request)))))
|
(not-found (request-uri request)))))
|
||||||
|
|
||||||
|
(define* (narinfo-string store-item
|
||||||
|
nar-bytevector
|
||||||
|
references
|
||||||
|
#:key
|
||||||
|
(nar-path "nar"))
|
||||||
|
(define (signed-string s)
|
||||||
|
(let* ((public-key (%narinfo-signing-public-key))
|
||||||
|
(hash (bytevector->hash-data (sha256 (string->utf8 s))
|
||||||
|
#:key-type (key-type public-key))))
|
||||||
|
(signature-sexp hash (%narinfo-signing-private-key) public-key)))
|
||||||
|
|
||||||
|
(let* ((hash (bytevector->nix-base32-string
|
||||||
|
(sha256 nar-bytevector)))
|
||||||
|
(size (bytevector-length nar-bytevector))
|
||||||
|
(references (string-join
|
||||||
|
(map basename references)
|
||||||
|
" "))
|
||||||
|
(info (format #f
|
||||||
|
"\
|
||||||
|
StorePath: ~a
|
||||||
|
URL: ~a
|
||||||
|
Compression: none
|
||||||
|
NarHash: sha256:~a
|
||||||
|
NarSize: ~d
|
||||||
|
References: ~a~%"
|
||||||
|
store-item
|
||||||
|
(encode-and-join-uri-path
|
||||||
|
(list nar-path
|
||||||
|
(basename store-item)))
|
||||||
|
hash
|
||||||
|
size
|
||||||
|
references)))
|
||||||
|
(if (%narinfo-signing-private-key)
|
||||||
|
(format #f "~aSignature: 1;~a;~a~%"
|
||||||
|
info
|
||||||
|
(gethostname)
|
||||||
|
(base64-encode
|
||||||
|
(string->utf8
|
||||||
|
(canonical-sexp->string (signed-string info)))))
|
||||||
|
info)))
|
||||||
|
|
|
||||||
|
|
@ -27,8 +27,11 @@
|
||||||
(srfi srfi-37)
|
(srfi srfi-37)
|
||||||
(ice-9 textual-ports)
|
(ice-9 textual-ports)
|
||||||
(system repl server)
|
(system repl server)
|
||||||
|
(gcrypt pk-crypto)
|
||||||
|
(guix pki)
|
||||||
(guix-data-service config)
|
(guix-data-service config)
|
||||||
(guix-data-service web server))
|
(guix-data-service web server)
|
||||||
|
(guix-data-service web nar controller))
|
||||||
|
|
||||||
(define %default-repl-server-port
|
(define %default-repl-server-port
|
||||||
;; Default port to run REPL server on, if --listen-repl is provided
|
;; Default port to run REPL server on, if --listen-repl is provided
|
||||||
|
|
@ -56,6 +59,12 @@
|
||||||
(string-trim-right
|
(string-trim-right
|
||||||
(call-with-input-file arg get-string-all))
|
(call-with-input-file arg get-string-all))
|
||||||
result)))
|
result)))
|
||||||
|
(option '("narinfo-signing-public-key") #t #f
|
||||||
|
(lambda (opt name arg result)
|
||||||
|
(alist-cons 'narinfo-signing-public-key-file arg result)))
|
||||||
|
(option '("narinfo-signing-private-key") #t #f
|
||||||
|
(lambda (opt name arg result)
|
||||||
|
(alist-cons 'narinfo-signing-private-key-file arg result)))
|
||||||
(option '("update-database") #f #f
|
(option '("update-database") #f #f
|
||||||
(lambda (opt name _ result)
|
(lambda (opt name _ result)
|
||||||
(alist-cons 'update-database #t result)))
|
(alist-cons 'update-database #t result)))
|
||||||
|
|
@ -74,6 +83,8 @@
|
||||||
(define %default-options
|
(define %default-options
|
||||||
;; Alist of default option values
|
;; Alist of default option values
|
||||||
`((listen-repl . #f)
|
`((listen-repl . #f)
|
||||||
|
(narinfo-signing-public-key . ,%public-key-file)
|
||||||
|
(narinfo-signing-private-key . ,%private-key-file)
|
||||||
(update-database . #f)
|
(update-database . #f)
|
||||||
(port . 8765)
|
(port . 8765)
|
||||||
(host . "0.0.0.0")))
|
(host . "0.0.0.0")))
|
||||||
|
|
@ -129,6 +140,27 @@
|
||||||
(simple-format #t "starting the server on port ~A\n"
|
(simple-format #t "starting the server on port ~A\n"
|
||||||
(assq-ref opts 'port))
|
(assq-ref opts 'port))
|
||||||
|
|
||||||
|
(parameterize ((%narinfo-signing-public-key
|
||||||
|
(and=> (assoc-ref opts 'narinfo-signing-public-key)
|
||||||
|
read-file-sexp))
|
||||||
|
(%narinfo-signing-private-key
|
||||||
|
(catch
|
||||||
|
'system-error
|
||||||
|
(lambda ()
|
||||||
|
(and=> (assoc-ref opts 'narinfo-signing-private-key)
|
||||||
|
read-file-sexp))
|
||||||
|
(lambda (key . args)
|
||||||
|
(simple-format
|
||||||
|
(current-error-port)
|
||||||
|
"warning: failed to load narinfo signing private key from ~A\n"
|
||||||
|
(assoc-ref opts 'narinfo-signing-private-key))
|
||||||
|
(simple-format (current-error-port)
|
||||||
|
" ~A: ~A\n"
|
||||||
|
key args)
|
||||||
|
(display "warning: not signing narinfo files\n"
|
||||||
|
(current-error-port))
|
||||||
|
#f))))
|
||||||
|
|
||||||
(start-guix-data-service-web-server (assq-ref opts 'port)
|
(start-guix-data-service-web-server (assq-ref opts 'port)
|
||||||
(assq-ref opts 'host)
|
(assq-ref opts 'host)
|
||||||
(assq-ref opts 'secret-key-base)))
|
(assq-ref opts 'secret-key-base))))
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue