Compare commits

..

1 Commits

Author SHA1 Message Date
Janne Heß
d288e401ba Add option to disable search 2026-01-05 22:48:44 +01:00
25 changed files with 158 additions and 170 deletions

22
flake.lock generated
View File

@@ -3,16 +3,16 @@
"nix": {
"flake": false,
"locked": {
"lastModified": 1768160797,
"narHash": "sha256-TVKn52SoKq8mMyW/x3NPPskGVurFdnGGV0DGvnL0gak=",
"lastModified": 1767367029,
"narHash": "sha256-RsVlkBkxvPPePEo59AVolBFdayxny9FFv8X4aNq9qFc=",
"owner": "NixOS",
"repo": "nix",
"rev": "fb562abba93fb15f66a71a9fc1d94bb1ea21a2d4",
"rev": "394a8da9dd9c046de715e451a96b70e64ce4aa7a",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "2.33-maintenance",
"ref": "2.32-maintenance",
"repo": "nix",
"type": "github"
}
@@ -20,27 +20,27 @@
"nix-eval-jobs": {
"flake": false,
"locked": {
"lastModified": 1767025318,
"narHash": "sha256-i68miKHGdueWggcDAF+Kca9g6S3ipkW629XbMpQYfn0=",
"lastModified": 1760478325,
"narHash": "sha256-hA+NOH8KDcsuvH7vJqSwk74PyZP3MtvI/l+CggZcnTc=",
"owner": "nix-community",
"repo": "nix-eval-jobs",
"rev": "79dd7adbb5f75b08fb4b9bddd712ebc52baa46bc",
"rev": "daa42f9e9c84aeff1e325dd50fda321f53dfd02c",
"type": "github"
},
"original": {
"owner": "nix-community",
"ref": "v2.33.0",
"ref": "v2.32.1",
"repo": "nix-eval-jobs",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1768332487,
"narHash": "sha256-Q0bSMhDIhb/S7r+XRyuPy58kEXa0rmpw5j99ubJzovg=",
"lastModified": 1767475907,
"narHash": "sha256-w10AFfl20h5MSBCsCegD4xtmcgDlQQeoFsOaIFwHOrE=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "6b0609442afc4ce51ff1466e7db555c2e2fc28d4",
"rev": "7a0d60a03534a2d14b0805616aa1fd403fccfa55",
"type": "github"
},
"original": {

View File

@@ -4,13 +4,13 @@
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.11-small";
inputs.nix = {
url = "github:NixOS/nix/2.33-maintenance";
url = "github:NixOS/nix/2.32-maintenance";
# We want to control the deps precisely
flake = false;
};
inputs.nix-eval-jobs = {
url = "github:nix-community/nix-eval-jobs/v2.33.0";
url = "github:nix-community/nix-eval-jobs/v2.32.1";
# We want to control the deps precisely
flake = false;
};

View File

@@ -1,71 +0,0 @@
#/usr/bin/env python3
#imports
import os
import json
from http.server import BaseHTTPRequestHandler, HTTPServer
import urllib.request
#Vars
baseurl="git.dynamicdiscord.de"
owner="ahtlon"
repo="infrastructure"
host="127.0.0.1"
port=27364
def _get_api_response():
###https://docs.gitea.com/api/1.21/#tag/repository/operation/repoListPullRequests
###GET /api/v1/repos/{owner}/{repo}/pulls
url=(f"https://{baseurl}/api/v1/repos/{owner}/{repo}/pulls?state=open")
headers={"Accept": "application/json"}
req=urllib.request.Request(url, headers=headers)
with urllib.request.urlopen(req) as resp:
return json.loads(resp.read().decode("utf-8"))
def _parse_response():
target_repo_url=f"https://{baseurl}/{owner}/{repo}.git"
pulls: dict={}
response=_get_api_response()
for pr in response:
pr["target_repo_url"]=target_repo_url
pulls[str(pr["number"])]=pr
return pulls
class PullsHandler(BaseHTTPRequestHandler):
_VALID_PATHS={"/", "/gitea-pulls-sorted.json"}
def do_GET(self):
if self.path not in self._VALID_PATHS:
self.send_error(404, "Not Found")
return
answer=dict(_parse_response())
body=json.dumps(answer, indent=2, sort_keys=True).encode("utf-8")
self.send_response(200)
self.send_header("Content-Type", "application/json; charset=utf-8")
self.send_header("Content-Length", str(len(body)))
self.end_headers()
self.wfile.write(body)
def log_message(self, fmt, *args):
print(
f"[gitea-translator] {self.address_string()} - {fmt % args}",
flush=True,
)
def main():
print(
f"[gitea-translator] Starting, pulling from {baseurl}/{owner}/{repo}",
flush=True,
)
server=HTTPServer((host, port), PullsHandler)
print(
f"[gitea-translator] online @ {host}:{port}",
flush=True,
)
server.serve_forever()
if __name__ == "__main__":
main()

View File

@@ -273,7 +273,7 @@ static BuildResult performBuild(
auto drvOutput = DrvOutput { outputHash, outputName };
successP->builtOutputs.insert_or_assign(
std::move(outputName),
Realisation { {.outPath = *outputPath}, drvOutput });
Realisation { drvOutput, *outputPath });
}
}
}

