aboutsummaryrefslogtreecommitdiff
path: root/src/libstore/build/derivation-goal.hh
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstore/build/derivation-goal.hh')
-rw-r--r--src/libstore/build/derivation-goal.hh235
1 files changed, 171 insertions, 64 deletions
diff --git a/src/libstore/build/derivation-goal.hh b/src/libstore/build/derivation-goal.hh
index 707e38b4b..ee8f06f25 100644
--- a/src/libstore/build/derivation-goal.hh
+++ b/src/libstore/build/derivation-goal.hh
@@ -1,4 +1,5 @@
#pragma once
+///@file
#include "parsed-derivations.hh"
#include "lock.hh"
@@ -15,8 +16,10 @@ struct HookInstance;
typedef enum {rpAccept, rpDecline, rpPostpone} HookReply;
-/* Unless we are repairing, we don't both to test validity and just assume it,
- so the choices are `Absent` or `Valid`. */
+/**
+ * Unless we are repairing, we don't both to test validity and just assume it,
+ * so the choices are `Absent` or `Valid`.
+ */
enum struct PathStatus {
Corrupt,
Absent,
@@ -26,11 +29,15 @@ enum struct PathStatus {
struct InitialOutputStatus {
StorePath path;
PathStatus status;
- /* Valid in the store, and additionally non-corrupt if we are repairing */
+ /**
+ * Valid in the store, and additionally non-corrupt if we are repairing
+ */
bool isValid() const {
return status == PathStatus::Valid;
}
- /* Merely present, allowed to be corrupt */
+ /**
+ * Merely present, allowed to be corrupt
+ */
bool isPresent() const {
return status == PathStatus::Corrupt
|| status == PathStatus::Valid;
@@ -45,59 +52,123 @@ struct InitialOutput {
struct DerivationGoal : public Goal
{
- /* Whether to use an on-disk .drv file. */
+ /**
+ * Whether to use an on-disk .drv file.
+ */
bool useDerivation;
- /* The path of the derivation. */
+ /** The path of the derivation. */
StorePath drvPath;
- /* The goal for the corresponding resolved derivation */
+ /**
+ * The goal for the corresponding resolved derivation
+ */
std::shared_ptr<DerivationGoal> resolvedDrvGoal;
- /* The specific outputs that we need to build. Empty means all of
- them. */
+ /**
+ * The specific outputs that we need to build. Empty means all of
+ * them.
+ */
OutputsSpec wantedOutputs;
- /* Mapping from input derivations + output names to actual store
- paths. This is filled in by waiteeDone() as each dependency
- finishes, before inputsRealised() is reached, */
+ /**
+ * Mapping from input derivations + output names to actual store
+ * paths. This is filled in by waiteeDone() as each dependency
+ * finishes, before inputsRealised() is reached.
+ */
std::map<std::pair<StorePath, std::string>, StorePath> inputDrvOutputs;
- /* Whether additional wanted outputs have been added. */
- bool needRestart = false;
-
- /* Whether to retry substituting the outputs after building the
- inputs. This is done in case of an incomplete closure. */
- bool retrySubstitution = false;
-
- /* Whether we've retried substitution, in which case we won't try
- again. */
- bool retriedSubstitution = false;
-
- /* The derivation stored at drvPath. */
+ /**
+ * See `needRestart`; just for that field.
+ */
+ enum struct NeedRestartForMoreOutputs {
+ /**
+ * The goal state machine is progressing based on the current value of
+ * `wantedOutputs. No actions are needed.
+ */
+ OutputsUnmodifedDontNeed,
+ /**
+ * `wantedOutputs` has been extended, but the state machine is
+ * proceeding according to its old value, so we need to restart.
+ */
+ OutputsAddedDoNeed,
+ /**
+ * The goal state machine has progressed to the point of doing a build,
+ * in which case all outputs will be produced, so extensions to
+ * `wantedOutputs` no longer require a restart.
+ */
+ BuildInProgressWillNotNeed,
+ };
+
+ /**
+ * Whether additional wanted outputs have been added.
+ */
+ NeedRestartForMoreOutputs needRestart = NeedRestartForMoreOutputs::OutputsUnmodifedDontNeed;
+
+ /**
+ * See `retrySubstitution`; just for that field.
+ */
+ enum RetrySubstitution {
+ /**
+ * No issues have yet arose, no need to restart.
+ */
+ NoNeed,
+ /**
+ * Something failed and there is an incomplete closure. Let's retry
+ * substituting.
+ */
+ YesNeed,
+ /**
+ * We are current or have already retried substitution, and whether or
+ * not something goes wrong we will not retry again.
+ */
+ AlreadyRetried,
+ };
+
+ /**
+ * Whether to retry substituting the outputs after building the
+ * inputs. This is done in case of an incomplete closure.
+ */
+ RetrySubstitution retrySubstitution = RetrySubstitution::NoNeed;
+
+ /**
+ * The derivation stored at drvPath.
+ */
std::unique_ptr<Derivation> drv;
std::unique_ptr<ParsedDerivation> parsedDrv;
- /* The remainder is state held during the build. */
+ /**
+ * The remainder is state held during the build.
+ */
- /* Locks on (fixed) output paths. */
+ /**
+ * Locks on (fixed) output paths.
+ */
PathLocks outputLocks;
- /* All input paths (that is, the union of FS closures of the
- immediate input paths). */
+ /**
+ * 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. */
+ /**
+ * File descriptor for the log file.
+ */
AutoCloseFD fdLogFile;
std::shared_ptr<BufferedSink> logFileSink, logSink;
- /* Number of bytes received from the builder's stdout/stderr. */
+ /**
+ * Number of bytes received from the builder's stdout/stderr.
+ */
unsigned long logSize;
- /* The most recent log lines. */
+ /**
+ * The most recent log lines.
+ */
std::list<std::string> logTail;
std::string currentLogLine;
@@ -105,10 +176,14 @@ struct DerivationGoal : public Goal
std::string currentHookLine;
- /* The build hook. */
+ /**
+ * The build hook.
+ */
std::unique_ptr<HookInstance> hook;
- /* The sort of derivation we are building. */
+ /**
+ * The sort of derivation we are building.
+ */
DerivationType derivationType;
typedef void (DerivationGoal::*GoalState)();
@@ -120,12 +195,16 @@ struct DerivationGoal : public Goal
std::unique_ptr<Activity> act;
- /* Activity that denotes waiting for a lock. */
+ /**
+ * 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. */
+ /**
+ * The remote machine on which we're building.
+ */
std::string machineName;
DerivationGoal(const StorePath & drvPath,
@@ -142,10 +221,14 @@ struct DerivationGoal : public Goal
void work() override;
- /* Add wanted outputs to an already existing derivation goal. */
+ /**
+ * Add wanted outputs to an already existing derivation goal.
+ */
void addWantedOutputs(const OutputsSpec & outputs);
- /* The states. */
+ /**
+ * The states.
+ */
void getDerivation();
void loadDerivation();
void haveDerivation();
@@ -159,28 +242,42 @@ struct DerivationGoal : public Goal
void resolvedFinished();
- /* Is the build hook willing to perform the build? */
+ /**
+ * Is the build hook willing to perform the build?
+ */
HookReply tryBuildHook();
virtual int getChildStatus();
- /* Check that the derivation outputs all exist and register them
- as valid. */
- virtual DrvOutputs registerOutputs();
+ /**
+ * Check that the derivation outputs all exist and register them
+ * as valid.
+ */
+ virtual SingleDrvOutputs registerOutputs();
- /* Open a log file and a pipe to it. */
+ /**
+ * Open a log file and a pipe to it.
+ */
Path openLogFile();
- /* Sign the newly built realisation if the store allows it */
+ /**
+ * Sign the newly built realisation if the store allows it
+ */
virtual void signRealisation(Realisation&) {}
- /* Close the log file. */
+ /**
+ * Close the log file.
+ */
void closeLogFile();
- /* Close the read side of the logger pipe. */
+ /**
+ * Close the read side of the logger pipe.
+ */
virtual void closeReadPipes();
- /* Cleanup hooks for buildDone() */
+ /**
+ * Cleanup hooks for buildDone()
+ */
virtual void cleanupHookFinally();
virtual void cleanupPreChildKill();
virtual void cleanupPostChildKill();
@@ -190,30 +287,38 @@ struct DerivationGoal : public Goal
virtual bool isReadDesc(int fd);
- /* Callback used by the worker to write to the log. */
+ /**
+ * Callback used by the worker to write to the log.
+ */
void handleChildOutput(int fd, std::string_view data) override;
void handleEOF(int 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. */
+ /**
+ * 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();
OutputPathMap queryDerivationOutputMap();
- /* 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
- 'DrvOutputs' structure containing the valid and wanted
- outputs. */
- std::pair<bool, DrvOutputs> checkPathValidity();
-
- /* Aborts if any output is not valid or corrupt, and otherwise
- returns a 'DrvOutputs' structure containing the wanted
- outputs. */
- DrvOutputs assertPathValidity();
-
- /* Forcibly kill the child process, if any. */
+ /**
+ * 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.
+ */
virtual void killChild();
void repairClosure();
@@ -222,12 +327,14 @@ struct DerivationGoal : public Goal
void done(
BuildResult::Status status,
- DrvOutputs builtOutputs = {},
+ SingleDrvOutputs builtOutputs = {},
std::optional<Error> ex = {});
void waiteeDone(GoalPtr waitee, ExitCode result) override;
StorePathSet exportReferences(const StorePathSet & storePaths);
+
+ JobCategory jobCategory() override { return JobCategory::Build; };
};
MakeError(NotDeterministic, BuildError);