From 33fce80ada305a5c3489e5716d515106b0fe73b2 Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Wed, 23 Oct 2024 18:45:47 +0200 Subject: Add ci_start::rebuild() function --- mod/ci-common.cxx | 41 +++++++++++++++++++++++++++++++++++++++++ mod/ci-common.hxx | 35 +++++++++++++++++++++++++++++++++++ mod/mod-build-force.cxx | 6 ++++++ 3 files changed, 82 insertions(+) (limited to 'mod') diff --git a/mod/ci-common.cxx b/mod/ci-common.cxx index 5191d46..11d55af 100644 --- a/mod/ci-common.cxx +++ b/mod/ci-common.cxx @@ -14,6 +14,8 @@ #include // operator<<(ostream, process_args) #include +#include +#include #include #include @@ -815,4 +817,43 @@ namespace brep return true; } + + optional ci_start:: + rebuild (odb::core::database& db, const build_id& id) const + { + using namespace odb::core; + + // NOTE: don't forget to update build_force::handle() if changing anything + // here. + // + transaction t (db.begin ()); + + package_build pb; + if (!db.query_one (query::build::id == id, + pb) || + pb.archived) + { + return nullopt; + } + + const shared_ptr& b (pb.build); + build_state s (b->state); + + if (s != build_state::queued) + { + force_state force (s == build_state::built + ? force_state::forced + : force_state::forcing); + + if (b->force != force) + { + b->force = force; + db.update (b); + } + } + + t.commit (); + + return s; + } } diff --git a/mod/ci-common.hxx b/mod/ci-common.hxx index df580e4..d155398 100644 --- a/mod/ci-common.hxx +++ b/mod/ci-common.hxx @@ -9,6 +9,7 @@ #include #include +#include #include #include @@ -170,6 +171,40 @@ namespace brep odb::core::database&, const string& tenant_id) const; + // Schedule the re-build of the package build and return the build object + // current state. + // + // Specifically: + // + // - If the build has expired (build or package object doesn't exist or + // the package is archived or is not buildable anymore, etc), then do + // nothing and return nullopt. + // + // Note, however, that this function doesn't check if the build + // configuration still exists in the buildtab. It is supposed that the + // caller has already checked for that if necessary (see + // build_force::handle() for an example of this check). And if not + // then a re-build will be scheduled and later cleaned by the cleaner + // (without notifications). + // + // - Otherwise, if the build object is in the queued state, then do + // nothing and return build_state::queued. It is assumed that a build + // object in such a state is already about to be built. + // + // - Otherwise (the build object is in the building or built state), + // schedule the object for the rebuild and return the current state. + // + // Note that in contrast to the build-force handler, this function doesn't + // send the build_queued() notification to the tenant-associated service + // if the object is in the building state (which is done as soon as + // possible to avoid races). Instead, it is assumed the service will + // perform any equivalent actions directly based on the returned state. + // + // Note: should be called out of the database transaction. + // + optional + rebuild (odb::core::database&, const build_id&) const; + // Helpers. // diff --git a/mod/mod-build-force.cxx b/mod/mod-build-force.cxx index ea921e9..8666889 100644 --- a/mod/mod-build-force.cxx +++ b/mod/mod-build-force.cxx @@ -198,6 +198,9 @@ handle (request& rq, response& rs) // connection_ptr conn (build_db_->connection ()); + // NOTE: don't forget to update ci_start::rebuild() if changing anything + // here. + // { transaction t (conn->begin ()); @@ -206,8 +209,11 @@ handle (request& rq, response& rs) if (!build_db_->query_one ( query::build::id == id, pb) || + pb.archived || (b = move (pb.build))->state == build_state::queued) + { config_expired ("no package build"); + } force_state force (b->state == build_state::built ? force_state::forced -- cgit v1.1