Handle job aliases in AggregateConstituents

Aggregate constituents are derivations.  However there can be multiple
builds in an evaluation that have the same derivation, i.e. they can
alias each other (e.g. "emacs", "emacs24" and "emacs24Packages.emacs"
in Nixpkgs).  Previously we picked a build arbitrarily for the
AggregateConstituents table.  Now we pick the one with the shortest
name (e.g. "emacs").
This commit is contained in:
Eelco Dolstra 2013-08-27 11:48:02 +02:00
parent a98075f386
commit a57957df84
2 changed files with 18 additions and 7 deletions

View file

@ -433,7 +433,7 @@ sub checkBuild {
{ rows => 1, columns => ['id'], join => ['buildoutputs'] }); { rows => 1, columns => ['id'], join => ['buildoutputs'] });
if (defined $prevBuild) { if (defined $prevBuild) {
print STDERR " already scheduled/built as build ", $prevBuild->id, "\n"; print STDERR " already scheduled/built as build ", $prevBuild->id, "\n";
$buildMap->{$prevBuild->id} = { new => 0, drvPath => $drvPath }; $buildMap->{$prevBuild->id} = { id => $prevBuild->id, jobName => $jobName, new => 0, drvPath => $drvPath };
return; return;
} }
} }
@ -506,7 +506,7 @@ sub checkBuild {
$build->buildoutputs->create({ name => $_, path => $buildInfo->{output}->{$_}->{path} }) $build->buildoutputs->create({ name => $_, path => $buildInfo->{output}->{$_}->{path} })
foreach @outputNames; foreach @outputNames;
$buildMap->{$build->id} = { new => 1, drvPath => $drvPath }; $buildMap->{$build->id} = { id => $build->id, jobName => $jobName, new => 1, drvPath => $drvPath };
$$jobOutPathMap{$jobName . "\t" . $firstOutputPath} = $build->id; $$jobOutPathMap{$jobName . "\t" . $firstOutputPath} = $build->id;
if ($build->iscachedbuild) { if ($build->iscachedbuild) {

View file

@ -177,20 +177,31 @@ sub checkJobsetWrapped {
if ($hasNewBuilds) { if ($hasNewBuilds) {
# Create JobsetEvalMembers mappings. # Create JobsetEvalMembers mappings.
my %drvPathToId;
while (my ($id, $x) = each %buildMap) { while (my ($id, $x) = each %buildMap) {
$ev->jobsetevalmembers->create({ build => $id, isnew => $x->{new} }); $ev->jobsetevalmembers->create({ build => $id, isnew => $x->{new} });
$drvPathToId{$x->{drvPath}} = $id;
} }
# Create AggregateConstituents mappings. # Create AggregateConstituents mappings. Since there can
# be jobs that alias each other, if there are multiple
# builds for the same derivation, pick the one with the
# shortest name.
my %drvPathToId;
while (my ($id, $x) = each %buildMap) {
my $y = $drvPathToId{$x->{drvPath}};
if (defined $y) {
next if length $x->{jobName} > length $y->{jobName};
next if length $x->{jobName} == length $y->{jobName} && $x->{jobName} ge $y->{jobName};
}
$drvPathToId{$x->{drvPath}} = $x;
}
foreach my $job (@{$jobs->{job}}) { foreach my $job (@{$jobs->{job}}) {
next unless $job->{constituents}; next unless $job->{constituents};
my $id = $drvPathToId{$job->{drvPath}} or die; my $x = $drvPathToId{$job->{drvPath}} or die;
foreach my $drvPath (split / /, $job->{constituents}) { foreach my $drvPath (split / /, $job->{constituents}) {
my $constituent = $drvPathToId{$drvPath}; my $constituent = $drvPathToId{$drvPath};
if (defined $constituent) { if (defined $constituent) {
$db->resultset('AggregateConstituents')->update_or_create({aggregate => $id, constituent => $constituent}); $db->resultset('AggregateConstituents')->update_or_create({aggregate => $x->{id}, constituent => $constituent->{id}});
} else { } else {
warn "aggregate job $job->{jobName} has a constituent $drvPath that doesn't correspond to a Hydra build\n"; warn "aggregate job $job->{jobName} has a constituent $drvPath that doesn't correspond to a Hydra build\n";
} }