From ed8e64ca8525872c97f9331cb5c882b40864b84e Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Fri, 8 Mar 2024 20:24:35 +0300 Subject: Add support for build auxiliary machines related manifest values --- libbbot/manifest.cxx | 145 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 145 insertions(+) (limited to 'libbbot/manifest.cxx') diff --git a/libbbot/manifest.cxx b/libbbot/manifest.cxx index be642a0..ab392e4 100644 --- a/libbbot/manifest.cxx +++ b/libbbot/manifest.cxx @@ -7,11 +7,13 @@ #include #include #include // isxdigit() +#include // numeric_limits #include #include #include // size_t #include // move() #include // uint64_t +#include // strtoull() #include // find_if() #include // invalid_argument @@ -37,6 +39,29 @@ namespace bbot using butl::optional; + // machine_role + // + string + to_string (machine_role r) + { + switch (r) + { + case machine_role::build: return "build"; + case machine_role::auxiliary: return "auxiliary"; + } + + assert (false); + return string (); + } + + machine_role + to_machine_role (const string& s) + { + if (s == "build") return machine_role::build; + else if (s == "auxiliary") return machine_role::auxiliary; + else throw invalid_argument ("invalid machine role '" + s + '\''); + } + // result_status // string @@ -134,6 +159,29 @@ namespace bbot return true; } + // Return nullopt if the string is not a valid 64-bit unsigned integer. + // + static optional + parse_uint64 (const string& s) + { + if (!s.empty () && s[0] != '-' && s[0] != '+') // strtoull() allows these. + { + const char* b (s.c_str ()); + char* e (nullptr); + errno = 0; // We must clear it according to POSIX. + uint64_t v (strtoull (b, &e, 10)); // Can't throw. + + if (errno != ERANGE && + e == b + s.size () && + v <= numeric_limits::max ()) + { + return static_cast (v); + } + } + + return nullopt; + } + // machine_header_manifest // machine_header_manifest:: @@ -207,6 +255,40 @@ namespace bbot summary = move (v); } + else if (n == "role") + { + if (role) + bad_name ("machine role redefinition"); + + try + { + role = to_machine_role (v); + } + catch (const invalid_argument& e) + { + bad_value (e.what ()); + } + } + else if (n == "ram-minimum") + { + if (ram_minimum) + bad_name ("machine minimum RAM redefinition"); + + ram_minimum = parse_uint64 (v); + + if (!ram_minimum) + bad_value ("machine minimum RAM should be 64-bit unsigned integer"); + } + else if (n == "ram-maximum") + { + if (ram_maximum) + bad_name ("machine maximum RAM redefinition"); + + ram_maximum = parse_uint64 (v); + + if (!ram_maximum) + bad_value ("machine maximum RAM should be 64-bit unsigned integer"); + } else { switch (m) @@ -247,6 +329,15 @@ namespace bbot s.next ("name", name); s.next ("summary", summary); + if (role) + s.next ("role", to_string (*role)); + + if (ram_minimum) + s.next ("ram-minimum", std::to_string (*ram_minimum)); + + if (ram_maximum) + s.next ("ram-maximum", std::to_string (*ram_maximum)); + if (end_of_manifest) s.next ("", ""); // End of manifest. } @@ -358,6 +449,17 @@ namespace bbot fingerprint = move (v); } + else if (n == "auxiliary-ram") + { + if (auxiliary_ram) + bad_name ("auxiliary machines RAM limit redefinition"); + + auxiliary_ram = parse_uint64 (v); + + if (!auxiliary_ram) + bad_value ( + "auxiliary machines RAM limit should be 64-bit unsigned integer"); + } else if (!iu) bad_name ("unknown name '" + n + "' in task request manifest"); } @@ -423,6 +525,9 @@ namespace bbot if (fingerprint) s.next ("fingerprint", *fingerprint); + if (auxiliary_ram) + s.next ("auxiliary-ram", std::to_string (*auxiliary_ram)); + s.next ("", ""); // End of manifest. for (const machine_header_manifest& m: machines) @@ -644,6 +749,26 @@ namespace bbot machine = move (v); } + else if (n == "auxiliary-machine" || + (n.size () > 18 && n.compare (0, 18, "auxiliary-machine-") == 0)) + { + if (v.empty ()) + bad_value ("empty task auxiliary machine name"); + + auxiliary_machine m {move (v), + n.size () > 18 ? string (n, 18) : string ()}; + + if (find_if (auxiliary_machines.begin (), auxiliary_machines.end (), + [&m] (const auxiliary_machine& am) + { + return am.environment_name == m.environment_name; + }) != auxiliary_machines.end ()) + { + bad_name ("task auxiliary machine environment redefinition"); + } + + auxiliary_machines.push_back (move (m)); + } else if (n == "target") { if (!target.empty ()) @@ -668,6 +793,16 @@ namespace bbot environment = move (v); } + else if (n == "auxiliary-environment") + { + if (auxiliary_environment) + bad_name ("task auxiliary environment redefinition"); + + if (v.empty ()) + bad_value ("empty task auxiliary environment"); + + auxiliary_environment = move (v); + } else if (n == "config" || // @@ TMP Until toolchain 0.16.0 is released. n == "target-config") { @@ -815,11 +950,21 @@ namespace bbot s.next ("dependency-checksum", *dependency_checksum); s.next ("machine", machine); + + for (const auxiliary_machine& am: auxiliary_machines) + s.next ((!am.environment_name.empty () + ? "auxiliary-machine-" + am.environment_name + : "auxiliary-machine"), + am.name); + s.next ("target", target.string ()); if (environment) s.next ("environment", *environment); + if (auxiliary_environment) + s.next ("auxiliary-environment", *auxiliary_environment); + // Serialize an optional value of the strings type as a space-separated // string list. // -- cgit v1.1