Add option to change supervised node's working directory

This commit is contained in:
Jon Siwek 2020-01-06 18:39:14 -08:00
parent 8aa77436f9
commit aaa702fb4d
4 changed files with 36 additions and 4 deletions

View file

@ -22,6 +22,7 @@ export {
type Node: record { type Node: record {
name: string; name: string;
interface: string &optional; interface: string &optional;
directory: string &optional;
cluster: table[string] of ClusterEndpoint &default=table(); cluster: table[string] of ClusterEndpoint &default=table();
# TODO: separate node config fields from status fields ? # TODO: separate node config fields from status fields ?

View file

@ -2,7 +2,7 @@
#include <sys/types.h> #include <sys/types.h>
#include <sys/wait.h> #include <sys/wait.h>
#include <unistd.h> #include <unistd.h>
#include <signal.h> #include <csignal>
#include <fcntl.h> #include <fcntl.h>
#include <poll.h> #include <poll.h>
@ -720,6 +720,11 @@ Supervisor::Node Supervisor::Node::FromRecord(const RecordVal* node)
if ( iface_val ) if ( iface_val )
rval.interface = iface_val->AsString()->CheckString(); rval.interface = iface_val->AsString()->CheckString();
auto directory_val = node->Lookup("directory");
if ( directory_val )
rval.directory = directory_val->AsString()->CheckString();
auto cluster_table_val = node->Lookup("cluster")->AsTableVal(); auto cluster_table_val = node->Lookup("cluster")->AsTableVal();
auto cluster_table = cluster_table_val->AsTable(); auto cluster_table = cluster_table_val->AsTable();
auto c = cluster_table->InitForIteration(); auto c = cluster_table->InitForIteration();
@ -754,11 +759,12 @@ Supervisor::Node Supervisor::Node::FromJSON(const std::string& json)
auto j = nlohmann::json::parse(json); auto j = nlohmann::json::parse(json);
rval.name = j["name"]; rval.name = j["name"];
auto it = j.find("interface"); if ( auto it = j.find("interface"); it != j.end() )
if ( it != j.end() )
rval.interface = *it; rval.interface = *it;
if ( auto it = j.find("directory"); it != j.end() )
rval.directory= *it;
auto cluster = j["cluster"]; auto cluster = j["cluster"];
for ( const auto& e : cluster.items() ) for ( const auto& e : cluster.items() )
@ -803,6 +809,9 @@ IntrusivePtr<RecordVal> Supervisor::Node::ToRecord() const
if ( interface ) if ( interface )
rval->Assign(rt->FieldOffset("interface"), new StringVal(*interface)); rval->Assign(rt->FieldOffset("interface"), new StringVal(*interface));
if ( directory )
rval->Assign(rt->FieldOffset("directory"), new StringVal(*directory));
auto tt = BifType::Record::Supervisor::Node->FieldType("cluster"); auto tt = BifType::Record::Supervisor::Node->FieldType("cluster");
auto cluster_val = new TableVal(tt->AsTableType()); auto cluster_val = new TableVal(tt->AsTableType());
rval->Assign(rt->FieldOffset("cluster"), cluster_val); rval->Assign(rt->FieldOffset("cluster"), cluster_val);
@ -926,6 +935,15 @@ std::string Supervisor::Create(const Supervisor::Node& node)
if ( nodes.find(node.name) != nodes.end() ) if ( nodes.find(node.name) != nodes.end() )
return fmt("node with name '%s' already exists", node.name.data()); return fmt("node with name '%s' already exists", node.name.data());
if ( node.directory )
{
auto res = ensure_intermediate_dirs(node.directory->data());
if ( ! res )
return fmt("failed to create working directory %s\n",
node.directory->data());
}
auto msg = make_create_message(node); auto msg = make_create_message(node);
safe_write(stem_pipe->OutFD(), msg.data(), msg.size() + 1); safe_write(stem_pipe->OutFD(), msg.data(), msg.size() + 1);
nodes.emplace(node.name, node); nodes.emplace(node.name, node);

View file

@ -45,6 +45,7 @@ public:
std::string name; std::string name;
std::optional<std::string> interface; std::optional<std::string> interface;
std::optional<std::string> directory;
std::map<std::string, ClusterEndpoint> cluster; std::map<std::string, ClusterEndpoint> cluster;
pid_t pid = 0; pid_t pid = 0;

View file

@ -800,6 +800,18 @@ int main(int argc, char** argv)
exit(1); exit(1);
} }
} }
if ( zeek::supervised_node->directory )
{
if ( chdir(zeek::supervised_node->directory->data()) )
{
fprintf(stderr, "supervised node %s failed to chdir to %s: %s\n",
node_name.data(),
zeek::supervised_node->directory->data(),
strerror(errno));
exit(1);
}
}
} }
std::set_new_handler(bro_new_handler); std::set_new_handler(bro_new_handler);