diff options
author | regnat <rg@regnat.ovh> | 2021-05-19 10:36:48 +0200 |
---|---|---|
committer | regnat <rg@regnat.ovh> | 2021-05-26 16:59:09 +0200 |
commit | 63ebfc73c56978665bf6c58c3e4ad84485355b1a (patch) | |
tree | 287a8a64916e4b1d7644cfc011bb4f91bcaa56bc /src/libstore | |
parent | 8c30acc3e896839283a2c96ec97cc0c811e8ad6a (diff) |
Make `copyPaths` copy the whole realisations closure
Otherwise registering the realisations on the remote side might fail as
it now expects a complete closure
Diffstat (limited to 'src/libstore')
-rw-r--r-- | src/libstore/store-api.cc | 32 |
1 files changed, 26 insertions, 6 deletions
diff --git a/src/libstore/store-api.cc b/src/libstore/store-api.cc index 93fcb068f..08573f709 100644 --- a/src/libstore/store-api.cc +++ b/src/libstore/store-api.cc @@ -780,20 +780,40 @@ std::map<StorePath, StorePath> copyPaths(ref<Store> srcStore, ref<Store> dstStor RepairFlag repair, CheckSigsFlag checkSigs, SubstituteFlag substitute) { StorePathSet storePaths; - std::set<Realisation> realisations; + std::set<Realisation> toplevelRealisations; for (auto & path : paths) { storePaths.insert(path.path()); if (auto realisation = std::get_if<Realisation>(&path.raw)) { settings.requireExperimentalFeature("ca-derivations"); - realisations.insert(*realisation); + toplevelRealisations.insert(*realisation); } } auto pathsMap = copyPaths(srcStore, dstStore, storePaths, repair, checkSigs, substitute); + + ThreadPool pool; + try { - for (auto & realisation : realisations) { - dstStore->registerDrvOutput(realisation, checkSigs); - } - } catch (MissingExperimentalFeature & e) { + // Copy the realisation closure + processGraph<Realisation>( + pool, Realisation::closure(*srcStore, toplevelRealisations), + [&](const Realisation& current) -> std::set<Realisation> { + std::set<Realisation> children; + for (const auto& drvOutput : current.drvOutputDeps) { + auto currentChild = srcStore->queryRealisation(drvOutput); + if (!currentChild) + throw Error( + "Incomplete realisation closure: '%s' is a " + "dependency " + "of '%s' but isn’t registered", + drvOutput.to_string(), current.id.to_string()); + children.insert(*currentChild); + } + return children; + }, + [&](const Realisation& current) -> void { + dstStore->registerDrvOutput(current, checkSigs); + }); + } catch (MissingExperimentalFeature& e) { // Don't fail if the remote doesn't support CA derivations is it might // not be within our control to change that, and we might still want // to at least copy the output paths. |