Allow substituting paths when building remotely using ssh-ng://
Until now, it was not possible to substitute missing paths from e.g. `https://cache.nixos.org` on a remote server when building on it using the new `ssh-ng` protocol. This is because every store implementation except legacy `ssh://` ignores the substitution flag passed to `Store::queryValidPaths` while the `legacy-ssh-store` substitutes the remote store using `cmdQueryValidPaths` when the remote store is opened with `nix-store --serve`. This patch slightly modifies the daemon protocol to allow passing an integer value suggesting whether to substitute missing paths during `wopQueryValidPaths`. To implement this on the daemon-side, the substitution logic from `nix-store --serve` has been moved into a protected method named `Store::substitutePaths` which gets currently called from `LocalStore::queryValidPaths` and `Store::queryValidPaths` if `maybeSubstitute` is `true`. Fixes #2770
This commit is contained in:
parent
387f824cab
commit
3a63fc6cd5
|
@ -12,7 +12,7 @@
|
|||
versionSuffix =
|
||||
if officialRelease
|
||||
then ""
|
||||
else "pre${builtins.substring 0 8 (self.lastModifiedDate or self.lastModified)}_${self.shortRev or "dirty"}";
|
||||
else "pre${builtins.substring 0 8 (self.lastModifiedDate or self.lastModified or "19700101")}_${self.shortRev or "dirty"}";
|
||||
|
||||
officialRelease = false;
|
||||
|
||||
|
@ -117,6 +117,7 @@
|
|||
|
||||
nix = with final; with commonDeps pkgs; (stdenv.mkDerivation {
|
||||
name = "nix-${version}";
|
||||
inherit version;
|
||||
|
||||
src = self;
|
||||
|
||||
|
|
|
@ -274,8 +274,17 @@ static void performOp(TunnelLogger * logger, ref<Store> store,
|
|||
|
||||
case wopQueryValidPaths: {
|
||||
auto paths = worker_proto::read(*store, from, Phantom<StorePathSet> {});
|
||||
|
||||
SubstituteFlag substitute = NoSubstitute;
|
||||
if (GET_PROTOCOL_MINOR(clientVersion) >= 27) {
|
||||
substitute = readInt(from) ? Substitute : NoSubstitute;
|
||||
}
|
||||
|
||||
logger->startWork();
|
||||
auto res = store->queryValidPaths(paths);
|
||||
if (substitute) {
|
||||
store->substitutePaths(paths);
|
||||
}
|
||||
auto res = store->queryValidPaths(paths, substitute);
|
||||
logger->stopWork();
|
||||
worker_proto::write(*store, to, res);
|
||||
break;
|
||||
|
|
|
@ -259,6 +259,9 @@ StorePathSet RemoteStore::queryValidPaths(const StorePathSet & paths, Substitute
|
|||
} else {
|
||||
conn->to << wopQueryValidPaths;
|
||||
worker_proto::write(*this, conn->to, paths);
|
||||
if (GET_PROTOCOL_MINOR(conn->daemonVersion) >= 27) {
|
||||
conn->to << (settings.buildersUseSubstitutes ? 1 : 0);
|
||||
}
|
||||
conn.processStderr();
|
||||
return worker_proto::read(*this, conn->from, Phantom<StorePathSet> {});
|
||||
}
|
||||
|
|
|
@ -522,6 +522,28 @@ void Store::queryPathInfo(const StorePath & storePath,
|
|||
}
|
||||
|
||||
|
||||
void Store::substitutePaths(const StorePathSet & paths)
|
||||
{
|
||||
std::vector<StorePathWithOutputs> paths2;
|
||||
for (auto & path : paths)
|
||||
if (!path.isDerivation())
|
||||
paths2.push_back({path});
|
||||
uint64_t downloadSize, narSize;
|
||||
StorePathSet willBuild, willSubstitute, unknown;
|
||||
queryMissing(paths2,
|
||||
willBuild, willSubstitute, unknown, downloadSize, narSize);
|
||||
|
||||
if (!willSubstitute.empty())
|
||||
try {
|
||||
std::vector<StorePathWithOutputs> subs;
|
||||
for (auto & p : willSubstitute) subs.push_back({p});
|
||||
buildPaths(subs);
|
||||
} catch (Error & e) {
|
||||
logWarning(e.info());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
StorePathSet Store::queryValidPaths(const StorePathSet & paths, SubstituteFlag maybeSubstitute)
|
||||
{
|
||||
struct State
|
||||
|
|
|
@ -360,6 +360,11 @@ protected:
|
|||
|
||||
public:
|
||||
|
||||
/* If requested, substitute missing paths. This
|
||||
implements nix-copy-closure's --use-substitutes
|
||||
flag. */
|
||||
void substitutePaths(const StorePathSet & paths);
|
||||
|
||||
/* Query which of the given paths is valid. Optionally, try to
|
||||
substitute missing paths. */
|
||||
virtual StorePathSet queryValidPaths(const StorePathSet & paths,
|
||||
|
|
|
@ -6,7 +6,7 @@ namespace nix {
|
|||
#define WORKER_MAGIC_1 0x6e697863
|
||||
#define WORKER_MAGIC_2 0x6478696f
|
||||
|
||||
#define PROTOCOL_VERSION 0x11a
|
||||
#define PROTOCOL_VERSION 0x11b
|
||||
#define GET_PROTOCOL_MAJOR(x) ((x) & 0xff00)
|
||||
#define GET_PROTOCOL_MINOR(x) ((x) & 0x00ff)
|
||||
|
||||
|
|
|
@ -830,29 +830,8 @@ static void opServe(Strings opFlags, Strings opArgs)
|
|||
for (auto & path : paths)
|
||||
store->addTempRoot(path);
|
||||
|
||||
/* If requested, substitute missing paths. This
|
||||
implements nix-copy-closure's --use-substitutes
|
||||
flag. */
|
||||
if (substitute && writeAllowed) {
|
||||
/* Filter out .drv files (we don't want to build anything). */
|
||||
std::vector<StorePathWithOutputs> paths2;
|
||||
for (auto & path : paths)
|
||||
if (!path.isDerivation())
|
||||
paths2.push_back({path});
|
||||
uint64_t downloadSize, narSize;
|
||||
StorePathSet willBuild, willSubstitute, unknown;
|
||||
store->queryMissing(paths2,
|
||||
willBuild, willSubstitute, unknown, downloadSize, narSize);
|
||||
/* FIXME: should use ensurePath(), but it only
|
||||
does one path at a time. */
|
||||
if (!willSubstitute.empty())
|
||||
try {
|
||||
std::vector<StorePathWithOutputs> subs;
|
||||
for (auto & p : willSubstitute) subs.push_back({p});
|
||||
store->buildPaths(subs);
|
||||
} catch (Error & e) {
|
||||
logWarning(e.info());
|
||||
}
|
||||
store->substitutePaths(paths);
|
||||
}
|
||||
|
||||
worker_proto::write(*store, out, store->queryValidPaths(paths));
|
||||
|
|
Loading…
Reference in a new issue