aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mod/ci-common.cxx41
-rw-r--r--mod/ci-common.hxx35
-rw-r--r--mod/mod-build-force.cxx6
3 files changed, 82 insertions, 0 deletions
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 <libbutl/process-io.hxx> // operator<<(ostream, process_args)
#include <libbutl/manifest-serializer.hxx>
+#include <libbrep/build.hxx>
+#include <libbrep/build-odb.hxx>
#include <libbrep/build-package.hxx>
#include <libbrep/build-package-odb.hxx>
@@ -815,4 +817,43 @@ namespace brep
return true;
}
+
+ optional<build_state> 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<package_build> (query<package_build>::build::id == id,
+ pb) ||
+ pb.archived)
+ {
+ return nullopt;
+ }
+
+ const shared_ptr<build>& 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 <libbrep/types.hxx>
#include <libbrep/utility.hxx>
+#include <libbrep/build.hxx>
#include <libbrep/common.hxx>
#include <mod/diagnostics.hxx>
@@ -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<build_state>
+ 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<package_build> (
query<package_build>::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