2020-10-08 18:36:51 +03:00
|
|
|
#pragma once
|
2023-04-01 06:18:41 +03:00
|
|
|
///@file
|
2020-10-08 18:36:51 +03:00
|
|
|
|
2023-01-30 17:12:44 +02:00
|
|
|
#include <variant>
|
|
|
|
|
|
|
|
#include "hash.hh"
|
2020-10-08 18:36:51 +03:00
|
|
|
#include "path.hh"
|
2020-12-08 22:07:52 +02:00
|
|
|
#include <nlohmann/json_fwd.hpp>
|
2021-02-04 16:11:05 +02:00
|
|
|
#include "comparator.hh"
|
2021-03-08 12:56:33 +02:00
|
|
|
#include "crypto.hh"
|
2020-12-14 18:24:30 +02:00
|
|
|
|
2020-10-08 18:36:51 +03:00
|
|
|
namespace nix {
|
|
|
|
|
2023-01-19 15:49:44 +02:00
|
|
|
class Store;
|
2023-01-31 13:51:12 +02:00
|
|
|
struct OutputsSpec;
|
2023-01-19 15:49:44 +02:00
|
|
|
|
2023-04-15 01:18:32 +03:00
|
|
|
/**
|
|
|
|
* A general `Realisation` key.
|
|
|
|
*
|
|
|
|
* This is similar to a `DerivedPath::Opaque`, but the derivation is
|
|
|
|
* identified by its "hash modulo" instead of by its store path.
|
|
|
|
*/
|
2020-10-08 18:36:51 +03:00
|
|
|
struct DrvOutput {
|
2023-04-15 01:18:32 +03:00
|
|
|
/**
|
|
|
|
* The hash modulo of the derivation.
|
|
|
|
*
|
|
|
|
* Computed from the derivation itself for most types of
|
|
|
|
* derivations, but computed from the (fixed) content address of the
|
|
|
|
* output for fixed-output derivations.
|
|
|
|
*/
|
2020-12-09 17:56:56 +02:00
|
|
|
Hash drvHash;
|
2023-04-15 01:18:32 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* The name of the output.
|
|
|
|
*/
|
2020-10-08 18:36:51 +03:00
|
|
|
std::string outputName;
|
|
|
|
|
|
|
|
std::string to_string() const;
|
|
|
|
|
2020-12-09 17:56:56 +02:00
|
|
|
std::string strHash() const
|
|
|
|
{ return drvHash.to_string(Base16, true); }
|
|
|
|
|
2020-10-08 18:36:51 +03:00
|
|
|
static DrvOutput parse(const std::string &);
|
|
|
|
|
2020-12-14 18:24:30 +02:00
|
|
|
GENERATE_CMP(DrvOutput, me->drvHash, me->outputName);
|
2020-10-08 18:36:51 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
struct Realisation {
|
|
|
|
DrvOutput id;
|
|
|
|
StorePath outPath;
|
|
|
|
|
2021-03-08 12:56:33 +02:00
|
|
|
StringSet signatures;
|
|
|
|
|
2021-05-26 17:09:02 +03:00
|
|
|
/**
|
|
|
|
* The realisations that are required for the current one to be valid.
|
|
|
|
*
|
|
|
|
* When importing this realisation, the store will first check that all its
|
|
|
|
* dependencies exist, and map to the correct output path
|
|
|
|
*/
|
|
|
|
std::map<DrvOutput, StorePath> dependentRealisations;
|
2020-11-10 15:49:25 +02:00
|
|
|
|
2020-12-08 22:07:52 +02:00
|
|
|
nlohmann::json toJSON() const;
|
|
|
|
static Realisation fromJSON(const nlohmann::json& json, const std::string& whence);
|
2020-12-14 18:24:30 +02:00
|
|
|
|
2021-03-08 12:56:33 +02:00
|
|
|
std::string fingerprint() const;
|
|
|
|
void sign(const SecretKey &);
|
|
|
|
bool checkSignature(const PublicKeys & publicKeys, const std::string & sig) const;
|
|
|
|
size_t checkSignatures(const PublicKeys & publicKeys) const;
|
|
|
|
|
2021-06-21 17:37:45 +03:00
|
|
|
static std::set<Realisation> closure(Store &, const std::set<Realisation> &);
|
2021-07-19 16:43:08 +03:00
|
|
|
static void closure(Store &, const std::set<Realisation> &, std::set<Realisation> & res);
|
2021-05-19 11:26:58 +03:00
|
|
|
|
2021-05-19 17:19:46 +03:00
|
|
|
bool isCompatibleWith(const Realisation & other) const;
|
|
|
|
|
2020-12-14 18:24:30 +02:00
|
|
|
StorePath getPath() const { return outPath; }
|
|
|
|
|
|
|
|
GENERATE_CMP(Realisation, me->id, me->outPath);
|
|
|
|
};
|
|
|
|
|
2023-04-15 01:18:32 +03:00
|
|
|
/**
|
|
|
|
* Collection type for a single derivation's outputs' `Realisation`s.
|
|
|
|
*
|
|
|
|
* Since these are the outputs of a single derivation, we know the
|
|
|
|
* output names are unique so we can use them as the map key.
|
|
|
|
*/
|
|
|
|
typedef std::map<std::string, Realisation> SingleDrvOutputs;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Collection type for multiple derivations' outputs' `Realisation`s.
|
|
|
|
*
|
|
|
|
* `DrvOutput` is used because in general the derivations are not all
|
|
|
|
* the same, so we need to identify firstly which derivation, and
|
|
|
|
* secondly which output of that derivation.
|
|
|
|
*/
|
2021-01-26 11:48:41 +02:00
|
|
|
typedef std::map<DrvOutput, Realisation> DrvOutputs;
|
|
|
|
|
2023-01-31 13:51:12 +02:00
|
|
|
/**
|
|
|
|
* Filter a SingleDrvOutputs to include only specific output names
|
|
|
|
*
|
|
|
|
* Moves the `outputs` input.
|
|
|
|
*/
|
|
|
|
SingleDrvOutputs filterDrvOutputs(const OutputsSpec&, SingleDrvOutputs&&);
|
|
|
|
|
|
|
|
|
2020-12-14 18:24:30 +02:00
|
|
|
struct OpaquePath {
|
|
|
|
StorePath path;
|
|
|
|
|
|
|
|
StorePath getPath() const { return path; }
|
|
|
|
|
|
|
|
GENERATE_CMP(OpaquePath, me->path);
|
2020-10-08 18:36:51 +03:00
|
|
|
};
|
|
|
|
|
2020-12-14 18:24:30 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* A store path with all the history of how it went into the store
|
|
|
|
*/
|
|
|
|
struct RealisedPath {
|
|
|
|
/*
|
|
|
|
* A path is either the result of the realisation of a derivation or
|
|
|
|
* an opaque blob that has been directly added to the store
|
|
|
|
*/
|
|
|
|
using Raw = std::variant<Realisation, OpaquePath>;
|
|
|
|
Raw raw;
|
|
|
|
|
|
|
|
using Set = std::set<RealisedPath>;
|
|
|
|
|
|
|
|
RealisedPath(StorePath path) : raw(OpaquePath{path}) {}
|
|
|
|
RealisedPath(Realisation r) : raw(r) {}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the raw store path associated to this
|
|
|
|
*/
|
|
|
|
StorePath path() const;
|
|
|
|
|
|
|
|
void closure(Store& store, Set& ret) const;
|
|
|
|
static void closure(Store& store, const Set& startPaths, Set& ret);
|
|
|
|
Set closure(Store& store) const;
|
|
|
|
|
|
|
|
GENERATE_CMP(RealisedPath, me->raw);
|
|
|
|
};
|
2020-10-08 18:36:51 +03:00
|
|
|
|
2023-01-02 18:35:48 +02:00
|
|
|
class MissingRealisation : public Error
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
MissingRealisation(DrvOutput & outputId)
|
|
|
|
: Error( "cannot operate on an output of the "
|
|
|
|
"unbuilt derivation '%s'",
|
|
|
|
outputId.to_string())
|
|
|
|
{}
|
|
|
|
};
|
|
|
|
|
2020-10-08 18:36:51 +03:00
|
|
|
}
|