From 7bee79b400b8fe048397aa208290b9faab3eb0f7 Mon Sep 17 00:00:00 2001 From: Christian Kreibich Date: Wed, 7 Jul 2021 15:17:39 -0700 Subject: [PATCH] Add optional bare-mode boolean flag to Supervisor's node configuration When omitted, the node inherits the Supervisor's bare-mode status. When true/false, the new Zeek node will enable/disable bare mode, respectively. It continues to load any scripts passed at the command line and in the additional scripts list already provided in the node configuration. Includes testcase. --- scripts/base/frameworks/supervisor/api.zeek | 3 + src/supervisor/Supervisor.cc | 14 ++++ src/supervisor/Supervisor.h | 5 ++ .../zeek.bare.node.out | 4 + .../zeek.default.node.out | 4 + .../zeek.inherit.node.out | 4 + .../btest/supervisor/config-bare-mode.zeek | 74 +++++++++++++++++++ 7 files changed, 108 insertions(+) create mode 100644 testing/btest/Baseline/supervisor.config-bare-mode/zeek.bare.node.out create mode 100644 testing/btest/Baseline/supervisor.config-bare-mode/zeek.default.node.out create mode 100644 testing/btest/Baseline/supervisor.config-bare-mode/zeek.inherit.node.out create mode 100644 testing/btest/supervisor/config-bare-mode.zeek diff --git a/scripts/base/frameworks/supervisor/api.zeek b/scripts/base/frameworks/supervisor/api.zeek index fa32d23b53..01c41f6f14 100644 --- a/scripts/base/frameworks/supervisor/api.zeek +++ b/scripts/base/frameworks/supervisor/api.zeek @@ -42,6 +42,9 @@ export { stdout_file: string &optional; ## The filename/path to which the node's stderr will be redirected. stderr_file: string &optional; + ## Whether to start the node in bare mode. When left out, the node + ## inherits the bare-mode status the supervisor itself runs with. + bare_mode: bool &optional; ## Additional script filenames/paths that the node should load. scripts: vector of string &default = vector(); ## Environment variables to define in the supervised node. diff --git a/src/supervisor/Supervisor.cc b/src/supervisor/Supervisor.cc index d56f9b1083..ac16bae1ff 100644 --- a/src/supervisor/Supervisor.cc +++ b/src/supervisor/Supervisor.cc @@ -1251,6 +1251,11 @@ Supervisor::NodeConfig Supervisor::NodeConfig::FromRecord(const RecordVal* node) if ( affinity_val ) rval.cpu_affinity = affinity_val->AsInt(); + const auto& bare_mode_val = node->GetField("bare_mode"); + + if ( bare_mode_val ) + rval.bare_mode = bare_mode_val->AsBool(); + auto scripts_val = node->GetField("scripts")->AsVectorVal(); for ( auto i = 0u; i < scripts_val->Size(); ++i ) @@ -1324,6 +1329,9 @@ Supervisor::NodeConfig Supervisor::NodeConfig::FromJSON(std::string_view json) if ( auto it = j.FindMember("cpu_affinity"); it != j.MemberEnd() ) rval.cpu_affinity = it->value.GetInt(); + if ( auto it = j.FindMember("bare_mode"); it != j.MemberEnd() ) + rval.bare_mode = it->value.GetBool(); + auto& scripts = j["scripts"]; for ( auto it = scripts.Begin(); it != scripts.End(); ++it ) @@ -1385,6 +1393,9 @@ RecordValPtr Supervisor::NodeConfig::ToRecord() const if ( cpu_affinity ) rval->AssignField("cpu_affinity", *cpu_affinity); + if ( bare_mode ) + rval->AssignField("bare_mode", *bare_mode); + auto st = rt->GetFieldType("scripts"); auto scripts_val = make_intrusive(std::move(st)); @@ -1590,6 +1601,9 @@ void SupervisedNode::Init(Options* options) const options->filter_supervised_node_options(); + if ( config.bare_mode ) + options->bare_mode = *config.bare_mode; + if ( config.interface ) options->interface = *config.interface; diff --git a/src/supervisor/Supervisor.h b/src/supervisor/Supervisor.h index 5c05c9e1ed..0fb02d35b9 100644 --- a/src/supervisor/Supervisor.h +++ b/src/supervisor/Supervisor.h @@ -186,6 +186,11 @@ public: * A cpu/core number to which the node will try to pin itself. */ std::optional cpu_affinity; + /** + * Whether to start the node in bare mode. When not present, the + * node inherits the bare-mode status of the supervisor. + */ + std::optional bare_mode; /** * Additional script filename/paths that the node should load. */ diff --git a/testing/btest/Baseline/supervisor.config-bare-mode/zeek.bare.node.out b/testing/btest/Baseline/supervisor.config-bare-mode/zeek.bare.node.out new file mode 100644 index 0000000000..45c8a185df --- /dev/null +++ b/testing/btest/Baseline/supervisor.config-bare-mode/zeek.bare.node.out @@ -0,0 +1,4 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +supervised node zeek_init() +bare mode +supervised node zeek_done() diff --git a/testing/btest/Baseline/supervisor.config-bare-mode/zeek.default.node.out b/testing/btest/Baseline/supervisor.config-bare-mode/zeek.default.node.out new file mode 100644 index 0000000000..9a9a51018c --- /dev/null +++ b/testing/btest/Baseline/supervisor.config-bare-mode/zeek.default.node.out @@ -0,0 +1,4 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +supervised node zeek_init() +default mode +supervised node zeek_done() diff --git a/testing/btest/Baseline/supervisor.config-bare-mode/zeek.inherit.node.out b/testing/btest/Baseline/supervisor.config-bare-mode/zeek.inherit.node.out new file mode 100644 index 0000000000..45c8a185df --- /dev/null +++ b/testing/btest/Baseline/supervisor.config-bare-mode/zeek.inherit.node.out @@ -0,0 +1,4 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +supervised node zeek_init() +bare mode +supervised node zeek_done() diff --git a/testing/btest/supervisor/config-bare-mode.zeek b/testing/btest/supervisor/config-bare-mode.zeek new file mode 100644 index 0000000000..0e3f9c77e2 --- /dev/null +++ b/testing/btest/supervisor/config-bare-mode.zeek @@ -0,0 +1,74 @@ +# This test verifies the functionality of the bare_mode flag in NodeConfig. +# We launch two nodes, one regular, one in bare mode. Each outputs a different +# string depending on mode, and exits. We verify the resulting outputs. + +# @TEST-PORT: BROKER_PORT +# @TEST-EXEC: btest-bg-run zeek zeek -j -b %INPUT +# @TEST-EXEC: btest-bg-wait 30 +# @TEST-EXEC: btest-diff zeek/inherit/node.out +# @TEST-EXEC: btest-diff zeek/bare/node.out +# @TEST-EXEC: btest-diff zeek/default/node.out + + +# So the supervised node doesn't terminate right away. +redef exit_only_after_terminate=T; + +global node_output_file: file; +global topic = "test-topic"; + +event do_destroy(name: string) + { + Supervisor::destroy(name); + + # When no nodes are left, exit. + local status = Supervisor::status(); + if ( |status$nodes| == 0) + terminate(); + } + +event zeek_init() + { + if ( Supervisor::is_supervisor() ) + { + Broker::subscribe(topic); + Broker::listen("127.0.0.1", to_port(getenv("BROKER_PORT"))); + + # Create a node that inherits basre mode from us. + local sn = Supervisor::NodeConfig($name="inherit", $directory="inherit"); + Supervisor::create(sn); + + # Create a node that specifies bare mode. + sn = Supervisor::NodeConfig($name="bare", $directory="bare", $bare_mode=T); + Supervisor::create(sn); + + # Create a node that specifies default mode. + sn = Supervisor::NodeConfig($name="default", $directory="default", $bare_mode=F); + Supervisor::create(sn); + + } + else + { + Broker::peer("127.0.0.1", to_port(getenv("BROKER_PORT"))); + node_output_file = open("node.out"); + print node_output_file, "supervised node zeek_init()"; + +# This is only defined when we're loading init-default.zeek: +@ifdef ( Notice::Info ) + print node_output_file, "default mode"; +@else + print node_output_file, "bare mode"; +@endif + } + } + +event Broker::peer_added(endpoint: Broker::EndpointInfo, msg: string) + { + if ( Supervisor::is_supervised() ) + Broker::publish(topic, do_destroy, Supervisor::node()$name); + } + +event zeek_done() + { + if ( Supervisor::is_supervised() ) + print node_output_file, "supervised node zeek_done()"; + }