aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/build-remote/build-remote.cc43
-rw-r--r--src/libstore/daemon.cc2
-rw-r--r--src/libstore/store-api.cc43
-rw-r--r--src/libstore/store-api.hh27
-rw-r--r--src/nix/daemon.cc26
5 files changed, 113 insertions, 28 deletions
diff --git a/src/build-remote/build-remote.cc b/src/build-remote/build-remote.cc
index 0559aeaf4..72752d624 100644
--- a/src/build-remote/build-remote.cc
+++ b/src/build-remote/build-remote.cc
@@ -248,6 +248,8 @@ static int main_build_remote(int argc, char * * argv)
connected:
close(5);
+ assert(sshStore);
+
std::cerr << "# accept\n" << storeUri << "\n";
auto inputs = readStrings<PathSet>(source);
@@ -268,31 +270,39 @@ connected:
auto substitute = settings.buildersUseSubstitutes ? Substitute : NoSubstitute;
+ auto copyStorePathImpl = sshStore->isTrusting ? copyStorePathAdapter : copyOrBuildStorePath;
+
{
Activity act(*logger, lvlTalkative, actUnknown, fmt("copying dependencies to '%s'", storeUri));
- copyPaths(*store, *sshStore, store->parseStorePathSet(inputs), NoRepair, NoCheckSigs, substitute);
+ copyPaths(*store, *sshStore, store->parseStorePathSet(inputs), NoRepair, NoCheckSigs, substitute, copyStorePathImpl);
}
uploadLock = -1;
auto drv = store->readDerivation(*drvPath);
- auto outputHashes = staticOutputHashes(*store, drv);
-
- // Hijack the inputs paths of the derivation to include all the paths
- // that come from the `inputDrvs` set.
- // We don’t do that for the derivations whose `inputDrvs` is empty
- // because
- // 1. It’s not needed
- // 2. Changing the `inputSrcs` set changes the associated output ids,
- // which break CA derivations
- if (!drv.inputDrvs.empty())
- drv.inputSrcs = store->parseStorePathSet(inputs);
- auto result = sshStore->buildDerivation(*drvPath, drv);
+ std::optional<BuildResult> optResult;
+ if (sshStore->isTrusting || derivationIsCA(drv.type())) {
+ // Hijack the inputs paths of the derivation to include all the paths
+ // that come from the `inputDrvs` set.
+ // We don’t do that for the derivations whose `inputDrvs` is empty
+ // because
+ // 1. It’s not needed
+ // 2. Changing the `inputSrcs` set changes the associated output ids,
+ // which break CA derivations
+ if (!drv.inputDrvs.empty())
+ drv.inputSrcs = store->parseStorePathSet(inputs);
+ optResult = sshStore->buildDerivation(*drvPath, (const BasicDerivation &) drv);
+ auto & result = *optResult;
+ if (!result.success())
+ throw Error("build of '%s' on '%s' failed: %s", store->printStorePath(*drvPath), storeUri, result.errorMsg);
+ } else {
+ copyPaths(*store, *sshStore, StorePathSet {*drvPath}, NoRepair, NoCheckSigs, substitute, copyStorePathImpl);
+ sshStore->buildPaths({ DerivedPath::Built { *drvPath, {} } });
+ }
- if (!result.success())
- throw Error("build of '%s' on '%s' failed: %s", store->printStorePath(*drvPath), storeUri, result.errorMsg);
+ auto outputHashes = staticOutputHashes(*store, drv);
std::set<Realisation> missingRealisations;
StorePathSet missingPaths;
if (settings.isExperimentalFeatureEnabled("ca-derivations") && !derivationHasKnownOutputPaths(drv.type())) {
@@ -301,6 +311,8 @@ connected:
auto thisOutputId = DrvOutput{ thisOutputHash, outputName };
if (!store->queryRealisation(thisOutputId)) {
debug("missing output %s", outputName);
+ assert(optResult);
+ auto & result = *optResult;
assert(result.builtOutputs.count(thisOutputId));
auto newRealisation = result.builtOutputs.at(thisOutputId);
missingRealisations.insert(newRealisation);
@@ -321,6 +333,7 @@ connected:
if (auto localStore = store.dynamic_pointer_cast<LocalStore>())
for (auto & path : missingPaths)
localStore->locksHeld.insert(store->printStorePath(path)); /* FIXME: ugly */
+ /* No `copyStorePathImpl` because we always trust ourselves. */
copyPaths(*sshStore, *store, missingPaths, NoRepair, NoCheckSigs, NoSubstitute);
}
// XXX: Should be done as part of `copyPaths`
diff --git a/src/libstore/daemon.cc b/src/libstore/daemon.cc
index 164a9b2be..bfcdb8d95 100644
--- a/src/libstore/daemon.cc
+++ b/src/libstore/daemon.cc
@@ -987,6 +987,8 @@ void processConnection(
opCount++;
+ debug("performing daemon worker op: %d", op);
+
try {
performOp(tunnelLogger, store, trusted, recursive, clientVersion, from, to, op);
} catch (Error & e) {
diff --git a/src/libstore/store-api.cc b/src/libstore/store-api.cc
index b5ff3dccf..49bc91614 100644
--- a/src/libstore/store-api.cc
+++ b/src/libstore/store-api.cc
@@ -847,13 +847,47 @@ void copyStorePath(
}
+void copyStorePathAdapter(Store & srcStore, Store & dstStore,
+ const ValidPathInfo & info, RepairFlag repair, CheckSigsFlag checkSigs)
+{
+ copyStorePath(srcStore, dstStore, info.path, repair, checkSigs);
+}
+
+void copyOrBuildStorePath(Store & srcStore, Store & dstStore,
+ const ValidPathInfo & info, RepairFlag repair, CheckSigsFlag checkSigs)
+{
+ auto storePath = info.path;
+ if (dstStore.isTrusting || info.ca) {
+ copyStorePath(srcStore, dstStore, storePath, repair, checkSigs);
+ } else if (info.deriver && dstStore.storeDir == srcStore.storeDir) {
+ auto drvPath = *info.deriver;
+ auto outputMap = srcStore.queryDerivationOutputMap(drvPath);
+ auto p = std::find_if(outputMap.begin(), outputMap.end(), [&](auto & i) {
+ return i.second == storePath;
+ });
+ // drv file is always CA
+ srcStore.ensurePath(drvPath);
+ copyStorePath(srcStore, dstStore, drvPath, repair, checkSigs);
+ dstStore.buildPaths({
+ DerivedPath::Built {
+ .drvPath = drvPath,
+ .outputs = p != outputMap.end() ? StringSet { p->first } : StringSet {},
+ },
+ });
+ } else {
+ dstStore.ensurePath(storePath);
+ }
+}
+
+
std::map<StorePath, StorePath> copyPaths(
Store & srcStore,
Store & dstStore,
const RealisedPath::Set & paths,
RepairFlag repair,
CheckSigsFlag checkSigs,
- SubstituteFlag substitute)
+ SubstituteFlag substitute,
+ std::function<void(Store &, Store &, const ValidPathInfo &, RepairFlag, CheckSigsFlag)> copyStorePathImpl)
{
StorePathSet storePaths;
std::set<Realisation> toplevelRealisations;
@@ -864,7 +898,7 @@ std::map<StorePath, StorePath> copyPaths(
toplevelRealisations.insert(*realisation);
}
}
- auto pathsMap = copyPaths(srcStore, dstStore, storePaths, repair, checkSigs, substitute);
+ auto pathsMap = copyPaths(srcStore, dstStore, storePaths, repair, checkSigs, substitute, copyStorePathImpl);
ThreadPool pool;
@@ -907,7 +941,8 @@ std::map<StorePath, StorePath> copyPaths(
const StorePathSet & storePaths,
RepairFlag repair,
CheckSigsFlag checkSigs,
- SubstituteFlag substitute)
+ SubstituteFlag substitute,
+ std::function<void(Store &, Store &, const ValidPathInfo &, RepairFlag, CheckSigsFlag)> copyStorePathImpl)
{
auto valid = dstStore.queryValidPaths(storePaths, substitute);
@@ -1007,7 +1042,7 @@ std::map<StorePath, StorePath> copyPaths(
MaintainCount<decltype(nrRunning)> mc(nrRunning);
showProgress();
try {
- copyStorePath(srcStore, dstStore, storePath, repair, checkSigs);
+ copyStorePathImpl(srcStore, dstStore, *info, repair, checkSigs);
} catch (Error &e) {
nrFailed++;
if (!settings.keepGoing)
diff --git a/src/libstore/store-api.hh b/src/libstore/store-api.hh
index 54471bdf2..24b9228f9 100644
--- a/src/libstore/store-api.hh
+++ b/src/libstore/store-api.hh
@@ -192,7 +192,9 @@ struct StoreConfig : public Config
const Setting<int> pathInfoCacheSize{this, 65536, "path-info-cache-size", "size of the in-memory store path information cache"};
- const Setting<bool> isTrusted{this, false, "trusted", "whether paths from this store can be used as substitutes even when they lack trusted signatures"};
+ const Setting<bool> isTrusted{this, false, "trusted", "whether paths from this store can be used as substitutes even when they lack trusted signatures. Compare \"trusting\""};
+
+ Setting<bool> isTrusting{this, true, "trusting", "whether (we think) paths can be added to this store even when they lack trusted signatures. Compare \"trusted\""};
Setting<int> priority{this, 0, "priority", "priority of this substituter (lower value means higher priority)"};
@@ -767,25 +769,42 @@ void copyStorePath(
CheckSigsFlag checkSigs = CheckSigs);
+/* copyStorePath wrapped to be used with `copyPaths`. */
+void copyStorePathAdapter(Store & srcStore, Store & dstStore,
+ const ValidPathInfo & info, RepairFlag repair = NoRepair, CheckSigsFlag checkSigs = CheckSigs);
+
+/* The more liberal alternative to `copyStorePathAdapter`, useful for remote
+ stores that do not trust us. */
+void copyOrBuildStorePath(Store & srcStore, Store & dstStore,
+ const ValidPathInfo & info, RepairFlag repair = NoRepair, CheckSigsFlag checkSigs = CheckSigs);
+
/* Copy store paths from one store to another. The paths may be copied
in parallel. They are copied in a topologically sorted order (i.e.
if A is a reference of B, then A is copied before B), but the set
of store paths is not automatically closed; use copyClosure() for
that. Returns a map of what each path was copied to the dstStore
- as. */
+ as.
+
+ The `copyStorePathImpl` parameter allows doing something other than just
+ copying. For example, this is used with the build hook to allow the other
+ side to build dependencies we don't have permission to copy. This behavior
+ isn't just the default that way `nix copy` etc. still can be relied upon to
+ not build anything. */
std::map<StorePath, StorePath> copyPaths(
Store & srcStore, Store & dstStore,
const RealisedPath::Set &,
RepairFlag repair = NoRepair,
CheckSigsFlag checkSigs = CheckSigs,
- SubstituteFlag substitute = NoSubstitute);
+ SubstituteFlag substitute = NoSubstitute,
+ std::function<void(Store &, Store &, const ValidPathInfo &, RepairFlag, CheckSigsFlag)> copyStorePathImpl = copyStorePathAdapter);
std::map<StorePath, StorePath> copyPaths(
Store & srcStore, Store & dstStore,
const StorePathSet & paths,
RepairFlag repair = NoRepair,
CheckSigsFlag checkSigs = CheckSigs,
- SubstituteFlag substitute = NoSubstitute);
+ SubstituteFlag substitute = NoSubstitute,
+ std::function<void(Store &, Store &, const ValidPathInfo &, RepairFlag, CheckSigsFlag)> copyStorePathImpl = copyStorePathAdapter);
/* Copy the closure of `paths` from `srcStore` to `dstStore`. */
void copyClosure(
diff --git a/src/nix/daemon.cc b/src/nix/daemon.cc
index 6a40a0bd3..da8d91029 100644
--- a/src/nix/daemon.cc
+++ b/src/nix/daemon.cc
@@ -265,10 +265,16 @@ static void daemonLoop()
}
}
-static void runDaemon(bool stdio)
+static void runDaemon(bool stdio, std::optional<TrustedFlag> isTrustedOpt = {})
{
+ auto ensureNoTrustedFlag = [&]() {
+ if (isTrustedOpt)
+ throw Error("--trust and --no-trust flags are only for use with --stdio when this nix-daemon process is not proxying another");
+ };
+
if (stdio) {
if (auto store = openUncachedStore().dynamic_pointer_cast<RemoteStore>()) {
+ ensureNoTrustedFlag();
auto conn = store->openConnectionWrapper();
int from = conn->from.fd;
int to = conn->to.fd;
@@ -302,16 +308,20 @@ static void runDaemon(bool stdio)
/* Auth hook is empty because in this mode we blindly trust the
standard streams. Limiting access to those is explicitly
not `nix-daemon`'s responsibility. */
- processConnection(openUncachedStore(), from, to, Trusted, NotRecursive, [&](Store & _){});
+ auto isTrusted = isTrustedOpt.value_or(Trusted);
+ processConnection(openUncachedStore(), from, to, isTrusted, NotRecursive, [&](Store & _){});
}
- } else
+ } else {
+ ensureNoTrustedFlag();
daemonLoop();
+ }
}
static int main_nix_daemon(int argc, char * * argv)
{
{
auto stdio = false;
+ std::optional<TrustedFlag> isTrustedOpt;
parseCmdLine(argc, argv, [&](Strings::iterator & arg, const Strings::iterator & end) {
if (*arg == "--daemon")
@@ -322,11 +332,17 @@ static int main_nix_daemon(int argc, char * * argv)
printVersion("nix-daemon");
else if (*arg == "--stdio")
stdio = true;
- else return false;
+ else if (*arg == "--trust") {
+ settings.requireExperimentalFeature("nix-testing");
+ isTrustedOpt = Trusted;
+ } else if (*arg == "--no-trust") {
+ settings.requireExperimentalFeature("nix-testing");
+ isTrustedOpt = NotTrusted;
+ } else return false;
return true;
});
- runDaemon(stdio);
+ runDaemon(stdio, isTrustedOpt);
return 0;
}