2020-06-01 21:32:27 +00:00
|
|
|
|
#pragma once
|
|
|
|
|
|
2020-06-01 22:53:31 +00:00
|
|
|
|
#include <variant>
|
2020-06-01 21:32:27 +00:00
|
|
|
|
#include "hash.hh"
|
2020-10-07 13:52:20 +00:00
|
|
|
|
#include "path.hh"
|
2022-03-25 22:40:40 +00:00
|
|
|
|
#include "comparator.hh"
|
2020-06-01 21:32:27 +00:00
|
|
|
|
|
|
|
|
|
namespace nix {
|
|
|
|
|
|
2020-10-07 13:52:20 +00:00
|
|
|
|
/*
|
2020-10-13 03:30:14 +00:00
|
|
|
|
* Content addressing method
|
2020-10-07 13:52:20 +00:00
|
|
|
|
*/
|
|
|
|
|
|
2020-10-12 23:51:23 +00:00
|
|
|
|
/* We only have one way to hash text with references, so this is a single-value
|
|
|
|
|
type, mainly useful with std::variant.
|
|
|
|
|
*/
|
2023-03-30 20:28:53 +00:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* The single way we can serialize "text" file system objects.
|
|
|
|
|
*
|
|
|
|
|
* Somewhat obscure, used by \ref Derivation derivations and
|
|
|
|
|
* `builtins.toFile` currently.
|
|
|
|
|
*/
|
2020-10-12 23:51:23 +00:00
|
|
|
|
struct TextHashMethod : std::monostate { };
|
|
|
|
|
|
2023-03-25 23:12:44 +00:00
|
|
|
|
/**
|
2023-03-30 20:28:53 +00:00
|
|
|
|
* An enumeration of the main ways we can serialize file system
|
|
|
|
|
* objects.
|
2023-03-25 23:12:44 +00:00
|
|
|
|
*/
|
2020-06-01 21:32:27 +00:00
|
|
|
|
enum struct FileIngestionMethod : uint8_t {
|
2023-03-25 23:12:44 +00:00
|
|
|
|
/**
|
|
|
|
|
* Flat-file hashing. Directly ingest the contents of a single file
|
|
|
|
|
*/
|
2020-06-01 21:32:27 +00:00
|
|
|
|
Flat = false,
|
2023-03-25 23:12:44 +00:00
|
|
|
|
/**
|
|
|
|
|
* Recursive (or NAR) hashing. Serializes the file-system object in Nix
|
|
|
|
|
* Archive format and ingest that
|
|
|
|
|
*/
|
2020-06-01 21:32:27 +00:00
|
|
|
|
Recursive = true
|
|
|
|
|
};
|
|
|
|
|
|
2023-03-30 20:28:53 +00:00
|
|
|
|
/**
|
|
|
|
|
* Compute the prefix to the hash algorithm which indicates how the
|
|
|
|
|
* files were ingested.
|
|
|
|
|
*/
|
2020-10-12 23:51:23 +00:00
|
|
|
|
std::string makeFileIngestionPrefix(FileIngestionMethod m);
|
|
|
|
|
|
|
|
|
|
|
2023-03-30 20:28:53 +00:00
|
|
|
|
/**
|
|
|
|
|
* An enumeration of all the ways we can serialize file system objects.
|
|
|
|
|
*
|
|
|
|
|
* Just the type of a content address. Combine with the hash itself, and
|
|
|
|
|
* we have a `ContentAddress` as defined below. Combine that, in turn,
|
|
|
|
|
* with info on references, and we have `ContentAddressWithReferences`,
|
|
|
|
|
* as defined further below.
|
|
|
|
|
*/
|
2020-10-12 23:51:23 +00:00
|
|
|
|
typedef std::variant<
|
|
|
|
|
TextHashMethod,
|
|
|
|
|
FileIngestionMethod
|
|
|
|
|
> ContentAddressMethod;
|
|
|
|
|
|
|
|
|
|
/* Parse and pretty print the algorithm which indicates how the files
|
|
|
|
|
were ingested, with the the fixed output case not prefixed for back
|
|
|
|
|
compat. */
|
|
|
|
|
|
|
|
|
|
std::string makeContentAddressingPrefix(ContentAddressMethod m);
|
|
|
|
|
|
|
|
|
|
ContentAddressMethod parseContentAddressingPrefix(std::string_view & m);
|
|
|
|
|
|
|
|
|
|
/* Parse and pretty print a content addressing method and hash in a
|
|
|
|
|
nicer way, prefixing both cases. */
|
|
|
|
|
|
|
|
|
|
std::string renderContentAddressMethodAndHash(ContentAddressMethod cam, HashType ht);
|
|
|
|
|
|
|
|
|
|
std::pair<ContentAddressMethod, HashType> parseContentAddressMethod(std::string_view caMethod);
|
|
|
|
|
|
2020-10-07 13:52:20 +00:00
|
|
|
|
|
2020-10-13 03:30:14 +00:00
|
|
|
|
/*
|
|
|
|
|
* Mini content address
|
|
|
|
|
*/
|
2020-10-07 13:52:20 +00:00
|
|
|
|
|
2023-03-25 23:12:44 +00:00
|
|
|
|
/**
|
|
|
|
|
* Somewhat obscure, used by \ref Derivation derivations and
|
|
|
|
|
* `builtins.toFile` currently.
|
|
|
|
|
*/
|
2020-06-01 23:26:40 +00:00
|
|
|
|
struct TextHash {
|
2023-03-25 23:12:44 +00:00
|
|
|
|
/**
|
|
|
|
|
* Hash of the contents of the text/file.
|
|
|
|
|
*/
|
2020-06-01 23:26:40 +00:00
|
|
|
|
Hash hash;
|
2022-03-25 22:40:40 +00:00
|
|
|
|
|
|
|
|
|
GENERATE_CMP(TextHash, me->hash);
|
2020-06-01 23:26:40 +00:00
|
|
|
|
};
|
|
|
|
|
|
2023-03-25 23:12:44 +00:00
|
|
|
|
/**
|
2023-03-30 20:28:53 +00:00
|
|
|
|
* Used by most store objects that are content-addressed.
|
2023-03-25 23:12:44 +00:00
|
|
|
|
*/
|
2020-06-19 15:18:19 +00:00
|
|
|
|
struct FixedOutputHash {
|
2023-03-25 23:12:44 +00:00
|
|
|
|
/**
|
|
|
|
|
* How the file system objects are serialized
|
|
|
|
|
*/
|
2020-06-01 21:32:27 +00:00
|
|
|
|
FileIngestionMethod method;
|
2023-03-25 23:12:44 +00:00
|
|
|
|
/**
|
|
|
|
|
* Hash of that serialization
|
|
|
|
|
*/
|
2020-06-01 21:32:27 +00:00
|
|
|
|
Hash hash;
|
2023-03-25 23:12:44 +00:00
|
|
|
|
|
2020-06-01 21:32:27 +00:00
|
|
|
|
std::string printMethodAlgo() const;
|
2022-03-25 22:40:40 +00:00
|
|
|
|
|
|
|
|
|
GENERATE_CMP(FixedOutputHash, me->method, me->hash);
|
2020-06-01 21:32:27 +00:00
|
|
|
|
};
|
|
|
|
|
|
2023-03-25 23:12:44 +00:00
|
|
|
|
/**
|
|
|
|
|
* We've accumulated several types of content-addressed paths over the
|
|
|
|
|
* years; fixed-output derivations support multiple hash algorithms and
|
|
|
|
|
* serialisation methods (flat file vs NAR). Thus, ‘ca’ has one of the
|
|
|
|
|
* following forms:
|
|
|
|
|
*
|
|
|
|
|
* - ‘text:sha256:<sha256 hash of file contents>’: For paths
|
|
|
|
|
* computed by Store::makeTextPath() / Store::addTextToStore().
|
|
|
|
|
*
|
|
|
|
|
* - ‘fixed:<r?>:<ht>:<h>’: For paths computed by
|
|
|
|
|
* Store::makeFixedOutputPath() / Store::addToStore().
|
|
|
|
|
*/
|
2020-06-01 22:53:31 +00:00
|
|
|
|
typedef std::variant<
|
2023-03-25 23:12:44 +00:00
|
|
|
|
TextHash,
|
|
|
|
|
FixedOutputHash
|
2020-06-01 22:53:31 +00:00
|
|
|
|
> ContentAddress;
|
|
|
|
|
|
2023-03-25 23:12:44 +00:00
|
|
|
|
/**
|
|
|
|
|
* Compute the content-addressability assertion (ValidPathInfo::ca) for
|
|
|
|
|
* paths created by Store::makeFixedOutputPath() / Store::addToStore().
|
|
|
|
|
*/
|
2020-06-01 23:26:40 +00:00
|
|
|
|
std::string renderContentAddress(ContentAddress ca);
|
|
|
|
|
|
|
|
|
|
std::string renderContentAddress(std::optional<ContentAddress> ca);
|
|
|
|
|
|
2020-06-02 15:00:10 +00:00
|
|
|
|
ContentAddress parseContentAddress(std::string_view rawCa);
|
2020-06-02 00:37:43 +00:00
|
|
|
|
|
2020-06-02 15:00:10 +00:00
|
|
|
|
std::optional<ContentAddress> parseContentAddressOpt(std::string_view rawCaOpt);
|
2020-06-02 00:37:43 +00:00
|
|
|
|
|
2020-07-10 11:21:37 +00:00
|
|
|
|
Hash getContentAddressHash(const ContentAddress & ca);
|
|
|
|
|
|
2020-09-17 15:15:05 +00:00
|
|
|
|
|
2023-03-30 20:28:53 +00:00
|
|
|
|
/**
|
|
|
|
|
* A set of references to other store objects.
|
|
|
|
|
*
|
|
|
|
|
* References to other store objects are tracked with store paths, self
|
|
|
|
|
* references however are tracked with a boolean.
|
2020-10-07 13:52:20 +00:00
|
|
|
|
*/
|
2023-01-14 21:38:43 +00:00
|
|
|
|
struct StoreReferences {
|
2023-03-30 20:28:53 +00:00
|
|
|
|
/**
|
|
|
|
|
* References to other store objects
|
|
|
|
|
*/
|
2023-01-14 21:38:43 +00:00
|
|
|
|
StorePathSet others;
|
2023-03-30 20:28:53 +00:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Reference to this store object
|
|
|
|
|
*/
|
2023-01-14 21:38:43 +00:00
|
|
|
|
bool self = false;
|
|
|
|
|
|
2023-03-30 20:28:53 +00:00
|
|
|
|
/**
|
|
|
|
|
* @return true iff no references, i.e. others is empty and self is
|
|
|
|
|
* false.
|
|
|
|
|
*/
|
2023-01-14 21:38:43 +00:00
|
|
|
|
bool empty() const;
|
2023-03-30 20:28:53 +00:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Returns the numbers of references, i.e. the size of others + 1
|
|
|
|
|
* iff self is true.
|
|
|
|
|
*/
|
2023-01-14 21:38:43 +00:00
|
|
|
|
size_t size() const;
|
|
|
|
|
|
|
|
|
|
GENERATE_CMP(StoreReferences, me->self, me->others);
|
|
|
|
|
};
|
2020-10-07 13:52:20 +00:00
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Full content address
|
|
|
|
|
*
|
|
|
|
|
* See the schema for store paths in store-api.cc
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
// This matches the additional info that we need for makeTextPath
|
2023-02-28 17:13:43 +00:00
|
|
|
|
struct TextInfo {
|
|
|
|
|
TextHash hash;
|
2023-03-30 20:28:53 +00:00
|
|
|
|
/**
|
|
|
|
|
* References to other store objects only; self references
|
|
|
|
|
* disallowed
|
|
|
|
|
*/
|
2020-10-07 13:52:20 +00:00
|
|
|
|
StorePathSet references;
|
2022-03-25 22:40:40 +00:00
|
|
|
|
|
2023-02-28 17:13:43 +00:00
|
|
|
|
GENERATE_CMP(TextInfo, me->hash, me->references);
|
2020-10-07 13:52:20 +00:00
|
|
|
|
};
|
|
|
|
|
|
2023-02-28 17:13:43 +00:00
|
|
|
|
struct FixedOutputInfo {
|
|
|
|
|
FixedOutputHash hash;
|
2023-03-30 20:28:53 +00:00
|
|
|
|
/**
|
|
|
|
|
* References to other store objects or this one.
|
|
|
|
|
*/
|
2023-01-06 20:36:05 +00:00
|
|
|
|
StoreReferences references;
|
2022-03-25 22:40:40 +00:00
|
|
|
|
|
2023-02-28 17:13:43 +00:00
|
|
|
|
GENERATE_CMP(FixedOutputInfo, me->hash, me->references);
|
2020-10-07 13:52:20 +00:00
|
|
|
|
};
|
|
|
|
|
|
2023-03-25 23:12:44 +00:00
|
|
|
|
/**
|
|
|
|
|
* Ways of content addressing but not a complete ContentAddress.
|
|
|
|
|
*
|
|
|
|
|
* A ContentAddress without a Hash.
|
|
|
|
|
*/
|
2020-10-07 13:52:20 +00:00
|
|
|
|
typedef std::variant<
|
|
|
|
|
TextInfo,
|
|
|
|
|
FixedOutputInfo
|
|
|
|
|
> ContentAddressWithReferences;
|
|
|
|
|
|
2023-03-30 20:28:53 +00:00
|
|
|
|
/**
|
|
|
|
|
* Create a ContentAddressWithReferences from a mere ContentAddress, by
|
|
|
|
|
* assuming no references in all cases.
|
|
|
|
|
*/
|
2020-10-07 13:52:20 +00:00
|
|
|
|
ContentAddressWithReferences caWithoutRefs(const ContentAddress &);
|
|
|
|
|
|
2020-10-12 23:51:23 +00:00
|
|
|
|
ContentAddressWithReferences contentAddressFromMethodHashAndRefs(
|
2023-01-06 20:37:31 +00:00
|
|
|
|
ContentAddressMethod method, Hash && hash, StoreReferences && refs);
|
2020-10-12 23:51:23 +00:00
|
|
|
|
|
|
|
|
|
ContentAddressMethod getContentAddressMethod(const ContentAddressWithReferences & ca);
|
|
|
|
|
Hash getContentAddressHash(const ContentAddressWithReferences & ca);
|
|
|
|
|
|
|
|
|
|
std::string printMethodAlgo(const ContentAddressWithReferences &);
|
|
|
|
|
|
2020-06-01 21:32:27 +00:00
|
|
|
|
}
|