Get data needed by getBuildOutput() from the incoming NAR in a streaming fashion
[?]
Jul 27, 2020, 6:38 PM
N3G7LLGEYREJGGZFBFN4W3LPXQO4LPLTEATUFMUSNA3HXXH5KKKACDependencies
- [2]
ZMICO7M6Remove TokenServer in preparation of making NAR copying O(1) memory - [3]
5JMO43B4buildRemote(): Copy paths to the destination store in O(1) memory - [4]
N4IROACVMove buildRemote() into State - [5]
XCDTFZUYhydra-queue-runner: Fix build - [6]
BAFICF73Support hydra-build-products on binary cache stores - [7]
YNO7CQ6Phydra-queue-runner: More accurate memory accounting - [8]
EBJP3MNABuild against nix-master - [9]
T5BIOVJEAdd support for tracking custom metrics - [10]
2DNPZFPNStep cancellation: Don't use pthread_cancel() - [11]
BG6PEOB2Make the output size limit configurable - [12]
YSZQ3ORRFix build - [13]
5AIYUMTBBasic remote building - [14]
WV4SSAIYBuild against nix-master - [15]
U55WNIDPAbort unsupported build steps - [16]
DKJFD6JNProcess Nix API changes - [17]
YHP5DSOOImprove parsing of hydra-build-products - [18]
NAYQT2GThydra-queue-runner: Use cmdBuildDerivation - [19]
2GRQJZT6hydra-queue-runner: Support running in a NixOS container - [20]
24BMQDZAStart of single-process hydra-queue-runner - [21]
HPXFXHFSRemove SHA-1 hash from BuildProducts - [22]
3YSJ3LYKRemove finally.hh - [23]
MHVIT4JYSplit hydra-queue-runner.cc more - [24]
FITVNQ2SKeep track of the time we spend copying to/from build machines - [25]
NJJ7H64SVery basic multi-threaded queue runner - [26]
V6H6BWMKSync with Nix - [27]
G7KWXSFMDistinguish build step states - [28]
73YR46NJhydra-queue-runner: Write directly to a binary cache - [29]
WHULPA6SHandle failure with output - [30]
WDGARQ76Reuse build products / metrics stored in the database - [31]
UVNTWTWGPrevent download of NARs we just uploaded - [32]
LVQXQIYAKill active build steps when builds are cancelled - [33]
BYVRA54QTemporarily disable machines on any exception, not just connection failures - [34]
ACBS7C6Qhydra-queue-runner: Detect changes to the scheduling shares - [35]
EPWEMRI2Allow determinism checking for entire jobsets - [*]
HJOEIMLRRefactor - [*]
SL3WSRAChydra-queue-runner: Limit memory usage
Change contents
- replacement in src/hydra-queue-runner/Makefile.am at line 4
builder.cc build-result.cc build-remote.cc \build-result.hh counter.hh state.hh db.hhbuilder.cc build-result.cc build-remote.cc \build-result.hh counter.hh state.hh db.hh \nar-extractor.cc nar-extractor.hh - replacement in src/hydra-queue-runner/build-remote.cc at line 163
std::function<void(StepState)> updateStep)std::function<void(StepState)> updateStep,NarMemberDatas & narMembers) - edit in src/hydra-queue-runner/build-remote.cc at line 431
result.accessor = destStore->getFSAccessor(); - replacement in src/hydra-queue-runner/build-remote.cc at line 477
destStore->addToStore(info, from);/* Receive the NAR from the remote and add it to thedestination store. Meanwhile, extract all the info from theNAR that getBuildOutput() needs. */auto source2 = sinkToSource([&](Sink & sink){TeeSource tee(from, sink);extractNarData(tee, localStore->printStorePath(path), narMembers);});destStore->addToStore(info, *source2); - replacement in src/hydra-queue-runner/build-result.cc at line 11
BuildOutput getBuildOutput(nix::ref<Store> store,nix::ref<nix::FSAccessor> accessor, const Derivation & drv)BuildOutput getBuildOutput(nix::ref<Store> store,NarMemberDatas & narMembers,const Derivation & drv) - edit in src/hydra-queue-runner/build-result.cc at line 27
}/* Fetch missing data. Usually buildRemote() will have extractedthis data from the incoming NARs. */for (auto & output : outputs) {auto outputS = store->printStorePath(output);if (!narMembers.count(outputS)) {printInfo("fetching NAR contents of '%s'...", outputS);auto source = sinkToSource([&](Sink & sink){store->narFromPath(output, sink);});extractNarData(*source, outputS, narMembers);} - replacement in src/hydra-queue-runner/build-result.cc at line 58[4.3493]→[4.3493:3552](∅→∅),[4.3045]→[4.142:217](∅→∅),[4.3552]→[4.142:217](∅→∅),[4.58]→[4.142:217](∅→∅)
Path failedFile = outputS + "/nix-support/failed";if (accessor->stat(failedFile).type == FSAccessor::Type::tRegular)if (narMembers.count(outputS + "/nix-support/failed")) - replacement in src/hydra-queue-runner/build-result.cc at line 61[4.114]→[4.3553:3628](∅→∅),[4.3121]→[4.323:400](∅→∅),[4.3628]→[4.323:400](∅→∅),[4.323]→[4.323:400](∅→∅)
Path productsFile = outputS + "/nix-support/hydra-build-products";if (accessor->stat(productsFile).type != FSAccessor::Type::tRegular)auto productsFile = narMembers.find(outputS + "/nix-support/hydra-build-products");if (productsFile == narMembers.end() ||productsFile->second.type != FSAccessor::Type::tRegular) - edit in src/hydra-queue-runner/build-result.cc at line 65
assert(productsFile->second.contents); - replacement in src/hydra-queue-runner/build-result.cc at line 69
for (auto & line : tokenizeString<Strings>(accessor->readFile(productsFile), "\n")) {for (auto & line : tokenizeString<Strings>(productsFile->second.contents.value(), "\n")) { - replacement in src/hydra-queue-runner/build-result.cc at line 89
auto st = accessor->stat(product.path);if (st.type == FSAccessor::Type::tMissing) continue;auto file = narMembers.find(product.path);if (file == narMembers.end()) continue; - replacement in src/hydra-queue-runner/build-result.cc at line 94
if (st.type == FSAccessor::Type::tRegular) {if (file->second.type == FSAccessor::Type::tRegular) { - replacement in src/hydra-queue-runner/build-result.cc at line 96
product.fileSize = st.fileSize;auto contents = accessor->readFile(product.path);product.sha256hash = hashString(htSHA256, contents);product.fileSize = file->second.fileSize.value();product.sha256hash = file->second.sha256.value(); - replacement in src/hydra-queue-runner/build-result.cc at line 114[4.3665]→[4.1185:1292](∅→∅),[4.1292]→[4.3862:3935](∅→∅),[4.3428]→[4.1375:1432](∅→∅),[4.3935]→[4.1375:1432](∅→∅),[4.1375]→[4.1375:1432](∅→∅)
auto st = accessor->stat(product.path);if (st.type == FSAccessor::Type::tMissing)throw Error("getting status of ‘%s’", product.path);if (st.type == FSAccessor::Type::tDirectory)auto file = narMembers.find(product.path);assert(file != narMembers.end());if (file->second.type == FSAccessor::Type::tDirectory) - replacement in src/hydra-queue-runner/build-result.cc at line 123[4.4043]→[4.3936:4020](∅→∅),[4.3513]→[4.1433:1509](∅→∅),[4.4020]→[4.1433:1509](∅→∅),[4.4104]→[4.1433:1509](∅→∅),[4.1509]→[4.1103:1117](∅→∅),[4.4142]→[4.1103:1117](∅→∅),[4.1117]→[4.1510:1569](∅→∅),[4.1569]→[4.1166:1208](∅→∅),[4.1166]→[4.1166:1208](∅→∅)
auto p = store->printStorePath(output) + "/nix-support/hydra-release-name";if (accessor->stat(p).type != FSAccessor::Type::tRegular) continue;try {res.releaseName = trim(accessor->readFile(p));} catch (Error & e) { continue; }auto file = narMembers.find(store->printStorePath(output) + "/nix-support/hydra-release-name");if (file == narMembers.end() ||file->second.type != FSAccessor::Type::tRegular)continue;res.releaseName = trim(file->second.contents.value()); - replacement in src/hydra-queue-runner/build-result.cc at line 133[4.664]→[4.4021:4110](∅→∅),[4.3603]→[4.1636:1815](∅→∅),[4.4110]→[4.1636:1815](∅→∅),[4.1636]→[4.1636:1815](∅→∅)
auto metricsFile = store->printStorePath(output) + "/nix-support/hydra-metrics";if (accessor->stat(metricsFile).type != FSAccessor::Type::tRegular) continue;for (auto & line : tokenizeString<Strings>(accessor->readFile(metricsFile), "\n")) {auto file = narMembers.find(store->printStorePath(output) + "/nix-support/hydra-metrics");if (file == narMembers.end() ||file->second.type != FSAccessor::Type::tRegular)continue;for (auto & line : tokenizeString<Strings>(file->second.contents.value(), "\n")) { - edit in src/hydra-queue-runner/build-result.hh at line 8
#include "nar-extractor.hh" - replacement in src/hydra-queue-runner/build-result.hh at line 42
BuildOutput getBuildOutput(nix::ref<nix::Store> store,nix::ref<nix::FSAccessor> accessor, const nix::Derivation & drv);[4.4741]BuildOutput getBuildOutput(nix::ref<nix::Store> store,NarMemberDatas & narMembers,const nix::Derivation & drv); - edit in src/hydra-queue-runner/builder.cc at line 204
NarMemberDatas narMembers; - replacement in src/hydra-queue-runner/builder.cc at line 208
buildRemote(destStore, machine, step, maxSilentTime, buildTimeout, repeats, result, activeStep, updateStep);buildRemote(destStore, machine, step, maxSilentTime, buildTimeout, repeats, result, activeStep, updateStep, narMembers); - replacement in src/hydra-queue-runner/builder.cc at line 223
res = getBuildOutput(destStore, ref<FSAccessor>(result.accessor), *step->drv);res = getBuildOutput(destStore, narMembers, *step->drv); - edit in src/hydra-queue-runner/builder.cc at line 225
result.accessor = 0; - file addition: nar-extractor.cc[4.187]
#include "nar-extractor.hh"#include "archive.hh"#include <unordered_set>using namespace nix;struct Extractor : ParseSink{std::unordered_set<Path> filesToKeep {"/nix-support/hydra-build-products","/nix-support/hydra-release-name","/nix-support/hydra-metrics",};NarMemberDatas & members;NarMemberData * curMember = nullptr;Path prefix;Extractor(NarMemberDatas & members, const Path & prefix): members(members), prefix(prefix){ }void createDirectory(const Path & path) override{members.insert_or_assign(prefix + path, NarMemberData { .type = FSAccessor::Type::tDirectory });}void createRegularFile(const Path & path) override{curMember = &members.insert_or_assign(prefix + path, NarMemberData {.type = FSAccessor::Type::tRegular,.fileSize = 0,.contents = filesToKeep.count(path) ? std::optional("") : std::nullopt,}).first->second;}std::optional<unsigned long long> expectedSize;std::unique_ptr<HashSink> hashSink;void preallocateContents(unsigned long long size) override{expectedSize = size;hashSink = std::make_unique<HashSink>(htSHA256);}void receiveContents(unsigned char * data, unsigned int len) override{assert(expectedSize);assert(curMember);assert(hashSink);*curMember->fileSize += len;(*hashSink)(data, len);if (curMember->contents) {curMember->contents->append((char *) data, len);}assert(curMember->fileSize <= expectedSize);if (curMember->fileSize == expectedSize) {auto [hash, len] = hashSink->finish();assert(curMember->fileSize == len);curMember->sha256 = hash;hashSink.reset();}}void createSymlink(const Path & path, const string & target) override{members.insert_or_assign(prefix + path, NarMemberData { .type = FSAccessor::Type::tSymlink });}};void extractNarData(Source & source,const Path & prefix,NarMemberDatas & members){Extractor extractor(members, prefix);parseDump(extractor, source);// Note: this point may not be reached if we're in a coroutine.} - file addition: nar-extractor.hh[4.187]
#pragma once#include "fs-accessor.hh"#include "types.hh"#include "serialise.hh"#include "hash.hh"struct NarMemberData{nix::FSAccessor::Type type;std::optional<unsigned long long> fileSize;std::optional<std::string> contents;std::optional<nix::Hash> sha256;};typedef std::map<nix::Path, NarMemberData> NarMemberDatas;/* Read a NAR from a source and get to some info about every fileinside the NAR. */void extractNarData(nix::Source & source,const nix::Path & prefix,NarMemberDatas & members); - replacement in src/hydra-queue-runner/queue-monitor.cc at line 675
return getBuildOutput(destStore, destStore->getFSAccessor(), drv);NarMemberDatas narMembers;return getBuildOutput(destStore, narMembers, drv); - edit in src/hydra-queue-runner/state.hh at line 17[38.1567][37.1461]
#include "nar-extractor.hh" - edit in src/hydra-queue-runner/state.hh at line 68
std::shared_ptr<nix::FSAccessor> accessor; - replacement in src/hydra-queue-runner/state.hh at line 521
std::function<void(StepState)> updateStep);std::function<void(StepState)> updateStep,NarMemberDatas & narMembers);