Subject: bug#28659: v0.13: guix pull fails; libgit2-0.26.0 and 0.25.1 content hashes fail

From: [email-masked] (Ludovic Courtès)
Date: Thu, 14 Dec 2017 17:53:37 +0100

[email-masked] (Ludovic Courtès) skribis:

> Thinking more about it, why not simply always enable substitutes for
> fixed-output derivations, like this:
>
> diff --git a/nix/libstore/build.cc b/nix/libstore/build.cc
> index d68e8b2bc..03a8f5080 100644
> --- a/nix/libstore/build.cc
> +++ b/nix/libstore/build.cc
> @@ -1034,8 +1034,10 @@ void DerivationGoal::haveDerivation()
>  
>      /* We are first going to try to create the invalid output paths
>         through substitutes.  If that doesn't work, we'll build
> -       them. */
> -    if (settings.useSubstitutes && substitutesAllowed(drv))
> +       them.  Always enable substitutes for fixed-output derivations to
> +       protect against disappearing files and in-place modifications on
> +       upstream sites.  */
> +    if ((fixedOutput || settings.useSubstitutes) && substitutesAllowed(drv))
>          foreach (PathSet::iterator, i, invalidOutputs)
>              addWaitee(worker.makeSubstitutionGoal(*i, buildMode == bmRepair));

[...]

> The downside is that it still requires one to authorize the server’s
> key, although it’s in theory unnecessary since it’s content addressed.
> I’m not sure how to solve that because ‘guix substitute’ doesn’t know
> that it’s substituting a fixed-output derivation.  I suppose we’d need
> to modify the “protocol” between guix-daemon and ‘guix substitute’.

I looked at how to address this by having ‘guix substitute’
automatically determine whether it’s being asked for a content-addressed
item or not.  The guts of it is this procedure:

  (define* (content-addressed-item? item hash
                                    #:key (hash-algo 'sha256))
    "Return true if ITEM, a store file name, is definitely a content-addressed
  item (result of a fixed-output derivation) with the given HASH of type
  HASH-ALGO, false otherwise.

  Note: This procedure is useful when the deriver of ITEM is unknown.  In other
  cases, the recommended approach is to check 'fixed-output-derivation?' on the
  deriver."
    ;; XXX: This returns #f for "text" items produced by 'add-text-to-store'.
    ;; There's not much we can do because the file name for these is a function
    ;; of their content.
    (let ((name (store-path-package-name item)))
      (or (string=? item (fixed-output-path name hash #:recursive? #f
                                            #:hash-algo hash-algo))
          (string=? item (fixed-output-path name hash #:recursive? #t
                                            #:hash-algo hash-algo)))))

It works as expected for the result of “recursive fixed-output
derivations”—i.e., fixed-output derivations that produce a directory,
such as VCS checkouts.

However it doesn’t work for fixed-output derivations that produce a flat
file, such as origins with the ‘url-fetch’ method.  The reason is
because in the case of non-recursive derivations, the store file name is
computed as a function of the file hash, not as a function of the nar
hash, whereas narinfos only contains the nar hash (the thing that ‘guix
hash -r’ computes.)

So I think we have to communicate more info from the daemon to ‘guix
substitute’.

Ludo’.