2012-07-18 21:59:03 +03:00
|
|
|
#pragma once
|
2023-04-01 06:18:41 +03:00
|
|
|
///@file
|
2006-11-30 20:35:50 +02:00
|
|
|
|
2016-02-23 17:40:16 +02:00
|
|
|
#include <limits>
|
2006-11-30 20:35:50 +02:00
|
|
|
#include <string>
|
|
|
|
|
|
|
|
#include "store-api.hh"
|
2022-03-01 20:31:36 +02:00
|
|
|
#include "gc-store.hh"
|
2022-03-08 20:20:39 +02:00
|
|
|
#include "log-store.hh"
|
2006-11-30 20:35:50 +02:00
|
|
|
|
|
|
|
|
|
|
|
namespace nix {
|
|
|
|
|
|
|
|
|
2006-11-30 21:54:43 +02:00
|
|
|
class Pipe;
|
|
|
|
class Pid;
|
|
|
|
struct FdSink;
|
|
|
|
struct FdSource;
|
2016-02-23 16:00:59 +02:00
|
|
|
template<typename T> class Pool;
|
2006-11-30 21:54:43 +02:00
|
|
|
|
2020-09-10 11:55:51 +03:00
|
|
|
struct RemoteStoreConfig : virtual StoreConfig
|
2006-11-30 20:35:50 +02:00
|
|
|
{
|
2020-09-10 11:55:51 +03:00
|
|
|
using StoreConfig::StoreConfig;
|
2006-11-30 20:35:50 +02:00
|
|
|
|
2023-10-31 00:12:37 +02:00
|
|
|
const Setting<int> maxConnections{this, 1, "max-connections",
|
2023-03-22 15:23:36 +02:00
|
|
|
"Maximum number of concurrent connections to the Nix daemon."};
|
2017-04-13 16:55:38 +03:00
|
|
|
|
2023-10-31 00:12:37 +02:00
|
|
|
const Setting<unsigned int> maxConnectionAge{this,
|
2023-03-22 15:23:36 +02:00
|
|
|
std::numeric_limits<unsigned int>::max(),
|
|
|
|
"max-connection-age",
|
|
|
|
"Maximum age of a connection before it is closed."};
|
2020-09-10 11:55:51 +03:00
|
|
|
};
|
|
|
|
|
2023-04-07 16:55:28 +03:00
|
|
|
/**
|
|
|
|
* \todo RemoteStore is a misnomer - should be something like
|
|
|
|
* DaemonStore.
|
|
|
|
*/
|
2022-03-08 20:20:39 +02:00
|
|
|
class RemoteStore : public virtual RemoteStoreConfig,
|
|
|
|
public virtual Store,
|
|
|
|
public virtual GcStore,
|
|
|
|
public virtual LogStore
|
2020-09-10 11:55:51 +03:00
|
|
|
{
|
|
|
|
public:
|
2017-09-14 19:10:38 +03:00
|
|
|
|
2017-03-03 20:05:50 +02:00
|
|
|
RemoteStore(const Params & params);
|
2015-03-25 18:06:12 +02:00
|
|
|
|
2006-11-30 20:35:50 +02:00
|
|
|
/* Implementations of abstract store API methods. */
|
2015-03-25 18:06:12 +02:00
|
|
|
|
2019-12-05 20:11:09 +02:00
|
|
|
bool isValidPathUncached(const StorePath & path) override;
|
2006-11-30 20:35:50 +02:00
|
|
|
|
2019-12-05 20:11:09 +02:00
|
|
|
StorePathSet queryValidPaths(const StorePathSet & paths,
|
2017-06-28 19:11:01 +03:00
|
|
|
SubstituteFlag maybeSubstitute = NoSubstitute) override;
|
2015-03-25 18:06:12 +02:00
|
|
|
|
2019-12-05 20:11:09 +02:00
|
|
|
StorePathSet queryAllValidPaths() override;
|
2015-03-25 18:06:12 +02:00
|
|
|
|
2019-12-05 20:11:09 +02:00
|
|
|
void queryPathInfoUncached(const StorePath & path,
|
2018-09-25 19:54:16 +03:00
|
|
|
Callback<std::shared_ptr<const ValidPathInfo>> callback) noexcept override;
|
2006-11-30 20:35:50 +02:00
|
|
|
|
2019-12-05 20:11:09 +02:00
|
|
|
void queryReferrers(const StorePath & path, StorePathSet & referrers) override;
|
2015-03-25 18:06:12 +02:00
|
|
|
|
2019-12-05 20:11:09 +02:00
|
|
|
StorePathSet queryValidDerivers(const StorePath & path) override;
|
2012-12-20 19:41:44 +02:00
|
|
|
|
2019-12-05 20:11:09 +02:00
|
|
|
StorePathSet queryDerivationOutputs(const StorePath & path) override;
|
2015-03-25 18:06:12 +02:00
|
|
|
|
2023-07-19 21:52:35 +03:00
|
|
|
std::map<std::string, std::optional<StorePath>> queryPartialDerivationOutputMap(const StorePath & path, Store * evalStore = nullptr) override;
|
2019-12-05 20:11:09 +02:00
|
|
|
std::optional<StorePath> queryPathFromHashPart(const std::string & hashPart) override;
|
2015-03-25 18:06:12 +02:00
|
|
|
|
2019-12-05 20:11:09 +02:00
|
|
|
StorePathSet querySubstitutablePaths(const StorePathSet & paths) override;
|
2015-03-25 18:06:12 +02:00
|
|
|
|
2020-06-17 22:03:05 +03:00
|
|
|
void querySubstitutablePathInfos(const StorePathCAMap & paths,
|
|
|
|
SubstitutablePathInfos & infos) override;
|
2015-03-25 18:06:12 +02:00
|
|
|
|
2023-04-07 16:55:28 +03:00
|
|
|
/**
|
|
|
|
* Add a content-addressable store path. `dump` will be drained.
|
|
|
|
*/
|
2020-09-22 12:40:19 +03:00
|
|
|
ref<const ValidPathInfo> addCAToStore(
|
2023-11-28 15:20:27 +02:00
|
|
|
Source & dump,
|
|
|
|
std::string_view name,
|
|
|
|
ContentAddressMethod caMethod,
|
|
|
|
HashAlgorithm hashAlgo,
|
|
|
|
const StorePathSet & references,
|
|
|
|
RepairFlag repair);
|
2020-09-17 21:19:15 +03:00
|
|
|
|
2023-04-07 16:55:28 +03:00
|
|
|
/**
|
2023-11-04 22:25:41 +02:00
|
|
|
* Add a content-addressable store path. `dump` will be drained.
|
2023-04-07 16:55:28 +03:00
|
|
|
*/
|
2023-11-04 22:25:41 +02:00
|
|
|
StorePath addToStoreFromDump(
|
|
|
|
Source & dump,
|
|
|
|
std::string_view name,
|
|
|
|
ContentAddressMethod method = FileIngestionMethod::Recursive,
|
|
|
|
HashAlgorithm hashAlgo = HashAlgorithm::SHA256,
|
|
|
|
const StorePathSet & references = StorePathSet(),
|
|
|
|
RepairFlag repair = NoRepair) override;
|
2020-09-17 20:27:11 +03:00
|
|
|
|
2018-03-22 00:42:21 +02:00
|
|
|
void addToStore(const ValidPathInfo & info, Source & nar,
|
2020-07-13 18:37:44 +03:00
|
|
|
RepairFlag repair, CheckSigsFlag checkSigs) override;
|
2016-05-04 14:36:54 +03:00
|
|
|
|
2021-07-26 14:31:09 +03:00
|
|
|
void addMultipleToStore(
|
|
|
|
Source & source,
|
|
|
|
RepairFlag repair,
|
|
|
|
CheckSigsFlag checkSigs) override;
|
|
|
|
|
2022-06-08 15:03:46 +03:00
|
|
|
void addMultipleToStore(
|
2022-08-22 16:30:38 +03:00
|
|
|
PathsSource & pathsToCopy,
|
|
|
|
Activity & act,
|
|
|
|
RepairFlag repair,
|
|
|
|
CheckSigsFlag checkSigs) override;
|
2022-06-08 15:03:46 +03:00
|
|
|
|
2020-10-08 18:36:51 +03:00
|
|
|
void registerDrvOutput(const Realisation & info) override;
|
|
|
|
|
2021-10-27 12:36:51 +03:00
|
|
|
void queryRealisationUncached(const DrvOutput &,
|
|
|
|
Callback<std::shared_ptr<const Realisation>> callback) noexcept override;
|
2020-10-08 18:36:51 +03:00
|
|
|
|
2021-07-19 16:43:08 +03:00
|
|
|
void buildPaths(const std::vector<DerivedPath> & paths, BuildMode buildMode, std::shared_ptr<Store> evalStore) override;
|
2006-11-30 20:35:50 +02:00
|
|
|
|
Make `KeyedBuildResult`, `BuildResult` like before, and fix bug another way
In https://github.com/NixOS/nix/pull/6311#discussion_r834863823, I
realized since derivation goals' wanted outputs can "grow" due to
overlapping dependencies (See `DerivationGoal::addWantedOutputs`, called
by `Worker::makeDerivationGoalCommon`), the previous bug fix had an
unfortunate side effect of causing more pointless rebuilds.
In paticular, we have this situation:
1. Goal made from `DerivedPath::Built { foo, {a} }`.
2. Goal gives on on substituting, starts building.
3. Goal made from `DerivedPath::Built { foo, {b} }`, in fact is just
modified original goal.
4. Though the goal had gotten as far as building, so all outputs were
going to be produced, `addWantedOutputs` no longer knows that and so
the goal is flagged to be restarted.
This might sound far-fetched with input-addressed drvs, where we usually
basically have all our goals "planned out" before we start doing
anything, but with CA derivation goals and especially RFC 92, where *drv
resolution* means goals are created after some building is completed, it
is more likely to happen.
So the first thing to do was restore the clearing of `wantedOutputs` we
used to do, and then filter the outputs in `buildPathsWithResults` to
only get the ones we care about.
But fix also has its own side effect in that the `DerivedPath` in the
`BuildResult` in `DerivationGoal` cannot be trusted; it is merely the
*first* `DerivedPath` for which this goal was originally created.
To remedy this, I made `BuildResult` be like it was before, and instead
made `KeyedBuildResult` be a subclass wit the path. Only
`buildPathsWithResults` returns `KeyedBuildResult`s, everything else
just becomes like it was before, where the "key" is unambiguous from
context.
I think separating the "primary key" field(s) from the other fields is
good practical in general anyways. (I would like to do the same thing
for `ValidPathInfo`.) Among other things, it allows constructions like
`std::map<Key, ThingWithKey>` where doesn't contain duplicate keys and
just precludes the possibility of those duplicate keys being out of
sync.
We might leverage the above someday to overload `buildPathsWithResults`
to take a *set* of return a *map* per the above.
-----
Unfortunately, we need to avoid C++20 strictness on designated
initializers.
(BTW
https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2287r1.html
this offers some new syntax for this use-case. Hopefully this will be
adopted and we can eventually use it.)
No having that yet, maybe it would be better to not make
`KeyedBuildResult` a subclass to just avoid this.
Co-authored-by: Robert Hensing <roberth@users.noreply.github.com>
2022-03-25 03:26:07 +02:00
|
|
|
std::vector<KeyedBuildResult> buildPathsWithResults(
|
2022-03-08 20:50:46 +02:00
|
|
|
const std::vector<DerivedPath> & paths,
|
|
|
|
BuildMode buildMode,
|
|
|
|
std::shared_ptr<Store> evalStore) override;
|
|
|
|
|
2019-12-05 20:11:09 +02:00
|
|
|
BuildResult buildDerivation(const StorePath & drvPath, const BasicDerivation & drv,
|
Allow remote builds without sending the derivation closure
Previously, to build a derivation remotely, we had to copy the entire
closure of the .drv file to the remote machine, even though we only
need the top-level derivation. This is very wasteful: the closure can
contain thousands of store paths, and in some Hydra use cases, include
source paths that are very large (e.g. Git/Mercurial checkouts).
So now there is a new operation, StoreAPI::buildDerivation(), that
performs a build from an in-memory representation of a derivation
(BasicDerivation) rather than from a on-disk .drv file. The only files
that need to be in the Nix store are the sources of the derivation
(drv.inputSrcs), and the needed output paths of the dependencies (as
described by drv.inputDrvs). "nix-store --serve" exposes this
interface.
Note that this is a privileged operation, because you can construct a
derivation that builds any store path whatsoever. Fixing this will
require changing the hashing scheme (i.e., the output paths should be
computed from the other fields in BasicDerivation, allowing them to be
verified without access to other derivations). However, this would be
quite nice because it would allow .drv-free building (e.g. "nix-env
-i" wouldn't have to write any .drv files to disk).
Fixes #173.
2015-07-17 18:57:40 +03:00
|
|
|
BuildMode buildMode) override;
|
|
|
|
|
2019-12-05 20:11:09 +02:00
|
|
|
void ensurePath(const StorePath & path) override;
|
2006-11-30 20:35:50 +02:00
|
|
|
|
2019-12-05 20:11:09 +02:00
|
|
|
void addTempRoot(const StorePath & path) override;
|
2006-12-02 18:41:36 +02:00
|
|
|
|
2019-03-14 14:50:07 +02:00
|
|
|
Roots findRoots(bool censor) override;
|
2006-12-05 04:18:46 +02:00
|
|
|
|
2015-09-18 02:22:06 +03:00
|
|
|
void collectGarbage(const GCOptions & options, GCResults & results) override;
|
2015-03-25 18:06:12 +02:00
|
|
|
|
2015-09-18 02:22:06 +03:00
|
|
|
void optimiseStore() override;
|
|
|
|
|
2017-06-28 19:11:01 +03:00
|
|
|
bool verifyStore(bool checkContents, RepairFlag repair) override;
|
2014-09-01 23:21:42 +03:00
|
|
|
|
2023-04-13 17:38:35 +03:00
|
|
|
/**
|
|
|
|
* The default instance would schedule the work on the client side, but
|
|
|
|
* for consistency with `buildPaths` and `buildDerivation` it should happen
|
|
|
|
* on the remote side.
|
|
|
|
*
|
|
|
|
* We make this fail for now so we can add implement this properly later
|
|
|
|
* without it being a breaking change.
|
|
|
|
*/
|
|
|
|
void repairPath(const StorePath & path) override
|
|
|
|
{ unsupported("repairPath"); }
|
|
|
|
|
2019-12-05 20:11:09 +02:00
|
|
|
void addSignatures(const StorePath & storePath, const StringSet & sigs) override;
|
2016-04-05 16:30:22 +03:00
|
|
|
|
2021-04-05 16:48:18 +03:00
|
|
|
void queryMissing(const std::vector<DerivedPath> & targets,
|
2019-12-05 20:11:09 +02:00
|
|
|
StorePathSet & willBuild, StorePathSet & willSubstitute, StorePathSet & unknown,
|
2020-07-30 14:10:49 +03:00
|
|
|
uint64_t & downloadSize, uint64_t & narSize) override;
|
2017-04-06 19:40:19 +03:00
|
|
|
|
2022-01-17 20:45:21 +02:00
|
|
|
void addBuildLog(const StorePath & drvPath, std::string_view log) override;
|
|
|
|
|
2022-01-25 22:14:27 +02:00
|
|
|
std::optional<std::string> getVersion() override;
|
|
|
|
|
2017-05-02 15:18:46 +03:00
|
|
|
void connect() override;
|
|
|
|
|
2018-08-31 00:28:47 +03:00
|
|
|
unsigned int getProtocol() override;
|
|
|
|
|
2022-12-26 22:21:08 +02:00
|
|
|
std::optional<TrustedFlag> isTrustedClient() override;
|
|
|
|
|
2017-09-14 19:10:38 +03:00
|
|
|
void flushBadConnections();
|
|
|
|
|
2023-04-17 20:40:46 +03:00
|
|
|
struct Connection;
|
2006-12-04 15:28:14 +02:00
|
|
|
|
2017-03-03 20:35:34 +02:00
|
|
|
ref<Connection> openConnectionWrapper();
|
|
|
|
|
2020-08-19 22:34:47 +03:00
|
|
|
protected:
|
|
|
|
|
2016-09-02 21:15:04 +03:00
|
|
|
virtual ref<Connection> openConnection() = 0;
|
|
|
|
|
|
|
|
void initConnection(Connection & conn);
|
|
|
|
|
2016-02-23 16:00:59 +02:00
|
|
|
ref<Pool<Connection>> connections;
|
2007-09-18 12:11:20 +03:00
|
|
|
|
2018-03-05 14:42:15 +02:00
|
|
|
virtual void setOptions(Connection & conn);
|
|
|
|
|
2021-11-05 17:17:49 +02:00
|
|
|
void setOptions() override;
|
|
|
|
|
2023-04-17 19:14:15 +03:00
|
|
|
struct ConnectionHandle;
|
|
|
|
|
2018-10-17 00:36:15 +03:00
|
|
|
ConnectionHandle getConnection();
|
|
|
|
|
2018-10-26 20:34:29 +03:00
|
|
|
friend struct ConnectionHandle;
|
2018-10-17 00:36:15 +03:00
|
|
|
|
2023-11-01 18:09:28 +02:00
|
|
|
virtual ref<SourceAccessor> getFSAccessor(bool requireValidPath) override;
|
2020-09-07 12:26:09 +03:00
|
|
|
|
|
|
|
virtual void narFromPath(const StorePath & path, Sink & sink) override;
|
|
|
|
|
2016-09-02 21:15:04 +03:00
|
|
|
private:
|
|
|
|
|
2017-03-03 20:35:34 +02:00
|
|
|
std::atomic_bool failed{false};
|
|
|
|
|
2022-03-08 20:50:46 +02:00
|
|
|
void copyDrvsFromEvalStore(
|
|
|
|
const std::vector<DerivedPath> & paths,
|
|
|
|
std::shared_ptr<Store> evalStore);
|
2016-09-02 21:15:04 +03:00
|
|
|
};
|
2007-09-18 12:11:20 +03:00
|
|
|
|
2006-11-30 20:35:50 +02:00
|
|
|
}
|