View File

@@ -537,12 +537,12 @@ void State::notifyBuildFinished(pqxx::work & txn, BuildID buildId,
std::shared_ptr<PathLocks> State::acquireGlobalLock()
{
auto lockPath = std::filesystem::path(hydraData) / "queue-runner/lock";
Path lockPath = hydraData + "/queue-runner/lock";
createDirs(lockPath.parent_path());
createDirs(dirOf(lockPath));
auto lock = std::make_shared<PathLocks>();
if (!lock->lockPaths({lockPath}, "", false)) return 0;
if (!lock->lockPaths(PathSet({lockPath}), "", false)) return 0;
return lock;
}

View File

@@ -1,6 +1,5 @@
#include "state.hh"
#include "hydra-build-result.hh"
#include <nix/store/derived-path.hh>
#include <nix/store/globals.hh>
#include <nix/store/parsed-derivations.hh>
#include <nix/util/thread-pool.hh>
@@ -488,24 +487,24 @@ Step::ptr State::createStep(ref<Store> destStore,
it's not runnable yet, and other threads won't make it
runnable while step->created == false. */
step->drv = std::make_unique<Derivation>(localStore->readDerivation(drvPath));
DerivationOptions<nix::SingleDerivedPath> drvOptions;
try {
drvOptions = derivationOptionsFromStructuredAttrs(
*localStore,
step->drv->inputDrvs,
step->drv->env,
get(step->drv->structuredAttrs));
} catch (Error & e) {
e.addTrace({}, "while parsing derivation '%s'", localStore->printStorePath(drvPath));
throw;
{
try {
step->drvOptions = std::make_unique<DerivationOptions>(
DerivationOptions::fromStructuredAttrs(
step->drv->env,
step->drv->structuredAttrs ? &*step->drv->structuredAttrs : nullptr));
} catch (Error & e) {
e.addTrace({}, "while parsing derivation '%s'", localStore->printStorePath(drvPath));
throw;
}
}
step->preferLocalBuild = drvOptions.willBuildLocally(*localStore, *step->drv);
step->preferLocalBuild = step->drvOptions->willBuildLocally(*localStore, *step->drv);
step->isDeterministic = getOr(step->drv->env, "isDetermistic", "0") == "1";
step->systemType = step->drv->platform;
{
StringSet features = step->requiredSystemFeatures = drvOptions.getRequiredSystemFeatures(*step->drv);
StringSet features = step->requiredSystemFeatures = step->drvOptions->getRequiredSystemFeatures(*step->drv);
if (step->preferLocalBuild)
features.insert("local");
if (!features.empty()) {

View File

@@ -172,6 +172,7 @@ struct Step
nix::StorePath drvPath;
std::unique_ptr<nix::Derivation> drv;
std::unique_ptr<nix::DerivationOptions> drvOptions;
nix::StringSet requiredSystemFeatures;
bool preferLocalBuild;
bool isDeterministic;

View File

@@ -495,6 +495,9 @@ sub steps :Local Args(0) {
sub search :Local Args(0) {
my ($self, $c) = @_;
badRequest($c, "Search is disabled in this Hydra instance") if $c->config->{disable_search};
$c->stash->{template} = 'search.tt';
my $query = trim $c->request->params->{"query"};

View File

@@ -106,11 +106,11 @@ sub doEmailLogin {
my $allowed_domains = $c->config->{allowed_domains} // ($c->config->{persona_allowed_domains} // "");
if ($allowed_domains ne "") {
my $email_ok = 0;
my @domains = split /,/, $allowed_domains;
my @domains = split ',', $allowed_domains;
map { $_ =~ s/^\s*(.*?)\s*$/$1/ } @domains;
foreach my $domain (@domains) {
$email_ok = $email_ok || ((split /@/, $email)[1] eq $domain);
$email_ok = $email_ok || ((split '@', $email)[1] eq $domain);
}
error($c, "Your email address does not belong to a domain that is allowed to log in.\n")
unless $email_ok;

View File

@@ -71,7 +71,7 @@ sub buildFinished {
my $to = $build->jobset->emailoverride ne "" ? $build->jobset->emailoverride : $build->maintainers;
foreach my $address (split /,/, ($to // "")) {
foreach my $address (split ",", ($to // "")) {
$address = trim $address;
$addresses{$address} //= { builds => [] };

View File

@@ -38,7 +38,7 @@ sub _parseValue {
$start_options = 2;
}
foreach my $option (@parts[$start_options .. $#parts]) {
(my $key, my $value) = split(/=/, $option);
(my $key, my $value) = split('=', $option);
$options->{$key} = $value;
}
return ($uri, $branch, $deepClone, $options);
@@ -265,7 +265,7 @@ sub getCommits {
my $res = [];
foreach my $line (split /\n/, $out) {
my ($revision, $author, $email, $date) = split /\t/, $line;
my ($revision, $author, $email, $date) = split "\t", $line;
push @$res, { revision => $revision, author => decode("utf-8", $author), email => $email };
}

View File

@@ -31,10 +31,10 @@ 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;
my ($url, $rel) = split ";", $link;
if (trim($rel) eq 'rel="next"') {
$next = substr trim($url), 1, -1;
last;

View File

@@ -83,10 +83,10 @@ sub _iterate {
$refs->{$ref_name} = $ref;
}
# 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;
my ($url, $rel) = split ";", $link;
if (trim($rel) eq 'rel="next"') {
$next = substr trim($url), 1, -1;
last;

View File

@@ -49,10 +49,10 @@ sub _iterate {
$pulls->{$pull->{iid}} = $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;
my ($url, $rel) = split ";", $link;
if (trim($rel) eq 'rel="next"') {
$next = substr trim($url), 1, -1;
last;

View File

@@ -126,7 +126,7 @@ sub getCommits {
my $res = [];
foreach my $line (split /\n/, $out) {
if ($line ne "") {
my ($revision, $author, $email) = split /\t/, $line;
my ($revision, $author, $email) = split "\t", $line;
push @$res, { revision => $revision, author => $author, email => $email };
}
}

View File

@@ -85,7 +85,7 @@ sub isBuildEligibleForDynamicRunCommand {
sub configSectionMatches {
my ($name, $project, $jobset, $job) = @_;
my @elems = split /:/, $name;
my @elems = split ':', $name;
die "invalid section name '$name'\n" if scalar(@elems) > 3;

View File

@@ -66,11 +66,6 @@ __PACKAGE__->table("jobsetevalinputs");
data_type: 'text'
is_nullable: 1
=head2 shortRevLength
data_type: 'number'
is_nullable: 1
=head2 value
data_type: 'text'
@@ -107,8 +102,6 @@ __PACKAGE__->add_columns(
{ data_type => "text", is_nullable => 1 },
"revision",
{ data_type => "text", is_nullable => 1 },
"shortRevLength",
{ data_type => "integer", is_nullable => 1 },
"value",
{ data_type => "text", is_nullable => 1 },
"dependency",
@@ -190,28 +183,4 @@ sub json_hint {
return \%hint;
}
# Revision to be rendered by the frontend
sub frontend_revision() {
my ($self) = @_;
my $type = $self->get_column('type');
if ($type eq 'svn' or $type eq 'svn-checkout' or $type eq 'bzr' or $type eq 'bzr-checkout') {
return 'r' . $self->get_column('revision');
} elsif ($type eq 'git') {
# Find the longest revision length of this URI
my $schema = $self->result_source->schema;
my $maxLength = $schema
->resultset('JobsetEvalInputs')
->search({ uri => $self->get_column('uri')})
->get_column('shortRevLength')
->max;
# Fall back to a fixed value if there was no value
return substr($self->get_column('revision'), 0, $maxLength || 12);
} elsif ($type eq 'bzr') {
return substr($self->get_column('revision'), 0, 12);
} else {
return $self->get_column('revision');
}
}
1;

View File

@@ -347,10 +347,9 @@ BLOCK renderDiffUri;
url = res.0;
branch = res.1;
IF bi1.type == "hg" || bi1.type == "git" %]
[% IF url.substr(0, 19) == "https://github.com/";
github_url = url.replace('\.git$', '') %]
[% IF url.substr(0, 19) == "https://github.com/" %]
<a target="_blank" [% HTML.attributes(href =>
github_url
url
_ "/compare/"
_ bi1.revision
_ "..."
@@ -422,7 +421,7 @@ BLOCK renderInputDiff; %]
[% ELSIF bi1.uri == bi2.uri && bi1.revision != bi2.revision %]
[% IF bi1.type == "git" %]
<tr><td>
<b>[% HTML.escape(bi1.name) %]</b></td><td><tt>[% INCLUDE renderDiffUri contents=(bi1.frontend_revision _ ' to ' _ bi2.frontend_revision) %]</tt>
<b>[% HTML.escape(bi1.name) %]</b></td><td><tt>[% INCLUDE renderDiffUri contents=(bi1.revision.substr(0, 12) _ ' to ' _ bi2.revision.substr(0, 12)) %]</tt>
</td></tr>
[% ELSE %]
<tr><td>
@@ -463,10 +462,16 @@ BLOCK renderPager %]
BLOCK renderShortEvalInput;
IF input.type == "build" || input.type == "sysbuild" %]
IF input.type == "svn" || input.type == "svn-checkout" || input.type == "bzr" || input.type == "bzr-checkout" %]
r[% input.revision %]
[% ELSIF input.type == "git" %]
<tt>[% input.revision.substr(0, 7) | html %]</tt>
[% ELSIF input.type == "hg" %]
<tt>[% input.revision.substr(0, 12) | html %]</tt>
[% ELSIF input.type == "build" || input.type == "sysbuild" %]
<a [% HTML.attributes(href => c.uri_for('/build' input.get_column('dependency'))) %]>[% HTML.escape(input.get_column('dependency')) %]</a>
[% ELSE %]
<tt>[% input.frontend_revision | html %]</tt>
<tt>[% input.revision | html %]</tt>
[% END;
END;

View File

@@ -117,7 +117,7 @@ else
revCount="$(cat "$tmpDir/[% input.name %]/rev-count")"
fi
args+=(--arg '[% input.name %]' "{ outPath = $inputDir; rev = \"[% input.revision %]\"; shortRev = \"[% input.frontend_revision %]\"; revCount = $revCount; }")
args+=(--arg '[% input.name %]' "{ outPath = $inputDir; rev = \"[% input.revision %]\"; shortRev = \"[% input.revision.substr(0, 7) %]\"; revCount = $revCount; }")
[%+ ELSIF input.type == "hg" %]

View File

@@ -121,9 +121,11 @@
[% END %]
[% IF showPrivate %]
<form class="form-inline" action="[% c.uri_for('/search') %]">
<input name="query" type="text" class="form-control" placeholder="Search" [% HTML.attributes(value => c.req.params.query) %]/>
</form>
[% UNLESS c.config.disable_search %]
<form class="form-inline" action="[% c.uri_for('/search') %]">
<input name="query" type="text" class="form-control" placeholder="Search" [% HTML.attributes(value => c.req.params.query) %]/>
</form>
[% END %]
[% END %]
<ul class="navbar-nav">

View File

@@ -891,7 +891,6 @@ sub checkJobsetWrapped {
, type => $input->{type}
, uri => $input->{uri}
, revision => $input->{revision}
, shortRevLength => length($input->{shortRev})
, value => $input->{value}
, dependency => $input->{id}
, path => $input->{storePath} || "" # !!! temporary hack

View File

@@ -487,12 +487,11 @@ create table JobsetEvalInputs (
altNr integer not null,
-- Copied from the jobsetinputs from which the build was created.
type text not null,
uri text,
revision text,
shortRevLength smallint, -- length of a short revision at the time this was checked out
value text,
dependency integer, -- build ID of the input, for type == 'build'
type text not null,
uri text,
revision text,
value text,
dependency integer, -- build ID of the input, for type == 'build'
path text,

View File

@@ -1,7 +1,90 @@
# Install all SQL files in this directory.
# This includes hydra.sql, test.sql, update-dbix.pl, and all upgrade-*.sql files.
install_subdir('.',
install_dir: hydra_libexecdir / 'sql',
strip_directory: true,
exclude_files: ['meson.build', 'update-dbix-harness.sh'],
sql_files = files(
'hydra.sql',
'test.sql',
'update-dbix.pl',
'upgrade-2.sql',
'upgrade-3.sql',
'upgrade-4.sql',
'upgrade-5.sql',
'upgrade-6.sql',
'upgrade-7.sql',
'upgrade-8.sql',
'upgrade-9.sql',
'upgrade-10.sql',
'upgrade-11.sql',
'upgrade-12.sql',
'upgrade-13.sql',
'upgrade-14.sql',
'upgrade-15.sql',
'upgrade-16.sql',
'upgrade-17.sql',
'upgrade-18.sql',
'upgrade-19.sql',
'upgrade-20.sql',
'upgrade-21.sql',
'upgrade-22.sql',
'upgrade-23.sql',
'upgrade-24.sql',
'upgrade-25.sql',
'upgrade-26.sql',
'upgrade-27.sql',
'upgrade-28.sql',
'upgrade-29.sql',
'upgrade-30.sql',
'upgrade-31.sql',
'upgrade-32.sql',
'upgrade-33.sql',
'upgrade-34.sql',
'upgrade-35.sql',
'upgrade-36.sql',
'upgrade-37.sql',
'upgrade-38.sql',
'upgrade-39.sql',
'upgrade-40.sql',
'upgrade-41.sql',
'upgrade-42.sql',
'upgrade-43.sql',
'upgrade-44.sql',
'upgrade-45.sql',
'upgrade-46.sql',
'upgrade-47.sql',
'upgrade-48.sql',
'upgrade-49.sql',
'upgrade-50.sql',
'upgrade-51.sql',
'upgrade-52.sql',
'upgrade-53.sql',
'upgrade-54.sql',
'upgrade-55.sql',
'upgrade-56.sql',
'upgrade-57.sql',
'upgrade-58.sql',
'upgrade-59.sql',
'upgrade-60.sql',
'upgrade-61.sql',
'upgrade-62.sql',
'upgrade-63.sql',
'upgrade-64.sql',
'upgrade-65.sql',
'upgrade-66.sql',
'upgrade-67.sql',
'upgrade-68.sql',
'upgrade-69.sql',
'upgrade-70.sql',
'upgrade-71.sql',
'upgrade-72.sql',
'upgrade-73.sql',
'upgrade-74.sql',
'upgrade-75.sql',
'upgrade-76.sql',
'upgrade-77.sql',
'upgrade-78.sql',
'upgrade-79.sql',
'upgrade-80.sql',
'upgrade-81.sql',
'upgrade-82.sql',
'upgrade-83.sql',
'upgrade-84.sql',
)
install_data(sql_files, install_dir: hydra_libexecdir / 'sql')

View File

@@ -1 +0,0 @@
ALTER TABLE JobsetEvalInputs ADD COLUMN shortRevLength smallint;

View File

@@ -109,7 +109,7 @@ subtest "Build: not substitutable, unsubstitutable" => sub {
subtest "Second notification: step_finished" => sub {
my ($channelName, $pid, $payload) = @{$dbh->func("pg_notifies")};
is($channelName, "step_finished", "The event is for the step finishing");
my ($buildId, $stepNr, $logFile) = split /\t/, $payload;
my ($buildId, $stepNr, $logFile) = split "\t", $payload;
is($buildId, $build->id, "The payload is the build's ID");
is($stepNr, 1, "The payload is the build's step number");
isnt($logFile, undef, "The log file is passed");