From e9848beca704d27a13e28b4403251725bd485bb2 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 16 Jul 2021 09:37:33 +0200 Subject: [PATCH] nix-build: Copy drv closure between eval store and build store --- src/libcmd/installables.cc | 27 +----------------------- src/libstore/store-api.cc | 27 ++++++++++++++++++++++++ src/libstore/store-api.hh | 6 ++++++ src/nix-build/nix-build.cc | 7 ++++-- src/nix-copy-closure/nix-copy-closure.cc | 5 +---- 5 files changed, 40 insertions(+), 32 deletions(-) diff --git a/src/libcmd/installables.cc b/src/libcmd/installables.cc index ca4d509c2..124df34ea 100644 --- a/src/libcmd/installables.cc +++ b/src/libcmd/installables.cc @@ -12,7 +12,6 @@ #include "eval-cache.hh" #include "url.hh" #include "registry.hh" -#include "remote-store.hh" #include #include @@ -393,31 +392,7 @@ DerivedPaths InstallableValue::toDerivedPaths() for (auto & i : drvsToOutputs) res.push_back(DerivedPath::Built { i.first, i.second }); - // FIXME: Temporary hack - if (state->store != state->buildStore) { - RealisedPath::Set closure; - RealisedPath::closure(*state->store, drvsToCopy, closure); - - if (dynamic_cast(&*state->buildStore)) { - StorePathSet closure2; - for (auto & p : closure) - closure2.insert(p.path()); - - auto valid = state->buildStore->queryValidPaths(closure2); - StorePathSet missing; - for (auto & p : closure2) - if (!valid.count(p)) missing.insert(p); - - if (!missing.empty()) { - auto source = sinkToSource([&](Sink & sink) { - state->store->exportPaths(missing, sink); - }); - state->buildStore->importPaths(*source, NoCheckSigs); - } - - } else - copyPaths(state->store, state->buildStore, closure); - } + copyClosure(state->store, state->buildStore, drvsToCopy); return res; } diff --git a/src/libstore/store-api.cc b/src/libstore/store-api.cc index 40a406468..d040560ca 100644 --- a/src/libstore/store-api.cc +++ b/src/libstore/store-api.cc @@ -9,6 +9,7 @@ #include "url.hh" #include "archive.hh" #include "callback.hh" +#include "remote-store.hh" #include @@ -881,6 +882,16 @@ std::map copyPaths(ref srcStore, ref dstStor for (auto & path : storePaths) pathsMap.insert_or_assign(path, path); + // FIXME: Temporary hack to copy closures in a single round-trip. + if (dynamic_cast(&*dstStore)) { + if (!missing.empty()) { + auto source = sinkToSource([&](Sink & sink) { + srcStore->exportPaths(missing, sink); + }); + dstStore->importPaths(*source, NoCheckSigs); + } + return pathsMap; + } Activity act(*logger, lvlInfo, actCopyPaths, fmt("copying %d paths", missing.size())); @@ -958,6 +969,22 @@ std::map copyPaths(ref srcStore, ref dstStor return pathsMap; } +void copyClosure( + ref srcStore, + ref dstStore, + const RealisedPath::Set & paths, + RepairFlag repair, + CheckSigsFlag checkSigs, + SubstituteFlag substitute) +{ + if (srcStore == dstStore) return; + + RealisedPath::Set closure; + RealisedPath::closure(*srcStore, paths, closure); + + copyPaths(srcStore, dstStore, closure, repair, checkSigs, substitute); +} + std::optional decodeValidPathInfo(const Store & store, std::istream & str, std::optional hashGiven) { std::string path; diff --git a/src/libstore/store-api.hh b/src/libstore/store-api.hh index 356ae615c..c39d9f894 100644 --- a/src/libstore/store-api.hh +++ b/src/libstore/store-api.hh @@ -773,6 +773,12 @@ std::map copyPaths(ref srcStore, ref dstStor CheckSigsFlag checkSigs = CheckSigs, SubstituteFlag substitute = NoSubstitute); +/* Copy the closure of `paths` from `srcStore` to `dstStore`. */ +void copyClosure(ref srcStore, ref dstStore, + const RealisedPath::Set & paths, + RepairFlag repair = NoRepair, + CheckSigsFlag checkSigs = CheckSigs, + SubstituteFlag substitute = NoSubstitute); /* Remove the temporary roots file for this process. Any temporary root becomes garbage after this point unless it has been registered diff --git a/src/nix-build/nix-build.cc b/src/nix-build/nix-build.cc index 4305c0ac1..4ee471520 100755 --- a/src/nix-build/nix-build.cc +++ b/src/nix-build/nix-build.cc @@ -532,6 +532,7 @@ static void main_nix_build(int argc, char * * argv) std::vector pathsToBuild; std::vector> pathsToBuildOrdered; + RealisedPath::Set drvsToCopy; std::map> drvMap; @@ -544,15 +545,17 @@ static void main_nix_build(int argc, char * * argv) pathsToBuild.push_back({drvPath, {outputName}}); pathsToBuildOrdered.push_back({drvPath, {outputName}}); + drvsToCopy.insert(drvPath); auto i = drvMap.find(drvPath); if (i != drvMap.end()) i->second.second.insert(outputName); - else { + else drvMap[drvPath] = {drvMap.size(), {outputName}}; - } } + copyClosure(state->store, state->buildStore, drvsToCopy); + buildPaths(pathsToBuild); if (dryRun) return; diff --git a/src/nix-copy-closure/nix-copy-closure.cc b/src/nix-copy-closure/nix-copy-closure.cc index 02ccbe541..7c38e55e4 100755 --- a/src/nix-copy-closure/nix-copy-closure.cc +++ b/src/nix-copy-closure/nix-copy-closure.cc @@ -54,10 +54,7 @@ static int main_nix_copy_closure(int argc, char ** argv) for (auto & path : storePaths) storePaths2.insert(from->followLinksToStorePath(path)); - RealisedPath::Set closure; - RealisedPath::closure(*from, storePaths2, closure); - - copyPaths(from, to, closure, NoRepair, NoCheckSigs, useSubstitutes); + copyClosure(from, to, storePaths2, NoRepair, NoCheckSigs, useSubstitutes); return 0; }