[System Monitor] Add grpc to harvester and dockyard_host
This CL adds a dockyard_host test application and demonstrates a round-trip
communication between the host and fuchsia device over grpc.
Test: see bin/system_monitor/dockyard_host/README.md
Change-Id: I165bda8da3d21f39f64090b2424916f7d5764a72
diff --git a/bin/system_monitor/dockyard_host/BUILD.gn b/bin/system_monitor/dockyard_host/BUILD.gn
new file mode 100644
index 0000000..c19b4ac
--- /dev/null
+++ b/bin/system_monitor/dockyard_host/BUILD.gn
@@ -0,0 +1,27 @@
+# Copyright 2019 The Fuchsia Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//build/host.gni")
+
+if (current_toolchain == host_toolchain) {
+executable("dockyard_host") {
+ sources = [
+ "dockyard_host.cc",
+ ]
+
+ deps = [
+ "//third_party/grpc:grpc++",
+ "//garnet/lib/system_monitor/dockyard:lib",
+ ]
+}
+}
+
+install_host_tools("host_tools") {
+ deps = [
+ ":dockyard_host",
+ ]
+ outputs = [
+ "dockyard_host",
+ ]
+}
diff --git a/bin/system_monitor/dockyard_host/README.md b/bin/system_monitor/dockyard_host/README.md
new file mode 100644
index 0000000..a31a4fa
--- /dev/null
+++ b/bin/system_monitor/dockyard_host/README.md
@@ -0,0 +1,32 @@
+# Dockyard Host
+
+The `dockyard_host` is a host (developer machine) server that runs the Fuchsia
+System Monitor Dockyard without a GUI. The initial development is primarily for
+testing, though this could evolve into an independent host Dockyard.
+
+To be effective, a dockyard needs a connection to a running harvester. The
+harvester will transmit sample data to the dockyard for storage.
+
+## To test
+
+In one terminal window run
+```
+$ out/x64/host_x64/dockyard_host
+Starting dockyard host
+Server listening on 0.0.0.0:50051
+```
+
+In a second terminal window run
+```
+$ killall -r qemu-; fx run -N -u $FUCHSIA_DIR/scripts/start-dhcp-server.sh
+<there will be a lot of output, after it calms down>
+$ system_monitor_harvester 192.168.3.53:50051
+harvester received: Hello world
+```
+If the harvester is not able to connect to the dockyard_host, try using your
+host's local IP instead of 192.168.3.53 (see `ifconfig` for your IP addresses).
+
+The message `Hello world` means that a connection and round-trip communication
+was done (which all the dockyard_host and harvester do so far).
+
+See also: ../README.md
diff --git a/bin/system_monitor/dockyard_host/dockyard_host.cc b/bin/system_monitor/dockyard_host/dockyard_host.cc
new file mode 100644
index 0000000..592c6e1
--- /dev/null
+++ b/bin/system_monitor/dockyard_host/dockyard_host.cc
@@ -0,0 +1,59 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <iostream>
+#include <memory>
+#include <string>
+
+#include <grpc++/grpc++.h>
+
+#include "garnet/lib/system_monitor/protos/dockyard.grpc.pb.h"
+
+using dockyard::Greeter;
+using dockyard::HelloReply;
+using dockyard::HelloRequest;
+using grpc::Server;
+using grpc::ServerBuilder;
+using grpc::ServerContext;
+using grpc::Status;
+
+constexpr char DEFAULT_SERVER_ADDRESS[] = "0.0.0.0:50051";
+
+// Logic and data behind the server's behavior.
+class DockyardServiceImpl final : public Greeter::Service {
+ Status SayHello(ServerContext* context, const HelloRequest* request,
+ HelloReply* reply) override {
+ std::string prefix("Hello ");
+ reply->set_message(prefix + request->name());
+ return Status::OK;
+ }
+};
+
+// Listen for Harvester connections from the Fuchsia device.
+void RunGrpcServer(const char* listen_at) {
+ // This is an arbitrary default port.
+ std::string server_address(listen_at);
+ DockyardServiceImpl service;
+
+ ServerBuilder builder;
+ // Listen on the given address without any authentication mechanism.
+ builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());
+ // Register "service" as the instance through which we'll communicate with
+ // clients. In this case it corresponds to a *synchronous* service.
+ builder.RegisterService(&service);
+ // Finally assemble the server.
+ std::unique_ptr<Server> server(builder.BuildAndStart());
+ std::cout << "Server listening on " << server_address << std::endl;
+
+ // Wait for the server to shutdown. Note that some other thread must be
+ // responsible for shutting down the server for this call to ever return.
+ server->Wait();
+}
+
+int main(int argc, char** argv) {
+ std::cout << "Starting dockyard host" << std::endl;
+ RunGrpcServer(DEFAULT_SERVER_ADDRESS);
+
+ return 0;
+}
diff --git a/bin/system_monitor/harvester/BUILD.gn b/bin/system_monitor/harvester/BUILD.gn
index 70845d0..874e92f 100644
--- a/bin/system_monitor/harvester/BUILD.gn
+++ b/bin/system_monitor/harvester/BUILD.gn
@@ -12,6 +12,9 @@
]
deps = [
+ "//third_party/grpc:grpc++",
+ "//garnet/lib/system_monitor/dockyard:protos",
+ "//garnet/lib/system_monitor/dockyard:lib",
]
}
diff --git a/bin/system_monitor/harvester/README.md b/bin/system_monitor/harvester/README.md
index da4b8f5..699ed51b 100644
--- a/bin/system_monitor/harvester/README.md
+++ b/bin/system_monitor/harvester/README.md
@@ -6,3 +6,11 @@
The Harvester should not unduly impact the Fuchsia device being monitored.
So the Harvester does not store samples. Instead the samples are moved to
the Dockyard as soon as reasonable.
+
+## qemu
+
+On the host, run
+$ fx run -N -u $FUCHSIA_DIR/scripts/start-dhcp-server.sh
+
+Tip: If you're doing edit-compile-run development, you might prefer this:
+$ killall -r qemu-; fx build && fx run -N -u $FUCHSIA_DIR/scripts/start-dhcp-server.sh
diff --git a/bin/system_monitor/harvester/harvester.cc b/bin/system_monitor/harvester/harvester.cc
index 1bbb3e1..21fc171 100644
--- a/bin/system_monitor/harvester/harvester.cc
+++ b/bin/system_monitor/harvester/harvester.cc
@@ -2,17 +2,77 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include <stdio.h>
-
/*
Hey, so there's not a whole lot here. That's because this is a work in
progress. Starting from something like a hello world program, this will
progress into a System Monitor for Fuchsia.
+ The code below is largely straight out of the grpc hello world example.
+
See also: ./README.md
*/
+#include <iostream>
+#include <memory>
+#include <string>
+
+#include <grpc++/grpc++.h>
+
+#include "garnet/lib/system_monitor/protos/dockyard.grpc.pb.h"
+
+using dockyard::Greeter;
+using dockyard::HelloReply;
+using dockyard::HelloRequest;
+using grpc::Channel;
+using grpc::ClientContext;
+using grpc::Status;
+
+class Harvester {
+ public:
+ Harvester(std::shared_ptr<Channel> channel)
+ : stub_(Greeter::NewStub(channel)) {}
+
+ std::string SayHello(const std::string& user) {
+ // Data we are sending to the server.
+ HelloRequest request;
+ request.set_name(user);
+
+ // Container for the data we expect from the server.
+ HelloReply reply;
+
+ // Context for the client. It could be used to convey extra information to
+ // the server and/or tweak certain RPC behaviors.
+ ClientContext context;
+
+ // The actual RPC.
+ Status status = stub_->SayHello(&context, request, &reply);
+ if (status.ok()) {
+ return reply.message();
+ } else {
+ std::cout << status.error_code() << ": " << status.error_message()
+ << std::endl;
+ return "Unable to send to dockyard.";
+ }
+ }
+
+ private:
+ std::unique_ptr<Greeter::Stub> stub_;
+};
+
int main(int argc, char** argv) {
- printf("System Monitor Harvester - wip\n");
+ printf("System Monitor Harvester - wip 5\n");
+ if (argc < 2) {
+ std::cout << "Please specify an IP:Port, such as localhost:50051"
+ << std::endl;
+ exit(1);
+ }
+ // TODO(dschuyler): This channel isn't authenticated
+ // (InsecureChannelCredentials()).
+ Harvester harvester(
+ grpc::CreateChannel(argv[1], grpc::InsecureChannelCredentials()));
+ std::string user("world");
+ std::string reply = harvester.SayHello(user);
+ std::cout << "harvester received: " << reply << std::endl;
+
return 0;
-}
\ No newline at end of file
+}
diff --git a/lib/system_monitor/dockyard/BUILD.gn b/lib/system_monitor/dockyard/BUILD.gn
index 85020c0..67b5899 100644
--- a/lib/system_monitor/dockyard/BUILD.gn
+++ b/lib/system_monitor/dockyard/BUILD.gn
@@ -2,13 +2,36 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-source_set("system_monitor_dockyard") {
+import("//third_party/protobuf/proto_library.gni")
+
+source_set("lib") {
sources = [
"dockyard.cc",
"dockyard.h",
"test_sample_generator.cc",
"test_sample_generator.h",
]
+ public_deps = [
+ ":protos",
+ ]
+}
+
+proto_library("protos") {
+ sources = [
+ "../protos/dockyard.proto",
+ ]
+
+ generate_python = false
+ cc_generator_options = "lite"
+ generator_plugin_suffix = ".grpc.pb"
+ generator_plugin_label = "//third_party/grpc:grpc_cpp_plugin"
+
+ import_dirs = [
+ #"//garnet/lib/system_monitor/protos",
+ ]
+ deps = [
+ "//third_party/grpc:grpc++",
+ ]
}
source_set("tests") {
@@ -19,7 +42,7 @@
]
deps = [
- ":system_monitor_dockyard",
+ ":lib",
"//third_party/googletest:gtest",
]
}
diff --git a/lib/system_monitor/protos/dockyard.proto b/lib/system_monitor/protos/dockyard.proto
new file mode 100644
index 0000000..00385a4
--- /dev/null
+++ b/lib/system_monitor/protos/dockyard.proto
@@ -0,0 +1,28 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+syntax = "proto3";
+
+option java_multiple_files = true;
+option java_package = "io.grpc.system_monitor.dockyard";
+option java_outer_classname = "DockyardProto";
+option objc_class_prefix = "HLW";
+
+package dockyard;
+
+// The greeting service definition.
+service Greeter {
+ // Sends a greeting
+ rpc SayHello (HelloRequest) returns (HelloReply) {}
+}
+
+// The request message containing the user's name.
+message HelloRequest {
+ string name = 1;
+}
+
+// The response message containing the greetings
+message HelloReply {
+ string message = 1;
+}
diff --git a/packages/products/devtools b/packages/products/devtools
index a656e84..1117440 100644
--- a/packages/products/devtools
+++ b/packages/products/devtools
@@ -10,6 +10,7 @@
"garnet/packages/prod/ssh",
"garnet/packages/prod/tracing",
"garnet/packages/products/base",
+ "garnet/packages/tools/dockyard_host",
"garnet/packages/tools/zxdb"
]
}
diff --git a/packages/tools/all b/packages/tools/all
index a2720d7..a2e0cdd 100644
--- a/packages/tools/all
+++ b/packages/tools/all
@@ -3,6 +3,7 @@
"garnet/packages/tools/audio",
"garnet/packages/tools/bluetooth",
"garnet/packages/tools/curl",
+ "garnet/packages/tools/dockyard_host",
"garnet/packages/tools/fidlmerge",
"garnet/packages/tools/iperf",
"garnet/packages/tools/make-efi",
diff --git a/packages/tools/dockyard_host b/packages/tools/dockyard_host
new file mode 100644
index 0000000..19383a6
--- /dev/null
+++ b/packages/tools/dockyard_host
@@ -0,0 +1,5 @@
+{
+ "labels": [
+ "//garnet/bin/system_monitor/dockyard_host:host_tools"
+ ]
+}