~ruther/guix-local

4348947c7455056fe1c207e559fe497884646d2d — Ludovic Courtès 2 years ago 7e11369
weather: Report unauthorized substitute servers.

The goal is to make it easier to diagnose substitute
misconfiguration (where we’re passing a substitute URL whose
corresponding key is not authorized).

Suggested by Emmanuel Agullo.

* guix/scripts/weather.scm (check-narinfo-authorization): New procedure.
(report-server-coverage): Use it.
* doc/guix.texi (Invoking guix weather): Document it.
(Getting Substitutes from Other Servers): Add “Troubleshooting” frame.

Change-Id: I0a049c39eefb10d6a06634c8b16aa86902769791
2 files changed, 71 insertions(+), 3 deletions(-)

M doc/guix.texi
M guix/scripts/weather.scm
M doc/guix.texi => doc/guix.texi +20 -1
@@ 4059,6 4059,7 @@ guix-daemon}).  It can also be disabled temporarily by passing the

@node Getting Substitutes from Other Servers
@subsection Getting Substitutes from Other Servers
@c Note: This section name appears in a hint printed by 'guix weather'.

@cindex substitute servers, adding more
Guix can look up and fetch substitutes from several servers.  This is


@@ 4158,6 4159,21 @@ can list as many substitute servers as you like, with the caveat that
substitute lookup can be slowed down if too many servers need to be
contacted.

@quotation Troubleshooting
To diagnose problems, you can run @command{guix weather}.  For example,
running:

@example
guix weather coreutils
@end example

@noindent
not only tells you which of the currently-configured servers has
substitutes for the @code{coreutils} package, it also reports whether
one of these servers is unauthorized.  @xref{Invoking guix weather}, for
more information.
@end quotation

Note that there are also situations where one may want to add the URL of
a substitute server @emph{without} authorizing its key.
@xref{Substitute Authentication}, to understand this fine point.


@@ 16499,7 16515,10 @@ up building packages by yourself (@pxref{Substitutes}).  The
specified servers so you can have an idea of whether you'll be grumpy
today.  It can sometimes be useful info as a user, but it is primarily
useful to people running @command{guix publish} (@pxref{Invoking guix
publish}).
publish}).  Sometimes substitutes @emph{are} available but they are not
authorized on your system; @command{guix weather} reports it so you can
authorize them if you want (@pxref{Getting Substitutes from Other
Servers}).

@cindex statistics, for substitutes
@cindex availability of substitutes

M guix/scripts/weather.scm => guix/scripts/weather.scm +51 -2
@@ 35,6 35,8 @@
  #:use-module ((guix build utils) #:select (every*))
  #:use-module (guix substitutes)
  #:use-module (guix narinfo)
  #:use-module (guix pki)
  #:autoload   (gcrypt pk-crypto) (canonical-sexp->string)
  #:use-module (guix http-client)
  #:use-module (guix ci)
  #:use-module (guix sets)


@@ 185,6 187,44 @@ or #f if it could not be determined."
    (()
     #f)))

(define (check-narinfo-authorization narinfo)
  "Print a warning when NARINFO is not signed by an authorized key."
  (define acl
    (catch 'system-error
      (lambda ()
        (current-acl))
      (lambda args
        (warning (G_ "could not read '~a': ~a~%")
                 %acl-file (strerror (system-error-errno args)))
        (warning (G_ "'~a' is unreadable, cannot determine whether \
substitutes are authorized~%")
                 %acl-file)
        #f)))

  (unless (or (not acl) (valid-narinfo? narinfo acl))
    (warning (G_ "substitutes from '~a' are unauthorized~%")
             (narinfo-uri-base narinfo))
    ;; The "all substitutes" below reflects the fact that, in reality, it *is*
    ;; possible to download "unauthorized" substitutes, as long as they match
    ;; authorized substitutes.
    (display-hint (G_ "To authorize all substitutes from @uref{~a} to be
downloaded, the following command needs to be run as root:

@example
guix archive --authorize <<EOF
~a
EOF
@end example

Alternatively, on Guix System, you can add the signing key above to the
@code{authorized-keys} field of @code{guix-configuration}.

See \"Getting Substitutes from Other Servers\" in the manual for more
information.")
                  (narinfo-uri-base narinfo)
                  (canonical-sexp->string
                   (signature-subject (narinfo-signature narinfo))))))

(define* (report-server-coverage server items
                                 #:key display-missing?)
  "Report the subset of ITEMS available as substitutes on SERVER.


@@ 204,6 244,12 @@ In case ITEMS is an empty list, return 1 instead."
                    #:make-progress-reporter
                    (lambda* (total #:key url #:allow-other-keys)
                      (progress-reporter/bar total)))))
    (match narinfos
      (() #f)
      ((narinfo . _)
       ;; Help diagnose missing substitute authorizations.
       (check-narinfo-authorization narinfo)))

    (let ((obtained  (length narinfos))
          (requested (length items))
          (missing   (lset-difference string=?


@@ 586,8 632,11 @@ SERVER.  Display information for packages with at least THRESHOLD dependents."
                           (with-store store
                             (substitute-urls store))
                           (begin
                             (warning (G_ "could not determine current \
substitute URLs; using defaults~%"))
                             ;; Could not determine the daemon's current
                             ;; substitute URLs, presumably because it's too
                             ;; old.
                             (warning (G_ "using default \
substitute URLs~%"))
                             %default-substitute-urls)))
             (systems  (match (filter-map (match-lambda
                                            (('system . system) system)