David Thompson <dthomps...@worcester.edu> skribis: > From a40d47dc64571aade0c92b4bdf3c56f6870842cc Mon Sep 17 00:00:00 2001 > From: David Thompson <dthomps...@worcester.edu> > Date: Tue, 17 Mar 2015 10:21:31 -0400 > Subject: [PATCH 2/2] scripts: Add 'publish' command. > > * guix/scripts/publish.scm: New file. > * po/guix/POTFILES.in: Add it. > * tests/publish.scm: New file. > * Makefile.am (MODULES): Add script module. > (SCM_TESTS): Add test module. > * doc/guix.texi ("Invoking guix publish"): New node.
[...] > +@node Invoking guix publish > +@section Invoking @command{guix publish} > + > +The purpose of @command{guix publish} is to enable users to easily share > +their store with others. When @command{guix publish} runs, it spawns an > +HTTP server which allows anyone with network access to obtain > +substitutes from it. This means that any machine running Guix can also > +act as if it were a build farm, since the HTTP interface is > +Hydra-compatible. For security, each substitute is signed with the > +system's signing key (@pxref{Invoking guix archive}). I would skip a line after “Hydra-compatible,” and make it like: For security, each substitute is signed, allowing recipients to check their authenticity and integrity (@pxref{Substitutes}). Because @command{guix publish} uses the system's signing key, which is only readable by the system administrator, it must run as root. > +@command{guix publish} is a tool for system administrators, so only the > +root user may invoke it. ... so this sentence can be removed. Note for later: it should drop privileges once the key has been read and the port open. > +Once a publishing server has been authorized (@pxref{Invoking guix archive}), > +the Guix daemon may use it to download substitutes: “the daemon may download substitutes from it:” > +(define (read-file-sexp file) > + (call-with-input-file file > + (compose string->canonical-sexp > + get-string-all))) > + > +(define %private-key > + (read-file-sexp %private-key-file)) > + > +(define %public-key > + (read-file-sexp %public-key-file)) Since this can throw, it should not be done at the top-level. So it should be wrapped it in ‘delay’ or in a thunk. > +(define (narinfo-string store-path path-info key) Docstring please. :-) > +(define (render-nar request store-item) > + "Render archive of the store path corresponding to STORE-ITEM." > + (let ((store-path (string-append %store-directory "/" store-item))) > + ;; The ISO-8859-1 charset *must* be used otherwise HTTP clients will > + ;; interpret the byte stream as UTF-8 and arbitrarily change invalid byte > + ;; sequences. > + (if (file-exists? store-path) > + (values '((content-type . (application/x-nix-archive > + (charset . "ISO-8859-1")))) > + (lambda (port) > + (write-file store-path port))) > + (not-found request)))) This is OK for now, but I just realized that this will be blocking the server for the duration of the whole transfer. Someone could DoS you by substituting TeX Live. ;-) We’ll need a solution but it seems that it’ll be hard to avoid threads. Thoughts? > +(define (guix-publish . args) > + (with-error-handling > + (let* ((opts (parse-command-line args %options (list %default-options))) I had overlooked it but it should use plain ‘args-fold*’ instead of ‘parse-command-line’ (the latter handles $GUIX_BUILD_OPTIONS and ‘guix publish’ doesn’t build anything.) > + (store (open-connection))) Use (with-store store body ...) instead. OK to push with these changes. Thanks! Ludo’.