diff --git a/src/hydra-queue-runner/hydra-queue-runner.cc b/src/hydra-queue-runner/hydra-queue-runner.cc index 28ed6deb5..24f037f8d 100644 --- a/src/hydra-queue-runner/hydra-queue-runner.cc +++ b/src/hydra-queue-runner/hydra-queue-runner.cc @@ -333,11 +333,12 @@ unsigned int State::createBuildStep(pqxx::work & txn, time_t startTime, BuildID for (auto & [name, output] : getDestStore()->queryPartialDerivationOutputMap(step->drvPath, &*localStore)) txn.exec_params0 - ("insert into BuildStepOutputs (build, stepnr, name, path) values ($1, $2, $3, $4)", + ("insert into BuildStepOutputs (build, stepnr, name, path, contentAddressed) values ($1, $2, $3, $4, $5)", buildId, stepNr, name, output ? std::optional { localStore->printStorePath(*output)} - : std::nullopt); + : std::nullopt, + step->drv->type().isCA()); if (status == bsBusy) txn.exec(fmt("notify step_started, '%d\t%d'", buildId, stepNr)); @@ -409,9 +410,10 @@ int State::createSubstitutionStep(pqxx::work & txn, time_t startTime, time_t sto if (r.affected_rows() == 0) goto restart; txn.exec_params0 - ("insert into BuildStepOutputs (build, stepnr, name, path) values ($1, $2, $3, $4)", + ("insert into BuildStepOutputs (build, stepnr, name, path, contentAddressed) values ($1, $2, $3, $4, $5)", build->id, stepNr, outputName, - localStore->printStorePath(storePath)); + localStore->printStorePath(storePath), + drv.type().isCA()); return stepNr; } diff --git a/src/lib/Hydra/Controller/Build.pm b/src/lib/Hydra/Controller/Build.pm index de2c204d9..4c488c13f 100644 --- a/src/lib/Hydra/Controller/Build.pm +++ b/src/lib/Hydra/Controller/Build.pm @@ -114,6 +114,18 @@ sub build_GET { $c->stash->{steps} = [$build->buildsteps->search({}, {order_by => "stepnr desc"})]; + $c->stash->{contentAddressed} = 0; + # Hydra marks single outputs as CA but currently in Nix only derivations + # can be CA (and *all* their outputs are CA). + # So the next check (which assumes that if a step's output is CA then + # all the other outptus and the whole derivation are CA) is safe. + foreach my $step (@{$c->stash->{steps}}) { + if ($step->buildstepoutputs->search({contentaddressed => 1})->count > 0) { + $c->stash->{contentAddressed} = 1; + last; + } + } + $c->stash->{binaryCachePublicUri} = $c->config->{binary_cache_public_uri}; } diff --git a/src/lib/Hydra/Schema/Result/BuildStepOutputs.pm b/src/lib/Hydra/Schema/Result/BuildStepOutputs.pm index 6d997a8ca..42392190f 100644 --- a/src/lib/Hydra/Schema/Result/BuildStepOutputs.pm +++ b/src/lib/Hydra/Schema/Result/BuildStepOutputs.pm @@ -57,6 +57,11 @@ __PACKAGE__->table("buildstepoutputs"); data_type: 'text' is_nullable: 1 +=head2 contentaddressed + + data_type: 'boolean' + is_nullable: 0 + =cut __PACKAGE__->add_columns( @@ -68,6 +73,8 @@ __PACKAGE__->add_columns( { data_type => "text", is_nullable => 0 }, "path", { data_type => "text", is_nullable => 1 }, + "contentaddressed", + { data_type => "boolean", is_nullable => 0 }, ); =head1 PRIMARY KEY diff --git a/src/root/build.tt b/src/root/build.tt index 93a02e0f7..79b0a1e6e 100644 --- a/src/root/build.tt +++ b/src/root/build.tt @@ -20,8 +20,13 @@ END; %] [% BLOCK renderOutputs %] - [% start=1; FOREACH output IN outputs %] - [% IF !start %],
[% END; start=0; output.path %] + [% start=1; FOREACH output IN step.buildstepoutputs %] + [% IF !start %],
[% END; start=0; %] + [% IF step.status != 0 && output.contentaddressed %] + [% output.name %] + [% ELSE %] + [% output.path %] + [% END %] [% END %] [% END %] @@ -40,9 +45,9 @@ END; [% step.stepnr %] [% IF step.type == 0 %] - Build of [% INCLUDE renderOutputs outputs=step.buildstepoutputs %] + Build of [% INCLUDE renderOutputs step=step %] [% ELSE %] - Substitution of [% INCLUDE renderOutputs outputs=step.buildstepoutputs %] + Substitution of [% INCLUDE renderOutputs step=step %] [% END %] @@ -382,9 +387,21 @@ END; [% build.drvpath %] - Output store paths: - [% INCLUDE renderOutputs outputs=build.buildoutputs %] + Content addressed: + + [% IF contentAddressed %] + Yes + [% ELSE %] + No + [% END %] + + [% IF !contentAddressed || step.status == 0 %] + + Output store paths: + [% INCLUDE renderOutputs step=step %] + + [% END %] [% chartsURL = c.uri_for('/job' build.project.name build.jobset.name build.job) _ "#tabs-charts" %] [% IF build.finished && build.closuresize %] diff --git a/src/sql/hydra.sql b/src/sql/hydra.sql index e94579720..02159fe8e 100644 --- a/src/sql/hydra.sql +++ b/src/sql/hydra.sql @@ -300,13 +300,14 @@ create table BuildSteps ( create table BuildStepOutputs ( - build integer not null, - stepnr integer not null, - name text not null, - path text, - primary key (build, stepnr, name), - foreign key (build) references Builds(id) on delete cascade, - foreign key (build, stepnr) references BuildSteps(build, stepnr) on delete cascade + build integer not null, + stepnr integer not null, + name text not null, + path text, + contentAddressed boolean not null, + primary key (build, stepnr, name), + foreign key (build) references Builds(id) on delete cascade, + foreign key (build, stepnr) references BuildSteps(build, stepnr) on delete cascade );