1
1
Fork 0
mirror of https://github.com/NixOS/nix.git synced 2025-11-18 08:19:35 +01:00

Trustless remote building

Co-authored-by: Matthew Bauer <mjbauer95@gmail.com>
This commit is contained in:
John Ericson 2020-08-12 03:47:36 +00:00
parent 53f92c779a
commit cbc4344297
15 changed files with 181 additions and 12 deletions

View file

@ -247,6 +247,9 @@ static int _main(int argc, char * * argv)
connected:
close(5);
assert(sshStore);
auto sshStore2 = ref<Store>(sshStore);
std::cerr << "# accept\n" << storeUri << "\n";
auto inputs = readStrings<PathSet>(source);
@ -269,18 +272,23 @@ connected:
{
Activity act(*logger, lvlTalkative, actUnknown, fmt("copying dependencies to '%s'", storeUri));
copyPaths(store, ref<Store>(sshStore), store->parseStorePathSet(inputs), NoRepair, NoCheckSigs, substitute);
copyPaths(store, sshStore2, store->parseStorePathSet(inputs), NoRepair, NoCheckSigs, substitute);
}
uploadLock = -1;
auto drv = store->readDerivation(*drvPath);
drv.inputSrcs = store->parseStorePathSet(inputs);
BasicDerivation drv = store->readDerivation(*drvPath);
auto result = sshStore->buildDerivation(*drvPath, drv);
if (sshStore2->isTrusting || derivationIsCA(drv.type())) {
drv.inputSrcs = store->parseStorePathSet(inputs);
auto result = sshStore2->buildDerivation(*drvPath, drv);
if (!result.success())
throw Error("build of '%s' on '%s' failed: %s", store->printStorePath(*drvPath), storeUri, result.errorMsg);
} else {
copyPaths(store, sshStore2, {*drvPath}, NoRepair, NoCheckSigs, substitute);
sshStore2->buildPaths({{*drvPath}});
}
if (!result.success())
throw Error("build of '%s' on '%s' failed: %s", store->printStorePath(*drvPath), storeUri, result.errorMsg);
StorePathSet missing;
for (auto & path : outputs)
@ -290,7 +298,7 @@ connected:
Activity act(*logger, lvlTalkative, actUnknown, fmt("copying outputs from '%s'", storeUri));
for (auto & i : missing)
store->locksHeld.insert(store->printStorePath(i)); /* FIXME: ugly */
copyPaths(ref<Store>(sshStore), store, missing, NoRepair, NoCheckSigs, NoSubstitute);
copyPaths(sshStore2, store, missing, NoRepair, NoCheckSigs, NoSubstitute);
}
return 0;

View file

@ -914,6 +914,8 @@ void processConnection(
opCount++;
debug("performing daemon worker op: %d", op);
try {
performOp(tunnelLogger, store, trusted, recursive, clientVersion, from, to, op);
} catch (Error & e) {

View file

@ -834,7 +834,23 @@ std::map<StorePath, StorePath> copyPaths(ref<Store> srcStore, ref<Store> dstStor
MaintainCount<decltype(nrRunning)> mc(nrRunning);
showProgress();
try {
copyStorePath(srcStore, dstStore, storePath, repair, checkSigs);
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
copyStorePath(srcStore, dstStore, drvPath, repair, checkSigs);
dstStore->buildPaths({{
drvPath,
p != outputMap.end() ? StringSet { p->first } : StringSet {},
}});
} else {
dstStore->ensurePath(storePath);
}
} catch (Error &e) {
nrFailed++;
if (!settings.keepGoing)

View file

@ -158,7 +158,9 @@ public:
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)"};

View file

@ -268,6 +268,7 @@ static int _main(int argc, char * * argv)
{
{
auto stdio = false;
std::optional<TrustedFlag> isTrustedOpt;
parseCmdLine(argc, argv, [&](Strings::iterator & arg, const Strings::iterator & end) {
if (*arg == "--daemon")
@ -278,14 +279,26 @@ static int _main(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;
});
initPlugins();
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 (getStoreType() == tDaemon) {
ensureNoTrustedFlag();
// Forward on this connection to the real daemon
auto socketPath = settings.nixDaemonSocketFile;
auto s = socket(PF_UNIX, SOCK_STREAM, 0);
@ -335,9 +348,11 @@ static int _main(int argc, char * * argv)
/* Auth hook is empty because in this mode we blindly trust the
standard streams. Limitting access to thoses 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 {
ensureNoTrustedFlag();
daemonLoop(argv);
}