Skip to content

Commit

Permalink
Use BINARY_CACHE_STORE where appropriate
Browse files Browse the repository at this point in the history
Replaces / Closes NixOS#1352

Consider the following setup:

* `store_uri` points to a "special" store, e.g. `s3://` or `file://`.
* Hydra runs inside e.g. an nspawn container and exclusively builds
  on remote systems.

Then, build products are never in the nspawn's `/nix/store`. This in
turn means that `$MACHINE_LOCAL_STORE->isValidPath` is always `false`
(or `0` 🤷) for output paths and thus Hydra wrongly claims that the
output got garbage collected.

Instead, use the BINARY_CACHE_STORE to look for the availability in the
correct store.

Everything touching the `drv` rather than the output paths still uses
MACHINE_LOCAL_STORE: this is because `hydra-eval-jobs` does `openStore()`
on `auto`, so the derivations end up there rather than on the
BINARY_CACHE_STORE.
  • Loading branch information
Ma27 committed Feb 12, 2024
1 parent e499509 commit 507bd9c
Show file tree
Hide file tree
Showing 4 changed files with 10 additions and 8 deletions.
2 changes: 1 addition & 1 deletion src/lib/Hydra/Base/Controller/NixChannel.pm
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ sub getChannelData {
my $outputs = {};
foreach my $output (@outputs) {
my $outPath = $output->get_column("outpath");
next if $checkValidity && !$MACHINE_LOCAL_STORE->isValidPath($outPath);
next if $checkValidity && !$BINARY_CACHE_STORE->isValidPath($outPath);
$outputs->{$output->get_column("outname")} = $outPath;
push @storePaths, $outPath;
# Put the system type in the manifest (for top-level
Expand Down
12 changes: 6 additions & 6 deletions src/lib/Hydra/Controller/Build.pm
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ sub build_GET {
# false because `$_->path` will be empty
$c->stash->{available} =
$c->stash->{isLocalStore}
? all { $_->path && $MACHINE_LOCAL_STORE->isValidPath($_->path) } $build->buildoutputs->all
? all { $_->path && $BINARY_CACHE_STORE->isValidPath($_->path) } $build->buildoutputs->all
: 1;
$c->stash->{drvAvailable} = $MACHINE_LOCAL_STORE->isValidPath($build->drvpath);

Expand Down Expand Up @@ -306,7 +306,7 @@ sub output : Chained('buildChain') PathPart Args(1) {
error($c, "This build is not finished yet.") unless $build->finished;
my $output = $build->buildoutputs->find({name => $outputName});
notFound($c, "This build has no output named ‘$outputName") unless defined $output;
gone($c, "Output is no longer available.") unless $MACHINE_LOCAL_STORE->isValidPath($output->path);
gone($c, "Output is no longer available.") unless $BINARY_CACHE_STORE->isValidPath($output->path);

$c->response->header('Content-Disposition', "attachment; filename=\"build-${\$build->id}-${\$outputName}.nar.bz2\"");
$c->stash->{current_view} = 'NixNAR';
Expand Down Expand Up @@ -423,15 +423,15 @@ sub getDependencyGraph {
};
$$done{$path} = $node;
my @refs;
foreach my $ref ($MACHINE_LOCAL_STORE->queryReferences($path)) {
foreach my $ref ($BINARY_CACHE_STORE->queryReferences($path)) {
next if $ref eq $path;
next unless $runtime || $ref =~ /\.drv$/;
getDependencyGraph($self, $c, $runtime, $done, $ref);
push @refs, $ref;
}
# Show in reverse topological order to flatten the graph.
# Should probably do a proper BFS.
my @sorted = reverse $MACHINE_LOCAL_STORE->topoSortPaths(@refs);
my @sorted = reverse $BINARY_CACHE_STORE->topoSortPaths(@refs);
$node->{refs} = [map { $$done{$_} } @sorted];
}

Expand Down Expand Up @@ -459,7 +459,7 @@ sub runtime_deps : Chained('buildChain') PathPart('runtime-deps') {

requireLocalStore($c);

error($c, "Build outputs no longer available.") unless all { $MACHINE_LOCAL_STORE->isValidPath($_) } @outPaths;
error($c, "Build outputs no longer available.") unless all { $BINARY_CACHE_STORE->isValidPath($_) } @outPaths;

my $done = {};
$c->stash->{runtimeGraph} = [ map { getDependencyGraph($self, $c, 1, $done, $_) } @outPaths ];
Expand All @@ -479,7 +479,7 @@ sub nix : Chained('buildChain') PathPart('nix') CaptureArgs(0) {
if (isLocalStore) {
foreach my $out ($build->buildoutputs) {
notFound($c, "Path " . $out->path . " is no longer available.")
unless $MACHINE_LOCAL_STORE->isValidPath($out->path);
unless $BINARY_CACHE_STORE->isValidPath($out->path);
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/lib/Hydra/Controller/Root.pm
Original file line number Diff line number Diff line change
Expand Up @@ -395,7 +395,7 @@ sub narinfo :Path :Args(StrMatch[NARINFO_REGEX]) {
my ($hash) = $narinfo =~ NARINFO_REGEX;

die("Hash length was not 32") if length($hash) != 32;
my $path = $MACHINE_LOCAL_STORE->queryPathFromHashPart($hash);
my $path = $BINARY_CACHE_STORE->queryPathFromHashPart($hash);

if (!$path) {
$c->response->status(404);
Expand Down
2 changes: 2 additions & 0 deletions src/lib/Hydra/Helper/Nix.pm
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,11 @@ our @EXPORT = qw(
restartBuilds
run
$MACHINE_LOCAL_STORE
$BINARY_CACHE_STORE
);

our $MACHINE_LOCAL_STORE = Nix::Store->new();
our $BINARY_CACHE_STORE = Nix::Store->new(getStoreUri());


sub getHydraHome {
Expand Down

0 comments on commit 507bd9c

Please sign in to comment.