aboutsummaryrefslogtreecommitdiff
path: root/libbbot/manifest.cxx
diff options
context:
space:
mode:
authorKaren Arutyunov <karen@codesynthesis.com>2024-03-08 20:24:35 +0300
committerKaren Arutyunov <karen@codesynthesis.com>2024-03-12 16:27:58 +0300
commited8e64ca8525872c97f9331cb5c882b40864b84e (patch)
tree62abb95ed6dac0a8b25c7f5123d2093d5d26628c /libbbot/manifest.cxx
parent1d30ee0f8a017be6611e2eebffc5c539a8b1d12c (diff)
Add support for build auxiliary machines related manifest values
Diffstat (limited to 'libbbot/manifest.cxx')
-rw-r--r--libbbot/manifest.cxx145
1 files changed, 145 insertions, 0 deletions
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 <vector>
#include <string>
#include <cctype> // isxdigit()
+#include <limits> // numeric_limits
#include <cassert>
#include <sstream>
#include <cstddef> // size_t
#include <utility> // move()
#include <cstdint> // uint64_t
+#include <cstdlib> // strtoull()
#include <algorithm> // find_if()
#include <stdexcept> // 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<uint64_t>
+ 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<uint64_t>::max ())
+ {
+ return static_cast<uint64_t> (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.
//