Keep track of failed paths in the Hydra database
[?]
Jun 10, 2015, 12:57 PM
RYTQLATYOZ6ODIKYVJ63TC4OIQBXHSCV3NA2YD4NFP7443GQVSRQCDependencies
- [2]
VHV6GI4LAdd a jobset eval action to restart all aborted/cancelled builds - [3]
KSBB33REAdd a dashboard - [4]
6SJQECSCFix broken redirects - [5]
LJILHOJ7Create BuildSteps race-free - [6]
ZWCTAZGLadded newsitems, added some admin options to clear various caches. - [7]
NJJ7H64SVery basic multi-threaded queue runner - [8]
24BMQDZAStart of single-process hydra-queue-runner - [9]
YZAI5GQUImplement a database connection pool - [10]
KBZHIGLGRecord the machine used for a build step - [11]
J5ITV54PMake restartBuilds faster - [12]
FQQRJUO4Mark builds as busy - [13]
5NSQUYBSClear failed builds etc.: Redirect back to the referrer - [14]
ENXUSMSVMake concurrency more robust - [15]
UOINKJ2JAdd an action to cancel all builds in a jobset eval - [16]
5AIYUMTBBasic remote building - [*]
2GK5DOU7* Downloading closures. - [*]
D5QIOJGP* Move everything up one directory. - [*]
N22GPKYT* Put info about logs / build products in the DB.
Change contents
- replacement in src/hydra-queue-runner/hydra-queue-runner.cc at line 783
printMsg(lvlError, format("build thread for ‘%1%’: %2%") % step->drvPath % e.what());printMsg(lvlError, format("error building ‘%1%’: %2%") % step->drvPath % e.what()); - edit in src/hydra-queue-runner/hydra-queue-runner.cc at line 831
/* Create a build step record indicating that we startedbuilding. Also, mark the selected build as busy. */ - edit in src/hydra-queue-runner/hydra-queue-runner.cc at line 832
- edit in src/hydra-queue-runner/hydra-queue-runner.cc at line 834
BuildResult res;int stepNr = 0; - replacement in src/hydra-queue-runner/hydra-queue-runner.cc at line 838
int stepNr;/* If any of the outputs have previously failed, then don'tretry. */bool cachedFailure = false; - replacement in src/hydra-queue-runner/hydra-queue-runner.cc at line 844[6.739]→[6.1015:1112](∅→∅),[6.1112]→[6.456:545](∅→∅),[6.456]→[6.456:545](∅→∅),[6.546]→[6.15674:15696](∅→∅),[6.13380]→[6.15674:15696](∅→∅),[6.15674]→[6.15674:15696](∅→∅)
stepNr = createBuildStep(txn, result.startTime, build, step, machine->sshName, bssBusy);txn.parameterized("update Builds set busy = 1 where id = $1")(build->id).exec();txn.commit();for (auto & path : outputPaths(step->drv))if (!txn.parameterized("select 1 from FailedPaths where path = $1")(path).exec().empty()) {cachedFailure = true;break;} - replacement in src/hydra-queue-runner/hydra-queue-runner.cc at line 851[6.15755]→[6.15755:15765](∅→∅),[6.15765]→[6.13381:13486](∅→∅),[6.13486]→[6.15842:15868](∅→∅),[6.15842]→[6.15842:15868](∅→∅),[6.15868]→[6.13487:13652](∅→∅),[6.13652]→[6.15896:15902](∅→∅),[6.15896]→[6.15896:15902](∅→∅)
try {buildRemote(store, machine->sshName, machine->sshKey, step->drvPath, step->drv, logDir, result);} catch (Error & e) {result.status = RemoteResult::rrMiscFailure;result.errorMsg = e.msg();printMsg(lvlError, format("ERROR: %1%") % e.msg());abort();}if (cachedFailure)result.status = RemoteResult::rrPermanentFailure;else { - replacement in src/hydra-queue-runner/hydra-queue-runner.cc at line 855
if (!result.stopTime) result.stopTime = time(0);/* Create a build step record indicating that we startedbuilding. Also, mark the selected build as busy. */{pqxx::work txn(*conn);stepNr = createBuildStep(txn, result.startTime, build, step, machine->sshName, bssBusy);txn.parameterized("update Builds set busy = 1 where id = $1")(build->id).exec();txn.commit();} - replacement in src/hydra-queue-runner/hydra-queue-runner.cc at line 864
BuildResult res;if (result.status == RemoteResult::rrSuccess) res = getBuildResult(store, step->drv);try {buildRemote(store, machine->sshName, machine->sshKey, step->drvPath, step->drv, logDir, result);} catch (Error & e) {result.status = RemoteResult::rrMiscFailure;result.errorMsg = e.msg();printMsg(lvlError, format("ERROR: %1%") % e.msg());abort();} - replacement in src/hydra-queue-runner/hydra-queue-runner.cc at line 873
// FIXME: handle failed-with-outputif (result.status == RemoteResult::rrSuccess) res = getBuildResult(store, step->drv);// FIXME: handle failed-with-output} - edit in src/hydra-queue-runner/hydra-queue-runner.cc at line 878
if (!result.stopTime) result.stopTime = time(0); - replacement in src/hydra-queue-runner/hydra-queue-runner.cc at line 917[6.16605]→[6.16605:16702](∅→∅),[6.16787]→[6.9048:9093](∅→∅),[6.9093]→[6.16828:16875](∅→∅),[6.16828]→[6.16828:16875](∅→∅),[6.16875]→[6.1367:1493](∅→∅),[6.1493]→[6.16969:16983](∅→∅),[6.14278]→[6.16969:16983](∅→∅),[6.16969]→[6.16969:16983](∅→∅)
/* Create failed build steps for every build that dependson this. */for (auto build2 : dependents) {if (build == build2) continue;createBuildStep(txn, result.stopTime, build2, step, machine->sshName, bssFailed, result.errorMsg, build->id);}/* Failure case. */ - replacement in src/hydra-queue-runner/hydra-queue-runner.cc at line 919
finishBuildStep(txn, result.startTime, result.stopTime, build->id, stepNr, machine->sshName, bssFailed, result.errorMsg);/* For regular failures, we don't care about the errormessage. */if (result.status != RemoteResult::rrMiscFailure) result.errorMsg = "";if (!cachedFailure) {/* Create failed build steps for every build that dependson this. */for (auto build2 : dependents) {if (build == build2) continue;createBuildStep(txn, result.stopTime, build2, step, machine->sshName, bssFailed, result.errorMsg, build->id);} - edit in src/hydra-queue-runner/hydra-queue-runner.cc at line 932
finishBuildStep(txn, result.startTime, result.stopTime, build->id, stepNr, machine->sshName, bssFailed, result.errorMsg);} - replacement in src/hydra-queue-runner/hydra-queue-runner.cc at line 939
("update Builds set finished = 1, busy = 0, isCachedBuild = 0, buildStatus = $2, startTime = $3, stopTime = $4 where id = $1")("update Builds set finished = 1, busy = 0, buildStatus = $2, startTime = $3, stopTime = $4, isCachedBuild = $5 where id = $1") - replacement in src/hydra-queue-runner/hydra-queue-runner.cc at line 943
(result.stopTime).exec();(result.stopTime)(cachedFailure ? 1 : 0).exec(); - edit in src/hydra-queue-runner/hydra-queue-runner.cc at line 947
/* Remember failed paths in the database so that theywon't be built again. */if (!cachedFailure && result.status == RemoteResult::rrPermanentFailure)for (auto & path : outputPaths(step->drv))txn.parameterized("insert into FailedPaths values ($1)")(path).exec(); - replacement in src/lib/Hydra/Controller/Admin.pm at line 48
my $r = `nix-store --clear-failed-paths '*'`;$c->model('DB::FailedPaths')->delete; - replacement in src/lib/Hydra/Helper/Nix.pm at line 468
# Clear Nix's negative failure cache.# Clear the failed paths cache. - replacement in src/lib/Hydra/Helper/Nix.pm at line 470
system("nix-store", "--clear-failed-paths", @paths);# FIXME: clear the dependencies?$db->resultset('FailedPaths')->search({ path => [ @paths ]})->delete; - file addition: FailedPaths.pm[19.477]
use utf8;package Hydra::Schema::FailedPaths;# Created by DBIx::Class::Schema::Loader# DO NOT MODIFY THE FIRST PART OF THIS FILE=head1 NAMEHydra::Schema::FailedPaths=cutuse strict;use warnings;use base 'DBIx::Class::Core';=head1 COMPONENTS LOADED=over 4=item * L<Hydra::Component::ToJSON>=back=cut__PACKAGE__->load_components("+Hydra::Component::ToJSON");=head1 TABLE: C<FailedPaths>=cut__PACKAGE__->table("FailedPaths");=head1 ACCESSORS=head2 pathdata_type: 'text'is_nullable: 0=cut__PACKAGE__->add_columns("path", { data_type => "text", is_nullable => 0 });=head1 PRIMARY KEY=over 4=item * L</path>=back=cut__PACKAGE__->set_primary_key("path");# Created by DBIx::Class::Schema::Loader v0.07033 @ 2015-06-10 14:48:16# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:WFgjfjH+szE6Ntcicmaflw# You can replace this text with custom code or comments, and it will be preserved on regeneration1; - edit in src/sql/hydra.sql at line 511
);-- The output paths that have permanently failed.create table FailedPaths (path text primary key not null - edit in src/sql/hydra.sql at line 518
#ifdef POSTGRESQL-- Needed because Postgres doesn't have "ignore duplicate" or upsert-- yet.create rule IdempotentInsert as on insert to FailedPathswhere exists (select 1 from FailedPaths where path = new.path)do instead nothing;#endif