mirror of
https://github.com/NixOS/nix.git
synced 2025-12-04 16:10:59 +01:00
Merge branch 'path-info' into ca-drv-exotic
This commit is contained in:
commit
7c82213813
97 changed files with 1868 additions and 1001 deletions
|
|
@ -63,7 +63,7 @@
|
|||
namespace nix {
|
||||
|
||||
DerivationGoal::DerivationGoal(const StorePath & drvPath,
|
||||
const StringSet & wantedOutputs, Worker & worker, BuildMode buildMode)
|
||||
const OutputsSpec & wantedOutputs, Worker & worker, BuildMode buildMode)
|
||||
: Goal(worker, DerivedPath::Built { .drvPath = drvPath, .outputs = wantedOutputs })
|
||||
, useDerivation(true)
|
||||
, drvPath(drvPath)
|
||||
|
|
@ -82,7 +82,7 @@ DerivationGoal::DerivationGoal(const StorePath & drvPath,
|
|||
|
||||
|
||||
DerivationGoal::DerivationGoal(const StorePath & drvPath, const BasicDerivation & drv,
|
||||
const StringSet & wantedOutputs, Worker & worker, BuildMode buildMode)
|
||||
const OutputsSpec & wantedOutputs, Worker & worker, BuildMode buildMode)
|
||||
: Goal(worker, DerivedPath::Built { .drvPath = drvPath, .outputs = wantedOutputs })
|
||||
, useDerivation(false)
|
||||
, drvPath(drvPath)
|
||||
|
|
@ -142,18 +142,12 @@ void DerivationGoal::work()
|
|||
(this->*state)();
|
||||
}
|
||||
|
||||
void DerivationGoal::addWantedOutputs(const StringSet & outputs)
|
||||
void DerivationGoal::addWantedOutputs(const OutputsSpec & outputs)
|
||||
{
|
||||
/* If we already want all outputs, there is nothing to do. */
|
||||
if (wantedOutputs.empty()) return;
|
||||
|
||||
if (outputs.empty()) {
|
||||
wantedOutputs.clear();
|
||||
auto newWanted = wantedOutputs.union_(outputs);
|
||||
if (!newWanted.isSubsetOf(wantedOutputs))
|
||||
needRestart = true;
|
||||
} else
|
||||
for (auto & i : outputs)
|
||||
if (wantedOutputs.insert(i).second)
|
||||
needRestart = true;
|
||||
wantedOutputs = newWanted;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -390,7 +384,7 @@ void DerivationGoal::repairClosure()
|
|||
auto outputs = queryDerivationOutputMap();
|
||||
StorePathSet outputClosure;
|
||||
for (auto & i : outputs) {
|
||||
if (!wantOutput(i.first, wantedOutputs)) continue;
|
||||
if (!wantedOutputs.contains(i.first)) continue;
|
||||
worker.store.computeFSClosure(i.second, outputClosure);
|
||||
}
|
||||
|
||||
|
|
@ -422,7 +416,7 @@ void DerivationGoal::repairClosure()
|
|||
if (drvPath2 == outputsToDrv.end())
|
||||
addWaitee(upcast_goal(worker.makePathSubstitutionGoal(i, Repair)));
|
||||
else
|
||||
addWaitee(worker.makeDerivationGoal(drvPath2->second, StringSet(), bmRepair));
|
||||
addWaitee(worker.makeDerivationGoal(drvPath2->second, OutputsSpec::All(), bmRepair));
|
||||
}
|
||||
|
||||
if (waitees.empty()) {
|
||||
|
|
@ -991,10 +985,15 @@ void DerivationGoal::resolvedFinished()
|
|||
|
||||
StorePathSet outputPaths;
|
||||
|
||||
// `wantedOutputs` might be empty, which means “all the outputs”
|
||||
auto realWantedOutputs = wantedOutputs;
|
||||
if (realWantedOutputs.empty())
|
||||
realWantedOutputs = resolvedDrv.outputNames();
|
||||
// `wantedOutputs` might merely indicate “all the outputs”
|
||||
auto realWantedOutputs = std::visit(overloaded {
|
||||
[&](const OutputsSpec::All &) {
|
||||
return resolvedDrv.outputNames();
|
||||
},
|
||||
[&](const OutputsSpec::Names & names) {
|
||||
return static_cast<std::set<std::string>>(names);
|
||||
},
|
||||
}, wantedOutputs.raw());
|
||||
|
||||
for (auto & wantedOutput : realWantedOutputs) {
|
||||
auto initialOutput = get(initialOutputs, wantedOutput);
|
||||
|
|
@ -1322,7 +1321,14 @@ std::pair<bool, DrvOutputs> DerivationGoal::checkPathValidity()
|
|||
if (!drv->type().isPure()) return { false, {} };
|
||||
|
||||
bool checkHash = buildMode == bmRepair;
|
||||
auto wantedOutputsLeft = wantedOutputs;
|
||||
auto wantedOutputsLeft = std::visit(overloaded {
|
||||
[&](const OutputsSpec::All &) {
|
||||
return StringSet {};
|
||||
},
|
||||
[&](const OutputsSpec::Names & names) {
|
||||
return static_cast<StringSet>(names);
|
||||
},
|
||||
}, wantedOutputs.raw());
|
||||
DrvOutputs validOutputs;
|
||||
|
||||
for (auto & i : queryPartialDerivationOutputMap()) {
|
||||
|
|
@ -1331,7 +1337,7 @@ std::pair<bool, DrvOutputs> DerivationGoal::checkPathValidity()
|
|||
// this is an invalid output, gets catched with (!wantedOutputsLeft.empty())
|
||||
continue;
|
||||
auto & info = *initialOutput;
|
||||
info.wanted = wantOutput(i.first, wantedOutputs);
|
||||
info.wanted = wantedOutputs.contains(i.first);
|
||||
if (info.wanted)
|
||||
wantedOutputsLeft.erase(i.first);
|
||||
if (i.second) {
|
||||
|
|
@ -1369,7 +1375,7 @@ std::pair<bool, DrvOutputs> DerivationGoal::checkPathValidity()
|
|||
validOutputs.emplace(drvOutput, Realisation { drvOutput, info.known->path });
|
||||
}
|
||||
|
||||
// If we requested all the outputs via the empty set, we are always fine.
|
||||
// If we requested all the outputs, we are always fine.
|
||||
// If we requested specific elements, the loop above removes all the valid
|
||||
// ones, so any that are left must be invalid.
|
||||
if (!wantedOutputsLeft.empty())
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include "parsed-derivations.hh"
|
||||
#include "lock.hh"
|
||||
#include "outputs-spec.hh"
|
||||
#include "store-api.hh"
|
||||
#include "pathlocks.hh"
|
||||
#include "goal.hh"
|
||||
|
|
@ -55,7 +56,7 @@ struct DerivationGoal : public Goal
|
|||
|
||||
/* The specific outputs that we need to build. Empty means all of
|
||||
them. */
|
||||
StringSet wantedOutputs;
|
||||
OutputsSpec wantedOutputs;
|
||||
|
||||
/* Mapping from input derivations + output names to actual store
|
||||
paths. This is filled in by waiteeDone() as each dependency
|
||||
|
|
@ -128,10 +129,10 @@ struct DerivationGoal : public Goal
|
|||
std::string machineName;
|
||||
|
||||
DerivationGoal(const StorePath & drvPath,
|
||||
const StringSet & wantedOutputs, Worker & worker,
|
||||
const OutputsSpec & wantedOutputs, Worker & worker,
|
||||
BuildMode buildMode = bmNormal);
|
||||
DerivationGoal(const StorePath & drvPath, const BasicDerivation & drv,
|
||||
const StringSet & wantedOutputs, Worker & worker,
|
||||
const OutputsSpec & wantedOutputs, Worker & worker,
|
||||
BuildMode buildMode = bmNormal);
|
||||
virtual ~DerivationGoal();
|
||||
|
||||
|
|
@ -142,7 +143,7 @@ struct DerivationGoal : public Goal
|
|||
void work() override;
|
||||
|
||||
/* Add wanted outputs to an already existing derivation goal. */
|
||||
void addWantedOutputs(const StringSet & outputs);
|
||||
void addWantedOutputs(const OutputsSpec & outputs);
|
||||
|
||||
/* The states. */
|
||||
void getDerivation();
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ BuildResult Store::buildDerivation(const StorePath & drvPath, const BasicDerivat
|
|||
BuildMode buildMode)
|
||||
{
|
||||
Worker worker(*this, *this);
|
||||
auto goal = worker.makeBasicDerivationGoal(drvPath, drv, {}, buildMode);
|
||||
auto goal = worker.makeBasicDerivationGoal(drvPath, drv, OutputsSpec::All {}, buildMode);
|
||||
|
||||
try {
|
||||
worker.run(Goals{goal});
|
||||
|
|
@ -89,7 +89,10 @@ BuildResult Store::buildDerivation(const StorePath & drvPath, const BasicDerivat
|
|||
return BuildResult {
|
||||
.status = BuildResult::MiscFailure,
|
||||
.errorMsg = e.msg(),
|
||||
.path = DerivedPath::Built { .drvPath = drvPath },
|
||||
.path = DerivedPath::Built {
|
||||
.drvPath = drvPath,
|
||||
.outputs = OutputsSpec::All { },
|
||||
},
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -130,7 +133,8 @@ void LocalStore::repairPath(const StorePath & path)
|
|||
auto info = queryPathInfo(path);
|
||||
if (info->deriver && isValidPath(*info->deriver)) {
|
||||
goals.clear();
|
||||
goals.insert(worker.makeDerivationGoal(*info->deriver, StringSet(), bmRepair));
|
||||
// FIXME: Should just build the specific output we need.
|
||||
goals.insert(worker.makeDerivationGoal(*info->deriver, OutputsSpec::All { }, bmRepair));
|
||||
worker.run(goals);
|
||||
} else
|
||||
throw Error(worker.exitStatus(), "cannot repair path '%s'", printStorePath(path));
|
||||
|
|
|
|||
|
|
@ -1459,7 +1459,7 @@ struct RestrictedStore : public virtual RestrictedStoreConfig, public virtual Lo
|
|||
unknown, downloadSize, narSize);
|
||||
}
|
||||
|
||||
virtual std::optional<std::string> getBuildLog(const StorePath & path) override
|
||||
virtual std::optional<std::string> getBuildLogExact(const StorePath & path) override
|
||||
{ return std::nullopt; }
|
||||
|
||||
virtual void addBuildLog(const StorePath & path, std::string_view log) override
|
||||
|
|
@ -2529,7 +2529,10 @@ DrvOutputs LocalDerivationGoal::registerOutputs()
|
|||
auto narHashAndSize = hashPath(htSHA256, actualPath);
|
||||
ValidPathInfo newInfo0 { requiredFinalPath, narHashAndSize.first };
|
||||
newInfo0.narSize = narHashAndSize.second;
|
||||
newInfo0.references = rewriteRefs();
|
||||
auto refs = rewriteRefs();
|
||||
newInfo0.references = std::move(refs.others);
|
||||
if (refs.self)
|
||||
newInfo0.references.insert(newInfo0.path);
|
||||
return newInfo0;
|
||||
},
|
||||
|
||||
|
|
@ -2738,7 +2741,7 @@ DrvOutputs LocalDerivationGoal::registerOutputs()
|
|||
signRealisation(thisRealisation);
|
||||
worker.store.registerDrvOutput(thisRealisation);
|
||||
}
|
||||
if (wantOutput(outputName, wantedOutputs))
|
||||
if (wantedOutputs.contains(outputName))
|
||||
builtOutputs.emplace(thisRealisation.id, thisRealisation);
|
||||
}
|
||||
|
||||
|
|
@ -2786,12 +2789,12 @@ void LocalDerivationGoal::checkOutputs(const std::map<std::string, ValidPathInfo
|
|||
auto i = outputsByPath.find(worker.store.printStorePath(path));
|
||||
if (i != outputsByPath.end()) {
|
||||
closureSize += i->second.narSize;
|
||||
for (auto & ref : i->second.referencesPossiblyToSelf())
|
||||
for (auto & ref : i->second.references)
|
||||
pathsLeft.push(ref);
|
||||
} else {
|
||||
auto info = worker.store.queryPathInfo(path);
|
||||
closureSize += info->narSize;
|
||||
for (auto & ref : info->referencesPossiblyToSelf())
|
||||
for (auto & ref : info->references)
|
||||
pathsLeft.push(ref);
|
||||
}
|
||||
}
|
||||
|
|
@ -2831,7 +2834,7 @@ void LocalDerivationGoal::checkOutputs(const std::map<std::string, ValidPathInfo
|
|||
|
||||
auto used = recursive
|
||||
? getClosure(info.path).first
|
||||
: info.referencesPossiblyToSelf();
|
||||
: info.references;
|
||||
|
||||
if (recursive && checks.ignoreSelfRefs)
|
||||
used.erase(info.path);
|
||||
|
|
|
|||
|
|
@ -165,8 +165,9 @@ void PathSubstitutionGoal::tryNext()
|
|||
|
||||
/* To maintain the closure invariant, we first have to realise the
|
||||
paths referenced by this one. */
|
||||
for (auto & i : info->references.others)
|
||||
addWaitee(worker.makePathSubstitutionGoal(i));
|
||||
for (auto & i : info->references)
|
||||
if (i != storePath) /* ignore self-references */
|
||||
addWaitee(worker.makePathSubstitutionGoal(i));
|
||||
|
||||
if (waitees.empty()) /* to prevent hang (no wake-up event) */
|
||||
referencesValid();
|
||||
|
|
@ -187,8 +188,9 @@ void PathSubstitutionGoal::referencesValid()
|
|||
return;
|
||||
}
|
||||
|
||||
for (auto & i : info->references.others)
|
||||
assert(worker.store.isValidPath(i));
|
||||
for (auto & i : info->references)
|
||||
if (i != storePath) /* ignore self-references */
|
||||
assert(worker.store.isValidPath(i));
|
||||
|
||||
state = &PathSubstitutionGoal::tryToRun;
|
||||
worker.wakeUp(shared_from_this());
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ Worker::~Worker()
|
|||
|
||||
std::shared_ptr<DerivationGoal> Worker::makeDerivationGoalCommon(
|
||||
const StorePath & drvPath,
|
||||
const StringSet & wantedOutputs,
|
||||
const OutputsSpec & wantedOutputs,
|
||||
std::function<std::shared_ptr<DerivationGoal>()> mkDrvGoal)
|
||||
{
|
||||
std::weak_ptr<DerivationGoal> & goal_weak = derivationGoals[drvPath];
|
||||
|
|
@ -59,7 +59,7 @@ std::shared_ptr<DerivationGoal> Worker::makeDerivationGoalCommon(
|
|||
|
||||
|
||||
std::shared_ptr<DerivationGoal> Worker::makeDerivationGoal(const StorePath & drvPath,
|
||||
const StringSet & wantedOutputs, BuildMode buildMode)
|
||||
const OutputsSpec & wantedOutputs, BuildMode buildMode)
|
||||
{
|
||||
return makeDerivationGoalCommon(drvPath, wantedOutputs, [&]() -> std::shared_ptr<DerivationGoal> {
|
||||
return !dynamic_cast<LocalStore *>(&store)
|
||||
|
|
@ -70,7 +70,7 @@ std::shared_ptr<DerivationGoal> Worker::makeDerivationGoal(const StorePath & drv
|
|||
|
||||
|
||||
std::shared_ptr<DerivationGoal> Worker::makeBasicDerivationGoal(const StorePath & drvPath,
|
||||
const BasicDerivation & drv, const StringSet & wantedOutputs, BuildMode buildMode)
|
||||
const BasicDerivation & drv, const OutputsSpec & wantedOutputs, BuildMode buildMode)
|
||||
{
|
||||
return makeDerivationGoalCommon(drvPath, wantedOutputs, [&]() -> std::shared_ptr<DerivationGoal> {
|
||||
return !dynamic_cast<LocalStore *>(&store)
|
||||
|
|
|
|||
|
|
@ -140,15 +140,15 @@ public:
|
|||
/* derivation goal */
|
||||
private:
|
||||
std::shared_ptr<DerivationGoal> makeDerivationGoalCommon(
|
||||
const StorePath & drvPath, const StringSet & wantedOutputs,
|
||||
const StorePath & drvPath, const OutputsSpec & wantedOutputs,
|
||||
std::function<std::shared_ptr<DerivationGoal>()> mkDrvGoal);
|
||||
public:
|
||||
std::shared_ptr<DerivationGoal> makeDerivationGoal(
|
||||
const StorePath & drvPath,
|
||||
const StringSet & wantedOutputs, BuildMode buildMode = bmNormal);
|
||||
const OutputsSpec & wantedOutputs, BuildMode buildMode = bmNormal);
|
||||
std::shared_ptr<DerivationGoal> makeBasicDerivationGoal(
|
||||
const StorePath & drvPath, const BasicDerivation & drv,
|
||||
const StringSet & wantedOutputs, BuildMode buildMode = bmNormal);
|
||||
const OutputsSpec & wantedOutputs, BuildMode buildMode = bmNormal);
|
||||
|
||||
/* substitution goal */
|
||||
std::shared_ptr<PathSubstitutionGoal> makePathSubstitutionGoal(const StorePath & storePath, RepairFlag repair = NoRepair, std::optional<ContentAddress> ca = std::nullopt);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue