From ef03df0af156df7179e31569725de314990e74ea Mon Sep 17 00:00:00 2001 From: Maximilian Bosch Date: Fri, 26 Jan 2024 16:57:37 +0100 Subject: [PATCH 1/2] Build: use `nix path-info` to test for build output availability When using the Perl bindings, this usually takes the wrong store, i.e. `auto` even if `store_uri` is a flat-file binary cache. See also https://github.com/NixOS/nix/issues/9859 Using fork/exec here on purpose to make sure that the output of `nix path-info` isn't spammed into stderr. This could probably done with `system("foo &>/dev/null")`, but I didn't want to worry about shell injection issues then. And finally, I can't seem to silence STDERR for `system` with a list as argument. Not a Perl dev though, so not sure if there's a better way. --- src/lib/Hydra/Controller/Build.pm | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/lib/Hydra/Controller/Build.pm b/src/lib/Hydra/Controller/Build.pm index c3869838d..22f3c797f 100644 --- a/src/lib/Hydra/Controller/Build.pm +++ b/src/lib/Hydra/Controller/Build.pm @@ -71,6 +71,17 @@ sub findBuildStepByDrvPath { sub build :Chained('buildChain') :PathPart('') :Args(0) :ActionClass('REST') { } +sub isValidPathNixCLI { + my $path = shift; + my $pid = fork(); + if (!$pid) { + open STDERR, ">", "/dev/null"; + exec "nix", "path-info", $path, "--store", getStoreUri(); + } + waitpid $pid, 0; + return $? == 0; +} + sub build_GET { my ($self, $c) = @_; @@ -82,7 +93,7 @@ sub build_GET { # false because `$_->path` will be empty $c->stash->{available} = $c->stash->{isLocalStore} - ? all { $_->path && isValidPath($_->path) } $build->buildoutputs->all + ? all { $_->path && isValidPathNixCLI($_->path) } $build->buildoutputs->all : 1; $c->stash->{drvAvailable} = isValidPath $build->drvpath; From 15b7d91b512ce565319ecbf6c6fa63f408ea41a9 Mon Sep 17 00:00:00 2001 From: Maximilian Bosch Date: Fri, 26 Jan 2024 18:57:47 +0100 Subject: [PATCH 2/2] Build: enable nix-command on `nix path-info` call, silence stdout as well `nix-store -q` (and `--outputs`) doesn't seem to complain if a path doesn't exist in a store anymore, so let's do it that way. This approach works fine on Nix 2.3 as well, it only warns about `experimental-features` being an unknown option, but that's silenced along with the rest of stderr. --- src/lib/Hydra/Controller/Build.pm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/lib/Hydra/Controller/Build.pm b/src/lib/Hydra/Controller/Build.pm index 22f3c797f..003cf0c59 100644 --- a/src/lib/Hydra/Controller/Build.pm +++ b/src/lib/Hydra/Controller/Build.pm @@ -76,7 +76,8 @@ sub isValidPathNixCLI { my $pid = fork(); if (!$pid) { open STDERR, ">", "/dev/null"; - exec "nix", "path-info", $path, "--store", getStoreUri(); + open STDOUT, ">", "/dev/null"; + exec "nix", "path-info", $path, "--store", getStoreUri(), "--option", "experimental-features", "nix-command"; } waitpid $pid, 0; return $? == 0;