unofficial mirror of guix-devel@gnu.org 
 help / color / mirror / code / Atom feed
From: ludo@gnu.org (Ludovic Courtès)
To: David Thompson <dthompson2@worcester.edu>
Cc: guix-devel@gnu.org
Subject: Re: [PATCH 2/2] scripts: Add 'publish' command.
Date: Wed, 18 Mar 2015 11:27:40 +0100	[thread overview]
Message-ID: <87k2yeha77.fsf@gnu.org> (raw)
In-Reply-To: <878uev1xcz.fsf@fsf.org> (David Thompson's message of "Tue, 17 Mar 2015 11:01:48 -0400")

[-- Attachment #1: Type: text/plain, Size: 1370 bytes --]

David Thompson <dthompson2@worcester.edu> skribis:

> From 7200a8ca892308a03a92e737b493244154bab358 Mon Sep 17 00:00:00 2001
> From: David Thompson <dthompson2@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.
> * Makefile.am (MODULES): Add it.
> * doc/guix.texi ("Invoking guix publish"): New node.

Yaaay!

> +@node Invoking guix publish
> +@section Invoking @command{guix publish}
> +
> +The purpose of @command{guix publish} is to expose a Hydra-compatible
> +HTTP API for sharing substitutes from the local store.

s/API/interface/ maybe

I think we should first describe the functionality (what it means to
share the store over HTTP), and only then mention Hydra-compatibility
(which is not something users really care about.)

There should be a word about signing, with an xref to ‘guix archive’ I
think.  Perhaps later we could add an option to choose the signing key.

> +@example
> +guix-daemon --substitute-urls=example.org:8080

It should have “http://”.

Eventually™ it will be possible to specify substitute URLs from the
client; whether to actually use them with still be decided based on the
keys the sysadmin authorized.  Preliminary patch that adds
‘--substitute-urls’ to ‘guix build’ et al.:


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: Type: text/x-patch, Size: 3429 bytes --]

--- a/guix/store.scm
+++ b/guix/store.scm
@@ -484,11 +512,11 @@ encoding conversion errors."
     (when (>= (nix-server-minor-version server) 10)
       (send (boolean use-substitutes?)))
     (when (>= (nix-server-minor-version server) 12)
-      (let ((pairs (if timeout
-                       `(("build-timeout" . ,(number->string timeout))
-                         ,@binary-caches)
-                       binary-caches)))
-        (send (string-pairs pairs))))
+      (let ((pairs `(,@(if timeout
+                           `(("build-timeout" . ,(number->string timeout)))
+                           '())
+                     ("substitute-urls" . ,(string-join substitute-urls)))))
+        (send (string-pairs (pk 'pairs pairs)))))
     (let loop ((done? (process-stderr server)))
       (or done? (process-stderr server)))))
 
diff --git a/guix/scripts/build.scm b/guix/scripts/build.scm
index 370c2a3..df38b5e 100644
--- a/guix/scripts/build.scm
+++ b/guix/scripts/build.scm
@@ -110,6 +110,9 @@ options handled by 'set-build-options-from-command-line', and listed in
   (display (_ "
       --no-substitutes   build instead of resorting to pre-built substitutes"))
   (display (_ "
+      --substitute-urls=URLS
+                         fetch substitute from URLS if they are authorized"))
+  (display (_ "
       --no-build-hook    do not attempt to offload builds via the build hook"))
   (display (_ "
       --max-silent-time=SECONDS
@@ -133,6 +136,8 @@ options handled by 'set-build-options-from-command-line', and listed in
                      #:max-build-jobs (or (assoc-ref opts 'max-jobs) 1)
                      #:fallback? (assoc-ref opts 'fallback?)
                      #:use-substitutes? (assoc-ref opts 'substitutes?)
+                     #:substitute-urls (or (assoc-ref opts 'substitute-urls)
+                                           '())
                      #:use-build-hook? (assoc-ref opts 'build-hook?)
                      #:max-silent-time (assoc-ref opts 'max-silent-time)
                      #:timeout (assoc-ref opts 'timeout)
@@ -166,6 +171,13 @@ options handled by 'set-build-options-from-command-line', and listed in
                          (alist-cons 'substitutes? #f
                                      (alist-delete 'substitutes? result))
                          rest)))
+        (option '("substitute-urls") #t #f
+                (lambda (opt name arg result . rest)
+                  (apply values
+                         (alist-cons 'substitute-urls
+                                     (string-tokenize arg)
+                                     (alist-delete 'substitute-urls result))
+                         rest)))
         (option '("no-build-hook") #f #f
                 (lambda (opt name arg result . rest)
                   (apply values

diff --git a/guix/scripts/substitute-binary.scm b/guix/scripts/substitute-binary.scm
index 903564c..1d45753 100755
--- a/guix/scripts/substitute-binary.scm
+++ b/guix/scripts/substitute-binary.scm
@@ -631,7 +631,10 @@ found."
   (assoc-ref (daemon-options) option))
 
 (define %cache-url
-  (match (and=> (find-daemon-option "substitute-urls")
+  (match (and=> (string-append
+                 (find-daemon-option "untrusted-substitute-urls") ;client
+                 " "
+                 (find-daemon-option "substitute-urls"))          ;admin
                 string-tokenize)
     ((url)
      url)

[-- Attachment #3: Type: text/plain, Size: 3438 bytes --]


I won’t commit it yet because at this point the substituter caches only
from one server, so users could populate
/var/guix/substitute-binary/cache and lead other users to use the
substituter that they chose (or to use nothing if the substituter server
in question returned 404 for all the narinfos.)

That should be easily fixed though (for the interested reader? ;-)).

> --- /dev/null
> +++ b/guix/scripts/publish.scm

Make sure to add the license header.

> +  (display (_ "Usage: guix publish [OPTION]...
> +Publish the store directory over HTTP.\n"))

Maybe “Publish ~a over HTTP” with (%store-directory) would be more
immediately obvious (and translations would be accurate ;-)).

> +(define (load-derivation file-name)
> +  "Read the derivation located at FILE-NAME."
> +  (with-input-from-file file-name
> +    (lambda ()
> +      (read-derivation (current-input-port)))))

(call-with-input-file file read-derivation)

> +(define (sign-string s)
> +  "Sign the hash of the string S with the daemon's key."
> +  (let ((hash (bytevector->hash-data (sha256 (string->utf8 s)))))
> +    (signature-sexp hash %private-key %public-key)))

I had to change it to:

  (define (sign-string s)
    "Sign the hash of the string S with the daemon's key."
    (let ((hash (bytevector->hash-data (sha256 (string->utf8 s))
                                       #:key-type (key-type %public-key))))
      (signature-sexp hash %private-key %public-key)))

Otherwise, ‘bytevector->hash-data’ will assume you have an ECC key and
‘sign’ will raise an exception if you happen to have an RSA key, for
instance.

Maybe ‘signed-string’ would be a more appropriate name since it’s a pure
function.

> +(define (narinfo-string store-path path-info derivation deriver key)

Docstring please.  I would suggest using keyword arguments for arguments
above position 2.

Aren’t ‘derivation’ and ‘deriver’ redundant with ‘path-info’?

> +  (let* ((url (string-append "nar/" (basename store-path)))
> +         (nar-hash (bytevector->base32-string
> +                    (path-info-hash path-info)))
> +         (nar-size (path-info-nar-size path-info))
> +         (references (string-join (map basename (path-info-refs path-info))
> +                                  " "))
> +         (system (derivation-system derivation))
> +         (deriver (basename deriver))
> +         (info (format #f

Please align the RHS and maybe use single-word identifiers.  (I hate it
when I look this fussy.)

> +    (values '((content-type . (application/x-nix-archive
> +                               (charset . "ISO-8859-1"))))

Please add a comment saying that choosing ISO-8859-1 is crucial since
otherwise HTTP clients will interpret the byte stream as UTF-8 and
arbitrarily change invalid byte sequences.  We don’t want anyone to feel
that pain again.  ;-)

> +      (format #t "Publishing store on port ~d~%" port)

Lowercase and use (_ "publishing ..."), and add the file to
po/guix/POTFILES.in.

Now, it would be good to add a bunch of tests.  :-)

Perhaps one way to do it would be to write them in Scheme, and invoke
‘guix-publish’ in a thread, similar to the HTTP tests in
tests/lint.scm.  From there we could check .narinfo and .nar URLs.
WDYT?

Thanks for working on it in spite of the numerous issues you
encountered!

Ludo’.

  reply	other threads:[~2015-03-18 10:28 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-03-17 14:57 [PATCH 0/2] Add 'guix publish' command David Thompson
2015-03-17 15:00 ` [PATCH 1/2] store: Add query-path-info operation David Thompson
2015-03-18  8:55   ` Ludovic Courtès
2015-03-27 16:56     ` David Thompson
2015-03-27 21:30       ` Ludovic Courtès
2015-03-17 15:01 ` [PATCH 2/2] scripts: Add 'publish' command David Thompson
2015-03-18 10:27   ` Ludovic Courtès [this message]
2015-03-27 16:58     ` David Thompson
2015-03-27 22:41       ` Ludovic Courtès
2015-03-29 17:02         ` Mark H Weaver
2015-03-29 17:29           ` David Thompson
2015-03-30 19:32             ` Ludovic Courtès
2015-04-04 18:30         ` David Thompson
2015-03-17 15:20 ` [PATCH 0/2] Add 'guix publish' command David Thompson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://guix.gnu.org/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87k2yeha77.fsf@gnu.org \
    --to=ludo@gnu.org \
    --cc=dthompson2@worcester.edu \
    --cc=guix-devel@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/guix.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).