aboutsummaryrefslogtreecommitdiff
path: root/libbrep
diff options
context:
space:
mode:
authorKaren Arutyunov <karen@codesynthesis.com>2024-04-15 21:36:02 +0300
committerKaren Arutyunov <karen@codesynthesis.com>2024-04-22 14:31:24 +0300
commit7c61322166eb0eab77ee5fb10031bae616ecb192 (patch)
treeb9b86de7b896a6264547acdb8b94eebb26320b33 /libbrep
parent42e0e515a36d72197c74813d0d21682d9120d625 (diff)
Add support for custom build bots
Diffstat (limited to 'libbrep')
-rw-r--r--libbrep/build-extra.sql45
-rw-r--r--libbrep/build-package.hxx110
-rw-r--r--libbrep/build.hxx2
-rw-r--r--libbrep/build.xml2
-rw-r--r--libbrep/common.cxx10
-rw-r--r--libbrep/common.hxx191
-rwxr-xr-xlibbrep/odb.sh4
-rw-r--r--libbrep/package.cxx31
-rw-r--r--libbrep/package.hxx126
-rw-r--r--libbrep/package.xml135
10 files changed, 558 insertions, 98 deletions
diff --git a/libbrep/build-extra.sql b/libbrep/build-extra.sql
index a931f31..9e51a51 100644
--- a/libbrep/build-extra.sql
+++ b/libbrep/build-extra.sql
@@ -6,6 +6,8 @@
-- package-extra.sql file for details.
--
+DROP FOREIGN TABLE IF EXISTS build_package_config_bot_keys;
+
DROP FOREIGN TABLE IF EXISTS build_package_config_auxiliaries;
DROP FOREIGN TABLE IF EXISTS build_package_config_constraints;
@@ -14,6 +16,8 @@ DROP FOREIGN TABLE IF EXISTS build_package_config_builds;
DROP FOREIGN TABLE IF EXISTS build_package_configs;
+DROP FOREIGN TABLE IF EXISTS build_package_bot_keys;
+
DROP FOREIGN TABLE IF EXISTS build_package_auxiliaries;
DROP FOREIGN TABLE IF EXISTS build_package_constraints;
@@ -30,6 +34,8 @@ DROP FOREIGN TABLE IF EXISTS build_package_requirements;
DROP FOREIGN TABLE IF EXISTS build_package;
+DROP FOREIGN TABLE IF EXISTS build_public_key;
+
DROP FOREIGN TABLE IF EXISTS build_repository;
DROP FOREIGN TABLE IF EXISTS build_tenant;
@@ -64,6 +70,14 @@ CREATE FOREIGN TABLE build_repository (
certificate_fingerprint TEXT NULL)
SERVER package_server OPTIONS (table_name 'repository');
+-- The foreign table for build_public_key object.
+--
+CREATE FOREIGN TABLE build_public_key (
+ tenant TEXT NOT NULL,
+ fingerprint TEXT NOT NULL,
+ "data" TEXT NOT NULL)
+SERVER package_server OPTIONS (table_name 'public_key');
+
-- The foreign table for build_package object.
--
CREATE FOREIGN TABLE build_package (
@@ -84,7 +98,8 @@ CREATE FOREIGN TABLE build_package (
build_error_email_comment TEXT NULL,
internal_repository_tenant TEXT NULL,
internal_repository_canonical_name TEXT NULL,
- buildable BOOLEAN NOT NULL)
+ buildable BOOLEAN NOT NULL,
+ custom_bot BOOLEAN NULL)
SERVER package_server OPTIONS (table_name 'package');
-- The foreign tables for the build_package object requirements member (that
@@ -214,6 +229,21 @@ CREATE FOREIGN TABLE build_package_auxiliaries (
comment TEXT NOT NULL)
SERVER package_server OPTIONS (table_name 'package_build_auxiliaries');
+-- The foreign table for the build_package object bot_keys member (that is
+-- of a container type).
+--
+CREATE FOREIGN TABLE build_package_bot_keys (
+ tenant TEXT NOT NULL,
+ name CITEXT NOT NULL,
+ version_epoch INTEGER NOT NULL,
+ version_canonical_upstream TEXT NOT NULL,
+ version_canonical_release TEXT NOT NULL COLLATE "C",
+ version_revision INTEGER NOT NULL,
+ index BIGINT NOT NULL,
+ key_tenant TEXT NOT NULL,
+ key_fingerprint TEXT NOT NULL)
+SERVER package_server OPTIONS (table_name 'package_build_bot_keys');
+
-- The foreign tables for the build_package object configs member (that is a
-- container of values containing containers.
--
@@ -277,3 +307,16 @@ CREATE FOREIGN TABLE build_package_config_auxiliaries (
config TEXT NOT NULL,
comment TEXT NOT NULL)
SERVER package_server OPTIONS (table_name 'package_build_config_auxiliaries');
+
+CREATE FOREIGN TABLE build_package_config_bot_keys (
+ tenant TEXT NOT NULL,
+ name CITEXT NOT NULL,
+ version_epoch INTEGER NOT NULL,
+ version_canonical_upstream TEXT NOT NULL,
+ version_canonical_release TEXT NOT NULL COLLATE "C",
+ version_revision INTEGER NOT NULL,
+ config_index BIGINT NOT NULL,
+ index BIGINT NOT NULL,
+ key_tenant TEXT NOT NULL,
+ key_fingerprint TEXT NOT NULL)
+SERVER package_server OPTIONS (table_name 'package_build_config_bot_keys');
diff --git a/libbrep/build-package.hxx b/libbrep/build-package.hxx
index 08fb781..b7bea87 100644
--- a/libbrep/build-package.hxx
+++ b/libbrep/build-package.hxx
@@ -23,9 +23,11 @@ namespace brep
//
// The mapping is established in build-extra.sql. We also explicitly mark
// non-primary key foreign-mapped members in the source object.
- //
+
// Foreign object that is mapped to a subset of the tenant object.
//
+ // Note: table created manually thus assign table name explicitly.
+ //
#pragma db object table("build_tenant") pointer(shared_ptr)
class build_tenant
{
@@ -50,6 +52,8 @@ namespace brep
// Foreign object that is mapped to a subset of the repository object.
//
+ // Note: table created manually thus assign table name explicitly.
+ //
#pragma db object table("build_repository") pointer(shared_ptr) readonly
class build_repository
{
@@ -75,6 +79,54 @@ namespace brep
build_repository (): canonical_name (id.canonical_name) {}
};
+ // Foreign object that is mapped to a subset of the public key object.
+ //
+ // Note: table created manually thus assign table name explicitly.
+ //
+ #pragma db object table("build_public_key") pointer(shared_ptr) readonly
+ class build_public_key: public string
+ {
+ public:
+ public_key_id id;
+
+ // Database mapping.
+ //
+ #pragma db member(id) id column("")
+
+ #pragma db member(data) virtual(string) access(this)
+
+ private:
+ friend class odb::access;
+ build_public_key () = default;
+ };
+
+ // build_package_config
+ //
+ using build_package_config =
+ build_package_config_template<lazy_shared_ptr<build_public_key>>;
+
+ using build_package_configs =
+ build_package_configs_template<lazy_shared_ptr<build_public_key>>;
+
+ #pragma db value(build_package_config) definition
+
+ #pragma db member(build_package_config::builds) transient
+ #pragma db member(build_package_config::constraints) transient
+ #pragma db member(build_package_config::auxiliaries) transient
+ #pragma db member(build_package_config::bot_keys) transient
+
+ // build_package_bot_keys
+ //
+ using build_package_bot_keys = vector<lazy_shared_ptr<build_public_key>>;
+ using build_package_bot_key_key = odb::nested_key<build_package_bot_keys>;
+
+ using build_package_bot_keys_map =
+ std::map<build_package_bot_key_key, lazy_shared_ptr<build_public_key>>;
+
+ #pragma db value(build_package_bot_key_key)
+ #pragma db member(build_package_bot_key_key::outer) column("config_index")
+ #pragma db member(build_package_bot_key_key::inner) column("index")
+
// Forward declarations.
//
class build_package;
@@ -107,6 +159,8 @@ namespace brep
// Foreign object that is mapped to a subset of the package object.
//
+ // Note: table created manually thus assign table name explicitly.
+ //
#pragma db object table("build_package") pointer(shared_ptr) readonly session
class build_package
{
@@ -132,21 +186,26 @@ namespace brep
lazy_shared_ptr<build_repository> internal_repository;
bool buildable;
+ optional<bool> custom_bot;
// Mapped to the package object builds, build_constraints,
- // build_auxiliaries, and build_configs members using the PostgreSQL
- // foreign table mechanism.
+ // build_auxiliaries, bot_keys, and build_configs members using the
+ // PostgreSQL foreign table mechanism.
//
- build_class_exprs builds;
- build_constraints constraints;
- build_auxiliaries auxiliaries;
- build_package_configs configs;
-
- // Group the builds and constraints members of this object as well as of
- // the nested configs entries for an explicit load. Note that the configs
- // top-level members are loaded implicitly.
+ build_class_exprs builds;
+ build_constraints constraints;
+ build_auxiliaries auxiliaries;
+ build_package_bot_keys bot_keys;
+ build_package_configs configs;
+
+ // Group the builds/constraints, auxiliaries, and bot_keys members of this
+ // object together with their respective nested configs entries into the
+ // separate sections for an explicit load. Note that the configs top-level
+ // members are loaded implicitly.
//
odb::section constraints_section;
+ odb::section auxiliaries_section;
+ odb::section bot_keys_section;
bool
internal () const noexcept {return internal_repository != nullptr;}
@@ -194,7 +253,7 @@ namespace brep
#pragma db member(requirements_tests_section) load(lazy) update(always)
- // builds, constraints, and auxiliaries
+ // builds, constraints, auxiliaries, and bot_keys
//
#pragma db member(builds) id_column("") value_column("") \
section(constraints_section)
@@ -203,13 +262,16 @@ namespace brep
section(constraints_section)
#pragma db member(auxiliaries) id_column("") value_column("") \
- section(constraints_section)
+ section(auxiliaries_section)
+
+ #pragma db member(bot_keys) id_column("") value_column("key_") \
+ section(bot_keys_section)
// configs
//
- // Note that build_package_config::{builds,constraints,auxiliaries} are
- // persisted/loaded via the separate nested containers (see commons.hxx
- // for details).
+ // Note that build_package_config::{builds,constraints,auxiliaries,bot_keys}
+ // are persisted/loaded via the separate nested containers (see
+ // commons.hxx for details).
//
#pragma db member(configs) id_column("") value_column("config_")
@@ -244,9 +306,23 @@ namespace brep
odb::nested_set (as, std::move (?)); \
move (as).to_configs (this.configs)) \
id_column("") key_column("") value_column("") \
- section(constraints_section)
+ section(auxiliaries_section)
+
+ #pragma db member(config_bot_keys) \
+ virtual(build_package_bot_keys_map) \
+ after(config_auxiliaries) \
+ get(odb::nested_get ( \
+ brep::build_package_config_bot_keys (this.configs))) \
+ set(brep::build_package_config_bot_keys< \
+ lazy_shared_ptr<brep::build_public_key>> bks; \
+ odb::nested_set (bks, std::move (?)); \
+ move (bks).to_configs (this.configs)) \
+ id_column("") key_column("") value_column("key_") \
+ section(bot_keys_section)
#pragma db member(constraints_section) load(lazy) update(always)
+ #pragma db member(auxiliaries_section) load(lazy) update(always)
+ #pragma db member(bot_keys_section) load(lazy) update(always)
private:
friend class odb::access;
diff --git a/libbrep/build.hxx b/libbrep/build.hxx
index 4c470cd..af49c03 100644
--- a/libbrep/build.hxx
+++ b/libbrep/build.hxx
@@ -28,7 +28,7 @@
//
#define LIBBREP_BUILD_SCHEMA_VERSION_BASE 20
-#pragma db model version(LIBBREP_BUILD_SCHEMA_VERSION_BASE, 26, closed)
+#pragma db model version(LIBBREP_BUILD_SCHEMA_VERSION_BASE, 27, closed)
// We have to keep these mappings at the global scope instead of inside the
// brep namespace because they need to be also effective in the bbot namespace
diff --git a/libbrep/build.xml b/libbrep/build.xml
index 815c915..1eba85a 100644
--- a/libbrep/build.xml
+++ b/libbrep/build.xml
@@ -1,4 +1,6 @@
<changelog xmlns="http://www.codesynthesis.com/xmlns/odb/changelog" database="pgsql" schema-name="build" version="1">
+ <changeset version="27"/>
+
<changeset version="26"/>
<changeset version="25">
diff --git a/libbrep/common.cxx b/libbrep/common.cxx
index c97a346..4f729a3 100644
--- a/libbrep/common.cxx
+++ b/libbrep/common.cxx
@@ -32,14 +32,4 @@ namespace brep
else if (r == "unbuildable") return unbuildable_reason::unbuildable;
else throw invalid_argument ("invalid unbuildable reason '" + r + '\'');
}
-
- build_package_config*
- find (const string& name, build_package_configs& cs)
- {
- auto i (find_if (cs.begin (), cs.end (),
- [&name] (const build_package_config& c)
- {return c.name == name;}));
-
- return i != cs.end () ? &*i : nullptr;
- }
}
diff --git a/libbrep/common.hxx b/libbrep/common.hxx
index ea18fd4..1433c8c 100644
--- a/libbrep/common.hxx
+++ b/libbrep/common.hxx
@@ -326,6 +326,19 @@ namespace brep
: tenant (move (t)), canonical_name (move (n)) {}
};
+ // public_key_id
+ //
+ #pragma db value
+ struct public_key_id
+ {
+ string tenant;
+ string fingerprint;
+
+ public_key_id () = default;
+ public_key_id (string t, string f)
+ : tenant (move (t)), fingerprint (move (f)) {}
+ };
+
// build_class_expr
//
using bpkg::build_class_expr;
@@ -370,31 +383,38 @@ namespace brep
#pragma db value(email) definition
#pragma db member(email::value) virtual(string) before access(this) column("")
- // build_package_config
+ // build_package_config_template
//
- using build_package_config = bpkg::build_package_config;
-
- #pragma db value(build_package_config) definition
+ using bpkg::build_package_config_template;
// 1 for the default configuration which is always present.
//
- using build_package_configs = small_vector<build_package_config, 1>;
+ template <typename K>
+ using build_package_configs_template =
+ small_vector<build_package_config_template<K>, 1>;
// Return the address of the configuration object with the specified name,
// if present, and NULL otherwise.
//
- build_package_config*
- find (const string& name, build_package_configs&);
+ template <typename K>
+ inline build_package_config_template<K>*
+ find (const string& name, build_package_configs_template<K>& cs)
+ {
+ auto i (find_if (cs.begin (), cs.end (),
+ [&name] (const build_package_config_template<K>& c)
+ {return c.name == name;}));
+
+ return i != cs.end () ? &*i : nullptr;
+ }
// Note that ODB doesn't support containers of value types which contain
// containers. Thus, we will persist/load
- // package_build_config::{builds,constraint,auxiliaries} via the separate
- // nested containers using the adapter classes.
- //
- // build_package_config::builds
+ // build_package_config_template<K>::{builds,constraint,auxiliaries,bot_keys}
+ // via the separate nested containers using the adapter classes.
//
- #pragma db member(build_package_config::builds) transient
+ // build_package_config_template<K>::builds
+ //
using build_class_expr_key = odb::nested_key<build_class_exprs>;
using build_class_exprs_map = std::map<build_class_expr_key, build_class_expr>;
@@ -402,24 +422,27 @@ namespace brep
#pragma db member(build_class_expr_key::outer) column("config_index")
#pragma db member(build_class_expr_key::inner) column("index")
- // Adapter for build_package_config::builds.
+ // Adapter for build_package_config_template<K>::builds.
+ //
+ // Note: 1 as for build_package_configs_template.
//
- class build_package_config_builds:
- public small_vector<build_class_exprs, 1> // 1 as for build_package_configs.
+ class build_package_config_builds: public small_vector<build_class_exprs, 1>
{
public:
build_package_config_builds () = default;
+ template <typename K>
explicit
- build_package_config_builds (const build_package_configs& cs)
+ build_package_config_builds (const build_package_configs_template<K>& cs)
{
reserve (cs.size ());
- for (const build_package_config& c: cs)
+ for (const build_package_config_template<K>& c: cs)
push_back (c.builds);
}
+ template <typename K>
void
- to_configs (build_package_configs& cs) &&
+ to_configs (build_package_configs_template<K>& cs) &&
{
// Note that the empty trailing entries will be missing (see ODB's
// nested-container.hxx for details).
@@ -432,10 +455,8 @@ namespace brep
}
};
- // build_package_config::constraints
+ // build_package_config_template<K>::constraints
//
- #pragma db member(build_package_config::constraints) transient
-
using build_constraint_key = odb::nested_key<build_constraints>;
using build_constraints_map = std::map<build_constraint_key, build_constraint>;
@@ -443,24 +464,29 @@ namespace brep
#pragma db member(build_constraint_key::outer) column("config_index")
#pragma db member(build_constraint_key::inner) column("index")
- // Adapter for build_package_config::constraints.
+ // Adapter for build_package_config_template<K>::constraints.
+ //
+ // Note: 1 as for build_package_configs_template.
//
class build_package_config_constraints:
- public small_vector<build_constraints, 1> // 1 as for build_package_configs.
+ public small_vector<build_constraints, 1>
{
public:
build_package_config_constraints () = default;
+ template <typename K>
explicit
- build_package_config_constraints (const build_package_configs& cs)
+ build_package_config_constraints (
+ const build_package_configs_template<K>& cs)
{
reserve (cs.size ());
- for (const build_package_config& c: cs)
+ for (const build_package_config_template<K>& c: cs)
push_back (c.constraints);
}
+ template <typename K>
void
- to_configs (build_package_configs& cs) &&
+ to_configs (build_package_configs_template<K>& cs) &&
{
// Note that the empty trailing entries will be missing (see ODB's
// nested-container.hxx for details).
@@ -473,10 +499,8 @@ namespace brep
}
};
- // build_package_config::auxiliaries
+ // build_package_config_template<K>::auxiliaries
//
- #pragma db member(build_package_config::auxiliaries) transient
-
using build_auxiliary_key = odb::nested_key<build_auxiliaries>;
using build_auxiliaries_map = std::map<build_auxiliary_key, build_auxiliary>;
@@ -484,24 +508,29 @@ namespace brep
#pragma db member(build_auxiliary_key::outer) column("config_index")
#pragma db member(build_auxiliary_key::inner) column("index")
- // Adapter for build_package_config::auxiliaries.
+ // Adapter for build_package_config_template<K>::auxiliaries.
+ //
+ // Note: 1 as for build_package_configs_template.
//
class build_package_config_auxiliaries:
- public small_vector<build_auxiliaries, 1> // 1 as for build_package_configs.
+ public small_vector<build_auxiliaries, 1>
{
public:
build_package_config_auxiliaries () = default;
+ template <typename K>
explicit
- build_package_config_auxiliaries (const build_package_configs& cs)
+ build_package_config_auxiliaries (
+ const build_package_configs_template<K>& cs)
{
reserve (cs.size ());
- for (const build_package_config& c: cs)
+ for (const build_package_config_template<K>& c: cs)
push_back (c.auxiliaries);
}
+ template <typename K>
void
- to_configs (build_package_configs& cs) &&
+ to_configs (build_package_configs_template<K>& cs) &&
{
// Note that the empty trailing entries will be missing (see ODB's
// nested-container.hxx for details).
@@ -514,6 +543,40 @@ namespace brep
}
};
+ // build_package_config_template<K>::bot_keys
+ //
+ // Adapter for build_package_config_template<K>::bot_keys.
+ //
+ // Note: 1 as for build_package_configs_template.
+ //
+ template <typename K>
+ class build_package_config_bot_keys: public small_vector<vector<K>, 1>
+ {
+ public:
+ build_package_config_bot_keys () = default;
+
+ explicit
+ build_package_config_bot_keys (const build_package_configs_template<K>& cs)
+ {
+ this->reserve (cs.size ());
+ for (const build_package_config_template<K>& c: cs)
+ this->push_back (c.bot_keys);
+ }
+
+ void
+ to_configs (build_package_configs_template<K>& cs) &&
+ {
+ // Note that the empty trailing entries will be missing (see ODB's
+ // nested-container.hxx for details).
+ //
+ assert (this->size () <= cs.size ());
+
+ auto i (cs.begin ());
+ for (vector<K>& bks: *this)
+ i++->bot_keys = move (bks);
+ }
+ };
+
// The primary reason why a package is unbuildable by the build bot
// controller service.
//
@@ -611,13 +674,12 @@ namespace brep
// Version comparison operators.
//
- // They allow comparing objects that have epoch, canonical_upstream,
- // canonical_release, and revision data members. The idea is that this
- // works for both query members of types version and canonical_version.
- // Note, though, that the object revisions should be comparable (both
- // optional, numeric, etc), so to compare version to query member or
- // canonical_version you may need to explicitly convert the version object
- // to canonical_version.
+ // Compare objects that have epoch, canonical_upstream, canonical_release,
+ // and revision data members. The idea is that this works for both query
+ // members of types version and canonical_version. Note, though, that the
+ // object revisions should be comparable (both optional, numeric, etc), so
+ // to compare version to query member or canonical_version you may need to
+ // explicitly convert the version object to canonical_version.
//
template <typename T1, typename T2>
inline auto
@@ -769,10 +831,9 @@ namespace brep
return compare_version_lt (x.version, y.version, true);
}
- // They allow comparing objects that have tenant, name, and version data
- // members. The idea is that this works for both query members of package id
- // types (in particular in join conditions) as well as for values of
- // package_id type.
+ // Compare objects that have tenant, name, and version data members. The
+ // idea is that this works for both query members of package id types (in
+ // particular in join conditions) as well as for values of package_id type.
//
template <typename T1, typename T2>
inline auto
@@ -852,10 +913,10 @@ namespace brep
return x.canonical_name.compare (y.canonical_name) < 0;
}
- // They allow comparing objects that have tenant and canonical_name data
- // members. The idea is that this works for both query members of repository
- // id types (in particular in join conditions) as well as for values of
- // repository_id type.
+ // Compare objects that have tenant and canonical_name data members. The
+ // idea is that this works for both query members of repository id types (in
+ // particular in join conditions) as well as for values of repository_id
+ // type.
//
template <typename T1, typename T2>
inline auto
@@ -872,6 +933,38 @@ namespace brep
{
return x.tenant != y.tenant || x.canonical_name != y.canonical_name;
}
+
+ // Public key id comparison operators.
+ //
+ inline bool
+ operator< (const public_key_id& x, const public_key_id& y)
+ {
+ if (int r = x.tenant.compare (y.tenant))
+ return r < 0;
+
+ return x.fingerprint.compare (y.fingerprint) < 0;
+ }
+
+ // Compare objects that have tenant and fingerprint data members. The idea
+ // is that this works for both query members of public key id types (in
+ // particular in join conditions) as well as for values of public_key_id
+ // type.
+ //
+ template <typename T1, typename T2>
+ inline auto
+ operator== (const T1& x, const T2& y)
+ -> decltype (x.tenant == y.tenant && x.fingerprint == y.fingerprint)
+ {
+ return x.tenant == y.tenant && x.fingerprint == y.fingerprint;
+ }
+
+ template <typename T1, typename T2>
+ inline auto
+ operator!= (const T1& x, const T2& y)
+ -> decltype (x.tenant == y.tenant && x.fingerprint == y.fingerprint)
+ {
+ return x.tenant != y.tenant || x.fingerprint != y.fingerprint;
+ }
}
#endif // LIBBREP_COMMON_HXX
diff --git a/libbrep/odb.sh b/libbrep/odb.sh
index 9ee11fa..608ca41 100755
--- a/libbrep/odb.sh
+++ b/libbrep/odb.sh
@@ -53,7 +53,7 @@ $odb "${inc[@]}" -d pgsql --std c++14 --generate-query \
--hxx-prologue '#include <libbrep/common-traits.hxx>' \
-DLIBODB_BUILD2 -DLIBODB_PGSQL_BUILD2 \
--include-with-brackets --include-prefix libbrep \
- --guard-prefix LIBBREP \
+ --guard-prefix LIBBREP \
common.hxx
$odb "${inc[@]}" -d pgsql --std c++14 --generate-query --generate-schema \
@@ -74,7 +74,7 @@ $odb "${inc[@]}" -d pgsql --std c++14 --generate-query --generate-schema \
--odb-epilogue '#include <libbrep/wrapper-traits.hxx>' \
--generate-prepared -DLIBODB_BUILD2 -DLIBODB_PGSQL_BUILD2 \
--include-with-brackets --include-prefix libbrep \
- --guard-prefix LIBBREP \
+ --guard-prefix LIBBREP \
build.hxx
$odb "${inc[@]}" -d pgsql --std c++14 --generate-query \
diff --git a/libbrep/package.cxx b/libbrep/package.cxx
index 37795f0..4eb6fe8 100644
--- a/libbrep/package.cxx
+++ b/libbrep/package.cxx
@@ -82,7 +82,8 @@ namespace brep
build_class_exprs bs,
build_constraints_type bc,
build_auxiliaries_type ac,
- build_package_configs bcs,
+ package_build_bot_keys bk,
+ package_build_configs bcs,
optional<path> lc,
optional<string> fr,
optional<string> sh,
@@ -116,6 +117,7 @@ namespace brep
builds (move (bs)),
build_constraints (move (bc)),
build_auxiliaries (move (ac)),
+ build_bot_keys (move (bk)),
build_configs (move (bcs)),
internal_repository (move (rp)),
location (move (lc)),
@@ -134,6 +136,31 @@ namespace brep
buildable = !unbuildable_reason;
+ // If the package is buildable deduce the custom_bot flag.
+ //
+ if (buildable)
+ {
+ for (const package_build_config& bc: build_configs)
+ {
+ bool custom (!bc.effective_bot_keys (build_bot_keys).empty ());
+
+ if (!custom_bot)
+ {
+ custom_bot = custom;
+ }
+ //
+ // If both the custom and default bots are used by the package, then
+ // reset the custom_bot flag to nullopt and bail out from the build
+ // package configurations loop.
+ //
+ else if (*custom_bot != custom)
+ {
+ custom_bot = nullopt;
+ break;
+ }
+ }
+ }
+
assert (internal_repository->internal);
}
@@ -143,7 +170,7 @@ namespace brep
build_class_exprs bs,
build_constraints_type bc,
build_auxiliaries_type ac,
- build_package_configs bcs,
+ package_build_configs bcs,
shared_ptr<repository_type> rp)
: id (rp->tenant, move (nm), vr),
tenant (id.tenant),
diff --git a/libbrep/package.hxx b/libbrep/package.hxx
index b8c3c33..3878530 100644
--- a/libbrep/package.hxx
+++ b/libbrep/package.hxx
@@ -20,7 +20,7 @@
//
#define LIBBREP_PACKAGE_SCHEMA_VERSION_BASE 27
-#pragma db model version(LIBBREP_PACKAGE_SCHEMA_VERSION_BASE, 32, closed)
+#pragma db model version(LIBBREP_PACKAGE_SCHEMA_VERSION_BASE, 33, closed)
namespace brep
{
@@ -248,8 +248,8 @@ namespace brep
string id;
- // If true, display the packages in the web interface only in the tenant
- // view mode.
+ // If this flag is true, then display the packages in the web interface
+ // only in the tenant view mode.
//
bool private_; // Note: foreign-mapped in build.
@@ -456,6 +456,58 @@ namespace brep
#pragma db member(text) column("")
};
+ // Tweak public_key_id mapping to include a constraint (this only affects the
+ // database schema).
+ //
+ #pragma db member(public_key_id::tenant) points_to(tenant)
+
+ #pragma db object pointer(shared_ptr) session
+ class public_key: public string
+ {
+ public:
+ public_key (string tenant, string fingerprint, string key)
+ : string (move (key)), id (move (tenant), move (fingerprint)) {}
+
+ public_key_id id;
+
+ // Database mapping.
+ //
+ #pragma db member(id) id column("")
+
+ #pragma db member(data) virtual(string) access(this)
+
+ private:
+ friend class odb::access;
+ public_key () = default;
+ };
+
+ // package_build_config
+ //
+ using package_build_config =
+ build_package_config_template<lazy_shared_ptr<public_key>>;
+
+ using package_build_configs =
+ build_package_configs_template<lazy_shared_ptr<public_key>>;
+
+ #pragma db value(package_build_config) definition
+
+ #pragma db member(package_build_config::builds) transient
+ #pragma db member(package_build_config::constraints) transient
+ #pragma db member(package_build_config::auxiliaries) transient
+ #pragma db member(package_build_config::bot_keys) transient
+
+ // package_build_bot_keys
+ //
+ using package_build_bot_keys = vector<lazy_shared_ptr<public_key>>;
+ using package_build_bot_key_key = odb::nested_key<package_build_bot_keys>;
+
+ using package_build_bot_keys_map = std::map<package_build_bot_key_key,
+ lazy_shared_ptr<public_key>>;
+
+ #pragma db value(package_build_bot_key_key)
+ #pragma db member(package_build_bot_key_key::outer) column("config_index")
+ #pragma db member(package_build_bot_key_key::inner) column("index")
+
// Tweak package_id mapping to include a constraint (this only affects the
// database schema).
//
@@ -507,7 +559,8 @@ namespace brep
build_class_exprs,
build_constraints_type,
build_auxiliaries_type,
- build_package_configs,
+ package_build_bot_keys,
+ package_build_configs,
optional<path> location,
optional<string> fragment,
optional<string> sha256sum,
@@ -535,7 +588,7 @@ namespace brep
build_class_exprs,
build_constraints_type,
build_auxiliaries_type,
- build_package_configs,
+ package_build_configs,
shared_ptr<repository_type>);
bool
@@ -589,15 +642,25 @@ namespace brep
requirements_type requirements; // Note: foreign-mapped in build.
small_vector<test_dependency, 1> tests; // Note: foreign-mapped in build.
- // Common build classes, constraints, and auxiliaries that apply to all
- // configurations unless overridden.
+ // Common build classes, constraints, auxiliaries, and bot keys that apply
+ // to all configurations unless overridden.
//
build_class_exprs builds; // Note: foreign-mapped in build.
build_constraints_type build_constraints; // Note: foreign-mapped in build.
build_auxiliaries_type build_auxiliaries; // Note: foreign-mapped in build.
+ package_build_bot_keys build_bot_keys; // Note: foreign-mapped in build.
+ package_build_configs build_configs; // Note: foreign-mapped in build.
- build_package_configs build_configs; // Note: foreign-mapped in build.
-
+ // Group the build_configs, builds, and build_constraints members of this
+ // object together with their respective nested configs entries into the
+ // separate section for an explicit load.
+ //
+ // Note that while the build auxiliaries and bot keys are persisted via
+ // the newly created package objects, they are only used via the
+ // foreign-mapped build_package objects (see build-package.hxx for
+ // details). Thus, we add them to the never-loaded unused_section (see
+ // below).
+ //
odb::section build_section;
// Note that it is foreign-mapped in build.
@@ -628,6 +691,18 @@ namespace brep
bool buildable; // Note: foreign-mapped in build.
optional<brep::unbuildable_reason> unbuildable_reason;
+ // If this flag is true, then all the package configurations are buildable
+ // with the custom build bots. If false, then all configurations are
+ // buildable with the default bots. If nullopt, then some configurations
+ // are buildable with the custom and some with the default build bots.
+ //
+ // Note: meaningless if buildable is false.
+ //
+ optional<bool> custom_bot; // Note: foreign-mapped in build.
+
+ private:
+ odb::section unused_section;
+
// Database mapping.
//
#pragma db member(id) id column("")
@@ -750,13 +825,19 @@ namespace brep
// build_auxiliaries
//
#pragma db member(build_auxiliaries) id_column("") value_column("") \
- section(build_section)
+ section(unused_section)
+
+ // build_bot_keys
+ //
+ #pragma db member(build_bot_keys) \
+ id_column("") value_column("key_") value_not_null \
+ section(unused_section)
// build_configs
//
- // Note that build_package_config::{builds,constraints,auxiliaries} are
- // persisted/loaded via the separate nested containers (see commons.hxx
- // for details).
+ // Note that package_build_config::{builds,constraints,auxiliaries,
+ // bot_keys} are persisted/loaded via the separate nested containers (see
+ // commons.hxx for details).
//
#pragma db member(build_configs) id_column("") value_column("config_") \
section(build_section)
@@ -792,9 +873,22 @@ namespace brep
odb::nested_set (as, std::move (?)); \
move (as).to_configs (this.build_configs)) \
id_column("") key_column("") value_column("") \
- section(build_section)
-
- #pragma db member(build_section) load(lazy) update(always)
+ section(unused_section)
+
+ #pragma db member(build_config_bot_keys) \
+ virtual(package_build_bot_keys_map) \
+ after(build_config_auxiliaries) \
+ get(odb::nested_get ( \
+ brep::build_package_config_bot_keys (this.build_configs))) \
+ set(brep::build_package_config_bot_keys< \
+ lazy_shared_ptr<brep::public_key>> bks; \
+ odb::nested_set (bks, std::move (?)); \
+ move (bks).to_configs (this.build_configs)) \
+ id_column("") key_column("") value_column("key_") value_not_null \
+ section(unused_section)
+
+ #pragma db member(build_section) load(lazy) update(always)
+ #pragma db member(unused_section) load(lazy) update(manual)
// other_repositories
//
diff --git a/libbrep/package.xml b/libbrep/package.xml
index b66a66d..96e93a7 100644
--- a/libbrep/package.xml
+++ b/libbrep/package.xml
@@ -1,4 +1,139 @@
<changelog xmlns="http://www.codesynthesis.com/xmlns/odb/changelog" database="pgsql" schema-name="package" version="1">
+ <changeset version="33">
+ <add-table name="public_key" kind="object">
+ <column name="tenant" type="TEXT" null="false"/>
+ <column name="fingerprint" type="TEXT" null="false"/>
+ <column name="data" type="TEXT" null="false"/>
+ <primary-key>
+ <column name="tenant"/>
+ <column name="fingerprint"/>
+ </primary-key>
+ <foreign-key name="tenant_fk" deferrable="DEFERRED">
+ <column name="tenant"/>
+ <references table="tenant">
+ <column name="id"/>
+ </references>
+ </foreign-key>
+ </add-table>
+ <alter-table name="package">
+ <add-column name="custom_bot" type="BOOLEAN" null="true"/>
+ </alter-table>
+ <add-table name="package_build_bot_keys" kind="container">
+ <column name="tenant" type="TEXT" null="false"/>
+ <column name="name" type="CITEXT" null="false"/>
+ <column name="version_epoch" type="INTEGER" null="false"/>
+ <column name="version_canonical_upstream" type="TEXT" null="false"/>
+ <column name="version_canonical_release" type="TEXT" null="false" options="COLLATE &quot;C&quot;"/>
+ <column name="version_revision" type="INTEGER" null="false"/>
+ <column name="index" type="BIGINT" null="false"/>
+ <column name="key_tenant" type="TEXT" null="false"/>
+ <column name="key_fingerprint" type="TEXT" null="false"/>
+ <foreign-key name="tenant_fk" deferrable="DEFERRED">
+ <column name="tenant"/>
+ <references table="tenant">
+ <column name="id"/>
+ </references>
+ </foreign-key>
+ <foreign-key name="object_id_fk" on-delete="CASCADE">
+ <column name="tenant"/>
+ <column name="name"/>
+ <column name="version_epoch"/>
+ <column name="version_canonical_upstream"/>
+ <column name="version_canonical_release"/>
+ <column name="version_revision"/>
+ <references table="package">
+ <column name="tenant"/>
+ <column name="name"/>
+ <column name="version_epoch"/>
+ <column name="version_canonical_upstream"/>
+ <column name="version_canonical_release"/>
+ <column name="version_revision"/>
+ </references>
+ </foreign-key>
+ <index name="package_build_bot_keys_object_id_i">
+ <column name="tenant"/>
+ <column name="name"/>
+ <column name="version_epoch"/>
+ <column name="version_canonical_upstream"/>
+ <column name="version_canonical_release"/>
+ <column name="version_revision"/>
+ </index>
+ <index name="package_build_bot_keys_index_i">
+ <column name="index"/>
+ </index>
+ <foreign-key name="key_tenant_fk" deferrable="DEFERRED">
+ <column name="key_tenant"/>
+ <references table="tenant">
+ <column name="id"/>
+ </references>
+ </foreign-key>
+ <foreign-key name="key_fk" deferrable="DEFERRED">
+ <column name="key_tenant"/>
+ <column name="key_fingerprint"/>
+ <references table="public_key">
+ <column name="tenant"/>
+ <column name="fingerprint"/>
+ </references>
+ </foreign-key>
+ </add-table>
+ <add-table name="package_build_config_bot_keys" kind="container">
+ <column name="tenant" type="TEXT" null="false"/>
+ <column name="name" type="CITEXT" null="false"/>
+ <column name="version_epoch" type="INTEGER" null="false"/>
+ <column name="version_canonical_upstream" type="TEXT" null="false"/>
+ <column name="version_canonical_release" type="TEXT" null="false" options="COLLATE &quot;C&quot;"/>
+ <column name="version_revision" type="INTEGER" null="false"/>
+ <column name="config_index" type="BIGINT" null="false"/>
+ <column name="index" type="BIGINT" null="false"/>
+ <column name="key_tenant" type="TEXT" null="false"/>
+ <column name="key_fingerprint" type="TEXT" null="false"/>
+ <foreign-key name="tenant_fk" deferrable="DEFERRED">
+ <column name="tenant"/>
+ <references table="tenant">
+ <column name="id"/>
+ </references>
+ </foreign-key>
+ <foreign-key name="object_id_fk" on-delete="CASCADE">
+ <column name="tenant"/>
+ <column name="name"/>
+ <column name="version_epoch"/>
+ <column name="version_canonical_upstream"/>
+ <column name="version_canonical_release"/>
+ <column name="version_revision"/>
+ <references table="package">
+ <column name="tenant"/>
+ <column name="name"/>
+ <column name="version_epoch"/>
+ <column name="version_canonical_upstream"/>
+ <column name="version_canonical_release"/>
+ <column name="version_revision"/>
+ </references>
+ </foreign-key>
+ <index name="package_build_config_bot_keys_object_id_i">
+ <column name="tenant"/>
+ <column name="name"/>
+ <column name="version_epoch"/>
+ <column name="version_canonical_upstream"/>
+ <column name="version_canonical_release"/>
+ <column name="version_revision"/>
+ </index>
+ <foreign-key name="key_tenant_fk" deferrable="DEFERRED">
+ <column name="key_tenant"/>
+ <references table="tenant">
+ <column name="id"/>
+ </references>
+ </foreign-key>
+ <foreign-key name="key_fk" deferrable="DEFERRED">
+ <column name="key_tenant"/>
+ <column name="key_fingerprint"/>
+ <references table="public_key">
+ <column name="tenant"/>
+ <column name="fingerprint"/>
+ </references>
+ </foreign-key>
+ </add-table>
+ </changeset>
+
<changeset version="32">
<alter-table name="tenant">
<add-column name="build_toolchain_name" type="TEXT" null="true"/>