aboutsummaryrefslogtreecommitdiff
path: root/mod/mod-build-result.cxx
diff options
context:
space:
mode:
authorKaren Arutyunov <karen@codesynthesis.com>2023-04-13 19:36:23 +0300
committerKaren Arutyunov <karen@codesynthesis.com>2023-04-14 12:27:01 +0300
commit531943d795a2a01e7293af6fd724e626b91156c9 (patch)
tree47cec76fa7babc0761f4e2b5155f0203326507f8 /mod/mod-build-result.cxx
parent43a47ce352dc43662dc5a59123ce4823e9ba7189 (diff)
Add support for interrupt build result status
Diffstat (limited to 'mod/mod-build-result.cxx')
-rw-r--r--mod/mod-build-result.cxx238
1 files changed, 138 insertions, 100 deletions
diff --git a/mod/mod-build-result.cxx b/mod/mod-build-result.cxx
index 6f40a0b..99bdc8d 100644
--- a/mod/mod-build-result.cxx
+++ b/mod/mod-build-result.cxx
@@ -435,126 +435,164 @@ handle (request& rq, response&)
if (auth)
{
- // Verify the result status/checksums.
+ // If the build is interrupted, then revert it to the original built
+ // state if this is a rebuild and delete it from the database
+ // otherwise.
//
- // Specifically, if the result status is skip, then it can only be in
- // response to the soft rebuild task (all checksums are present in the
- // build object) and the result checksums must match the build object
- // checksums. On verification failure respond with the bad request
- // HTTP code (400).
- //
- if (rqm.result.status == result_status::skip)
+ if (rqm.result.status == result_status::interrupt)
{
- if (!b->agent_checksum ||
- !b->worker_checksum ||
- !b->dependency_checksum)
- throw invalid_request (400, "unexpected skip result status");
-
- // Can only be absent for initial build, in which case the checksums
- // are also absent and we would end up with the above 400 response.
- //
- assert (b->status);
-
- // Verify that the result checksum matches the build checksum and
- // throw invalid_request(400) if that's not the case.
- //
- auto verify = [] (const string& build_checksum,
- const optional<string>& result_checksum,
- const char* what)
+ if (b->status) // Is this a rebuild?
{
- if (!result_checksum)
- throw invalid_request (
- 400,
- string (what) +
- " checksum is expected for skip result status");
-
- if (*result_checksum != build_checksum)
- throw invalid_request (
- 400,
- string (what) + " checksum '" + build_checksum +
- "' is expected instead of '" + *result_checksum +
- "' for skip result status");
- };
-
- verify (*b->agent_checksum, rqm.agent_checksum, "agent");
-
- verify (*b->worker_checksum,
- rqm.result.worker_checksum,
- "worker");
-
- verify (*b->dependency_checksum,
- rqm.result.dependency_checksum,
- "dependency");
- }
+ b->state = build_state::built;
- unforced = b->force == force_state::unforced;
+ // Keep the force rebuild indication. Note that the forcing state
+ // is only valid for the building state.
+ //
+ if (b->force == force_state::forcing)
+ b->force = force_state::forced;
- // Don't send email to the build-email address for the
- // success-to-success status change, unless the build was forced.
- //
- build_notify = !(rqm.result.status == result_status::success &&
- b->status &&
- *b->status == rqm.result.status &&
- unforced);
+ // Cleanup the interactive build login information.
+ //
+ b->interactive = nullopt;
- b->state = build_state::built;
- b->force = force_state::unforced;
+ // Cleanup the authentication data.
+ //
+ b->agent_fingerprint = nullopt;
+ b->agent_challenge = nullopt;
- // Cleanup the interactive build login information.
- //
- b->interactive = nullopt;
+ // Note that we are unable to restore the pre-rebuild timestamp
+ // since it has been overwritten when the build task was issued.
+ // That, however, feels ok and we just keep it unchanged.
- // Cleanup the authentication data.
- //
- b->agent_fingerprint = nullopt;
- b->agent_challenge = nullopt;
+ build_db_->update (b);
+ }
+ else
+ build_db_->erase (b);
+ }
+ else
+ {
+ // Verify the result status/checksums.
+ //
+ // Specifically, if the result status is skip, then it can only be
+ // in response to the soft rebuild task (all checksums are present
+ // in the build object) and the result checksums must match the
+ // build object checksums. On verification failure respond with the
+ // bad request HTTP code (400).
+ //
+ if (rqm.result.status == result_status::skip)
+ {
+ if (!b->agent_checksum ||
+ !b->worker_checksum ||
+ !b->dependency_checksum)
+ throw invalid_request (400, "unexpected skip result status");
+
+ // Can only be absent for initial build, in which case the
+ // checksums are also absent and we would end up with the above
+ // 400 response.
+ //
+ assert (b->status);
+
+ // Verify that the result checksum matches the build checksum and
+ // throw invalid_request(400) if that's not the case.
+ //
+ auto verify = [] (const string& build_checksum,
+ const optional<string>& result_checksum,
+ const char* what)
+ {
+ if (!result_checksum)
+ throw invalid_request (
+ 400,
+ string (what) +
+ " checksum is expected for skip result status");
+
+ if (*result_checksum != build_checksum)
+ throw invalid_request (
+ 400,
+ string (what) + " checksum '" + build_checksum +
+ "' is expected instead of '" + *result_checksum +
+ "' for skip result status");
+ };
+
+ verify (*b->agent_checksum, rqm.agent_checksum, "agent");
+
+ verify (*b->worker_checksum,
+ rqm.result.worker_checksum,
+ "worker");
+
+ verify (*b->dependency_checksum,
+ rqm.result.dependency_checksum,
+ "dependency");
+ }
- b->timestamp = system_clock::now ();
- b->soft_timestamp = b->timestamp;
+ unforced = b->force == force_state::unforced;
- // If the result status is other than skip, then save the status,
- // results, and checksums and update the hard timestamp.
- //
- if (rqm.result.status != result_status::skip)
- {
- b->status = rqm.result.status;
- b->hard_timestamp = b->soft_timestamp;
+ // Don't send email to the build-email address for the
+ // success-to-success status change, unless the build was forced.
+ //
+ build_notify = !(rqm.result.status == result_status::success &&
+ b->status &&
+ *b->status == rqm.result.status &&
+ unforced);
+
+ b->state = build_state::built;
+ b->force = force_state::unforced;
- // Mark the section as loaded, so results are updated.
+ // Cleanup the interactive build login information.
//
- b->results_section.load ();
- b->results = move (rqm.result.results);
+ b->interactive = nullopt;
- // Save the checksums.
+ // Cleanup the authentication data.
//
- b->agent_checksum = move (rqm.agent_checksum);
- b->worker_checksum = move (rqm.result.worker_checksum);
- b->dependency_checksum = move (rqm.result.dependency_checksum);
- }
+ b->agent_fingerprint = nullopt;
+ b->agent_challenge = nullopt;
- build_db_->update (b);
+ b->timestamp = system_clock::now ();
+ b->soft_timestamp = b->timestamp;
- // Don't send the build notification email if the task result is
- // `skip`, the configuration is hidden, or is now excluded by the
- // package.
- //
- if (rqm.result.status != result_status::skip && belongs (*tc, "all"))
- {
- shared_ptr<build_package> p (
- build_db_->load<build_package> (b->id.package));
+ // If the result status is other than skip, then save the status,
+ // results, and checksums and update the hard timestamp.
+ //
+ if (rqm.result.status != result_status::skip)
+ {
+ b->status = rqm.result.status;
+ b->hard_timestamp = b->soft_timestamp;
+
+ // Mark the section as loaded, so results are updated.
+ //
+ b->results_section.load ();
+ b->results = move (rqm.result.results);
+
+ // Save the checksums.
+ //
+ b->agent_checksum = move (rqm.agent_checksum);
+ b->worker_checksum = move (rqm.result.worker_checksum);
+ b->dependency_checksum = move (rqm.result.dependency_checksum);
+ }
- // The package configuration should be present (see mod-builds.cxx
- // for details) but if it is not, let's log the warning.
+ build_db_->update (b);
+
+ // Don't send the build notification email if the task result is
+ // `skip`, the configuration is hidden, or is now excluded by the
+ // package.
//
- if (const build_package_config* pc = find (b->package_config_name,
- p->configs))
+ if (rqm.result.status != result_status::skip && belongs (*tc, "all"))
{
- if (!exclude (*pc, p->builds, p->constraints, *tc))
- bld = move (b);
+ shared_ptr<build_package> p (
+ build_db_->load<build_package> (b->id.package));
+
+ // The package configuration should be present (see mod-builds.cxx
+ // for details) but if it is not, let's log the warning.
+ //
+ if (const build_package_config* pc = find (b->package_config_name,
+ p->configs))
+ {
+ if (!exclude (*pc, p->builds, p->constraints, *tc))
+ bld = move (b);
+ }
+ else
+ warn << "cannot find configuration '" << b->package_config_name
+ << "' for package " << p->id.name << '/' << p->version;
}
- else
- warn << "cannot find configuration '" << b->package_config_name
- << "' for package " << p->id.name << '/' << p->version;
}
}
}