aboutsummaryrefslogtreecommitdiff
path: root/src/libstore/derivations.hh
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstore/derivations.hh')
-rw-r--r--src/libstore/derivations.hh104
1 files changed, 83 insertions, 21 deletions
diff --git a/src/libstore/derivations.hh b/src/libstore/derivations.hh
index 14e0e947a..2df440536 100644
--- a/src/libstore/derivations.hh
+++ b/src/libstore/derivations.hh
@@ -4,6 +4,7 @@
#include "types.hh"
#include "hash.hh"
#include "content-address.hh"
+#include "sync.hh"
#include <map>
#include <variant>
@@ -17,8 +18,6 @@ namespace nix {
/* The traditional non-fixed-output derivation type. */
struct DerivationOutputInputAddressed
{
- /* Will need to become `std::optional<StorePath>` once input-addressed
- derivations are allowed to depend on cont-addressed derivations */
StorePath path;
};
@@ -27,6 +26,7 @@ struct DerivationOutputInputAddressed
struct DerivationOutputCAFixed
{
FixedOutputHash hash; /* hash used for expected hash computation */
+ StorePath path(const Store & store, std::string_view drvName, std::string_view outputName) const;
};
/* Floating-output derivations, whose output paths are content addressed, but
@@ -39,25 +39,35 @@ struct DerivationOutputCAFloating
HashType hashType;
};
+/* Input-addressed output which depends on a (CA) derivation whose hash isn't
+ * known atm
+ */
+struct DerivationOutputDeferred {};
+
struct DerivationOutput
{
std::variant<
DerivationOutputInputAddressed,
DerivationOutputCAFixed,
- DerivationOutputCAFloating
+ DerivationOutputCAFloating,
+ DerivationOutputDeferred
> output;
- std::optional<HashType> hashAlgoOpt(const Store & store) const;
- std::optional<StorePath> pathOpt(const Store & store, std::string_view drvName) const;
- /* DEPRECATED: Remove after CA drvs are fully implemented */
- StorePath path(const Store & store, std::string_view drvName) const {
- auto p = pathOpt(store, drvName);
- if (!p) throw UnimplementedError("floating content-addressed derivations are not yet implemented");
- return *p;
- }
+
+ /* Note, when you use this function you should make sure that you're passing
+ the right derivation name. When in doubt, you should use the safer
+ interface provided by BasicDerivation::outputsAndOptPaths */
+ std::optional<StorePath> path(const Store & store, std::string_view drvName, std::string_view outputName) const;
};
typedef std::map<string, DerivationOutput> DerivationOutputs;
+/* These are analogues to the previous DerivationOutputs data type, but they
+ also contains, for each output, the (optional) store path in which it would
+ be written. To calculate values of these types, see the corresponding
+ functions in BasicDerivation */
+typedef std::map<string, std::pair<DerivationOutput, std::optional<StorePath>>>
+ DerivationOutputsAndOptPaths;
+
/* For inputs that are sub-derivations, we specify exactly which
output IDs we are interested in. */
typedef std::map<StorePath, StringSet> DerivationInputs;
@@ -66,6 +76,7 @@ typedef std::map<string, string> StringPairs;
enum struct DerivationType : uint8_t {
InputAddressed,
+ DeferredInputAddressed,
CAFixed,
CAFloating,
};
@@ -83,6 +94,11 @@ bool derivationIsFixed(DerivationType);
derivation is controlled separately. Never true for non-CA derivations. */
bool derivationIsImpure(DerivationType);
+/* Does the derivation knows its own output paths?
+ * Only true when there's no floating-ca derivation involved in the closure.
+ */
+bool derivationHasKnownOutputPaths(DerivationType);
+
struct BasicDerivation
{
DerivationOutputs outputs; /* keyed on symbolic IDs */
@@ -93,7 +109,7 @@ struct BasicDerivation
StringPairs env;
std::string name;
- BasicDerivation() { }
+ BasicDerivation() = default;
virtual ~BasicDerivation() { };
bool isBuiltin() const;
@@ -101,12 +117,14 @@ struct BasicDerivation
/* Return true iff this is a fixed-output derivation. */
DerivationType type() const;
- /* Return the output paths of a derivation. */
- StorePathSet outputPaths(const Store & store) const;
-
/* Return the output names of a derivation. */
StringSet outputNames() const;
+ /* Calculates the maps that contains all the DerivationOutputs, but
+ augmented with knowledge of the Store paths they would be written
+ into. */
+ DerivationOutputsAndOptPaths outputsAndOptPaths(const Store & store) const;
+
static std::string_view nameFromPath(const StorePath & storePath);
};
@@ -118,7 +136,17 @@ struct Derivation : BasicDerivation
std::string unparse(const Store & store, bool maskOutputs,
std::map<std::string, StringSet> * actualInputs = nullptr) const;
- Derivation() { }
+ /* Return the underlying basic derivation but with these changes:
+
+ 1. Input drvs are emptied, but the outputs of them that were used are
+ added directly to input sources.
+
+ 2. Input placeholders are replaced with realized input store paths. */
+ std::optional<BasicDerivation> tryResolve(Store & store);
+
+ Derivation() = default;
+ Derivation(const BasicDerivation & bd) : BasicDerivation(bd) { }
+ Derivation(BasicDerivation && bd) : BasicDerivation(std::move(bd)) { }
};
@@ -127,22 +155,34 @@ class Store;
enum RepairFlag : bool { NoRepair = false, Repair = true };
/* Write a derivation to the Nix store, and return its path. */
-StorePath writeDerivation(ref<Store> store,
- const Derivation & drv, std::string_view name, RepairFlag repair = NoRepair);
+StorePath writeDerivation(Store & store,
+ const Derivation & drv,
+ RepairFlag repair = NoRepair,
+ bool readOnly = false);
/* Read a derivation from a file. */
-Derivation readDerivation(const Store & store, const Path & drvPath, std::string_view name);
+Derivation parseDerivation(const Store & store, std::string && s, std::string_view name);
// FIXME: remove
bool isDerivation(const string & fileName);
+/* Calculate the name that will be used for the store path for this
+ output.
+
+ This is usually <drv-name>-<output-name>, but is just <drv-name> when
+ the output name is "out". */
+std::string outputPathName(std::string_view drvName, std::string_view outputName);
+
// known CA drv's output hashes, current just for fixed-output derivations
// whose output hashes are always known since they are fixed up-front.
typedef std::map<std::string, Hash> CaOutputHashes;
+struct DeferredHash { Hash hash; };
+
typedef std::variant<
Hash, // regular DRV normalized hash
- CaOutputHashes
+ CaOutputHashes, // Fixed-output derivation hashes
+ DeferredHash // Deferred hashes for floating outputs drvs and their dependencies
> DrvHashModulo;
/* Returns hashes with the details of fixed-output subderivations
@@ -170,10 +210,17 @@ typedef std::variant<
*/
DrvHashModulo hashDerivationModulo(Store & store, const Derivation & drv, bool maskOutputs);
+/*
+ Return a map associating each output to a hash that uniquely identifies its
+ derivation (modulo the self-references).
+ */
+std::map<std::string, Hash> staticOutputHashes(Store& store, const Derivation& drv);
+
/* Memoisation of hashDerivationModulo(). */
typedef std::map<StorePath, DrvHashModulo> DrvHashes;
-extern DrvHashes drvHashes; // FIXME: global, not thread-safe
+// FIXME: global, though at least thread-safe.
+extern Sync<DrvHashes> drvHashes;
bool wantOutput(const string & output, const std::set<string> & wanted);
@@ -183,6 +230,21 @@ struct Sink;
Source & readDerivation(Source & in, const Store & store, BasicDerivation & drv, std::string_view name);
void writeDerivation(Sink & out, const Store & store, const BasicDerivation & drv);
+/* This creates an opaque and almost certainly unique string
+ deterministically from the output name.
+
+ It is used as a placeholder to allow derivations to refer to their
+ own outputs without needing to use the hash of a derivation in
+ itself, making the hash near-impossible to calculate. */
std::string hashPlaceholder(const std::string & outputName);
+/* This creates an opaque and almost certainly unique string
+ deterministically from a derivation path and output name.
+
+ It is used as a placeholder to allow derivations to refer to
+ content-addressed paths whose content --- and thus the path
+ themselves --- isn't yet known. This occurs when a derivation has a
+ dependency which is a CA derivation. */
+std::string downstreamPlaceholder(const Store & store, const StorePath & drvPath, std::string_view outputName);
+
}