diff options
author | Karen Arutyunov <karen@codesynthesis.com> | 2024-04-15 21:36:02 +0300 |
---|---|---|
committer | Karen Arutyunov <karen@codesynthesis.com> | 2024-04-22 14:31:24 +0300 |
commit | 7c61322166eb0eab77ee5fb10031bae616ecb192 (patch) | |
tree | b9b86de7b896a6264547acdb8b94eebb26320b33 /libbrep | |
parent | 42e0e515a36d72197c74813d0d21682d9120d625 (diff) |
Add support for custom build bots
Diffstat (limited to 'libbrep')
-rw-r--r-- | libbrep/build-extra.sql | 45 | ||||
-rw-r--r-- | libbrep/build-package.hxx | 110 | ||||
-rw-r--r-- | libbrep/build.hxx | 2 | ||||
-rw-r--r-- | libbrep/build.xml | 2 | ||||
-rw-r--r-- | libbrep/common.cxx | 10 | ||||
-rw-r--r-- | libbrep/common.hxx | 191 | ||||
-rwxr-xr-x | libbrep/odb.sh | 4 | ||||
-rw-r--r-- | libbrep/package.cxx | 31 | ||||
-rw-r--r-- | libbrep/package.hxx | 126 | ||||
-rw-r--r-- | libbrep/package.xml | 135 |
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 "C""/> + <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 "C""/> + <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"/> |