forked from lix-project/hydra
Fail builds with previously failed steps early
This commit is contained in:
parent
c00bf7cd1a
commit
21aaa0596b
|
@ -248,6 +248,8 @@ public:
|
||||||
void markSucceededBuild(pqxx::work & txn, Build::ptr build,
|
void markSucceededBuild(pqxx::work & txn, Build::ptr build,
|
||||||
const BuildResult & res, bool isCachedBuild, time_t startTime, time_t stopTime);
|
const BuildResult & res, bool isCachedBuild, time_t startTime, time_t stopTime);
|
||||||
|
|
||||||
|
bool checkCachedFailure(Step::ptr step, Connection & conn);
|
||||||
|
|
||||||
void run();
|
void run();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -492,33 +494,50 @@ void State::getQueuedBuilds(Connection & conn, std::shared_ptr<StoreAPI> store,
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If any step has an unsupported system type, then fail the
|
/* If any step has an unsupported system type or has a
|
||||||
build. */
|
previously failed output path, then fail the build right
|
||||||
bool allSupported = true;
|
away. */
|
||||||
|
bool badStep = false;
|
||||||
for (auto & r : newSteps) {
|
for (auto & r : newSteps) {
|
||||||
|
BuildStatus buildStatus = bsSuccess;
|
||||||
|
BuildStepStatus buildStepStatus;
|
||||||
|
|
||||||
bool supported = false;
|
bool supported = false;
|
||||||
{
|
{
|
||||||
auto machines_(machines.lock()); // FIXME: use shared_mutex
|
auto machines_(machines.lock()); // FIXME: use shared_mutex
|
||||||
for (auto & m : *machines_)
|
for (auto & m : *machines_)
|
||||||
if (m->supportsStep(r)) { supported = true; break; }
|
if (m->supportsStep(r)) { supported = true; break; }
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!supported) {
|
if (!supported) {
|
||||||
allSupported = false;
|
|
||||||
printMsg(lvlError, format("aborting unsupported build %1%") % build->id);
|
printMsg(lvlError, format("aborting unsupported build %1%") % build->id);
|
||||||
pqxx::work txn(conn);
|
buildStatus = bsUnsupported;
|
||||||
|
buildStepStatus = bssUnsupported;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (checkCachedFailure(r, conn)) {
|
||||||
|
printMsg(lvlError, format("failing build %1% due to previous failure") % build->id);
|
||||||
|
buildStatus = step == r ? bsFailed : bsFailed;
|
||||||
|
buildStepStatus = bssFailed;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (buildStatus != bsSuccess) {
|
||||||
time_t now = time(0);
|
time_t now = time(0);
|
||||||
|
pqxx::work txn(conn);
|
||||||
txn.parameterized
|
txn.parameterized
|
||||||
("update Builds set finished = 1, busy = 0, buildStatus = $2, startTime = $3, stopTime = $3 where id = $1")
|
("update Builds set finished = 1, busy = 0, buildStatus = $2, startTime = $3, stopTime = $3, isCachedBuild = $4 where id = $1")
|
||||||
(build->id)
|
(build->id)
|
||||||
((int) bsUnsupported)
|
((int) buildStatus)
|
||||||
(now).exec();
|
(now)
|
||||||
createBuildStep(txn, now, build, r, "", bssUnsupported);
|
(buildStatus != bsUnsupported ? 1 : 0).exec();
|
||||||
|
createBuildStep(txn, now, build, r, "", buildStepStatus);
|
||||||
txn.commit();
|
txn.commit();
|
||||||
|
badStep = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!allSupported) continue;
|
if (badStep) continue;
|
||||||
|
|
||||||
/* Note: if we exit this scope prior to this, the build and
|
/* Note: if we exit this scope prior to this, the build and
|
||||||
all newly created steps are destroyed. */
|
all newly created steps are destroyed. */
|
||||||
|
@ -881,15 +900,7 @@ void State::doBuildStep(std::shared_ptr<StoreAPI> store, Step::ptr step,
|
||||||
|
|
||||||
/* If any of the outputs have previously failed, then don't
|
/* If any of the outputs have previously failed, then don't
|
||||||
retry. */
|
retry. */
|
||||||
bool cachedFailure = false;
|
bool cachedFailure = checkCachedFailure(step, *conn);
|
||||||
{
|
|
||||||
pqxx::work txn(*conn);
|
|
||||||
for (auto & path : outputPaths(step->drv))
|
|
||||||
if (!txn.parameterized("select 1 from FailedPaths where path = $1")(path).exec().empty()) {
|
|
||||||
cachedFailure = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cachedFailure)
|
if (cachedFailure)
|
||||||
result.status = RemoteResult::rrPermanentFailure;
|
result.status = RemoteResult::rrPermanentFailure;
|
||||||
|
@ -1051,6 +1062,16 @@ void State::markSucceededBuild(pqxx::work & txn, Build::ptr build,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool State::checkCachedFailure(Step::ptr step, Connection & conn)
|
||||||
|
{
|
||||||
|
pqxx::work txn(conn);
|
||||||
|
for (auto & path : outputPaths(step->drv))
|
||||||
|
if (!txn.parameterized("select 1 from FailedPaths where path = $1")(path).exec().empty())
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void State::run()
|
void State::run()
|
||||||
{
|
{
|
||||||
clearBusy(0);
|
clearBusy(0);
|
||||||
|
|
Loading…
Reference in a new issue