mirror of
https://github.com/NixOS/nix.git
synced 2025-11-27 20:51:00 +01:00
Use BuildableReq for buildPaths and ensurePath
This avoids an ambiguity where the `StorePathWithOutputs { drvPath, {}
}` could mean "build `brvPath`" or "substitute `drvPath`" depending on
context.
It also brings the internals closer in line to the new CLI, by
generalizing the `Buildable` type is used there and makes that
distinction already.
In doing so, relegate `StorePathWithOutputs` to being a type just for
backwards compatibility (CLI and RPC).
This commit is contained in:
parent
32f4454b9f
commit
255d145ba7
31 changed files with 364 additions and 126 deletions
|
|
@ -73,7 +73,7 @@ DerivationGoal::DerivationGoal(const StorePath & drvPath,
|
|||
state = &DerivationGoal::getDerivation;
|
||||
name = fmt(
|
||||
"building of '%s' from .drv file",
|
||||
StorePathWithOutputs { drvPath, wantedOutputs }.to_string(worker.store));
|
||||
to_string(worker.store, BuildableReqFromDrv { drvPath, wantedOutputs }));
|
||||
trace("created");
|
||||
|
||||
mcExpectedBuilds = std::make_unique<MaintainCount<uint64_t>>(worker.expectedBuilds);
|
||||
|
|
@ -94,7 +94,7 @@ DerivationGoal::DerivationGoal(const StorePath & drvPath, const BasicDerivation
|
|||
state = &DerivationGoal::haveDerivation;
|
||||
name = fmt(
|
||||
"building of '%s' from in-memory derivation",
|
||||
StorePathWithOutputs { drvPath, drv.outputNames() }.to_string(worker.store));
|
||||
to_string(worker.store, BuildableReqFromDrv { drvPath, drv.outputNames() }));
|
||||
trace("created");
|
||||
|
||||
mcExpectedBuilds = std::make_unique<MaintainCount<uint64_t>>(worker.expectedBuilds);
|
||||
|
|
|
|||
|
|
@ -6,16 +6,20 @@
|
|||
|
||||
namespace nix {
|
||||
|
||||
void Store::buildPaths(const std::vector<StorePathWithOutputs> & drvPaths, BuildMode buildMode)
|
||||
void Store::buildPaths(const std::vector<BuildableReq> & reqs, BuildMode buildMode)
|
||||
{
|
||||
Worker worker(*this);
|
||||
|
||||
Goals goals;
|
||||
for (auto & path : drvPaths) {
|
||||
if (path.path.isDerivation())
|
||||
goals.insert(worker.makeDerivationGoal(path.path, path.outputs, buildMode));
|
||||
else
|
||||
goals.insert(worker.makePathSubstitutionGoal(path.path, buildMode == bmRepair ? Repair : NoRepair));
|
||||
for (auto & br : reqs) {
|
||||
std::visit(overloaded {
|
||||
[&](BuildableReqFromDrv bfd) {
|
||||
goals.insert(worker.makeDerivationGoal(bfd.drvPath, bfd.outputs, buildMode));
|
||||
},
|
||||
[&](BuildableOpaque bo) {
|
||||
goals.insert(worker.makePathSubstitutionGoal(bo.path, buildMode == bmRepair ? Repair : NoRepair));
|
||||
},
|
||||
}, br);
|
||||
}
|
||||
|
||||
worker.run(goals);
|
||||
|
|
|
|||
|
|
@ -1190,6 +1190,26 @@ void LocalDerivationGoal::writeStructuredAttrs()
|
|||
chownToBuilder(tmpDir + "/.attrs.sh");
|
||||
}
|
||||
|
||||
|
||||
static StorePath pathPartOfReq(const BuildableReq & req)
|
||||
{
|
||||
return std::visit(overloaded {
|
||||
[&](BuildableOpaque bo) {
|
||||
return bo.path;
|
||||
},
|
||||
[&](BuildableReqFromDrv bfd) {
|
||||
return bfd.drvPath;
|
||||
},
|
||||
}, req);
|
||||
}
|
||||
|
||||
|
||||
bool LocalDerivationGoal::isAllowed(const BuildableReq & req)
|
||||
{
|
||||
return this->isAllowed(pathPartOfReq(req));
|
||||
}
|
||||
|
||||
|
||||
struct RestrictedStoreConfig : virtual LocalFSStoreConfig
|
||||
{
|
||||
using LocalFSStoreConfig::LocalFSStoreConfig;
|
||||
|
|
@ -1312,25 +1332,27 @@ struct RestrictedStore : public virtual RestrictedStoreConfig, public virtual Lo
|
|||
// an allowed derivation
|
||||
{ throw Error("queryRealisation"); }
|
||||
|
||||
void buildPaths(const std::vector<StorePathWithOutputs> & paths, BuildMode buildMode) override
|
||||
void buildPaths(const std::vector<BuildableReq> & paths, BuildMode buildMode) override
|
||||
{
|
||||
if (buildMode != bmNormal) throw Error("unsupported build mode");
|
||||
|
||||
StorePathSet newPaths;
|
||||
|
||||
for (auto & path : paths) {
|
||||
if (!goal.isAllowed(path.path))
|
||||
throw InvalidPath("cannot build unknown path '%s' in recursive Nix", printStorePath(path.path));
|
||||
for (auto & req : paths) {
|
||||
if (!goal.isAllowed(req))
|
||||
throw InvalidPath("cannot build '%s' in recursive Nix because path is unknown", to_string(*next, req));
|
||||
}
|
||||
|
||||
next->buildPaths(paths, buildMode);
|
||||
|
||||
for (auto & path : paths) {
|
||||
if (!path.path.isDerivation()) continue;
|
||||
auto outputs = next->queryDerivationOutputMap(path.path);
|
||||
for (auto & output : outputs)
|
||||
if (wantOutput(output.first, path.outputs))
|
||||
newPaths.insert(output.second);
|
||||
auto p = std::get_if<BuildableReqFromDrv>(&path);
|
||||
if (!p) continue;
|
||||
auto & bfd = *p;
|
||||
auto outputs = next->queryDerivationOutputMap(bfd.drvPath);
|
||||
for (auto & [outputName, outputPath] : outputs)
|
||||
if (wantOutput(outputName, bfd.outputs))
|
||||
newPaths.insert(outputPath);
|
||||
}
|
||||
|
||||
StorePathSet closure;
|
||||
|
|
@ -1358,7 +1380,7 @@ struct RestrictedStore : public virtual RestrictedStoreConfig, public virtual Lo
|
|||
void addSignatures(const StorePath & storePath, const StringSet & sigs) override
|
||||
{ unsupported("addSignatures"); }
|
||||
|
||||
void queryMissing(const std::vector<StorePathWithOutputs> & targets,
|
||||
void queryMissing(const std::vector<BuildableReq> & targets,
|
||||
StorePathSet & willBuild, StorePathSet & willSubstitute, StorePathSet & unknown,
|
||||
uint64_t & downloadSize, uint64_t & narSize) override
|
||||
{
|
||||
|
|
@ -1366,12 +1388,12 @@ struct RestrictedStore : public virtual RestrictedStoreConfig, public virtual Lo
|
|||
client about what paths will be built/substituted or are
|
||||
already present. Probably not a big deal. */
|
||||
|
||||
std::vector<StorePathWithOutputs> allowed;
|
||||
for (auto & path : targets) {
|
||||
if (goal.isAllowed(path.path))
|
||||
allowed.emplace_back(path);
|
||||
std::vector<BuildableReq> allowed;
|
||||
for (auto & req : targets) {
|
||||
if (goal.isAllowed(req))
|
||||
allowed.emplace_back(req);
|
||||
else
|
||||
unknown.insert(path.path);
|
||||
unknown.insert(pathPartOfReq(req));
|
||||
}
|
||||
|
||||
next->queryMissing(allowed, willBuild, willSubstitute,
|
||||
|
|
|
|||
|
|
@ -116,6 +116,7 @@ struct LocalDerivationGoal : public DerivationGoal
|
|||
{
|
||||
return inputPaths.count(path) || addedPaths.count(path);
|
||||
}
|
||||
bool isAllowed(const BuildableReq & req);
|
||||
|
||||
friend struct RestrictedStore;
|
||||
|
||||
|
|
|
|||
|
|
@ -226,14 +226,14 @@ void Worker::waitForAWhile(GoalPtr goal)
|
|||
|
||||
void Worker::run(const Goals & _topGoals)
|
||||
{
|
||||
std::vector<nix::StorePathWithOutputs> topPaths;
|
||||
std::vector<nix::BuildableReq> topPaths;
|
||||
|
||||
for (auto & i : _topGoals) {
|
||||
topGoals.insert(i);
|
||||
if (auto goal = dynamic_cast<DerivationGoal *>(i.get())) {
|
||||
topPaths.push_back({goal->drvPath, goal->wantedOutputs});
|
||||
topPaths.push_back(BuildableReqFromDrv{goal->drvPath, goal->wantedOutputs});
|
||||
} else if (auto goal = dynamic_cast<PathSubstitutionGoal *>(i.get())) {
|
||||
topPaths.push_back({goal->storePath});
|
||||
topPaths.push_back(BuildableOpaque{goal->storePath});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue