Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions maintainers/flake-module.nix
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,8 @@
''^src/libstore/store-api\.cc$''
''^src/libstore/include/nix/store/store-api\.hh$''
''^src/libstore/include/nix/store/store-dir-config\.hh$''
''^src/libstore/build/derivation-building-goal\.cc$''
''^src/libstore/include/nix/store/build/derivation-building-goal\.hh$''
''^src/libstore/build/derivation-goal\.cc$''
''^src/libstore/include/nix/store/build/derivation-goal\.hh$''
''^src/libstore/build/drv-output-substitution-goal\.cc$''
Expand Down
1,251 changes: 1,251 additions & 0 deletions src/libstore/build/derivation-building-goal.cc

Large diffs are not rendered by default.

1,104 changes: 39 additions & 1,065 deletions src/libstore/build/derivation-goal.cc

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/libstore/build/goal.cc
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ Goal::Done Goal::amDone(ExitCode result, std::optional<Error> ex)
exitCode = result;

if (ex) {
if (!waiters.empty())
if (!preserveException && !waiters.empty())
logError(ex->info());
else
this->ex = std::move(*ex);
Expand Down
26 changes: 24 additions & 2 deletions src/libstore/build/worker.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "nix/store/build/substitution-goal.hh"
#include "nix/store/build/drv-output-substitution-goal.hh"
#include "nix/store/build/derivation-goal.hh"
#include "nix/store/build/derivation-building-goal.hh"
#ifndef _WIN32 // TODO Enable building on Windows
# include "nix/store/build/hook-instance.hh"
#endif
Expand Down Expand Up @@ -87,6 +88,20 @@ std::shared_ptr<DerivationGoal> Worker::makeBasicDerivationGoal(const StorePath
}


std::shared_ptr<DerivationBuildingGoal> Worker::makeDerivationBuildingGoal(const StorePath & drvPath,
const Derivation & drv, BuildMode buildMode)
{
std::weak_ptr<DerivationBuildingGoal> & goal_weak = derivationBuildingGoals[drvPath];
auto goal = goal_weak.lock(); // FIXME
if (!goal) {
goal = std::make_shared<DerivationBuildingGoal>(drvPath, drv, *this, buildMode);
goal_weak = goal;
wakeUp(goal);
}
return goal;
}


std::shared_ptr<PathSubstitutionGoal> Worker::makePathSubstitutionGoal(const StorePath & path, RepairFlag repair, std::optional<ContentAddress> ca)
{
return initGoalIfNeeded(substitutionGoals[path], path, *this, repair, ca);
Expand Down Expand Up @@ -134,8 +149,9 @@ void Worker::removeGoal(GoalPtr goal)
{
if (auto drvGoal = std::dynamic_pointer_cast<DerivationGoal>(goal))
nix::removeGoal(drvGoal, derivationGoals);
else
if (auto subGoal = std::dynamic_pointer_cast<PathSubstitutionGoal>(goal))
else if (auto drvBuildingGoal = std::dynamic_pointer_cast<DerivationBuildingGoal>(goal))
nix::removeGoal(drvBuildingGoal, derivationBuildingGoals);
else if (auto subGoal = std::dynamic_pointer_cast<PathSubstitutionGoal>(goal))
nix::removeGoal(subGoal, substitutionGoals);
else if (auto subGoal = std::dynamic_pointer_cast<DrvOutputSubstitutionGoal>(goal))
nix::removeGoal(subGoal, drvOutputSubstitutionGoals);
Expand Down Expand Up @@ -198,6 +214,9 @@ void Worker::childStarted(GoalPtr goal, const std::set<MuxablePipePollState::Com
case JobCategory::Build:
nrLocalBuilds++;
break;
case JobCategory::Administration:
/* Intentionally not limited, see docs */
break;
default:
unreachable();
}
Expand All @@ -221,6 +240,9 @@ void Worker::childTerminated(Goal * goal, bool wakeSleepers)
assert(nrLocalBuilds > 0);
nrLocalBuilds--;
break;
case JobCategory::Administration:
/* Intentionally not limited, see docs */
break;
default:
unreachable();
}
Expand Down
194 changes: 194 additions & 0 deletions src/libstore/include/nix/store/build/derivation-building-goal.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
#pragma once
///@file

#include "nix/store/parsed-derivations.hh"
#include "nix/store/derivations.hh"
#include "nix/store/derivation-options.hh"
#include "nix/store/build/derivation-building-misc.hh"
#include "nix/store/outputs-spec.hh"
#include "nix/store/store-api.hh"
#include "nix/store/pathlocks.hh"
#include "nix/store/build/goal.hh"

namespace nix {

using std::map;

#ifndef _WIN32 // TODO enable build hook on Windows
struct HookInstance;
struct DerivationBuilder;
#endif

typedef enum {rpAccept, rpDecline, rpPostpone} HookReply;

/** Used internally */
void runPostBuildHook(
Store & store,
Logger & logger,
const StorePath & drvPath,
const StorePathSet & outputPaths);

/**
* A goal for building some or all of the outputs of a derivation.
*/
struct DerivationBuildingGoal : public Goal
{
/** The path of the derivation. */
StorePath drvPath;

/**
* The derivation stored at drvPath.
*/
std::unique_ptr<Derivation> drv;

std::unique_ptr<StructuredAttrs> parsedDrv;
std::unique_ptr<DerivationOptions> drvOptions;

/**
* The remainder is state held during the build.
*/

/**
* Locks on (fixed) output paths.
*/
PathLocks outputLocks;

/**
* All input paths (that is, the union of FS closures of the
* immediate input paths).
*/
StorePathSet inputPaths;

std::map<std::string, InitialOutput> initialOutputs;

/**
* File descriptor for the log file.
*/
AutoCloseFD fdLogFile;
std::shared_ptr<BufferedSink> logFileSink, logSink;

/**
* Number of bytes received from the builder's stdout/stderr.
*/
unsigned long logSize;

/**
* The most recent log lines.
*/
std::list<std::string> logTail;

std::string currentLogLine;
size_t currentLogLinePos = 0; // to handle carriage return

std::string currentHookLine;

#ifndef _WIN32 // TODO enable build hook on Windows
/**
* The build hook.
*/
std::unique_ptr<HookInstance> hook;

std::unique_ptr<DerivationBuilder> builder;
#endif

BuildMode buildMode;

std::unique_ptr<MaintainCount<uint64_t>> mcRunningBuilds;

std::unique_ptr<Activity> act;

/**
* Activity that denotes waiting for a lock.
*/
std::unique_ptr<Activity> actLock;

std::map<ActivityId, Activity> builderActivities;

/**
* The remote machine on which we're building.
*/
std::string machineName;

DerivationBuildingGoal(const StorePath & drvPath, const Derivation & drv,
Worker & worker,
BuildMode buildMode = bmNormal);
~DerivationBuildingGoal();

void timedOut(Error && ex) override;

std::string key() override;

/**
* The states.
*/
Co gaveUpOnSubstitution();
Co tryToBuild();
Co hookDone();

/**
* Is the build hook willing to perform the build?
*/
HookReply tryBuildHook();

/**
* Open a log file and a pipe to it.
*/
Path openLogFile();

/**
* Close the log file.
*/
void closeLogFile();

bool isReadDesc(Descriptor fd);

/**
* Callback used by the worker to write to the log.
*/
void handleChildOutput(Descriptor fd, std::string_view data) override;
void handleEOF(Descriptor fd) override;
void flushLine();

/**
* Wrappers around the corresponding Store methods that first consult the
* derivation. This is currently needed because when there is no drv file
* there also is no DB entry.
*/
std::map<std::string, std::optional<StorePath>> queryPartialDerivationOutputMap();

/**
* Update 'initialOutputs' to determine the current status of the
* outputs of the derivation. Also returns a Boolean denoting
* whether all outputs are valid and non-corrupt, and a
* 'SingleDrvOutputs' structure containing the valid outputs.
*/
std::pair<bool, SingleDrvOutputs> checkPathValidity();

/**
* Aborts if any output is not valid or corrupt, and otherwise
* returns a 'SingleDrvOutputs' structure containing all outputs.
*/
SingleDrvOutputs assertPathValidity();

/**
* Forcibly kill the child process, if any.
*/
void killChild();

void started();

Done done(
BuildResult::Status status,
SingleDrvOutputs builtOutputs = {},
std::optional<Error> ex = {});

void appendLogTailErrorMsg(std::string & msg);

StorePathSet exportReferences(const StorePathSet & storePaths);

JobCategory jobCategory() const override {
return JobCategory::Build;
};
};

}
Loading
Loading