From 54675a0d94adae6c6164e93ba088edcc1f527647 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Janne=20He=C3=9F?= Date: Sun, 13 Feb 2022 14:24:36 +0100 Subject: [PATCH 001/285] Fix local store detection and related issues - Add localStore into the stash because it's used in templates - Hide the Channels button for non-local stores because the link 404s anyway - Fix a style issue when having popovers in dark mode --- src/lib/Hydra/Controller/Root.pm | 1 + src/root/static/css/hydra.css | 2 +- src/root/topbar.tt | 6 +++--- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/lib/Hydra/Controller/Root.pm b/src/lib/Hydra/Controller/Root.pm index c6843d29..641002e7 100644 --- a/src/lib/Hydra/Controller/Root.pm +++ b/src/lib/Hydra/Controller/Root.pm @@ -52,6 +52,7 @@ sub begin :Private { $c->stash->{tracker} = defined $c->config->{tracker} ? $c->config->{tracker} : ""; $c->stash->{flashMsg} = $c->flash->{flashMsg}; $c->stash->{successMsg} = $c->flash->{successMsg}; + $c->stash->{localStore} = isLocalStore; $c->stash->{isPrivateHydra} = $c->config->{private} // "0" ne "0"; diff --git a/src/root/static/css/hydra.css b/src/root/static/css/hydra.css index 475d61c2..252ba815 100644 --- a/src/root/static/css/hydra.css +++ b/src/root/static/css/hydra.css @@ -151,7 +151,7 @@ td.step-status span.warn { html { background-color: #1f1f1f; } - body, div.popover { + body, div.popover, div.popover-body { background-color: #1f1f1f; color: #fafafa !important; } diff --git a/src/root/topbar.tt b/src/root/topbar.tt index fdfbf431..7165aa15 100644 --- a/src/root/topbar.tt +++ b/src/root/topbar.tt @@ -42,7 +42,7 @@ [% INCLUDE menuItem uri = c.uri_for(c.controller('Project').action_for('project'), [project.name]) title = "Overview" %] [% INCLUDE menuItem uri = c.uri_for(c.controller('Project').action_for('all'), [project.name]) title = "Latest builds" %] - [% INCLUDE menuItem uri = c.uri_for('/project' project.name 'channel' 'latest') title = "Channel" %] + [% IF localStore %][% INCLUDE menuItem uri = c.uri_for('/project' project.name 'channel' 'latest') title = "Channel" %][% END %] [% END %] [% END %] @@ -59,7 +59,7 @@ [% INCLUDE menuItem uri = c.uri_for(c.controller('Jobset').action_for('all'), [project.name, jobset.name]) title = "Latest builds" %] - [% INCLUDE menuItem uri = c.uri_for('/jobset' project.name jobset.name 'channel' 'latest') title = "Channel" %] + [% IF localStore %][% INCLUDE menuItem uri = c.uri_for('/jobset' project.name jobset.name 'channel' 'latest') title = "Channel" %][% END %] [% END %] [% END %] @@ -73,7 +73,7 @@ [% INCLUDE menuItem uri = c.uri_for(c.controller('Job').action_for('all'), [project.name, jobset.name, job]) title = "Latest builds" %] - [% INCLUDE menuItem uri = c.uri_for('/job' project.name jobset.name job 'channel' 'latest') title = "Channel" %] + [% IF localStore %][% INCLUDE menuItem uri = c.uri_for('/job' project.name jobset.name job 'channel' 'latest') title = "Channel" %][% END %] [% END %] [% END %] From 1c846765273018ff9b97edbfcaf9e5884fd9e140 Mon Sep 17 00:00:00 2001 From: ajs124 Date: Mon, 10 May 2021 14:32:24 +0200 Subject: [PATCH 002/285] Fit more content on screen --- src/root/static/css/hydra.css | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/root/static/css/hydra.css b/src/root/static/css/hydra.css index 475d61c2..53304b19 100644 --- a/src/root/static/css/hydra.css +++ b/src/root/static/css/hydra.css @@ -1,5 +1,5 @@ div.skip-topbar { - padding-top: 40px; + padding-top: 20px; margin-bottom: 1.5em; } @@ -146,6 +146,26 @@ td.step-status span.warn { padding-top: 1.5rem; } +.container { + max-width: 80%; +} + +.tab-content { + margin-right: 0 !important; +} + +body { + line-height: 1; +} + +.navbar-nav { + line-height: 1.5; +} + +.dropdown-item { + line-height: 1.5; +} + @media (prefers-color-scheme: dark) { /* Prevent some flickering */ html { From f1f2fc742700c6f80f87758687afedefd9d08ac6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 7 Mar 2022 19:07:06 +0000 Subject: [PATCH 003/285] build(deps): bump actions/checkout from 2 to 3 Bumps [actions/checkout](https://github.com/actions/checkout) from 2 to 3. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v2...v3) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 7d98e3ff..8d32f581 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -6,7 +6,7 @@ jobs: tests: runs-on: ubuntu-18.04 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: fetch-depth: 0 - uses: cachix/install-nix-action@v12 From 5db8642224e996d0ebe3492cd55dfef6276d5a15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9ophane=20Hufschmitt?= Date: Mon, 21 Mar 2022 16:02:51 +0100 Subject: [PATCH 004/285] Factor out a struct representing a connection to a machine --- src/hydra-queue-runner/state.hh | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/hydra-queue-runner/state.hh b/src/hydra-queue-runner/state.hh index 8f303d28..059b03a1 100644 --- a/src/hydra-queue-runner/state.hh +++ b/src/hydra-queue-runner/state.hh @@ -290,6 +290,16 @@ struct Machine { return sshName == "localhost"; } + + // A connection to a machine + struct Connection { + nix::FdSink to; + nix::FdSource from; + unsigned int remoteVersion; + + // Backpointer to the machine + ptr machine; + }; }; From 2f494b783425d6703f23bc4f2cdbc70592a31990 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9ophane=20Hufschmitt?= Date: Mon, 21 Mar 2022 10:42:44 +0100 Subject: [PATCH 005/285] Factor out the creation of the log file --- src/hydra-queue-runner/build-remote.cc | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/src/hydra-queue-runner/build-remote.cc b/src/hydra-queue-runner/build-remote.cc index 464a35c8..2e258484 100644 --- a/src/hydra-queue-runner/build-remote.cc +++ b/src/hydra-queue-runner/build-remote.cc @@ -175,6 +175,18 @@ StorePaths reverseTopoSortPaths(const std::map & paths return sorted; } +std::pair openLogFile(const std::string & logDir, const StorePath & drvPath) +{ + string base(drvPath.to_string()); + auto logFile = logDir + "/" + string(base, 0, 2) + "/" + string(base, 2); + + createDirs(dirOf(logFile)); + + AutoCloseFD logFD = open(logFile.c_str(), O_CREAT | O_TRUNC | O_WRONLY, 0666); + if (!logFD) throw SysError("creating log file ‘%s’", logFile); + + return {std::move(logFile), std::move(logFD)}; +} void State::buildRemote(ref destStore, Machine::ptr machine, Step::ptr step, @@ -185,14 +197,9 @@ void State::buildRemote(ref destStore, { assert(BuildResult::TimedOut == 8); - string base(step->drvPath.to_string()); - result.logFile = logDir + "/" + string(base, 0, 2) + "/" + string(base, 2); - AutoDelete autoDelete(result.logFile, false); - - createDirs(dirOf(result.logFile)); - - AutoCloseFD logFD = open(result.logFile.c_str(), O_CREAT | O_TRUNC | O_WRONLY, 0666); - if (!logFD) throw SysError("creating log file ‘%s’", result.logFile); + auto [logFile, logFD] = openLogFile(logDir, step->drvPath); + AutoDelete logFileDel(logFile, false); + result.logFile = logFile; nix::Path tmpDir = createTempDir(); AutoDelete tmpDirDel(tmpDir, true); @@ -316,7 +323,7 @@ void State::buildRemote(ref destStore, result.overhead += std::chrono::duration_cast(now2 - now1).count(); } - autoDelete.cancel(); + logFileDel.cancel(); /* Truncate the log to get rid of messages about substitutions etc. on the remote system. */ From 9f1b911625cbc92023b6aec936a505a46af3172f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9ophane=20Hufschmitt?= Date: Mon, 21 Mar 2022 11:35:38 +0100 Subject: [PATCH 006/285] Factor more stuff out --- src/hydra-queue-runner/build-remote.cc | 224 ++++++++++++++----------- 1 file changed, 122 insertions(+), 102 deletions(-) diff --git a/src/hydra-queue-runner/build-remote.cc b/src/hydra-queue-runner/build-remote.cc index 2e258484..360a8ef7 100644 --- a/src/hydra-queue-runner/build-remote.cc +++ b/src/hydra-queue-runner/build-remote.cc @@ -188,6 +188,87 @@ std::pair openLogFile(const std::string & logDir, const Store return {std::move(logFile), std::move(logFD)}; } +void handshake(Machine::Connection & conn, unsigned int repeats) +{ + conn.to << SERVE_MAGIC_1 << 0x204; + conn.to.flush(); + + unsigned int magic = readInt(conn.from); + if (magic != SERVE_MAGIC_2) + throw Error("protocol mismatch with ‘nix-store --serve’ on ‘%1%’", conn.machine->sshName); + conn.remoteVersion = readInt(conn.from); + if (GET_PROTOCOL_MAJOR(conn.remoteVersion) != 0x200) + throw Error("unsupported ‘nix-store --serve’ protocol version on ‘%1%’", conn.machine->sshName); + if (GET_PROTOCOL_MINOR(conn.remoteVersion) < 3 && repeats > 0) + throw Error("machine ‘%1%’ does not support repeating a build; please upgrade it to Nix 1.12", conn.machine->sshName); +} + +StorePathSet sendInputs( + State & state, + Step & step, + Store & localStore, + Store & destStore, + Machine::Connection & conn, + unsigned int & overhead, + counter & nrStepsWaiting, + counter & nrStepsCopyingTo +) +{ + + StorePathSet inputs; + BasicDerivation basicDrv(*step.drv); + + for (auto & p : step.drv->inputSrcs) + inputs.insert(p); + + for (auto & input : step.drv->inputDrvs) { + auto drv2 = localStore.readDerivation(input.first); + for (auto & name : input.second) { + if (auto i = get(drv2.outputs, name)) { + auto outPath = i->path(localStore, drv2.name, name); + inputs.insert(*outPath); + basicDrv.inputSrcs.insert(*outPath); + } + } + } + + /* Ensure that the inputs exist in the destination store. This is + a no-op for regular stores, but for the binary cache store, + this will copy the inputs to the binary cache from the local + store. */ + if (localStore.getUri() != destStore.getUri()) { + StorePathSet closure; + localStore.computeFSClosure(step.drv->inputSrcs, closure); + copyPaths(localStore, destStore, closure, NoRepair, NoCheckSigs, NoSubstitute); + } + + { + auto mc1 = std::make_shared>(nrStepsWaiting); + mc1.reset(); + MaintainCount mc2(nrStepsCopyingTo); + + printMsg(lvlDebug, "sending closure of ‘%s’ to ‘%s’", + localStore.printStorePath(step.drvPath), conn.machine->sshName); + + auto now1 = std::chrono::steady_clock::now(); + + /* Copy the input closure. */ + if (conn.machine->isLocalhost()) { + StorePathSet closure; + destStore.computeFSClosure(inputs, closure); + copyPaths(destStore, localStore, closure, NoRepair, NoCheckSigs, NoSubstitute); + } else { + copyClosureTo(conn.machine->state->sendLock, destStore, conn.from, conn.to, inputs, true); + } + + auto now2 = std::chrono::steady_clock::now(); + + overhead += std::chrono::duration_cast(now2 - now1).count(); + } + + return inputs; +} + void State::buildRemote(ref destStore, Machine::ptr machine, Step::ptr step, unsigned int maxSilentTime, unsigned int buildTimeout, unsigned int repeats, @@ -230,33 +311,21 @@ void State::buildRemote(ref destStore, process. Meh. */ }); - FdSource from(child.from.get()); - FdSink to(child.to.get()); + Machine::Connection conn; + conn.from = child.from.get(); + conn.to = child.to.get(); + conn.machine = machine; Finally updateStats([&]() { - bytesReceived += from.read; - bytesSent += to.written; + bytesReceived += conn.from.read; + bytesSent += conn.to.written; }); - /* Handshake. */ - unsigned int remoteVersion; - try { - to << SERVE_MAGIC_1 << 0x204; - to.flush(); - - unsigned int magic = readInt(from); - if (magic != SERVE_MAGIC_2) - throw Error("protocol mismatch with ‘nix-store --serve’ on ‘%1%’", machine->sshName); - remoteVersion = readInt(from); - if (GET_PROTOCOL_MAJOR(remoteVersion) != 0x200) - throw Error("unsupported ‘nix-store --serve’ protocol version on ‘%1%’", machine->sshName); - if (GET_PROTOCOL_MINOR(remoteVersion) < 3 && repeats > 0) - throw Error("machine ‘%1%’ does not support repeating a build; please upgrade it to Nix 1.12", machine->sshName); - + handshake(conn, repeats); } catch (EndOfFile & e) { child.pid.wait(); - string s = chomp(readFile(result.logFile)); + std::string s = chomp(readFile(result.logFile)); throw Error("cannot connect to ‘%1%’: %2%", machine->sshName, s); } @@ -272,61 +341,12 @@ void State::buildRemote(ref destStore, outputs of the input derivations. */ updateStep(ssSendingInputs); - StorePathSet inputs; - BasicDerivation basicDrv(*step->drv); - - for (auto & p : step->drv->inputSrcs) - inputs.insert(p); - - for (auto & input : step->drv->inputDrvs) { - auto drv2 = localStore->readDerivation(input.first); - for (auto & name : input.second) { - if (auto i = get(drv2.outputs, name)) { - auto outPath = i->path(*localStore, drv2.name, name); - inputs.insert(*outPath); - basicDrv.inputSrcs.insert(*outPath); - } - } - } - - /* Ensure that the inputs exist in the destination store. This is - a no-op for regular stores, but for the binary cache store, - this will copy the inputs to the binary cache from the local - store. */ - if (localStore != std::shared_ptr(destStore)) { - StorePathSet closure; - localStore->computeFSClosure(step->drv->inputSrcs, closure); - copyPaths(*localStore, *destStore, closure, NoRepair, NoCheckSigs, NoSubstitute); - } - - { - auto mc1 = std::make_shared>(nrStepsWaiting); - mc1.reset(); - MaintainCount mc2(nrStepsCopyingTo); - - printMsg(lvlDebug, "sending closure of ‘%s’ to ‘%s’", - localStore->printStorePath(step->drvPath), machine->sshName); - - auto now1 = std::chrono::steady_clock::now(); - - /* Copy the input closure. */ - if (machine->isLocalhost()) { - StorePathSet closure; - destStore->computeFSClosure(inputs, closure); - copyPaths(*destStore, *localStore, closure, NoRepair, NoCheckSigs, NoSubstitute); - } else { - copyClosureTo(machine->state->sendLock, *destStore, from, to, inputs, true); - } - - auto now2 = std::chrono::steady_clock::now(); - - result.overhead += std::chrono::duration_cast(now2 - now1).count(); - } + StorePathSet inputs = sendInputs(*this, *step, *localStore, *destStore, conn, result.overhead, nrStepsWaiting, nrStepsCopyingTo); logFileDel.cancel(); /* Truncate the log to get rid of messages about substitutions - etc. on the remote system. */ + etc. on the remote system. */ if (lseek(logFD.get(), SEEK_SET, 0) != 0) throw SysError("seeking to the start of log file ‘%s’", result.logFile); @@ -342,31 +362,31 @@ void State::buildRemote(ref destStore, updateStep(ssBuilding); - to << cmdBuildDerivation << localStore->printStorePath(step->drvPath); - writeDerivation(to, *localStore, basicDrv); - to << maxSilentTime << buildTimeout; - if (GET_PROTOCOL_MINOR(remoteVersion) >= 2) - to << maxLogSize; - if (GET_PROTOCOL_MINOR(remoteVersion) >= 3) { - to << repeats // == build-repeat + conn.to << cmdBuildDerivation << localStore->printStorePath(step->drvPath); + writeDerivation(conn.to, *localStore, BasicDerivation(*step->drv)); + conn.to << maxSilentTime << buildTimeout; + if (GET_PROTOCOL_MINOR(conn.remoteVersion) >= 2) + conn.to << maxLogSize; + if (GET_PROTOCOL_MINOR(conn.remoteVersion) >= 3) { + conn.to << repeats // == build-repeat << step->isDeterministic; // == enforce-determinism } - to.flush(); + conn.to.flush(); result.startTime = time(0); int res; { MaintainCount mc(nrStepsBuilding); - res = readInt(from); + res = readInt(conn.from); } result.stopTime = time(0); - result.errorMsg = readString(from); - if (GET_PROTOCOL_MINOR(remoteVersion) >= 3) { - result.timesBuilt = readInt(from); - result.isNonDeterministic = readInt(from); - auto start = readInt(from); - auto stop = readInt(from); + result.errorMsg = readString(conn.from); + if (GET_PROTOCOL_MINOR(conn.remoteVersion) >= 3) { + result.timesBuilt = readInt(conn.from); + result.isNonDeterministic = readInt(conn.from); + auto start = readInt(conn.from); + auto stop = readInt(conn.from); if (start && start) { /* Note: this represents the duration of a single round, rather than all rounds. */ @@ -374,8 +394,8 @@ void State::buildRemote(ref destStore, result.stopTime = stop; } } - if (GET_PROTOCOL_MINOR(remoteVersion) >= 6) { - worker_proto::read(*localStore, from, Phantom {}); + if (GET_PROTOCOL_MINOR(conn.remoteVersion) >= 6) { + worker_proto::read(*localStore, conn.from, Phantom {}); } switch ((BuildResult::Status) res) { case BuildResult::Built: @@ -451,19 +471,19 @@ void State::buildRemote(ref destStore, /* Get info about each output path. */ std::map infos; size_t totalNarSize = 0; - to << cmdQueryPathInfos; - worker_proto::write(*localStore, to, outputs); - to.flush(); + conn.to << cmdQueryPathInfos; + worker_proto::write(*localStore, conn.to, outputs); + conn.to.flush(); while (true) { - auto storePathS = readString(from); + auto storePathS = readString(conn.from); if (storePathS == "") break; - auto deriver = readString(from); // deriver - auto references = worker_proto::read(*localStore, from, Phantom {}); - readLongLong(from); // download size - auto narSize = readLongLong(from); - auto narHash = Hash::parseAny(readString(from), htSHA256); - auto ca = parseContentAddressOpt(readString(from)); - readStrings(from); // sigs + auto deriver = readString(conn.from); // deriver + auto references = worker_proto::read(*localStore, conn.from, Phantom {}); + readLongLong(conn.from); // download size + auto narSize = readLongLong(conn.from); + auto narHash = Hash::parseAny(readString(conn.from), htSHA256); + auto ca = parseContentAddressOpt(readString(conn.from)); + readStrings(conn.from); // sigs ValidPathInfo info(localStore->parseStorePath(storePathS), narHash); assert(outputs.count(info.path)); info.references = references; @@ -502,10 +522,10 @@ void State::buildRemote(ref destStore, lambda function only gets executed if someone tries to read from source2, we will send the command from here rather than outside the lambda. */ - to << cmdDumpStorePath << localStore->printStorePath(path); - to.flush(); + conn.to << cmdDumpStorePath << localStore->printStorePath(path); + conn.to.flush(); - TeeSource tee(from, sink); + TeeSource tee(conn.from, sink); extractNarData(tee, localStore->printStorePath(path), narMembers); }); From 365776f5d77112842d4a094a596cb725123b535d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9ophane=20Hufschmitt?= Date: Mon, 21 Mar 2022 12:14:37 +0100 Subject: [PATCH 007/285] Factor out the building part --- src/hydra-queue-runner/build-remote.cc | 207 ++++++++++++++++--------- src/hydra-queue-runner/state.hh | 2 + 2 files changed, 132 insertions(+), 77 deletions(-) diff --git a/src/hydra-queue-runner/build-remote.cc b/src/hydra-queue-runner/build-remote.cc index 360a8ef7..7934d401 100644 --- a/src/hydra-queue-runner/build-remote.cc +++ b/src/hydra-queue-runner/build-remote.cc @@ -269,6 +269,121 @@ StorePathSet sendInputs( return inputs; } +struct BuildOptions { + unsigned int maxSilentTime, buildTimeout, repeats; + size_t maxLogSize; + bool enforceDeterminism; +}; + +void RemoteResult::updateWithBuildResult(const nix::BuildResult & buildResult) +{ + RemoteResult thisArrow; + + startTime = buildResult.startTime; + stopTime = buildResult.stopTime; + timesBuilt = buildResult.timesBuilt; + errorMsg = buildResult.errorMsg; + isNonDeterministic = buildResult.isNonDeterministic; + + switch ((BuildResult::Status) buildResult.status) { + case BuildResult::Built: + stepStatus = bsSuccess; + break; + case BuildResult::Substituted: + case BuildResult::AlreadyValid: + stepStatus = bsSuccess; + isCached = true; + break; + case BuildResult::PermanentFailure: + stepStatus = bsFailed; + canCache = true; + errorMsg = ""; + break; + case BuildResult::InputRejected: + case BuildResult::OutputRejected: + stepStatus = bsFailed; + canCache = true; + break; + case BuildResult::TransientFailure: + stepStatus = bsFailed; + canRetry = true; + errorMsg = ""; + break; + case BuildResult::TimedOut: + stepStatus = bsTimedOut; + errorMsg = ""; + break; + case BuildResult::MiscFailure: + stepStatus = bsAborted; + canRetry = true; + break; + case BuildResult::LogLimitExceeded: + stepStatus = bsLogLimitExceeded; + break; + case BuildResult::NotDeterministic: + stepStatus = bsNotDeterministic; + canRetry = false; + canCache = true; + break; + default: + stepStatus = bsAborted; + break; + } + +} + +BuildResult performBuild( + Machine::Connection & conn, + Store & localStore, + StorePath drvPath, + const BasicDerivation & drv, + const BuildOptions & options, + counter & nrStepsBuilding +) +{ + + BuildResult result; + + conn.to << cmdBuildDerivation << localStore.printStorePath(drvPath); + writeDerivation(conn.to, localStore, drv); + conn.to << options.maxSilentTime << options.buildTimeout; + if (GET_PROTOCOL_MINOR(conn.remoteVersion) >= 2) + conn.to << options.maxLogSize; + if (GET_PROTOCOL_MINOR(conn.remoteVersion) >= 3) { + conn.to << options.repeats // == build-repeat + << options.enforceDeterminism; + } + conn.to.flush(); + + result.startTime = time(0); + + { + MaintainCount mc(nrStepsBuilding); + result.status = (BuildResult::Status)readInt(conn.from); + } + result.stopTime = time(0); + + + result.errorMsg = readString(conn.from); + if (GET_PROTOCOL_MINOR(conn.remoteVersion) >= 3) { + result.timesBuilt = readInt(conn.from); + result.isNonDeterministic = readInt(conn.from); + auto start = readInt(conn.from); + auto stop = readInt(conn.from); + if (start && start) { + /* Note: this represents the duration of a single + round, rather than all rounds. */ + result.startTime = start; + result.stopTime = stop; + } + } + if (GET_PROTOCOL_MINOR(conn.remoteVersion) >= 6) { + result.builtOutputs = worker_proto::read(localStore, conn.from, Phantom {}); + } + + return result; +} + void State::buildRemote(ref destStore, Machine::ptr machine, Step::ptr step, unsigned int maxSilentTime, unsigned int buildTimeout, unsigned int repeats, @@ -362,85 +477,23 @@ void State::buildRemote(ref destStore, updateStep(ssBuilding); - conn.to << cmdBuildDerivation << localStore->printStorePath(step->drvPath); - writeDerivation(conn.to, *localStore, BasicDerivation(*step->drv)); - conn.to << maxSilentTime << buildTimeout; - if (GET_PROTOCOL_MINOR(conn.remoteVersion) >= 2) - conn.to << maxLogSize; - if (GET_PROTOCOL_MINOR(conn.remoteVersion) >= 3) { - conn.to << repeats // == build-repeat - << step->isDeterministic; // == enforce-determinism - } - conn.to.flush(); + BuildResult buildResult = performBuild( + conn, + *localStore, + step->drvPath, + BasicDerivation(*step->drv), + { + .maxSilentTime = maxSilentTime, + .buildTimeout = buildTimeout, + .repeats = repeats, + .maxLogSize = maxLogSize, + .enforceDeterminism = step->isDeterministic, + }, + nrStepsBuilding + ); - result.startTime = time(0); - int res; - { - MaintainCount mc(nrStepsBuilding); - res = readInt(conn.from); - } - result.stopTime = time(0); + result.updateWithBuildResult(buildResult); - result.errorMsg = readString(conn.from); - if (GET_PROTOCOL_MINOR(conn.remoteVersion) >= 3) { - result.timesBuilt = readInt(conn.from); - result.isNonDeterministic = readInt(conn.from); - auto start = readInt(conn.from); - auto stop = readInt(conn.from); - if (start && start) { - /* Note: this represents the duration of a single - round, rather than all rounds. */ - result.startTime = start; - result.stopTime = stop; - } - } - if (GET_PROTOCOL_MINOR(conn.remoteVersion) >= 6) { - worker_proto::read(*localStore, conn.from, Phantom {}); - } - switch ((BuildResult::Status) res) { - case BuildResult::Built: - result.stepStatus = bsSuccess; - break; - case BuildResult::Substituted: - case BuildResult::AlreadyValid: - result.stepStatus = bsSuccess; - result.isCached = true; - break; - case BuildResult::PermanentFailure: - result.stepStatus = bsFailed; - result.canCache = true; - result.errorMsg = ""; - break; - case BuildResult::InputRejected: - case BuildResult::OutputRejected: - result.stepStatus = bsFailed; - result.canCache = true; - break; - case BuildResult::TransientFailure: - result.stepStatus = bsFailed; - result.canRetry = true; - result.errorMsg = ""; - break; - case BuildResult::TimedOut: - result.stepStatus = bsTimedOut; - result.errorMsg = ""; - break; - case BuildResult::MiscFailure: - result.stepStatus = bsAborted; - result.canRetry = true; - break; - case BuildResult::LogLimitExceeded: - result.stepStatus = bsLogLimitExceeded; - break; - case BuildResult::NotDeterministic: - result.stepStatus = bsNotDeterministic; - result.canRetry = false; - result.canCache = true; - break; - default: - result.stepStatus = bsAborted; - break; - } if (result.stepStatus != bsSuccess) return; result.errorMsg = ""; diff --git a/src/hydra-queue-runner/state.hh b/src/hydra-queue-runner/state.hh index 059b03a1..6292a2db 100644 --- a/src/hydra-queue-runner/state.hh +++ b/src/hydra-queue-runner/state.hh @@ -72,6 +72,8 @@ struct RemoteResult { return stepStatus == bsCachedFailure ? bsFailed : stepStatus; } + + void updateWithBuildResult(const nix::BuildResult &); }; From a778a89f0424b5bffa66818cf0b46ffa945403c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9ophane=20Hufschmitt?= Date: Mon, 21 Mar 2022 15:16:32 +0100 Subject: [PATCH 008/285] Factor out the `queryPathInfos` part of the build --- src/hydra-queue-runner/build-remote.cc | 65 +++++++++++++++----------- 1 file changed, 39 insertions(+), 26 deletions(-) diff --git a/src/hydra-queue-runner/build-remote.cc b/src/hydra-queue-runner/build-remote.cc index 7934d401..0451ccb7 100644 --- a/src/hydra-queue-runner/build-remote.cc +++ b/src/hydra-queue-runner/build-remote.cc @@ -384,6 +384,44 @@ BuildResult performBuild( return result; } +std::map queryPathInfos( + Machine::Connection & conn, + Store & localStore, + StorePathSet & outputs, + size_t & totalNarSize +) +{ + + /* Get info about each output path. */ + std::map infos; + conn.to << cmdQueryPathInfos; + worker_proto::write(localStore, conn.to, outputs); + conn.to.flush(); + while (true) { + auto storePathS = readString(conn.from); + if (storePathS == "") break; + auto deriver = readString(conn.from); // deriver + auto references = worker_proto::read(localStore, conn.from, Phantom {}); + readLongLong(conn.from); // download size + auto narSize = readLongLong(conn.from); + auto narHash = Hash::parseAny(readString(conn.from), htSHA256); + auto ca = parseContentAddressOpt(readString(conn.from)); + readStrings(conn.from); // sigs + ValidPathInfo info(localStore.parseStorePath(storePathS), narHash); + assert(outputs.count(info.path)); + info.references = references; + info.narSize = narSize; + totalNarSize += info.narSize; + info.narHash = narHash; + info.ca = ca; + if (deriver != "") + info.deriver = localStore.parseStorePath(deriver); + infos.insert_or_assign(info.path, info); + } + + return infos; +} + void State::buildRemote(ref destStore, Machine::ptr machine, Step::ptr step, unsigned int maxSilentTime, unsigned int buildTimeout, unsigned int repeats, @@ -521,33 +559,8 @@ void State::buildRemote(ref destStore, outputs.insert(*i.second.second); } - /* Get info about each output path. */ - std::map infos; size_t totalNarSize = 0; - conn.to << cmdQueryPathInfos; - worker_proto::write(*localStore, conn.to, outputs); - conn.to.flush(); - while (true) { - auto storePathS = readString(conn.from); - if (storePathS == "") break; - auto deriver = readString(conn.from); // deriver - auto references = worker_proto::read(*localStore, conn.from, Phantom {}); - readLongLong(conn.from); // download size - auto narSize = readLongLong(conn.from); - auto narHash = Hash::parseAny(readString(conn.from), htSHA256); - auto ca = parseContentAddressOpt(readString(conn.from)); - readStrings(conn.from); // sigs - ValidPathInfo info(localStore->parseStorePath(storePathS), narHash); - assert(outputs.count(info.path)); - info.references = references; - info.narSize = narSize; - totalNarSize += info.narSize; - info.narHash = narHash; - info.ca = ca; - if (deriver != "") - info.deriver = localStore->parseStorePath(deriver); - infos.insert_or_assign(info.path, info); - } + auto infos = queryPathInfos(conn, *localStore, outputs, totalNarSize); if (totalNarSize > maxOutputSize) { result.stepStatus = bsNarSizeLimitExceeded; From fd0ae78eba058ab456590da698b45082fcafb519 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9ophane=20Hufschmitt?= Date: Mon, 21 Mar 2022 15:26:31 +0100 Subject: [PATCH 009/285] Factor out the copying from the build store --- src/hydra-queue-runner/build-remote.cc | 76 +++++++++++++++++--------- 1 file changed, 49 insertions(+), 27 deletions(-) diff --git a/src/hydra-queue-runner/build-remote.cc b/src/hydra-queue-runner/build-remote.cc index 0451ccb7..79e5a231 100644 --- a/src/hydra-queue-runner/build-remote.cc +++ b/src/hydra-queue-runner/build-remote.cc @@ -422,6 +422,54 @@ std::map queryPathInfos( return infos; } +void copyPathFromRemote( + Machine::Connection & conn, + NarMemberDatas & narMembers, + Store & localStore, + Store & destStore, + const ValidPathInfo & info +) +{ + /* Receive the NAR from the remote and add it to the + destination store. Meanwhile, extract all the info from the + NAR that getBuildOutput() needs. */ + auto source2 = sinkToSource([&](Sink & sink) + { + /* Note: we should only send the command to dump the store + path to the remote if the NAR is actually going to get read + by the destination store, which won't happen if this path + is already valid on the destination store. Since this + lambda function only gets executed if someone tries to read + from source2, we will send the command from here rather + than outside the lambda. */ + conn.to << cmdDumpStorePath << localStore.printStorePath(info.path); + conn.to.flush(); + + TeeSource tee(conn.from, sink); + extractNarData(tee, localStore.printStorePath(info.path), narMembers); + }); + + destStore.addToStore(info, *source2, NoRepair, NoCheckSigs); +} + +void copyPathsFromRemote( + Machine::Connection & conn, + NarMemberDatas & narMembers, + Store & localStore, + Store & destStore, + const std::map & infos +) +{ + auto pathsSorted = reverseTopoSortPaths(infos); + + for (auto & path : pathsSorted) { + auto & info = infos.find(path)->second; + copyPathFromRemote(conn, narMembers, localStore, destStore, info); + } + +} + + void State::buildRemote(ref destStore, Machine::ptr machine, Step::ptr step, unsigned int maxSilentTime, unsigned int buildTimeout, unsigned int repeats, @@ -571,33 +619,7 @@ void State::buildRemote(ref destStore, printMsg(lvlDebug, "copying outputs of ‘%s’ from ‘%s’ (%d bytes)", localStore->printStorePath(step->drvPath), machine->sshName, totalNarSize); - auto pathsSorted = reverseTopoSortPaths(infos); - - for (auto & path : pathsSorted) { - auto & info = infos.find(path)->second; - - /* Receive the NAR from the remote and add it to the - destination store. Meanwhile, extract all the info from the - NAR that getBuildOutput() needs. */ - auto source2 = sinkToSource([&](Sink & sink) - { - /* Note: we should only send the command to dump the store - path to the remote if the NAR is actually going to get read - by the destination store, which won't happen if this path - is already valid on the destination store. Since this - lambda function only gets executed if someone tries to read - from source2, we will send the command from here rather - than outside the lambda. */ - conn.to << cmdDumpStorePath << localStore->printStorePath(path); - conn.to.flush(); - - TeeSource tee(conn.from, sink); - extractNarData(tee, localStore->printStorePath(path), narMembers); - }); - - destStore->addToStore(info, *source2, NoRepair, NoCheckSigs); - } - + copyPathsFromRemote(conn, narMembers, *localStore, *destStore, infos); auto now2 = std::chrono::steady_clock::now(); result.overhead += std::chrono::duration_cast(now2 - now1).count(); From b430d41afd6a4ca0e38343ae2eee4aa6307cf980 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9ophane=20Hufschmitt?= Date: Mon, 21 Mar 2022 16:33:25 +0100 Subject: [PATCH 010/285] Use the `BuildOptions` more eagerly --- src/hydra-queue-runner/build-remote.cc | 20 ++++---------------- src/hydra-queue-runner/builder.cc | 16 +++++++++------- src/hydra-queue-runner/state.hh | 9 +++++++-- 3 files changed, 20 insertions(+), 25 deletions(-) diff --git a/src/hydra-queue-runner/build-remote.cc b/src/hydra-queue-runner/build-remote.cc index 79e5a231..1e06e501 100644 --- a/src/hydra-queue-runner/build-remote.cc +++ b/src/hydra-queue-runner/build-remote.cc @@ -269,12 +269,6 @@ StorePathSet sendInputs( return inputs; } -struct BuildOptions { - unsigned int maxSilentTime, buildTimeout, repeats; - size_t maxLogSize; - bool enforceDeterminism; -}; - void RemoteResult::updateWithBuildResult(const nix::BuildResult & buildResult) { RemoteResult thisArrow; @@ -337,7 +331,7 @@ BuildResult performBuild( Store & localStore, StorePath drvPath, const BasicDerivation & drv, - const BuildOptions & options, + const State::BuildOptions & options, counter & nrStepsBuilding ) { @@ -472,7 +466,7 @@ void copyPathsFromRemote( void State::buildRemote(ref destStore, Machine::ptr machine, Step::ptr step, - unsigned int maxSilentTime, unsigned int buildTimeout, unsigned int repeats, + const BuildOptions & buildOptions, RemoteResult & result, std::shared_ptr activeStep, std::function updateStep, NarMemberDatas & narMembers) @@ -523,7 +517,7 @@ void State::buildRemote(ref destStore, }); try { - handshake(conn, repeats); + handshake(conn, buildOptions.repeats); } catch (EndOfFile & e) { child.pid.wait(); std::string s = chomp(readFile(result.logFile)); @@ -568,13 +562,7 @@ void State::buildRemote(ref destStore, *localStore, step->drvPath, BasicDerivation(*step->drv), - { - .maxSilentTime = maxSilentTime, - .buildTimeout = buildTimeout, - .repeats = repeats, - .maxLogSize = maxLogSize, - .enforceDeterminism = step->isDeterministic, - }, + buildOptions, nrStepsBuilding ); diff --git a/src/hydra-queue-runner/builder.cc b/src/hydra-queue-runner/builder.cc index 89aa7d15..b25b4e63 100644 --- a/src/hydra-queue-runner/builder.cc +++ b/src/hydra-queue-runner/builder.cc @@ -98,8 +98,10 @@ State::StepResult State::doBuildStep(nix::ref destStore, it). */ BuildID buildId; std::optional buildDrvPath; - unsigned int maxSilentTime, buildTimeout; - unsigned int repeats = step->isDeterministic ? 1 : 0; + BuildOptions buildOptions; + buildOptions.repeats = step->isDeterministic ? 1 : 0; + buildOptions.maxLogSize = maxLogSize; + buildOptions.enforceDeterminism = step->isDeterministic; auto conn(dbPool.get()); @@ -134,18 +136,18 @@ State::StepResult State::doBuildStep(nix::ref destStore, { auto i = jobsetRepeats.find(std::make_pair(build2->projectName, build2->jobsetName)); if (i != jobsetRepeats.end()) - repeats = std::max(repeats, i->second); + buildOptions.repeats = std::max(buildOptions.repeats, i->second); } } if (!build) build = *dependents.begin(); buildId = build->id; buildDrvPath = build->drvPath; - maxSilentTime = build->maxSilentTime; - buildTimeout = build->buildTimeout; + buildOptions.maxSilentTime = build->maxSilentTime; + buildOptions.buildTimeout = build->buildTimeout; printInfo("performing step ‘%s’ %d times on ‘%s’ (needed by build %d and %d others)", - localStore->printStorePath(step->drvPath), repeats + 1, machine->sshName, buildId, (dependents.size() - 1)); + localStore->printStorePath(step->drvPath), buildOptions.repeats + 1, machine->sshName, buildId, (dependents.size() - 1)); } if (!buildOneDone) @@ -206,7 +208,7 @@ State::StepResult State::doBuildStep(nix::ref destStore, try { /* FIXME: referring builds may have conflicting timeouts. */ - buildRemote(destStore, machine, step, maxSilentTime, buildTimeout, repeats, result, activeStep, updateStep, narMembers); + buildRemote(destStore, machine, step, buildOptions, result, activeStep, updateStep, narMembers); } catch (Error & e) { if (activeStep->state_.lock()->cancelled) { printInfo("marking step %d of build %d as cancelled", stepNr, buildId); diff --git a/src/hydra-queue-runner/state.hh b/src/hydra-queue-runner/state.hh index 6292a2db..f4d8ccce 100644 --- a/src/hydra-queue-runner/state.hh +++ b/src/hydra-queue-runner/state.hh @@ -447,6 +447,12 @@ private: public: State(); + struct BuildOptions { + unsigned int maxSilentTime, buildTimeout, repeats; + size_t maxLogSize; + bool enforceDeterminism; + }; + private: nix::MaintainCount startDbUpdate(); @@ -531,8 +537,7 @@ private: void buildRemote(nix::ref destStore, Machine::ptr machine, Step::ptr step, - unsigned int maxSilentTime, unsigned int buildTimeout, - unsigned int repeats, + const BuildOptions & buildOptions, RemoteResult & result, std::shared_ptr activeStep, std::function updateStep, NarMemberDatas & narMembers); From 92b627ac1b3e0f53f6b35fc5940406c12fa977da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9ophane=20Hufschmitt?= <7226587+thufschmitt@users.noreply.github.com> Date: Thu, 24 Mar 2022 09:39:24 +0100 Subject: [PATCH 011/285] Remove an accidental re-indenting of a comment Co-authored-by: Eelco Dolstra --- src/hydra-queue-runner/build-remote.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/hydra-queue-runner/build-remote.cc b/src/hydra-queue-runner/build-remote.cc index 1e06e501..901bbc89 100644 --- a/src/hydra-queue-runner/build-remote.cc +++ b/src/hydra-queue-runner/build-remote.cc @@ -233,9 +233,9 @@ StorePathSet sendInputs( } /* Ensure that the inputs exist in the destination store. This is - a no-op for regular stores, but for the binary cache store, - this will copy the inputs to the binary cache from the local - store. */ + a no-op for regular stores, but for the binary cache store, + this will copy the inputs to the binary cache from the local + store. */ if (localStore.getUri() != destStore.getUri()) { StorePathSet closure; localStore.computeFSClosure(step.drv->inputSrcs, closure); From 6e571e26ff068386bc949eaab6646e90613b23c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9ophane=20Hufschmitt?= Date: Thu, 24 Mar 2022 14:27:45 +0100 Subject: [PATCH 012/285] Build the resolved derivation and not the original one --- src/hydra-queue-runner/build-remote.cc | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/src/hydra-queue-runner/build-remote.cc b/src/hydra-queue-runner/build-remote.cc index 901bbc89..62461a65 100644 --- a/src/hydra-queue-runner/build-remote.cc +++ b/src/hydra-queue-runner/build-remote.cc @@ -203,7 +203,7 @@ void handshake(Machine::Connection & conn, unsigned int repeats) throw Error("machine ‘%1%’ does not support repeating a build; please upgrade it to Nix 1.12", conn.machine->sshName); } -StorePathSet sendInputs( +BasicDerivation sendInputs( State & state, Step & step, Store & localStore, @@ -214,19 +214,13 @@ StorePathSet sendInputs( counter & nrStepsCopyingTo ) { - - StorePathSet inputs; BasicDerivation basicDrv(*step.drv); - for (auto & p : step.drv->inputSrcs) - inputs.insert(p); - for (auto & input : step.drv->inputDrvs) { auto drv2 = localStore.readDerivation(input.first); for (auto & name : input.second) { if (auto i = get(drv2.outputs, name)) { auto outPath = i->path(localStore, drv2.name, name); - inputs.insert(*outPath); basicDrv.inputSrcs.insert(*outPath); } } @@ -255,10 +249,10 @@ StorePathSet sendInputs( /* Copy the input closure. */ if (conn.machine->isLocalhost()) { StorePathSet closure; - destStore.computeFSClosure(inputs, closure); + destStore.computeFSClosure(basicDrv.inputSrcs, closure); copyPaths(destStore, localStore, closure, NoRepair, NoCheckSigs, NoSubstitute); } else { - copyClosureTo(conn.machine->state->sendLock, destStore, conn.from, conn.to, inputs, true); + copyClosureTo(conn.machine->state->sendLock, destStore, conn.from, conn.to, basicDrv.inputSrcs, true); } auto now2 = std::chrono::steady_clock::now(); @@ -266,7 +260,7 @@ StorePathSet sendInputs( overhead += std::chrono::duration_cast(now2 - now1).count(); } - return inputs; + return basicDrv; } void RemoteResult::updateWithBuildResult(const nix::BuildResult & buildResult) @@ -535,8 +529,7 @@ void State::buildRemote(ref destStore, copy the immediate sources of the derivation and the required outputs of the input derivations. */ updateStep(ssSendingInputs); - - StorePathSet inputs = sendInputs(*this, *step, *localStore, *destStore, conn, result.overhead, nrStepsWaiting, nrStepsCopyingTo); + BasicDerivation resolvedDrv = sendInputs(*this, *step, *localStore, *destStore, conn, result.overhead, nrStepsWaiting, nrStepsCopyingTo); logFileDel.cancel(); @@ -561,7 +554,7 @@ void State::buildRemote(ref destStore, conn, *localStore, step->drvPath, - BasicDerivation(*step->drv), + resolvedDrv, buildOptions, nrStepsBuilding ); From a179f0be610f37635c981de441c73d246b88f1fb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 11 Apr 2022 15:26:03 +0000 Subject: [PATCH 013/285] build(deps): bump cachix/install-nix-action from 16 to 17 Bumps [cachix/install-nix-action](https://github.com/cachix/install-nix-action) from 16 to 17. - [Release notes](https://github.com/cachix/install-nix-action/releases) - [Commits](https://github.com/cachix/install-nix-action/compare/v16...v17) --- updated-dependencies: - dependency-name: cachix/install-nix-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 3ba4aba6..0f5f43da 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -9,6 +9,6 @@ jobs: - uses: actions/checkout@v3 with: fetch-depth: 0 - - uses: cachix/install-nix-action@v16 + - uses: cachix/install-nix-action@v17 #- run: nix flake check - run: nix-build -A checks.x86_64-linux.build -A checks.x86_64-linux.validate-openapi From 3c71be5b5b9b8fd4739c925ab46642f6121ec218 Mon Sep 17 00:00:00 2001 From: Ulrik Strid Date: Wed, 18 May 2022 08:14:00 +0200 Subject: [PATCH 014/285] GithubPulls: Don't fail on missing `Link` --- src/lib/Hydra/Plugin/GithubPulls.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/Hydra/Plugin/GithubPulls.pm b/src/lib/Hydra/Plugin/GithubPulls.pm index db0e8d25..9d8412c3 100644 --- a/src/lib/Hydra/Plugin/GithubPulls.pm +++ b/src/lib/Hydra/Plugin/GithubPulls.pm @@ -30,7 +30,7 @@ sub _iterate { $pulls->{$pull->{number}} = $pull; } # TODO Make Link header parsing more robust!!! - my @links = split ',', $res->header("Link"); + my @links = split ',', ($res->header("Link") // ""); my $next = ""; foreach my $link (@links) { my ($url, $rel) = split ";", $link; From a8b590014b4b3f59aaf8eec3465f600b5899b2fd Mon Sep 17 00:00:00 2001 From: Maximilian Bosch Date: Sun, 22 May 2022 14:14:14 +0200 Subject: [PATCH 015/285] Fix email notifications for jobsets w/git-inputs I started to wonder quite recently why Hydra doesn't send email notifications anymore to me. I saw the following issue in the log of `hydra-notify.service`: May 22 11:57:29 hydra 9bik0bxyxbrklhx6lqwifd6af8kj84va-hydra-notify[1887289]: fatal: unsafe repository ('/var/lib/hydra/scm/git/3e70c16c266ef70dc4198705a688acccf71e932878f178277c9ac47d133cc663' is owned by someone else) May 22 11:57:29 hydra 9bik0bxyxbrklhx6lqwifd6af8kj84va-hydra-notify[1887289]: To add an exception for this directory, call: May 22 11:57:29 hydra 9bik0bxyxbrklhx6lqwifd6af8kj84va-hydra-notify[1887289]: git config --global --add safe.directory /var/lib/hydra/scm/git/3e70c16c266ef70dc4198705a688acccf71e932878f178277c9ac47d133cc663 May 22 11:57:29 hydra 9bik0bxyxbrklhx6lqwifd6af8kj84va-hydra-notify[1886654]: error running build_finished hooks: command `git log --pretty=format:%H%x09%an%x09%ae%x09%at b0c30a7557685d25a8ab3f34fdb775e66db0bc4c..eaf28389fcebc2beca13a802f79b2cca6e9ca309 --git-dir=.git' failed with e> This is also a problem because of Git's fix for CVE-2022-24765[1], so I applied the same fix as for Nix[2], by using `--git-dir` which skips the code-path for the ownership-check[3]. [1] https://lore.kernel.org/git/xmqqv8veb5i6.fsf@gitster.g/ [2] https://github.com/NixOS/nix/pull/6440 [3] To quote `git(1)`: > Specifying the location of the ".git" directory using this option > (or GIT_DIR environment variable) turns off the repository > discovery that tries to find a directory with ".git" subdirectory --- src/lib/Hydra/Plugin/GitInput.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/Hydra/Plugin/GitInput.pm b/src/lib/Hydra/Plugin/GitInput.pm index aca35c30..e5fc7de9 100644 --- a/src/lib/Hydra/Plugin/GitInput.pm +++ b/src/lib/Hydra/Plugin/GitInput.pm @@ -261,7 +261,7 @@ sub getCommits { my $clonePath = getSCMCacheDir . "/git/" . sha256_hex($uri); - my $out = grab(cmd => ["git", "log", "--pretty=format:%H%x09%an%x09%ae%x09%at", "$rev1..$rev2"], dir => $clonePath); + my $out = grab(cmd => ["git", "--git-dir=.git", "log", "--pretty=format:%H%x09%an%x09%ae%x09%at", "$rev1..$rev2"], dir => $clonePath); my $res = []; foreach my $line (split /\n/, $out) { From b6ea85a601ddac9cb0716d8cb4d446439fa0778f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Josef=20Kemetm=C3=BCller?= Date: Fri, 27 May 2022 11:40:49 +0200 Subject: [PATCH 016/285] scmdiff: Hardcode `--git-dir` The newest version of git refuses to work on repositories not owned by the current user. This leads to issues with the /api/scmdiff endpoint: May 27 11:16:05 myhydra hydra-server[923698]: fatal: unsafe repository ('/var/lib/hydra/scm/git/57ea036ec7ecd85c8dd085e02ecc6f12dd5c079a6203d16aea49f586cadfb2be' is owned by someone else) May 27 11:16:05 myhydra hydra-server[923698]: To add an exception for this directory, call: May 27 11:16:05 myhydra hydra-server[923698]: git config --global --add safe.directory /var/lib/hydra/scm/git/57ea036ec7ecd85c8dd085e02ecc6f12dd5c079a6203d16aea49f586cadfb2be May 27 11:16:05 myhydra hydra-server[923701]: warning: Not a git repository. Use --no-index to compare two paths outside a working tree May 27 11:16:05 myhydra hydra-server[923701]: usage: git diff --no-index [] I used the same solution that was used in NixOS/nix#6440. Fixes #1214 --- src/lib/Hydra/Controller/API.pm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib/Hydra/Controller/API.pm b/src/lib/Hydra/Controller/API.pm index 6f10ef57..8ebed599 100644 --- a/src/lib/Hydra/Controller/API.pm +++ b/src/lib/Hydra/Controller/API.pm @@ -216,8 +216,8 @@ sub scmdiff : Path('/api/scmdiff') Args(0) { } elsif ($type eq "git") { my $clonePath = getSCMCacheDir . "/git/" . sha256_hex($uri); die if ! -d $clonePath; - $diff .= `(cd $clonePath; git log $rev1..$rev2)`; - $diff .= `(cd $clonePath; git diff $rev1..$rev2)`; + $diff .= `(cd $clonePath; git --git-dir .git log $rev1..$rev2)`; + $diff .= `(cd $clonePath; git --git-dir .git diff $rev1..$rev2)`; } $c->stash->{'plain'} = { data => (scalar $diff) || " " }; From 5c01800fbe49939c53566457047283eb5c93f51b Mon Sep 17 00:00:00 2001 From: Maximilian Bosch Date: Thu, 16 Jun 2022 14:54:57 +0200 Subject: [PATCH 017/285] flake: Update Nix to 2.9.1 NOTE: I'm well-aware that we have to be careful with this to avoid new regressions on hydra.nixos.org, so this should only be merged after extensive testing from more people. Motivation: I updated Nix in my deployment to 2.9.1 and decided to also update Hydra in one go (and compile it against the newer Nix). Given that this also updates the C++ code in `hydra-{queue-runner,eval-jobs}` this patch might become useful in the future though. --- flake.lock | 12 +++++++----- flake.nix | 2 +- src/hydra-eval-jobs/Makefile.am | 2 +- src/hydra-eval-jobs/hydra-eval-jobs.cc | 10 +++++----- src/hydra-queue-runner/queue-monitor.cc | 2 +- 5 files changed, 15 insertions(+), 13 deletions(-) diff --git a/flake.lock b/flake.lock index 5c726a24..1310c53d 100644 --- a/flake.lock +++ b/flake.lock @@ -39,16 +39,18 @@ "nixpkgs-regression": "nixpkgs-regression" }, "locked": { - "lastModified": 1649172203, - "narHash": "sha256-Q3nYaXqbseDOvZrlePKeIrx0/KzqyrtNpxHIUbtFHuI=", + "lastModified": 1654014617, + "narHash": "sha256-qNL3lQPBsnStkru3j1ajN/H+knXI+X3dku8/dBfSw3g=", "owner": "NixOS", "repo": "nix", - "rev": "5fe4fe823c193cbb7bfa05a468de91eeab09058d", + "rev": "624e38aa43f304fbb78b4779172809add042b513", "type": "github" }, "original": { - "id": "nix", - "type": "indirect" + "owner": "NixOS", + "ref": "2.9.1", + "repo": "nix", + "type": "github" } }, "nixpkgs": { diff --git a/flake.nix b/flake.nix index 01b0c988..794555ec 100644 --- a/flake.nix +++ b/flake.nix @@ -5,7 +5,7 @@ # even 2.7.0's Nixpkgs pin). inputs.newNixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable-small"; inputs.nixpkgs.follows = "nix/nixpkgs"; - #inputs.nix.url = github:NixOS/nix/2.7.0; + inputs.nix.url = github:NixOS/nix/2.9.1; outputs = { self, newNixpkgs, nixpkgs, nix }: let diff --git a/src/hydra-eval-jobs/Makefile.am b/src/hydra-eval-jobs/Makefile.am index 7a4e9c91..90742a30 100644 --- a/src/hydra-eval-jobs/Makefile.am +++ b/src/hydra-eval-jobs/Makefile.am @@ -1,5 +1,5 @@ bin_PROGRAMS = hydra-eval-jobs hydra_eval_jobs_SOURCES = hydra-eval-jobs.cc -hydra_eval_jobs_LDADD = $(NIX_LIBS) +hydra_eval_jobs_LDADD = $(NIX_LIBS) -lnixcmd hydra_eval_jobs_CXXFLAGS = $(NIX_CFLAGS) -I ../libhydra diff --git a/src/hydra-eval-jobs/hydra-eval-jobs.cc b/src/hydra-eval-jobs/hydra-eval-jobs.cc index 918bd451..18d39620 100644 --- a/src/hydra-eval-jobs/hydra-eval-jobs.cc +++ b/src/hydra-eval-jobs/hydra-eval-jobs.cc @@ -197,21 +197,21 @@ static void worker( /* If this is an aggregate, then get its constituents. */ auto a = v->attrs->get(state.symbols.create("_hydraAggregate")); - if (a && state.forceBool(*a->value, *a->pos)) { + if (a && state.forceBool(*a->value, a->pos)) { auto a = v->attrs->get(state.symbols.create("constituents")); if (!a) throw EvalError("derivation must have a ‘constituents’ attribute"); PathSet context; - state.coerceToString(*a->pos, *a->value, context, true, false); + state.coerceToString(a->pos, *a->value, context, true, false); for (auto & i : context) if (i.at(0) == '!') { size_t index = i.find("!", 1); job["constituents"].push_back(std::string(i, index + 1)); } - state.forceList(*a->value, *a->pos); + state.forceList(*a->value, a->pos); for (unsigned int n = 0; n < a->value->listSize(); ++n) { auto v = a->value->listElems()[n]; state.forceValue(*v, noPos); @@ -243,8 +243,8 @@ static void worker( else if (v->type() == nAttrs) { auto attrs = nlohmann::json::array(); StringSet ss; - for (auto & i : v->attrs->lexicographicOrder()) { - std::string name(i->name); + for (auto & i : v->attrs->lexicographicOrder(state.symbols)) { + std::string name(state.symbols[i->name]); if (name.find('.') != std::string::npos || name.find(' ') != std::string::npos) { printError("skipping job with illegal name '%s'", name); continue; diff --git a/src/hydra-queue-runner/queue-monitor.cc b/src/hydra-queue-runner/queue-monitor.cc index 3bde0d99..12d55b79 100644 --- a/src/hydra-queue-runner/queue-monitor.cc +++ b/src/hydra-queue-runner/queue-monitor.cc @@ -460,7 +460,7 @@ Step::ptr State::createStep(ref destStore, step->parsedDrv = std::make_unique(drvPath, *step->drv); step->preferLocalBuild = step->parsedDrv->willBuildLocally(*localStore); - step->isDeterministic = get(step->drv->env, "isDetermistic").value_or("0") == "1"; + step->isDeterministic = getOr(step->drv->env, "isDetermistic", "0") == "1"; step->systemType = step->drv->platform; { From 183f58ca9f10a0a6a18e42c75168145a1de864df Mon Sep 17 00:00:00 2001 From: Sandro Date: Thu, 16 Jun 2022 22:48:39 +0200 Subject: [PATCH 018/285] Remove url literal --- flake.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flake.nix b/flake.nix index 794555ec..2e891364 100644 --- a/flake.nix +++ b/flake.nix @@ -5,7 +5,7 @@ # even 2.7.0's Nixpkgs pin). inputs.newNixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable-small"; inputs.nixpkgs.follows = "nix/nixpkgs"; - inputs.nix.url = github:NixOS/nix/2.9.1; + inputs.nix.url = "github:NixOS/nix/2.9.1"; outputs = { self, newNixpkgs, nixpkgs, nix }: let From 750978a19232583e17620a1bd80435e957e7213a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sandro=20J=C3=A4ckel?= Date: Sat, 18 Jun 2022 13:22:42 +0200 Subject: [PATCH 019/285] Add gitea push hook --- doc/manual/src/webhooks.md | 20 +++++++++++++++++--- src/lib/Hydra/Controller/API.pm | 16 ++++++++++++++++ src/lib/Hydra/Controller/Root.pm | 3 ++- 3 files changed, 35 insertions(+), 4 deletions(-) diff --git a/doc/manual/src/webhooks.md b/doc/manual/src/webhooks.md index 2b26cd61..674e1064 100644 --- a/doc/manual/src/webhooks.md +++ b/doc/manual/src/webhooks.md @@ -1,9 +1,12 @@ # Webhooks -Hydra can be notified by github's webhook to trigger a new evaluation when a +Hydra can be notified by github or gitea with webhooks to trigger a new evaluation when a jobset has a github repo in its input. -To set up a github webhook go to `https://github.com///settings` and in the `Webhooks` tab -click on `Add webhook`. + +## GitHub + +To set up a webhook for a GitHub repository go to `https://github.com///settings` +and in the `Webhooks` tab click on `Add webhook`. - In `Payload URL` fill in `https:///api/push-github`. - In `Content type` switch to `application/json`. @@ -11,3 +14,14 @@ click on `Add webhook`. - For `Which events would you like to trigger this webhook?` keep the default option for events on `Just the push event.`. Then add the hook with `Add webhook`. + +## Gitea + +To set up a webhook for a Gitea repository go to the settings of the repository in your Gitea instance +and in the `Webhooks` tab click on `Add Webhook` and choose `Gitea` in the drop down. + +- In `Target URL` fill in `https:///api/push-gitea`. +- Keep HTTP method `POST`, POST Content Type `application/json` and Trigger On `Push Events`. +- Change the branch filter to match the git branch hydra builds. + +Then add the hook with `Add webhook`. diff --git a/src/lib/Hydra/Controller/API.pm b/src/lib/Hydra/Controller/API.pm index 6f10ef57..12073595 100644 --- a/src/lib/Hydra/Controller/API.pm +++ b/src/lib/Hydra/Controller/API.pm @@ -285,6 +285,22 @@ sub push_github : Chained('api') PathPart('push-github') Args(0) { $c->response->body(""); } +sub push_gitea : Chained('api') PathPart('push-gitea') Args(0) { + my ($self, $c) = @_; + + $c->{stash}->{json}->{jobsetsTriggered} = []; + + my $in = $c->request->{data}; + my $url = $in->{repository}->{clone_url} or die; + print STDERR "got push from Gitea repository $url\n"; + + triggerJobset($self, $c, $_, 0) foreach $c->model('DB::Jobsets')->search( + { 'project.enabled' => 1, 'me.enabled' => 1 }, + { join => 'project' + , where => \ [ 'me.flake like ? or exists (select 1 from JobsetInputAlts where project = me.project and jobset = me.name and value like ?)', [ 'flake', "%$url%"], [ 'value', "%$url%" ] ] + }); + $c->response->body(""); +} 1; diff --git a/src/lib/Hydra/Controller/Root.pm b/src/lib/Hydra/Controller/Root.pm index c6843d29..1b33db2a 100644 --- a/src/lib/Hydra/Controller/Root.pm +++ b/src/lib/Hydra/Controller/Root.pm @@ -32,6 +32,7 @@ sub noLoginNeeded { return $whitelisted || $c->request->path eq "api/push-github" || + $c->request->path eq "api/push-gitea" || $c->request->path eq "google-login" || $c->request->path eq "github-redirect" || $c->request->path eq "github-login" || @@ -77,7 +78,7 @@ sub begin :Private { $_->supportedInputTypes($c->stash->{inputTypes}) foreach @{$c->hydra_plugins}; # XSRF protection: require POST requests to have the same origin. - if ($c->req->method eq "POST" && $c->req->path ne "api/push-github") { + if ($c->req->method eq "POST" && $c->req->path ne "api/push-github" && $c->req->path ne "api/push-gitea") { my $referer = $c->req->header('Referer'); $referer //= $c->req->header('Origin'); my $base = $c->req->base; From bab671124df0bc43a521d708bf86eece908d33af Mon Sep 17 00:00:00 2001 From: ajs124 Date: Thu, 30 Jun 2022 00:24:09 +0200 Subject: [PATCH 020/285] replace nix cat-store with nix store cat the former was deprecated in favor of the latter --- src/lib/Hydra/Controller/Build.pm | 4 ++-- src/lib/Hydra/Helper/Nix.pm | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/lib/Hydra/Controller/Build.pm b/src/lib/Hydra/Controller/Build.pm index 552f31af..c7811c62 100644 --- a/src/lib/Hydra/Controller/Build.pm +++ b/src/lib/Hydra/Controller/Build.pm @@ -234,7 +234,7 @@ sub serveFile { elsif ($ls->{type} eq "regular") { $c->stash->{'plain'} = { data => grab(cmd => ["nix", "--experimental-features", "nix-command", - "cat-store", "--store", getStoreUri(), "$path"]) }; + "store", "cat", "--store", getStoreUri(), "$path"]) }; # Detect MIME type. Borrowed from Catalyst::Plugin::Static::Simple. my $type = "text/plain"; @@ -366,7 +366,7 @@ sub contents : Chained('buildChain') PathPart Args(1) { # FIXME: don't use shell invocations below. - # FIXME: use nix cat-store + # FIXME: use nix store cat my $res; diff --git a/src/lib/Hydra/Helper/Nix.pm b/src/lib/Hydra/Helper/Nix.pm index 514fb439..71a8a7d7 100644 --- a/src/lib/Hydra/Helper/Nix.pm +++ b/src/lib/Hydra/Helper/Nix.pm @@ -537,7 +537,7 @@ sub getStoreUri { sub readNixFile { my ($path) = @_; return grab(cmd => ["nix", "--experimental-features", "nix-command", - "cat-store", "--store", getStoreUri(), "$path"]); + "store", "cat", "--store", getStoreUri(), "$path"]); } From bb1f04ed8669cc012fc552a40a376f3b93228833 Mon Sep 17 00:00:00 2001 From: ajs124 Date: Thu, 30 Jun 2022 00:32:31 +0200 Subject: [PATCH 021/285] AddBuilds: fix declarative jobsets with dynamic runcommand enabled $project->{enable_dynamic_run_command} is undefined --- src/lib/Hydra/Helper/AddBuilds.pm | 2 +- t/Helper/AddBuilds/dynamic-disabled.t | 36 +++++++++++++++++++++------ t/Helper/AddBuilds/dynamic-enabled.t | 36 +++++++++++++++++++++------ 3 files changed, 59 insertions(+), 15 deletions(-) diff --git a/src/lib/Hydra/Helper/AddBuilds.pm b/src/lib/Hydra/Helper/AddBuilds.pm index 9e3ddfd2..a6373be5 100644 --- a/src/lib/Hydra/Helper/AddBuilds.pm +++ b/src/lib/Hydra/Helper/AddBuilds.pm @@ -67,7 +67,7 @@ sub validateDeclarativeJobset { my $enable_dynamic_run_command = defined $update{enable_dynamic_run_command} ? 1 : 0; if ($enable_dynamic_run_command && !($config->{dynamicruncommand}->{enable} - && $project->{enable_dynamic_run_command})) + && $project->enable_dynamic_run_command)) { die "Dynamic RunCommand is not enabled by the server or the parent project."; } diff --git a/t/Helper/AddBuilds/dynamic-disabled.t b/t/Helper/AddBuilds/dynamic-disabled.t index 0507b03e..0c91f382 100644 --- a/t/Helper/AddBuilds/dynamic-disabled.t +++ b/t/Helper/AddBuilds/dynamic-disabled.t @@ -6,11 +6,31 @@ use Test2::V0; require Catalyst::Test; use HTTP::Request::Common qw(POST PUT GET DELETE); use JSON::MaybeXS qw(decode_json encode_json); -use Hydra::Helper::AddBuilds qw(validateDeclarativeJobset); -use Hydra::Helper::Nix qw(getHydraConfig); my $ctx = test_context(); +Catalyst::Test->import('Hydra'); + +my $db = Hydra::Model::DB->new; +hydra_setup($db); + +my $user = $db->resultset('Users')->create({ username => 'alice', emailaddress => 'root@invalid.org', password => '!' }); +$user->setPassword('foobar'); +$user->userroles->update_or_create({ role => 'admin' }); + +my $project_with_dynamic_run_command = $db->resultset('Projects')->create({ + name => 'tests_with_dynamic_runcommand', + displayname => 'Tests with dynamic runcommand', + owner => 'alice', + enable_dynamic_run_command => 1, +}); +my $project_without_dynamic_run_command = $db->resultset('Projects')->create({ + name => 'tests_without_dynamic_runcommand', + displayname => 'Tests without dynamic runcommand', + owner => 'alice', + enable_dynamic_run_command => 0, +}); + sub makeJobsetSpec { my ($dynamic) = @_; @@ -29,14 +49,16 @@ sub makeJobsetSpec { }; subtest "validate declarative jobset with dynamic RunCommand disabled by server" => sub { - my $config = getHydraConfig(); + my $config = Hydra::Helper::Nix->getHydraConfig(); + require Hydra::Helper::AddBuilds; + Hydra::Helper::AddBuilds->import( qw(validateDeclarativeJobset) ); subtest "project enabled dynamic runcommand, declarative jobset enabled dynamic runcommand" => sub { like( dies { validateDeclarativeJobset( $config, - { enable_dynamic_run_command => 1 }, + $project_with_dynamic_run_command, "test-jobset", makeJobsetSpec(JSON::MaybeXS::true), ), @@ -49,7 +71,7 @@ subtest "validate declarative jobset with dynamic RunCommand disabled by server" ok( validateDeclarativeJobset( $config, - { enable_dynamic_run_command => 1 }, + $project_with_dynamic_run_command, "test-jobset", makeJobsetSpec(JSON::MaybeXS::false) ), @@ -61,7 +83,7 @@ subtest "validate declarative jobset with dynamic RunCommand disabled by server" dies { validateDeclarativeJobset( $config, - { enable_dynamic_run_command => 0 }, + $project_without_dynamic_run_command, "test-jobset", makeJobsetSpec(JSON::MaybeXS::true), ), @@ -74,7 +96,7 @@ subtest "validate declarative jobset with dynamic RunCommand disabled by server" ok( validateDeclarativeJobset( $config, - { enable_dynamic_run_command => 0 }, + $project_without_dynamic_run_command, "test-jobset", makeJobsetSpec(JSON::MaybeXS::false) ), diff --git a/t/Helper/AddBuilds/dynamic-enabled.t b/t/Helper/AddBuilds/dynamic-enabled.t index d2f5a386..46497bed 100644 --- a/t/Helper/AddBuilds/dynamic-enabled.t +++ b/t/Helper/AddBuilds/dynamic-enabled.t @@ -6,8 +6,6 @@ use Test2::V0; require Catalyst::Test; use HTTP::Request::Common qw(POST PUT GET DELETE); use JSON::MaybeXS qw(decode_json encode_json); -use Hydra::Helper::AddBuilds qw(validateDeclarativeJobset); -use Hydra::Helper::Nix qw(getHydraConfig); my $ctx = test_context( hydra_config => q| @@ -17,6 +15,28 @@ my $ctx = test_context( | ); +Catalyst::Test->import('Hydra'); + +my $db = Hydra::Model::DB->new; +hydra_setup($db); + +my $user = $db->resultset('Users')->create({ username => 'alice', emailaddress => 'root@invalid.org', password => '!' }); +$user->setPassword('foobar'); +$user->userroles->update_or_create({ role => 'admin' }); + +my $project_with_dynamic_run_command = $db->resultset('Projects')->create({ + name => 'tests_with_dynamic_runcommand', + displayname => 'Tests with dynamic runcommand', + owner => 'alice', + enable_dynamic_run_command => 1, +}); +my $project_without_dynamic_run_command = $db->resultset('Projects')->create({ + name => 'tests_without_dynamic_runcommand', + displayname => 'Tests without dynamic runcommand', + owner => 'alice', + enable_dynamic_run_command => 0, +}); + sub makeJobsetSpec { my ($dynamic) = @_; @@ -35,13 +55,15 @@ sub makeJobsetSpec { }; subtest "validate declarative jobset with dynamic RunCommand enabled by server" => sub { - my $config = getHydraConfig(); + my $config = Hydra::Helper::Nix->getHydraConfig(); + require Hydra::Helper::AddBuilds; + Hydra::Helper::AddBuilds->import( qw(validateDeclarativeJobset) ); subtest "project enabled dynamic runcommand, declarative jobset enabled dynamic runcommand" => sub { ok( validateDeclarativeJobset( $config, - { enable_dynamic_run_command => 1 }, + $project_with_dynamic_run_command, "test-jobset", makeJobsetSpec(JSON::MaybeXS::true) ), @@ -52,7 +74,7 @@ subtest "validate declarative jobset with dynamic RunCommand enabled by server" ok( validateDeclarativeJobset( $config, - { enable_dynamic_run_command => 1 }, + $project_with_dynamic_run_command, "test-jobset", makeJobsetSpec(JSON::MaybeXS::false) ), @@ -64,7 +86,7 @@ subtest "validate declarative jobset with dynamic RunCommand enabled by server" dies { validateDeclarativeJobset( $config, - { enable_dynamic_run_command => 0 }, + $project_without_dynamic_run_command, "test-jobset", makeJobsetSpec(JSON::MaybeXS::true), ), @@ -77,7 +99,7 @@ subtest "validate declarative jobset with dynamic RunCommand enabled by server" ok( validateDeclarativeJobset( $config, - { enable_dynamic_run_command => 0 }, + $project_without_dynamic_run_command, "test-jobset", makeJobsetSpec(JSON::MaybeXS::false) ), From a81c6a3a80d1055aa80934ab229e2dc49594edd2 Mon Sep 17 00:00:00 2001 From: Sandro Date: Fri, 1 Jul 2022 22:21:32 +0200 Subject: [PATCH 022/285] Match URIs that don't end in .git Co-authored-by: Charlotte --- src/lib/Hydra/Controller/API.pm | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lib/Hydra/Controller/API.pm b/src/lib/Hydra/Controller/API.pm index 12073595..5eeb0c04 100644 --- a/src/lib/Hydra/Controller/API.pm +++ b/src/lib/Hydra/Controller/API.pm @@ -292,6 +292,7 @@ sub push_gitea : Chained('api') PathPart('push-gitea') Args(0) { my $in = $c->request->{data}; my $url = $in->{repository}->{clone_url} or die; + $url =~ s/.git$//; print STDERR "got push from Gitea repository $url\n"; triggerJobset($self, $c, $_, 0) foreach $c->model('DB::Jobsets')->search( From 38e033e7ceb8fecea9fe3d8c621e77d1af884948 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Janne=20He=C3=9F?= Date: Sun, 10 Jul 2022 13:31:21 +0200 Subject: [PATCH 023/285] Remove yet another URL literal --- shell.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shell.nix b/shell.nix index 9e967032..1ad58f49 100644 --- a/shell.nix +++ b/shell.nix @@ -1,6 +1,6 @@ # The `default.nix` in flake-compat reads `flake.nix` and `flake.lock` from `src` and # returns an attribute set of the shape `{ defaultNix, shellNix }` -(import (fetchTarball https://github.com/edolstra/flake-compat/archive/master.tar.gz) { +(import (fetchTarball "https://github.com/edolstra/flake-compat/archive/master.tar.gz") { src = ./.; }).shellNix From 8dd1daac8a9bd1a5b4d8f37969c344d5ef593c6e Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 12 Jul 2022 12:14:50 +0200 Subject: [PATCH 024/285] Update to Nix 2.10 --- flake.nix | 28 +++++++++++++--------------- hydra-module.nix | 2 +- 2 files changed, 14 insertions(+), 16 deletions(-) diff --git a/flake.nix b/flake.nix index 2e891364..36863913 100644 --- a/flake.nix +++ b/flake.nix @@ -5,7 +5,7 @@ # even 2.7.0's Nixpkgs pin). inputs.newNixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable-small"; inputs.nixpkgs.follows = "nix/nixpkgs"; - inputs.nix.url = "github:NixOS/nix/2.9.1"; + inputs.nix.url = "github:NixOS/nix/2.10.0"; outputs = { self, newNixpkgs, nixpkgs, nix }: let @@ -14,7 +14,7 @@ pkgs = import nixpkgs { system = "x86_64-linux"; - overlays = [ self.overlay nix.overlay ]; + overlays = [ self.overlay nix.overlays.default ]; }; # NixOS configuration used for VM tests. @@ -332,7 +332,7 @@ url = "mirror://cpan/authors/id/A/AA/AAR/Net-LDAP-Server-0.43.tar.gz"; sha256 = "0qmh3cri3fpccmwz6bhwp78yskrb3qmalzvqn0a23hqbsfs4qv6x"; }; - propagatedBuildInputs = with final.perlPackages; [ NetLDAP ConvertASN1 ]; + propagatedBuildInputs = with final.perlPackages; [ perlldap ConvertASN1 ]; meta = { description = "LDAP server side protocol handling"; license = with final.lib.licenses; [ artistic1 ]; @@ -359,7 +359,7 @@ url = "mirror://cpan/authors/id/K/KA/KARMAN/Net-LDAP-Server-Test-0.22.tar.gz"; sha256 = "13idip7jky92v4adw60jn2gcc3zf339gsdqlnc9nnvqzbxxp285i"; }; - propagatedBuildInputs = with final.perlPackages; [ NetLDAP NetLDAPServer TestMore DataDump NetLDAPSID ]; + propagatedBuildInputs = with final.perlPackages; [ perlldap NetLDAPServer DataDump NetLDAPSID ]; meta = { description = "test Net::LDAP code"; license = with final.lib.licenses; [ artistic1 ]; @@ -373,8 +373,8 @@ url = "mirror://cpan/authors/id/I/IL/ILMARI/Catalyst-Authentication-Store-LDAP-1.016.tar.gz"; sha256 = "0cm399vxqqf05cjgs1j5v3sk4qc6nmws5nfhf52qvpbwc4m82mq8"; }; - propagatedBuildInputs = with final.perlPackages; [ NetLDAP CatalystPluginAuthentication ClassAccessorFast ]; - buildInputs = with final.perlPackages; [ TestMore TestMockObject TestException NetLDAPServerTest ]; + propagatedBuildInputs = with final.perlPackages; [ perlldap CatalystPluginAuthentication ClassAccessor ]; + buildInputs = with final.perlPackages; [ TestMockObject TestException NetLDAPServerTest ]; meta = { description = "Authentication from an LDAP Directory"; license = with final.lib.licenses; [ artistic1 ]; @@ -486,7 +486,6 @@ CatalystPluginSessionStateCookie CatalystPluginSessionStoreFastMmap CatalystPluginStackTrace - CatalystPluginUnicodeEncoding CatalystTraitForRequestProxyBase CatalystViewDownload CatalystViewJSON @@ -533,7 +532,6 @@ TermSizeAny TermReadKey Test2Harness - TestMore TestPostgreSQL TextDiff TextTable @@ -558,9 +556,9 @@ libtool unzip nukeReferences - pkgconfig + pkg-config libpqxx - gitAndTools.topGit + top-git mercurial darcs subversion @@ -585,7 +583,7 @@ cacert # FIXME: foreman is broken on all nix/nixpkgs pin, up to and # including 2.7.0 - newNixpkgs.legacyPackages.${final.system}.foreman + newNixpkgs.legacyPackages.${final.stdenv.system}.foreman glibcLocales libressl.nc openldap @@ -602,11 +600,11 @@ pixz gzip bzip2 - lzma + xz gnutar unzip git - gitAndTools.topGit + top-git mercurial darcs gnused @@ -661,7 +659,7 @@ dontStrip = true; - meta.description = "Build of Hydra on ${system}"; + meta.description = "Build of Hydra on ${final.stdenv.system}"; passthru = { inherit perlDeps; inherit (final) nix; }; }; }; @@ -966,7 +964,7 @@ nixosModules.hydra = { imports = [ ./hydra-module.nix ]; - nixpkgs.overlays = [ self.overlay nix.overlay ]; + nixpkgs.overlays = [ self.overlay nix.overlays.default ]; }; nixosModules.hydraTest = { diff --git a/hydra-module.nix b/hydra-module.nix index 0df5e690..f826ef36 100644 --- a/hydra-module.nix +++ b/hydra-module.nix @@ -268,7 +268,7 @@ in environment = env // { HYDRA_DBI = "${env.HYDRA_DBI};application_name=hydra-init"; }; - path = [ pkgs.utillinux ]; + path = [ pkgs.util-linux ]; preStart = '' ln -sf ${hydraConf} ${baseDir}/hydra.conf From e06c480fd67d71fe1ab175c3f14e694f08a0cae0 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 12 Jul 2022 11:58:38 +0200 Subject: [PATCH 025/285] flake.lock: Update MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Flake lock file updates: • Updated input 'newNixpkgs': 'github:NixOS/nixpkgs/6e3ee8957637a60f5072e33d78e05c0f65c54366' (2022-03-15) → 'github:NixOS/nixpkgs/de5b3dd17034e6106e75746e81618e5bd408de8a' (2022-07-10) • Updated input 'nix': 'github:NixOS/nix/624e38aa43f304fbb78b4779172809add042b513' (2022-05-31) → 'github:NixOS/nix/b9cf655150b52d071c85a337cb5db96e735fa64a' (2022-07-11) • Updated input 'nix/nixpkgs': 'github:NixOS/nixpkgs/530a53dcbc9437363471167a5e4762c5fcfa34a1' (2022-02-19) → 'github:NixOS/nixpkgs/2fa57ed190fd6c7c746319444f34b5917666e5c1' (2022-05-31) --- flake.lock | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/flake.lock b/flake.lock index 1310c53d..befc8e5b 100644 --- a/flake.lock +++ b/flake.lock @@ -18,11 +18,11 @@ }, "newNixpkgs": { "locked": { - "lastModified": 1647380550, - "narHash": "sha256-909TI9poX7CIUiFx203WL29YON6m/I6k0ExbZvR7bLM=", + "lastModified": 1657425264, + "narHash": "sha256-3aHvoI2e8vJKw3hvnHECaBpSsL5mxVsVtaLCnTdNcH8=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "6e3ee8957637a60f5072e33d78e05c0f65c54366", + "rev": "de5b3dd17034e6106e75746e81618e5bd408de8a", "type": "github" }, "original": { @@ -39,33 +39,34 @@ "nixpkgs-regression": "nixpkgs-regression" }, "locked": { - "lastModified": 1654014617, - "narHash": "sha256-qNL3lQPBsnStkru3j1ajN/H+knXI+X3dku8/dBfSw3g=", + "lastModified": 1657569404, + "narHash": "sha256-zJONRtGALmYifrWKzcH6MMfSKLxeuW2iqG13500OrY4=", "owner": "NixOS", "repo": "nix", - "rev": "624e38aa43f304fbb78b4779172809add042b513", + "rev": "b9cf655150b52d071c85a337cb5db96e735fa64a", "type": "github" }, "original": { "owner": "NixOS", - "ref": "2.9.1", + "ref": "2.10.0", "repo": "nix", "type": "github" } }, "nixpkgs": { "locked": { - "lastModified": 1645296114, - "narHash": "sha256-y53N7TyIkXsjMpOG7RhvqJFGDacLs9HlyHeSTBioqYU=", + "lastModified": 1653988320, + "narHash": "sha256-ZaqFFsSDipZ6KVqriwM34T739+KLYJvNmCWzErjAg7c=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "530a53dcbc9437363471167a5e4762c5fcfa34a1", + "rev": "2fa57ed190fd6c7c746319444f34b5917666e5c1", "type": "github" }, "original": { - "id": "nixpkgs", - "ref": "nixos-21.05-small", - "type": "indirect" + "owner": "NixOS", + "ref": "nixos-22.05-small", + "repo": "nixpkgs", + "type": "github" } }, "nixpkgs-regression": { @@ -78,9 +79,10 @@ "type": "github" }, "original": { - "id": "nixpkgs", + "owner": "NixOS", + "repo": "nixpkgs", "rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2", - "type": "indirect" + "type": "github" } }, "root": { From c72bed5cb4f24853ebb7daaf26bb67d3cb4397f7 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 12 Jul 2022 14:28:55 +0200 Subject: [PATCH 026/285] Fix tests Use $NIX_REMOTE instead of the legacy environment variables. --- t/lib/HydraTestContext.pm | 16 ++++++++++------ t/queue-runner/notifications.t | 4 +--- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/t/lib/HydraTestContext.pm b/t/lib/HydraTestContext.pm index badb3728..53eaa0f7 100644 --- a/t/lib/HydraTestContext.pm +++ b/t/lib/HydraTestContext.pm @@ -53,16 +53,19 @@ sub new { my $hydra_config = $opts{'hydra_config'} || ""; $hydra_config = "queue_runner_metrics_address = 127.0.0.1:0\n" . $hydra_config; if ($opts{'use_external_destination_store'} // 1) { - $hydra_config = "store_uri = file:$dir/nix/dest-store\n" . $hydra_config; + $hydra_config = "store_uri = file://$dir/nix/dest-store\n" . $hydra_config; } write_file($ENV{'HYDRA_CONFIG'}, $hydra_config); - $ENV{'NIX_LOG_DIR'} = "$dir/nix/var/log/nix"; + my $nix_store_dir = "$dir/nix/store"; + my $nix_state_dir = "$dir/nix/var/nix"; + my $nix_log_dir = "$dir/nix/var/log/nix"; + $ENV{'NIX_REMOTE_SYSTEMS'} = ''; - $ENV{'NIX_REMOTE'} = ''; - $ENV{'NIX_STATE_DIR'} = "$dir/nix/var/nix"; - $ENV{'NIX_STORE_DIR'} = "$dir/nix/store"; + $ENV{'NIX_REMOTE'} = "local?store=$nix_store_dir&state=$nix_state_dir&log=$nix_log_dir"; + $ENV{'NIX_STATE_DIR'} = $nix_state_dir; # FIXME: remove + $ENV{'NIX_STORE_DIR'} = $nix_store_dir; # FIXME: remove my $pgsql = Test::PostgreSQL->new( extra_initdb_args => "--locale C.UTF-8" @@ -73,7 +76,8 @@ sub new { _db => undef, db_handle => $pgsql, tmpdir => $dir, - nix_state_dir => "$dir/nix/var/nix", + nix_state_dir => $nix_state_dir, + nix_log_dir => $nix_log_dir, testdir => abs_path(dirname(__FILE__) . "/.."), jobsdir => abs_path(dirname(__FILE__) . "/../jobs") }, $class; diff --git a/t/queue-runner/notifications.t b/t/queue-runner/notifications.t index b35b2b2f..1966cde1 100644 --- a/t/queue-runner/notifications.t +++ b/t/queue-runner/notifications.t @@ -33,9 +33,6 @@ my $ctx = test_context( # the build locally. subtest "Pre-build the job, upload to the cache, and then delete locally" => sub { - my $scratchlogdir = File::Temp->newdir(); - $ENV{'NIX_LOG_DIR'} = "$scratchlogdir"; - my $outlink = $ctx->tmpdir . "/basic-canbesubstituted"; is(system('nix-build', $ctx->jobsdir . '/notifications.nix', '-A', 'canbesubstituted', '--out-link', $outlink), 0, "Building notifications.nix succeeded"); is(system('nix', 'copy', '--to', "file://${binarycachedir}", $outlink), 0, "Copying the closure to the binary cache succeeded"); @@ -46,6 +43,7 @@ subtest "Pre-build the job, upload to the cache, and then delete locally" => sub is(system('nix', 'log', $outpath), 0, "Reading the output's log succeeds"); is(system('nix-store', '--delete', $outpath), 0, "Deleting the notifications.nix output succeeded"); is(system("nix-collect-garbage"), 0, "Delete all the system's garbage"); + File::Path::rmtree($ctx->{nix_log_dir}); }; subtest "Ensure substituting the job works, but reading the log fails" => sub { From d5ba1bba50a7fa2f343d9ad284e293e13bb13f85 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 12 Jul 2022 14:46:48 +0200 Subject: [PATCH 027/285] Fix deprecation warning --- flake.nix | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/flake.nix b/flake.nix index 36863913..db4eb854 100644 --- a/flake.nix +++ b/flake.nix @@ -681,7 +681,7 @@ tests.install.x86_64-linux = with import (nixpkgs + "/nixos/lib/testing-python.nix") { system = "x86_64-linux"; }; simpleTest { - machine = hydraServer; + nodes.machine = hydraServer; testScript = '' machine.wait_for_job("hydra-init") @@ -696,7 +696,7 @@ tests.notifications.x86_64-linux = with import (nixpkgs + "/nixos/lib/testing-python.nix") { system = "x86_64-linux"; }; simpleTest { - machine = { pkgs, ... }: { + nodes.machine = { pkgs, ... }: { imports = [ hydraServer ]; services.hydra-dev.extraConfig = '' @@ -753,7 +753,7 @@ tests.gitea.x86_64-linux = with import (nixpkgs + "/nixos/lib/testing-python.nix") { system = "x86_64-linux"; }; makeTest { - machine = { pkgs, ... }: { + nodes.machine = { pkgs, ... }: { imports = [ hydraServer ]; services.hydra-dev.extraConfig = '' From 3e001a8f05cbd0f7f5a8c0fc2d8da8f839d7b3f8 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 12 Jul 2022 14:58:25 +0200 Subject: [PATCH 028/285] Remove newNixpkgs and a lot of packages that are in Nixpkgs 22.05 --- flake.lock | 17 --- flake.nix | 419 +---------------------------------------------------- 2 files changed, 3 insertions(+), 433 deletions(-) diff --git a/flake.lock b/flake.lock index befc8e5b..012d2407 100644 --- a/flake.lock +++ b/flake.lock @@ -16,22 +16,6 @@ "type": "github" } }, - "newNixpkgs": { - "locked": { - "lastModified": 1657425264, - "narHash": "sha256-3aHvoI2e8vJKw3hvnHECaBpSsL5mxVsVtaLCnTdNcH8=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "de5b3dd17034e6106e75746e81618e5bd408de8a", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixos-unstable-small", - "repo": "nixpkgs", - "type": "github" - } - }, "nix": { "inputs": { "lowdown-src": "lowdown-src", @@ -87,7 +71,6 @@ }, "root": { "inputs": { - "newNixpkgs": "newNixpkgs", "nix": "nix", "nixpkgs": [ "nix", diff --git a/flake.nix b/flake.nix index db4eb854..cb1d9aea 100644 --- a/flake.nix +++ b/flake.nix @@ -1,13 +1,10 @@ { description = "A Nix-based continuous build system"; - # FIXME: All the pinned versions of nix/nixpkgs have a broken foreman (yes, - # even 2.7.0's Nixpkgs pin). - inputs.newNixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable-small"; inputs.nixpkgs.follows = "nix/nixpkgs"; inputs.nix.url = "github:NixOS/nix/2.10.0"; - outputs = { self, newNixpkgs, nixpkgs, nix }: + outputs = { self, nixpkgs, nix }: let version = "${builtins.readFile ./version.txt}.${builtins.substring 0 8 (self.lastModifiedDate or "19700101")}.${self.shortRev or "DIRTY"}"; @@ -41,153 +38,8 @@ # A Nixpkgs overlay that provides a 'hydra' package. overlay = final: prev: { - # Overlay these packages to use dependencies from the Nixpkgs everything - # else uses, to side-step the version difference: glibc is 2.32 in the - # nix-pinned Nixpkgs, but 2.33 in the newNixpkgs commit. - civetweb = (final.callPackage "${newNixpkgs}/pkgs/development/libraries/civetweb" { }).overrideAttrs - # Can be dropped once newNixpkgs points to a revision containing - # https://github.com/NixOS/nixpkgs/pull/167751 - ({ cmakeFlags ? [ ], ... }: { - cmakeFlags = cmakeFlags ++ [ - "-DCIVETWEB_ENABLE_IPV6=1" - ]; - }); - prometheus-cpp = final.callPackage "${newNixpkgs}/pkgs/development/libraries/prometheus-cpp" { }; - # Add LDAP dependencies that aren't currently found within nixpkgs. perlPackages = prev.perlPackages // { - TestPostgreSQL = final.perlPackages.buildPerlModule { - pname = "Test-PostgreSQL"; - version = "1.28-1"; - src = final.fetchFromGitHub { - owner = "grahamc"; - repo = "Test-postgresql"; - rev = "release-1.28-1"; - hash = "sha256-SFC1C3q3dbcBos18CYd/s0TIcfJW4g04ld0+XQXVToQ="; - }; - buildInputs = with final.perlPackages; [ ModuleBuildTiny TestSharedFork pkgs.postgresql ]; - propagatedBuildInputs = with final.perlPackages; [ DBDPg DBI FileWhich FunctionParameters Moo TieHashMethod TryTiny TypeTiny ]; - - makeMakerFlags = "POSTGRES_HOME=${final.postgresql}"; - - meta = { - homepage = "https://github.com/grahamc/Test-postgresql/releases/tag/release-1.28-1"; - description = "PostgreSQL runner for tests"; - license = with final.lib.licenses; [ artistic2 ]; - }; - }; - - FunctionParameters = final.perlPackages.buildPerlPackage { - pname = "Function-Parameters"; - version = "2.001003"; - src = final.fetchurl { - url = "mirror://cpan/authors/id/M/MA/MAUKE/Function-Parameters-2.001003.tar.gz"; - sha256 = "eaa22c6b43c02499ec7db0758c2dd218a3b2ab47a714b2bdf8010b5ee113c242"; - }; - buildInputs = with final.perlPackages; [ DirSelf TestFatal ]; - meta = { - description = "Define functions and methods with parameter lists (\"subroutine signatures\")"; - license = with final.lib.licenses; [ artistic1 gpl1Plus ]; - }; - }; - - CatalystPluginPrometheusTiny = final.perlPackages.buildPerlPackage { - pname = "Catalyst-Plugin-PrometheusTiny"; - version = "0.005"; - src = final.fetchurl { - url = "mirror://cpan/authors/id/S/SY/SYSPETE/Catalyst-Plugin-PrometheusTiny-0.005.tar.gz"; - sha256 = "a42ef09efdc3053899ae007c41220d3ed7207582cc86e491b4f534539c992c5a"; - }; - buildInputs = with final.perlPackages; [ HTTPMessage Plack SubOverride TestDeep ]; - propagatedBuildInputs = with final.perlPackages; [ CatalystRuntime Moose PrometheusTiny PrometheusTinyShared ]; - meta = { - description = "Prometheus metrics for Catalyst"; - license = with final.lib.licenses; [ artistic1 gpl1Plus ]; - }; - }; - - CryptArgon2 = final.perlPackages.buildPerlModule { - pname = "Crypt-Argon2"; - version = "0.010"; - src = final.fetchurl { - url = "mirror://cpan/authors/id/L/LE/LEONT/Crypt-Argon2-0.010.tar.gz"; - sha256 = "3ea1c006f10ef66fd417e502a569df15c4cc1c776b084e35639751c41ce6671a"; - }; - nativeBuildInputs = [ pkgs.ld-is-cc-hook ]; - meta = { - description = "Perl interface to the Argon2 key derivation functions"; - license = final.lib.licenses.cc0; - }; - }; - - CryptPassphrase = final.perlPackages.buildPerlPackage { - pname = "Crypt-Passphrase"; - version = "0.003"; - src = final.fetchurl { - url = "mirror://cpan/authors/id/L/LE/LEONT/Crypt-Passphrase-0.003.tar.gz"; - sha256 = "685aa090f8179a86d6896212ccf8ccfde7a79cce857199bb14e2277a10d240ad"; - }; - meta = { - description = "A module for managing passwords in a cryptographically agile manner"; - license = with final.lib.licenses; [ artistic1 gpl1Plus ]; - }; - }; - - CryptPassphraseArgon2 = final.perlPackages.buildPerlPackage { - pname = "Crypt-Passphrase-Argon2"; - version = "0.002"; - src = final.fetchurl { - url = "mirror://cpan/authors/id/L/LE/LEONT/Crypt-Passphrase-Argon2-0.002.tar.gz"; - sha256 = "3906ff81697d13804ee21bd5ab78ffb1c4408b4822ce020e92ecf4737ba1f3a8"; - }; - propagatedBuildInputs = with final.perlPackages; [ CryptArgon2 CryptPassphrase ]; - meta = { - description = "An Argon2 encoder for Crypt::Passphrase"; - license = with final.lib.licenses; [ artistic1 gpl1Plus ]; - }; - }; - - DataRandom = final.perlPackages.buildPerlPackage { - pname = "Data-Random"; - version = "0.13"; - src = final.fetchurl { - url = "mirror://cpan/authors/id/B/BA/BAREFOOT/Data-Random-0.13.tar.gz"; - sha256 = "eb590184a8db28a7e49eab09e25f8650c33f1f668b6a472829de74a53256bfc0"; - }; - buildInputs = with final.perlPackages; [ FileShareDirInstall TestMockTime ]; - meta = { - description = "Perl module to generate random data"; - license = with final.lib.licenses; [ artistic1 gpl1Plus ]; - }; - }; - - DirSelf = final.perlPackages.buildPerlPackage { - pname = "Dir-Self"; - version = "0.11"; - src = final.fetchurl { - url = "mirror://cpan/authors/id/M/MA/MAUKE/Dir-Self-0.11.tar.gz"; - sha256 = "e251a51abc7d9ba3e708f73c2aa208e09d47a0c528d6254710fa78cc8d6885b5"; - }; - meta = { - homepage = "https://github.com/mauke/Dir-Self"; - description = "A __DIR__ constant for the directory your source file is in"; - license = with final.lib.licenses; [ artistic1 gpl1Plus ]; - }; - }; - - HashSharedMem = final.perlPackages.buildPerlModule { - pname = "Hash-SharedMem"; - version = "0.005"; - src = final.fetchurl { - url = "mirror://cpan/authors/id/Z/ZE/ZEFRAM/Hash-SharedMem-0.005.tar.gz"; - sha256 = "324776808602f7bdc44adaa937895365454029a926fa611f321c9bf6b940bb5e"; - }; - buildInputs = with final.perlPackages; [ ScalarString ]; - meta = { - description = "Efficient shared mutable hash"; - license = with final.lib.licenses; [ artistic1 gpl1Plus ]; - }; - }; PrometheusTiny = final.perlPackages.buildPerlPackage { pname = "Prometheus-Tiny"; @@ -204,269 +56,6 @@ }; }; - PrometheusTinyShared = final.perlPackages.buildPerlPackage { - pname = "Prometheus-Tiny-Shared"; - version = "0.023"; - src = final.fetchurl { - url = "mirror://cpan/authors/id/R/RO/ROBN/Prometheus-Tiny-Shared-0.023.tar.gz"; - sha256 = "7c2c72397be5d8e4839d1bf4033c1800f467f2509689673c6419df48794f2abe"; - }; - buildInputs = with final.perlPackages; [ DataRandom HTTPMessage Plack TestDifferences TestException ]; - propagatedBuildInputs = with final.perlPackages; [ HashSharedMem JSONXS PrometheusTiny ]; - meta = { - homepage = "https://github.com/robn/Prometheus-Tiny-Shared"; - description = "A tiny Prometheus client with a shared database behind it"; - license = with final.lib.licenses; [ artistic1 gpl1Plus ]; - }; - }; - - ReadonlyX = final.perlPackages.buildPerlModule { - pname = "ReadonlyX"; - version = "1.04"; - src = final.fetchurl { - url = "mirror://cpan/authors/id/S/SA/SANKO/ReadonlyX-1.04.tar.gz"; - sha256 = "81bb97dba93ac6b5ccbce04a42c3590eb04557d75018773ee18d5a30fcf48188"; - }; - buildInputs = with final.perlPackages; [ ModuleBuildTiny TestFatal ]; - meta = { - homepage = "https://github.com/sanko/readonly"; - description = "Faster facility for creating read-only scalars, arrays, hashes"; - license = final.lib.licenses.artistic2; - }; - }; - - TieHashMethod = final.perlPackages.buildPerlPackage { - pname = "Tie-Hash-Method"; - version = "0.02"; - src = final.fetchurl { - url = "mirror://cpan/authors/id/Y/YV/YVES/Tie-Hash-Method-0.02.tar.gz"; - sha256 = "d513fbb51413f7ca1e64a1bdce6194df7ec6076dea55066d67b950191eec32a9"; - }; - meta = { - description = "Tied hash with specific methods overriden by callbacks"; - license = with final.lib.licenses; [ artistic1 ]; - }; - }; - - Test2Harness = final.perlPackages.buildPerlPackage { - pname = "Test2-Harness"; - version = "1.000042"; - src = final.fetchurl { - url = "mirror://cpan/authors/id/E/EX/EXODIST/Test2-Harness-1.000042.tar.gz"; - sha256 = "aaf231a68af1a6ffd6a11188875fcf572e373e43c8285945227b9d687b43db2d"; - }; - - checkPhase = '' - patchShebangs ./t ./scripts/yath - ./scripts/yath test -j $NIX_BUILD_CORES - ''; - - propagatedBuildInputs = with final.perlPackages; [ DataUUID Importer LongJump ScopeGuard TermTable Test2PluginMemUsage Test2PluginUUID Test2Suite gotofile ]; - meta = { - description = "A new and improved test harness with better Test2 integration"; - license = with final.lib.licenses; [ artistic1 gpl1Plus ]; - }; - }; - - Test2PluginMemUsage = prev.perlPackages.buildPerlPackage { - pname = "Test2-Plugin-MemUsage"; - version = "0.002003"; - src = final.fetchurl { - url = "mirror://cpan/authors/id/E/EX/EXODIST/Test2-Plugin-MemUsage-0.002003.tar.gz"; - sha256 = "5e0662d5a823ae081641f5ce82843111eec1831cd31f883a6c6de54afdf87c25"; - }; - buildInputs = with final.perlPackages; [ Test2Suite ]; - meta = { - description = "Collect and display memory usage information"; - license = with final.lib.licenses; [ artistic1 gpl1Plus ]; - }; - }; - - Test2PluginUUID = prev.perlPackages.buildPerlPackage { - pname = "Test2-Plugin-UUID"; - version = "0.002001"; - src = final.fetchurl { - url = "mirror://cpan/authors/id/E/EX/EXODIST/Test2-Plugin-UUID-0.002001.tar.gz"; - sha256 = "4c6c8d484d7153d8779dc155a992b203095b5c5aa1cfb1ee8bcedcd0601878c9"; - }; - buildInputs = with final.perlPackages;[ Test2Suite ]; - propagatedBuildInputs = with final.perlPackages; [ DataUUID ]; - meta = { - description = "Use REAL UUIDs in Test2"; - license = with final.lib.licenses; [ artistic1 gpl1Plus ]; - }; - }; - - LongJump = final.perlPackages.buildPerlPackage { - pname = "Long-Jump"; - version = "0.000001"; - src = final.fetchurl { - url = "mirror://cpan/authors/id/E/EX/EXODIST/Long-Jump-0.000001.tar.gz"; - sha256 = "d5d6456d86992b559d8f66fc90960f919292cd3803c13403faac575762c77af4"; - }; - buildInputs = with final.perlPackages; [ Test2Suite ]; - meta = { - description = "Mechanism for returning to a specific point from a deeply nested stack"; - license = with final.lib.licenses; [ artistic1 gpl1Plus ]; - }; - }; - - gotofile = final.perlPackages.buildPerlPackage { - pname = "goto-file"; - version = "0.005"; - src = final.fetchurl { - url = "mirror://cpan/authors/id/E/EX/EXODIST/goto-file-0.005.tar.gz"; - sha256 = "c6cdd5ee4a6cdcbdbf314d92a4f9985dbcdf9e4258048cae76125c052aa31f77"; - }; - buildInputs = with final.perlPackages; [ Test2Suite ]; - meta = { - description = "Stop parsing the current file and move on to a different one"; - license = with final.lib.licenses; [ artistic1 gpl1Plus ]; - }; - }; - - NetLDAPServer = prev.perlPackages.buildPerlPackage { - pname = "Net-LDAP-Server"; - version = "0.43"; - src = final.fetchurl { - url = "mirror://cpan/authors/id/A/AA/AAR/Net-LDAP-Server-0.43.tar.gz"; - sha256 = "0qmh3cri3fpccmwz6bhwp78yskrb3qmalzvqn0a23hqbsfs4qv6x"; - }; - propagatedBuildInputs = with final.perlPackages; [ perlldap ConvertASN1 ]; - meta = { - description = "LDAP server side protocol handling"; - license = with final.lib.licenses; [ artistic1 ]; - }; - }; - - NetLDAPSID = prev.perlPackages.buildPerlPackage { - pname = "Net-LDAP-SID"; - version = "0.0001"; - src = final.fetchurl { - url = "mirror://cpan/authors/id/K/KA/KARMAN/Net-LDAP-SID-0.001.tar.gz"; - sha256 = "1mnnpkmj8kpb7qw50sm8h4sd8py37ssy2xi5hhxzr5whcx0cvhm8"; - }; - meta = { - description = "Active Directory Security Identifier manipulation"; - license = with final.lib.licenses; [ artistic2 ]; - }; - }; - - NetLDAPServerTest = prev.perlPackages.buildPerlPackage { - pname = "Net-LDAP-Server-Test"; - version = "0.22"; - src = final.fetchurl { - url = "mirror://cpan/authors/id/K/KA/KARMAN/Net-LDAP-Server-Test-0.22.tar.gz"; - sha256 = "13idip7jky92v4adw60jn2gcc3zf339gsdqlnc9nnvqzbxxp285i"; - }; - propagatedBuildInputs = with final.perlPackages; [ perlldap NetLDAPServer DataDump NetLDAPSID ]; - meta = { - description = "test Net::LDAP code"; - license = with final.lib.licenses; [ artistic1 ]; - }; - }; - - CatalystAuthenticationStoreLDAP = prev.perlPackages.buildPerlPackage { - pname = "Catalyst-Authentication-Store-LDAP"; - version = "1.016"; - src = final.fetchurl { - url = "mirror://cpan/authors/id/I/IL/ILMARI/Catalyst-Authentication-Store-LDAP-1.016.tar.gz"; - sha256 = "0cm399vxqqf05cjgs1j5v3sk4qc6nmws5nfhf52qvpbwc4m82mq8"; - }; - propagatedBuildInputs = with final.perlPackages; [ perlldap CatalystPluginAuthentication ClassAccessor ]; - buildInputs = with final.perlPackages; [ TestMockObject TestException NetLDAPServerTest ]; - meta = { - description = "Authentication from an LDAP Directory"; - license = with final.lib.licenses; [ artistic1 ]; - }; - }; - - PerlCriticCommunity = prev.perlPackages.buildPerlModule { - pname = "Perl-Critic-Community"; - version = "1.0.0"; - src = final.fetchurl { - url = "mirror://cpan/authors/id/D/DB/DBOOK/Perl-Critic-Community-v1.0.0.tar.gz"; - sha256 = "311b775da4193e9de94cf5225e993cc54dd096ae1e7ef60738cdae1d9b8854e7"; - }; - buildInputs = with final.perlPackages; [ ModuleBuildTiny ]; - propagatedBuildInputs = with final.perlPackages; [ PPI PathTiny PerlCritic PerlCriticPolicyVariablesProhibitLoopOnHash PerlCriticPulp ]; - meta = { - homepage = "https://github.com/Grinnz/Perl-Critic-Freenode"; - description = "Community-inspired Perl::Critic policies"; - license = final.lib.licenses.artistic2; - }; - }; - - PerlCriticPolicyVariablesProhibitLoopOnHash = prev.perlPackages.buildPerlPackage { - pname = "Perl-Critic-Policy-Variables-ProhibitLoopOnHash"; - version = "0.008"; - src = final.fetchurl { - url = "mirror://cpan/authors/id/X/XS/XSAWYERX/Perl-Critic-Policy-Variables-ProhibitLoopOnHash-0.008.tar.gz"; - sha256 = "12f5f0be96ea1bdc7828058577bd1c5c63ca23c17fac9c3709452b3dff5b84e0"; - }; - propagatedBuildInputs = with final.perlPackages; [ PerlCritic ]; - meta = { - description = "Don't write loops on hashes, only on keys and values of hashes"; - license = with final.lib.licenses; [ artistic1 gpl1Plus ]; - }; - }; - - PerlCriticPulp = prev.perlPackages.buildPerlPackage { - pname = "Perl-Critic-Pulp"; - version = "99"; - src = final.fetchurl { - url = "mirror://cpan/authors/id/K/KR/KRYDE/Perl-Critic-Pulp-99.tar.gz"; - sha256 = "b8fda842fcbed74d210257c0a284b6dc7b1d0554a47a3de5d97e7d542e23e7fe"; - }; - propagatedBuildInputs = with final.perlPackages; [ IOString ListMoreUtils PPI PerlCritic PodMinimumVersion ]; - meta = { - homepage = "http://user42.tuxfamily.org/perl-critic-pulp/index.html"; - description = "Some add-on policies for Perl::Critic"; - license = final.lib.licenses.gpl3Plus; - }; - }; - - PodMinimumVersion = prev.perlPackages.buildPerlPackage { - pname = "Pod-MinimumVersion"; - version = "50"; - src = final.fetchurl { - url = "mirror://cpan/authors/id/K/KR/KRYDE/Pod-MinimumVersion-50.tar.gz"; - sha256 = "0bd2812d9aacbd99bb71fa103a4bb129e955c138ba7598734207dc9fb67b5a6f"; - }; - propagatedBuildInputs = with final.perlPackages; [ IOString PodParser ]; - meta = { - homepage = "http://user42.tuxfamily.org/pod-minimumversion/index.html"; - description = "Determine minimum Perl version of POD directives"; - license = final.lib.licenses.free; - }; - }; - - StringCompareConstantTime = final.perlPackages.buildPerlPackage { - pname = "String-Compare-ConstantTime"; - version = "0.321"; - src = final.fetchurl { - url = "mirror://cpan/authors/id/F/FR/FRACTAL/String-Compare-ConstantTime-0.321.tar.gz"; - sha256 = "0b26ba2b121d8004425d4485d1d46f59001c83763aa26624dff6220d7735d7f7"; - }; - meta = { - description = "Timing side-channel protected string compare"; - license = with final.lib.licenses; [ artistic1 gpl1Plus ]; - }; - }; - - UUID4Tiny = final.perlPackages.buildPerlPackage { - pname = "UUID4-Tiny"; - version = "0.002"; - src = final.fetchurl { - url = "mirror://cpan/authors/id/C/CV/CVLIBRARY/UUID4-Tiny-0.002.tar.gz"; - sha256 = "e7535b31e386d432dec7adde214348389e1d5cf753e7ed07f1ae04c4360840cf"; - }; - meta = { - description = "Cryptographically secure v4 UUIDs for Linux x64"; - license = with final.lib.licenses; [ artistic1 gpl1Plus ]; - }; - }; - }; hydra = with final; let @@ -581,9 +170,7 @@ checkInputs = [ cacert - # FIXME: foreman is broken on all nix/nixpkgs pin, up to and - # including 2.7.0 - newNixpkgs.legacyPackages.${final.stdenv.system}.foreman + foreman glibcLocales libressl.nc openldap @@ -1015,7 +602,7 @@ self.nixosModules.hydraTest self.nixosModules.hydraProxy { - system.configurationRevision = self.rev; + system.configurationRevision = self.lastModifiedDate; boot.isContainer = true; networking.useDHCP = false; From 481ca71d6e7a391b7c93da7149f50ada02e9303f Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 12 Jul 2022 15:03:27 +0200 Subject: [PATCH 029/285] Use new flake output naming convention --- flake.nix | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/flake.nix b/flake.nix index cb1d9aea..c5d4b547 100644 --- a/flake.nix +++ b/flake.nix @@ -11,7 +11,7 @@ pkgs = import nixpkgs { system = "x86_64-linux"; - overlays = [ self.overlay nix.overlays.default ]; + overlays = [ self.overlays.default nix.overlays.default ]; }; # NixOS configuration used for VM tests. @@ -36,7 +36,7 @@ rec { # A Nixpkgs overlay that provides a 'hydra' package. - overlay = final: prev: { + overlays.default = final: prev: { # Add LDAP dependencies that aren't currently found within nixpkgs. perlPackages = prev.perlPackages // { @@ -547,11 +547,11 @@ checks.x86_64-linux.validate-openapi = hydraJobs.tests.validate-openapi; packages.x86_64-linux.hydra = pkgs.hydra; - defaultPackage.x86_64-linux = pkgs.hydra; + packages.x86_64-linux.default = pkgs.hydra; nixosModules.hydra = { imports = [ ./hydra-module.nix ]; - nixpkgs.overlays = [ self.overlay nix.overlays.default ]; + nixpkgs.overlays = [ self.overlays.default nix.overlays.default ]; }; nixosModules.hydraTest = { From 9656f16509665a2d49ff7de2905d7115b5fe4440 Mon Sep 17 00:00:00 2001 From: Amanda Cameron Date: Fri, 22 Jul 2022 10:35:38 -0400 Subject: [PATCH 030/285] Update hydra-module.nix to use newer nixos options nix.trustedUsers is deprecated as of 22.05, and since the nix.extraOptions config is just doing something similar, I moved that to the new nix.settings as well --- hydra-module.nix | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/hydra-module.nix b/hydra-module.nix index 0df5e690..1f46a3ca 100644 --- a/hydra-module.nix +++ b/hydra-module.nix @@ -228,8 +228,12 @@ in useDefaultShell = true; }; - nix.trustedUsers = [ "hydra-queue-runner" ]; - + nix.settings = { + trusted-users = [ "hydra-queue-runner" ]; + gc-keep-outputs = true; + gc-keep-derivations = true; + }; + services.hydra-dev.extraConfig = '' using_frontend_proxy = 1 @@ -256,11 +260,6 @@ in environment.variables = hydraEnv; - nix.extraOptions = '' - gc-keep-outputs = true - gc-keep-derivations = true - ''; - systemd.services.hydra-init = { wantedBy = [ "multi-user.target" ]; requires = optional haveLocalDB "postgresql.service"; From a58e2f1a642233672f9941a77c0f4bd5c3597878 Mon Sep 17 00:00:00 2001 From: Marco Rebhan Date: Thu, 4 Aug 2022 21:18:55 +0200 Subject: [PATCH 031/285] Use libmagic for better output MIME detection --- flake.nix | 1 + src/lib/Hydra/Controller/Build.pm | 39 ++++++------------------------- 2 files changed, 8 insertions(+), 32 deletions(-) diff --git a/flake.nix b/flake.nix index 2e891364..93186ee0 100644 --- a/flake.nix +++ b/flake.nix @@ -503,6 +503,7 @@ DigestSHA1 EmailMIME EmailSender + FileLibMagic FileSlurper FileWhich final.nix.perl-bindings diff --git a/src/lib/Hydra/Controller/Build.pm b/src/lib/Hydra/Controller/Build.pm index c7811c62..18a0eba3 100644 --- a/src/lib/Hydra/Controller/Build.pm +++ b/src/lib/Hydra/Controller/Build.pm @@ -7,15 +7,16 @@ use base 'Hydra::Base::Controller::NixChannel'; use Hydra::Helper::Nix; use Hydra::Helper::CatalystUtils; use File::Basename; +use File::LibMagic; use File::stat; use Data::Dump qw(dump); use Nix::Store; use Nix::Config; use List::SomeUtils qw(all); use Encode; -use MIME::Types; use JSON::PP; +use feature 'state'; sub buildChain :Chained('/') :PathPart('build') :CaptureArgs(1) { my ($self, $c, $id) = @_; @@ -236,14 +237,10 @@ sub serveFile { $c->stash->{'plain'} = { data => grab(cmd => ["nix", "--experimental-features", "nix-command", "store", "cat", "--store", getStoreUri(), "$path"]) }; - # Detect MIME type. Borrowed from Catalyst::Plugin::Static::Simple. - my $type = "text/plain"; - if ($path =~ /.*\.(\S{1,})$/xms) { - my $ext = $1; - my $mimeTypes = MIME::Types->new(only_complete => 1); - my $t = $mimeTypes->mimeTypeOf($ext); - $type = ref $t ? $t->type : $t if $t; - } + # Detect MIME type. + state $magic = File::LibMagic->new(follow_symlinks => 1); + my $info = $magic->info_from_filename($path); + my $type = $info->{mime_with_encoding}; $c->response->content_type($type); $c->forward('Hydra::View::Plain'); } @@ -288,29 +285,7 @@ sub download : Chained('buildChain') PathPart { my $path = $product->path; $path .= "/" . join("/", @path) if scalar @path > 0; - if (isLocalStore) { - - notFound($c, "File '" . $product->path . "' does not exist.") unless -e $product->path; - - # Make sure the file is in the Nix store. - $path = checkPath($self, $c, $path); - - # If this is a directory but no "/" is attached, then redirect. - if (-d $path && substr($c->request->uri, -1) ne "/") { - return $c->res->redirect($c->request->uri . "/"); - } - - $path = "$path/index.html" if -d $path && -e "$path/index.html"; - - notFound($c, "File '$path' does not exist.") if !-e $path; - - notFound($c, "Path '$path' is a directory.") if -d $path; - - $c->serve_static_file($path); - - } else { - serveFile($c, $path); - } + serveFile($c, $path); $c->response->headers->last_modified($c->stash->{build}->stoptime); } From f6d45b0f0cdedf940df67a935f4eb337b43300e7 Mon Sep 17 00:00:00 2001 From: Maximilian Bosch Date: Mon, 8 Aug 2022 13:35:56 +0200 Subject: [PATCH 032/285] doc/configuration: fix ldap role mapping example To group is called `cancel-build`, not `cancel-builds` (note the trailing `s`). --- doc/manual/src/configuration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/manual/src/configuration.md b/doc/manual/src/configuration.md index 2700625d..ab68df43 100644 --- a/doc/manual/src/configuration.md +++ b/doc/manual/src/configuration.md @@ -185,7 +185,7 @@ Example configuration: hydra_admin = admin # Allow all users in the dev group to restart jobs and cancel builds dev = restart-jobs - dev = cancel-builds + dev = cancel-build ``` From 74caaa696e5732313a621ada9a0d9283a57fa764 Mon Sep 17 00:00:00 2001 From: K900 Date: Thu, 11 Aug 2022 13:30:19 +0300 Subject: [PATCH 033/285] Run the JS code to make build trees collapsible at the right time --- src/root/build.tt | 4 ++-- src/root/common.tt | 6 +++++- src/root/static/js/common.js | 27 ++++++++++++++++----------- 3 files changed, 23 insertions(+), 14 deletions(-) diff --git a/src/root/build.tt b/src/root/build.tt index 027ce3e4..93a02e0f 100644 --- a/src/root/build.tt +++ b/src/root/build.tt @@ -481,11 +481,11 @@ END; [% END %] [% IF drvAvailable %] - [% INCLUDE makeLazyTab tabName="tabs-build-deps" uri=c.uri_for('/build' build.id 'build-deps') %] + [% INCLUDE makeLazyTab tabName="tabs-build-deps" uri=c.uri_for('/build' build.id 'build-deps') callback="makeTreeCollapsible" %] [% END %] [% IF available %] - [% INCLUDE makeLazyTab tabName="tabs-runtime-deps" uri=c.uri_for('/build' build.id 'runtime-deps') %] + [% INCLUDE makeLazyTab tabName="tabs-runtime-deps" uri=c.uri_for('/build' build.id 'runtime-deps') callback="makeTreeCollapsible" %] [% END %]
diff --git a/src/root/common.tt b/src/root/common.tt index 6b4e406e..32d6c8cc 100644 --- a/src/root/common.tt +++ b/src/root/common.tt @@ -520,7 +520,11 @@ BLOCK makeLazyTab %]
[% END; diff --git a/src/root/static/js/common.js b/src/root/static/js/common.js index 433c06d7..c51f769a 100644 --- a/src/root/static/js/common.js +++ b/src/root/static/js/common.js @@ -1,10 +1,9 @@ -$(document).ready(function() { - +function makeTreeCollapsible(tab) { /*** Tree toggles in logfiles. ***/ /* Set the appearance of the toggle depending on whether the corresponding subtree is initially shown or hidden. */ - $(".tree-toggle").map(function() { + tab.find(".tree-toggle").map(function() { if ($(this).siblings("ul:hidden").length == 0) { $(this).text("-"); } else { @@ -13,7 +12,7 @@ $(document).ready(function() { }); /* When a toggle is clicked, show or hide the subtree. */ - $(".tree-toggle").click(function() { + tab.find(".tree-toggle").click(function() { if ($(this).siblings("ul:hidden").length != 0) { $(this).siblings("ul").show(); $(this).text("-"); @@ -24,21 +23,23 @@ $(document).ready(function() { }); /* Implementation of the expand all link. */ - $(".tree-expand-all").click(function() { - $(".tree-toggle", $(this).parent().siblings(".tree")).map(function() { + tab.find(".tree-expand-all").click(function() { + tab.find(".tree-toggle", $(this).parent().siblings(".tree")).map(function() { $(this).siblings("ul").show(); $(this).text("-"); }); }); /* Implementation of the collapse all link. */ - $(".tree-collapse-all").click(function() { - $(".tree-toggle", $(this).parent().siblings(".tree")).map(function() { + tab.find(".tree-collapse-all").click(function() { + tab.find(".tree-toggle", $(this).parent().siblings(".tree")).map(function() { $(this).siblings("ul").hide(); $(this).text("+"); }); }); +} +$(document).ready(function() { $("table.clickable-rows").click(function(event) { if ($(event.target).closest("a").length) return; link = $(event.target).parents("tr").find("a.row-link"); @@ -132,7 +133,7 @@ $(document).ready(function() { var tabsLoaded = {}; -function makeLazyTab(tabName, uri) { +function makeLazyTab(tabName, uri, callback) { $('.nav-tabs').bind('show.bs.tab', function(e) { var pattern = /#.+/gi; var id = e.target.toString().match(pattern)[0]; @@ -140,11 +141,15 @@ function makeLazyTab(tabName, uri) { tabsLoaded[id] = 1; $('#' + tabName).load(uri, function(response, status, xhr) { var lazy = xhr.getResponseHeader("X-Hydra-Lazy") === "Yes"; + var tab = $('#' + tabName); if (status == "error" && !lazy) { - $('#' + tabName).html("
Error loading tab: " + xhr.status + " " + xhr.statusText + "
"); + tab.html("
Error loading tab: " + xhr.status + " " + xhr.statusText + "
"); } else { - $('#' + tabName).html(response); + tab.html(response); + if (callback) { + callback(tab); + } } }); } From 93bbd6925b8c08d8080d0a317b5f30694da1e67c Mon Sep 17 00:00:00 2001 From: K900 Date: Fri, 12 Aug 2022 09:46:17 +0300 Subject: [PATCH 034/285] Also restore the "expand all" and "collapse all" buttons --- src/root/build-deps.tt | 2 +- src/root/deps.tt | 9 ++++++++- src/root/static/css/hydra.css | 5 +++++ 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/root/build-deps.tt b/src/root/build-deps.tt index 157b113e..f15342fa 100644 --- a/src/root/build-deps.tt +++ b/src/root/build-deps.tt @@ -4,6 +4,6 @@
    - [% INCLUDE renderNode node=buildTimeGraph %] + [% INCLUDE renderNode node=buildTimeGraph isRoot=1 %]
diff --git a/src/root/deps.tt b/src/root/deps.tt index a2c1fbba..6daa9725 100644 --- a/src/root/deps.tt +++ b/src/root/deps.tt @@ -19,9 +19,16 @@ [% node.name %] (no info) [% END %] + [% IF isRoot %] + + (collapse all + – + expand all) + + [% END %] [% IF node.refs.size > 0 %]
    - [% FOREACH ref IN node.refs; INCLUDE renderNode node=ref; END %] + [% FOREACH ref IN node.refs; INCLUDE renderNode node=ref isRoot=0; END %]
[% END %] [% END %] diff --git a/src/root/static/css/hydra.css b/src/root/static/css/hydra.css index 3b50d246..aac3f1ea 100644 --- a/src/root/static/css/hydra.css +++ b/src/root/static/css/hydra.css @@ -33,6 +33,11 @@ span:target > span.dep-tree-line { font-weight: bold; } +span.dep-tree-buttons { + font-style: italic; + padding-left: 10px; +} + span.disabled-project, span.disabled-jobset, span.disabled-job { text-decoration: line-through; } From 2b8a8fdd9cd7c6ea7d2d892fa9c93acdfef0c25d Mon Sep 17 00:00:00 2001 From: K900 Date: Fri, 12 Aug 2022 09:46:32 +0300 Subject: [PATCH 035/285] Make the tree a little less dense --- src/root/static/css/tree.css | 1 + 1 file changed, 1 insertion(+) diff --git a/src/root/static/css/tree.css b/src/root/static/css/tree.css index 71df2f12..e80f6871 100644 --- a/src/root/static/css/tree.css +++ b/src/root/static/css/tree.css @@ -9,6 +9,7 @@ ul.tree, ul.subtree { ul.subtree > li { position: relative; padding-left: 2.0em; + line-height: 140%; border-left: 0.1em solid #6185a0; } From 9addaeb17fc9663f706b58b33e0de8ec57f4bf2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Janne=20He=C3=9F?= Date: Fri, 8 Jul 2022 22:23:35 +0200 Subject: [PATCH 036/285] Add a squiggly line to the Hydra link on hover The effect is the same as the one on links in mail bodys on https://lists.apache.org/ --- src/root/layout.tt | 2 +- src/root/static/css/hydra.css | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/root/layout.tt b/src/root/layout.tt index 8eb1f119..d67ff1b8 100644 --- a/src/root/layout.tt +++ b/src/root/layout.tt @@ -93,7 +93,7 @@