ludo@gnu.org (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’.