Add support for multiple hostnames for a given node
This will be useful both on a roboRIO and to allow encoding the team
number in the hostnames on the Pis.
Change-Id: I3975785240d7502bc3922c92e9faad4bdadda0d9
diff --git a/aos/BUILD b/aos/BUILD
index ac5c3e9..47de872 100644
--- a/aos/BUILD
+++ b/aos/BUILD
@@ -475,6 +475,7 @@
"testdata/expected.json",
"testdata/expected_multinode.json",
"testdata/good_multinode.json",
+ "testdata/good_multinode_hostnames.json",
"testdata/invalid_destination_node.json",
"testdata/invalid_nodes.json",
"testdata/invalid_source_node.json",
diff --git a/aos/configuration.cc b/aos/configuration.cc
index 2d4b867..1ca28ad 100644
--- a/aos/configuration.cc
+++ b/aos/configuration.cc
@@ -362,7 +362,7 @@
// Check that if there is a node list, all the source nodes are filled out and
// valid, and all the destination nodes are valid (and not the source). This
// is a basic consistency check.
- if (result.message().has_nodes()) {
+ if (result.message().has_nodes() && config.message().has_channels()) {
for (const Channel *c : *config.message().channels()) {
CHECK(c->has_source_node()) << ": Channel " << FlatbufferToJson(c)
<< " is missing \"source_node\"";
@@ -597,9 +597,16 @@
const Node *GetNodeFromHostname(const Configuration *config,
std::string_view hostname) {
for (const Node *node : *config->nodes()) {
- if (node->hostname()->string_view() == hostname) {
+ if (node->has_hostname() && node->hostname()->string_view() == hostname) {
return node;
}
+ if (node->has_hostnames()) {
+ for (const auto &candidate : *node->hostnames()) {
+ if (candidate->string_view() == hostname) {
+ return node;
+ }
+ }
+ }
}
return nullptr;
}
diff --git a/aos/configuration.fbs b/aos/configuration.fbs
index 317c100..576616e 100644
--- a/aos/configuration.fbs
+++ b/aos/configuration.fbs
@@ -126,6 +126,12 @@
hostname:string;
// Port to serve forwarded data from.
port:ushort = 9971;
+
+ // An alternative to hostname which allows specifying multiple hostnames,
+ // any of which will match this node.
+ //
+ // Don't specify a hostname in multiple nodes in the same configuration.
+ hostnames:[string];
}
// Overall configuration datastructure for the pubsub.
diff --git a/aos/configuration_test.cc b/aos/configuration_test.cc
index 0c0874b..c36bd93 100644
--- a/aos/configuration_test.cc
+++ b/aos/configuration_test.cc
@@ -677,6 +677,46 @@
GetNodeOrDie(&config.message(), config2.message().nodes()->Get(0)));
}
+TEST_F(ConfigurationTest, GetNodeFromHostname) {
+ FlatbufferDetachedBuffer<Configuration> config =
+ ReadConfig("aos/testdata/good_multinode.json");
+ EXPECT_EQ("pi1",
+ CHECK_NOTNULL(GetNodeFromHostname(&config.message(), "raspberrypi"))
+ ->name()
+ ->string_view());
+ EXPECT_EQ("pi2", CHECK_NOTNULL(
+ GetNodeFromHostname(&config.message(), "raspberrypi2"))
+ ->name()
+ ->string_view());
+ EXPECT_EQ(nullptr, GetNodeFromHostname(&config.message(), "raspberrypi3"));
+ EXPECT_EQ(nullptr, GetNodeFromHostname(&config.message(), "localhost"));
+ EXPECT_EQ(nullptr, GetNodeFromHostname(&config.message(), "3"));
+}
+
+TEST_F(ConfigurationTest, GetNodeFromHostnames) {
+ FlatbufferDetachedBuffer<Configuration> config =
+ ReadConfig("aos/testdata/good_multinode_hostnames.json");
+ EXPECT_EQ("pi1",
+ CHECK_NOTNULL(GetNodeFromHostname(&config.message(), "raspberrypi"))
+ ->name()
+ ->string_view());
+ EXPECT_EQ("pi2", CHECK_NOTNULL(
+ GetNodeFromHostname(&config.message(), "raspberrypi2"))
+ ->name()
+ ->string_view());
+ EXPECT_EQ("pi2", CHECK_NOTNULL(
+ GetNodeFromHostname(&config.message(), "raspberrypi3"))
+ ->name()
+ ->string_view());
+ EXPECT_EQ("pi2", CHECK_NOTNULL(
+ GetNodeFromHostname(&config.message(), "other"))
+ ->name()
+ ->string_view());
+ EXPECT_EQ(nullptr, GetNodeFromHostname(&config.message(), "raspberrypi4"));
+ EXPECT_EQ(nullptr, GetNodeFromHostname(&config.message(), "localhost"));
+ EXPECT_EQ(nullptr, GetNodeFromHostname(&config.message(), "3"));
+}
+
} // namespace testing
} // namespace configuration
} // namespace aos
diff --git a/aos/testdata/good_multinode_hostnames.json b/aos/testdata/good_multinode_hostnames.json
new file mode 100644
index 0000000..b82f6f3
--- /dev/null
+++ b/aos/testdata/good_multinode_hostnames.json
@@ -0,0 +1,18 @@
+{
+ "nodes": [
+ {
+ "name": "pi1",
+ "hostnames": [
+ "raspberrypi"
+ ]
+ },
+ {
+ "name": "pi2",
+ "hostnames": [
+ "raspberrypi2",
+ "raspberrypi3",
+ "other"
+ ]
+ }
+ ]
+}