aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKaren Arutyunov <karen@codesynthesis.com>2021-03-15 22:02:40 +0300
committerKaren Arutyunov <karen@codesynthesis.com>2021-03-26 10:40:12 +0300
commit7ec5a2ef1ac80d2a3b1715e75ac4e507330de4e6 (patch)
tree46bc96a1f0e3381c644c03ad79d5539952d4d0db
parentf131b3e4654ab5a70fb65930967ca02f7ca506f7 (diff)
Add support for interactive-{mode,login} task request and interactive task manifest values
-rw-r--r--libbbot/manifest.cxx89
-rw-r--r--libbbot/manifest.hxx69
-rw-r--r--tests/manifest/task-request.testscript64
-rw-r--r--tests/manifest/task-response.testscript1
-rw-r--r--tests/manifest/task.testscript16
5 files changed, 227 insertions, 12 deletions
diff --git a/libbbot/manifest.cxx b/libbbot/manifest.cxx
index c01a84b..33b5046 100644
--- a/libbbot/manifest.cxx
+++ b/libbbot/manifest.cxx
@@ -65,6 +65,31 @@ namespace bbot
else throw invalid_argument ("invalid result status '" + s + "'");
}
+ // interactive_mode
+ //
+ string
+ to_string (interactive_mode s)
+ {
+ switch (s)
+ {
+ case interactive_mode::false_: return "false";
+ case interactive_mode::true_: return "true";
+ case interactive_mode::both: return "both";
+ }
+
+ assert (false);
+ return string ();
+ }
+
+ interactive_mode
+ to_interactive_mode (const string& s)
+ {
+ if (s == "false") return interactive_mode::false_;
+ else if (s == "true") return interactive_mode::true_;
+ else if (s == "both") return interactive_mode::both;
+ else throw invalid_argument ("invalid interactive mode '" + s + "'");
+ }
+
// Utility functions
//
inline static bool
@@ -246,6 +271,11 @@ namespace bbot
if (nv.value != "1")
bad_value ("unsupported format version");
+ // Cache the interactive login manifest value and validate whether it's
+ // allowed later, after the interactive mode is parsed.
+ //
+ optional<name_value> interactive_login_nv;
+
// Parse the task request manifest.
//
for (nv = p.next (); !nv.empty (); nv = p.next ())
@@ -288,6 +318,30 @@ namespace bbot
e.what ());
}
}
+ else if (n == "interactive-mode")
+ {
+ if (interactive_mode)
+ bad_name ("task request interactive mode redefinition");
+
+ try
+ {
+ interactive_mode = to_interactive_mode (v);
+ }
+ catch (const invalid_argument&)
+ {
+ bad_value (string ("invalid task request interactive mode"));
+ }
+ }
+ else if (n == "interactive-login")
+ {
+ if (interactive_login_nv)
+ bad_name ("task request interactive login redefinition");
+
+ if (v.empty ())
+ bad_value ("empty task request interactive login");
+
+ interactive_login_nv = move (nv);
+ }
else if (n == "fingerprint")
{
if (fingerprint)
@@ -313,6 +367,22 @@ namespace bbot
if (toolchain_version.empty ())
bad_value ("no task request toolchain version specified");
+ if (effective_interactive_mode () != interactive_mode_type::false_)
+ {
+ if (!interactive_login_nv)
+ bad_value ("no task request interactive login specified");
+
+ interactive_login = move (interactive_login_nv->value);
+ }
+ else if (interactive_login_nv)
+ {
+ // Restore as bad_name() uses its line/column.
+ //
+ nv = move (*interactive_login_nv);
+
+ bad_name ("interactive login specified for non-interactive mode");
+ }
+
// Parse machine header manifests.
//
for (nv = p.next (); !nv.empty (); nv = p.next ())
@@ -338,6 +408,12 @@ namespace bbot
s.next ("toolchain-name", toolchain_name);
s.next ("toolchain-version", toolchain_version.string ());
+ if (interactive_mode)
+ s.next ("interactive-mode", to_string (*interactive_mode));
+
+ if (interactive_login)
+ s.next ("interactive-login", *interactive_login);
+
if (fingerprint)
s.next ("fingerprint", *fingerprint);
@@ -607,6 +683,16 @@ namespace bbot
if (warning_regex.empty ())
bad_value ("empty task warning regex");
}
+ else if (n == "interactive")
+ {
+ if (interactive)
+ bad_name ("task interactive value redefinition");
+
+ if (v.empty ())
+ bad_value ("empty task interactive value");
+
+ interactive = move (v);
+ }
else if (!iu)
bad_name ("unknown name '" + n + "' in task manifest");
}
@@ -704,6 +790,9 @@ namespace bbot
serialize_list ("config", config);
serialize_list ("warning-regex", warning_regex);
+ if (interactive)
+ s.next ("interactive", *interactive);
+
s.next ("", ""); // End of manifest.
}
diff --git a/libbbot/manifest.hxx b/libbbot/manifest.hxx
index daee743..c3bb6ce 100644
--- a/libbbot/manifest.hxx
+++ b/libbbot/manifest.hxx
@@ -62,14 +62,40 @@ namespace bbot
using machine_header_manifests = std::vector<machine_header_manifest>;
+ // Agent's capability to perform (non-)interactive builds.
+ //
+ enum class interactive_mode: std::uint8_t
+ {
+ false_,
+ true_,
+ both
+ };
+
+ LIBBBOT_EXPORT std::string
+ to_string (interactive_mode);
+
+ LIBBBOT_EXPORT interactive_mode
+ to_interactive_mode (const std::string&); // May throw invalid_argument.
+
+ inline std::ostream&
+ operator<< (std::ostream& os, interactive_mode m)
+ {
+ return os << to_string (m);
+ }
+
class LIBBBOT_EXPORT task_request_manifest
{
public:
+ using interactive_mode_type = bbot::interactive_mode;
+
std::string agent;
std::string toolchain_name;
butl::standard_version toolchain_version;
+ butl::optional<interactive_mode_type> interactive_mode;
+ butl::optional<std::string> interactive_login;
+
// Agent's public key SHA256 fingerprint.
//
// @@ How the fingerpring for openssl public key will be produced? Seems
@@ -82,16 +108,31 @@ namespace bbot
machine_header_manifests machines;
- task_request_manifest (std::string a,
- std::string n,
- butl::standard_version v,
- butl::optional<std::string> f,
- machine_header_manifests m)
- : agent (std::move (a)),
- toolchain_name (std::move (n)),
- toolchain_version (std::move (v)),
- fingerprint (std::move (f)),
- machines (std::move (m)) {}
+ // Return the effective interactive build mode. If the mode is not
+ // explicitly specified, then false is assumed.
+ //
+ interactive_mode_type
+ effective_interactive_mode () const noexcept
+ {
+ return interactive_mode
+ ? *interactive_mode
+ : interactive_mode_type::false_;
+ }
+
+ task_request_manifest (std::string ag,
+ std::string tn,
+ butl::standard_version tv,
+ butl::optional<interactive_mode_type> im,
+ butl::optional<std::string> il,
+ butl::optional<std::string> fp,
+ machine_header_manifests ms)
+ : agent (std::move (ag)),
+ toolchain_name (std::move (tn)),
+ toolchain_version (std::move (tv)),
+ interactive_mode (std::move (im)),
+ interactive_login (std::move (il)),
+ fingerprint (std::move (fp)),
+ machines (std::move (ms)) {}
public:
task_request_manifest () = default; // VC export.
@@ -146,6 +187,8 @@ namespace bbot
//
strings warning_regex;
+ butl::optional<std::string> interactive; // Interactive build breakpoint.
+
strings
unquoted_config () const;
@@ -161,7 +204,8 @@ namespace bbot
butl::target_triplet tg,
butl::optional<std::string> en,
strings cf,
- strings wr)
+ strings wr,
+ butl::optional<std::string> ir)
: name (std::move (nm)),
version (std::move (vr)),
repository (std::move (rl)),
@@ -171,7 +215,8 @@ namespace bbot
target (std::move (tg)),
environment (std::move (en)),
config (std::move (cf)),
- warning_regex (std::move (wr)){}
+ warning_regex (std::move (wr)),
+ interactive (std::move (ir)) {}
public:
task_manifest () = default; // VC export.
diff --git a/tests/manifest/task-request.testscript b/tests/manifest/task-request.testscript
index 4b797f6..cee21fb 100644
--- a/tests/manifest/task-request.testscript
+++ b/tests/manifest/task-request.testscript
@@ -15,6 +15,8 @@ test.options += -tq
agent: upsa
toolchain-name: queue
toolchain-version: 0.5.0
+ interactive-mode: both
+ interactive-login: 10.5.0.1:5901
fingerprint: 1105fb394ee870adb154b7abfbbae5755df7dcef6c81db34e8d1b68d2653734e
:
id: a2b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
@@ -124,3 +126,65 @@ toolchain-name: queue
toolchain-version: 0.5.0
fingerprint: 1105fb394ee870adb154b7abfbbae5755df7dcef6c81db34e8d1b68d2653734e
EOI
+
+: interactive
+:
+{
+ : redefinition
+ :
+ {
+ : mode
+ :
+ $* <<EOI 2>'stdin:3:1: error: task request interactive mode redefinition' == 1
+ : 1
+ interactive-mode: true
+ interactive-mode: both
+ EOI
+
+ : login
+ :
+ $* <<EOI 2>'stdin:3:1: error: task request interactive login redefinition' == 1
+ : 1
+ interactive-login: 10.5.0.1:5901
+ interactive-login: 10.5.0.1:5901
+ EOI
+ }
+
+ : invalid
+ :
+ {
+ : mode
+ :
+ $* <<EOI 2>'stdin:2:19: error: invalid task request interactive mode' == 1
+ : 1
+ interactive-mode: on
+ EOI
+
+ : login
+ :
+ $* <<EOI 2>'stdin:2:19: error: empty task request interactive login' == 1
+ : 1
+ interactive-login:
+ EOI
+ }
+
+ : no-login
+ :
+ $* <<EOI 2>'stdin:6:1: error: no task request interactive login specified' == 1
+ : 1
+ agent: upsa
+ toolchain-name: queue
+ toolchain-version: 0.5.0
+ interactive-mode: both
+ EOI
+
+ : unexpected-login
+ :
+ $* <<EOI 2>'stdin:5:1: error: interactive login specified for non-interactive mode' == 1
+ : 1
+ agent: upsa
+ toolchain-name: queue
+ toolchain-version: 0.5.0
+ interactive-login: 10.5.0.1:5901
+ EOI
+}
diff --git a/tests/manifest/task-response.testscript b/tests/manifest/task-response.testscript
index e7dbdb9..d486dda 100644
--- a/tests/manifest/task-response.testscript
+++ b/tests/manifest/task-response.testscript
@@ -80,6 +80,7 @@ test.options += -ts
: invalid
:
{
+
: challenge
:
{
diff --git a/tests/manifest/task.testscript b/tests/manifest/task.testscript
index 65ecd29..b5ca66a 100644
--- a/tests/manifest/task.testscript
+++ b/tests/manifest/task.testscript
@@ -24,6 +24,7 @@ test.options += -t
environment: lld
config: config.cc.coptions=/Z7 config.cc.loptions=/DEBUG
warning-regex: '^warning: ' '^.+: warning: '
+ interactive: error
EOF
: no-config-regex-environment
@@ -167,6 +168,14 @@ test.options += -t
warning-regex: '^warning: '
warning-regex: '^.+: warning: '
EOI
+
+ : interactive
+ :
+ $* <<EOI 2>'stdin:3:1: error: task interactive value redefinition' == 1
+ : 1
+ interactive: error
+ interactive: warning
+ EOI
}
: invalid
@@ -326,6 +335,13 @@ test.options += -t
: 1
trust: abc
EOI
+
+ : interactive
+ :
+ $* <<EOI 2>'stdin:2:13: error: empty task interactive value' == 1
+ : 1
+ interactive:
+ EOI
}
: unknown-name