diff --git a/corefx/src/main/java/com/core/client/grpc/CoreGrpcClient.java b/corefx/src/main/java/com/core/client/grpc/CoreGrpcClient.java index 4c062483..bc9098b3 100644 --- a/corefx/src/main/java/com/core/client/grpc/CoreGrpcClient.java +++ b/corefx/src/main/java/com/core/client/grpc/CoreGrpcClient.java @@ -955,8 +955,15 @@ public class CoreGrpcClient implements ICoreClient { @Override public String getTerminalCommand(CoreNode node) throws IOException { - // TODO: convert - return null; + CoreProto.GetNodeTerminalRequest request = CoreProto.GetNodeTerminalRequest.newBuilder() + .setSessionId(sessionId) + .setNodeId(node.getId()) + .build(); + try { + return blockingStub.getNodeTerminal(request).getTerminal(); + } catch (StatusRuntimeException ex) { + throw new IOException(ex); + } } @Override diff --git a/daemon/core/grpc/client.py b/daemon/core/grpc/client.py index 53b0538e..e61cc9a5 100644 --- a/daemon/core/grpc/client.py +++ b/daemon/core/grpc/client.py @@ -353,6 +353,19 @@ class CoreGrpcClient(object): request = core_pb2.NodeCommandRequest(session_id=session_id, node_id=node_id, command=command) return self.stub.NodeCommand(request) + def get_node_terminal(self, session_id, node_id): + """ + Retrieve terminal command string for launching a local terminal. + + :param int session_id: session id + :param int node_id: node id + :return: response with a node terminal command + :rtype: core_pb2.GetNodeTerminalResponse + :raises grpc.RpcError: when session or node doesn't exist + """ + request = core_pb2.GetNodeTerminalRequest(session_id=session_id, node_id=node_id) + return self.stub.GetNodeTerminal(request) + def get_node_links(self, session_id, node_id): """ Get current links for a node. diff --git a/daemon/core/grpc/server.py b/daemon/core/grpc/server.py index aedac46d..3e2215cf 100644 --- a/daemon/core/grpc/server.py +++ b/daemon/core/grpc/server.py @@ -454,10 +454,13 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer): interface_throughput.interface_id = interface_id interface_throughput.throughput = throughput elif key.startswith("b."): - node_id = int(key.split(".")[1]) - bridge_throughput = throughputs_event.bridge_throughputs.add() - bridge_throughput.node_id = node_id - bridge_throughput.throughput = throughput + try: + node_id = int(key.split(".")[1]) + bridge_throughput = throughputs_event.bridge_throughputs.add() + bridge_throughput.node_id = node_id + bridge_throughput.throughput = throughput + except ValueError: + pass yield throughputs_event @@ -549,6 +552,13 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer): _, output = node.cmd_output(request.command) return core_pb2.NodeCommandResponse(output=output) + def GetNodeTerminal(self, request, context): + logging.debug("getting node terminal: %s", request) + session = self.get_session(request.session_id, context) + node = self.get_node(session, request.node_id, context) + terminal = node.termcmdstring("/bin/bash") + return core_pb2.GetNodeTerminalResponse(terminal=terminal) + def GetNodeLinks(self, request, context): logging.debug("get node links: %s", request) session = self.get_session(request.session_id, context) diff --git a/daemon/proto/core.proto b/daemon/proto/core.proto index 9b84f19a..013135f2 100644 --- a/daemon/proto/core.proto +++ b/daemon/proto/core.proto @@ -43,6 +43,8 @@ service CoreApi { } rpc NodeCommand (NodeCommandRequest) returns (NodeCommandResponse) { } + rpc GetNodeTerminal (GetNodeTerminalRequest) returns (GetNodeTerminalResponse) { + } // link rpc rpc GetNodeLinks (GetNodeLinksRequest) returns (GetNodeLinksResponse) { @@ -323,6 +325,15 @@ message DeleteNodeResponse { bool result = 1; } +message GetNodeTerminalRequest { + int32 session_id = 1; + int32 node_id = 2; +} + +message GetNodeTerminalResponse { + string terminal = 1; +} + message NodeCommandRequest { int32 session_id = 1; int32 node_id = 2; diff --git a/daemon/tests/test_grpc.py b/daemon/tests/test_grpc.py index 13136931..948cfd54 100644 --- a/daemon/tests/test_grpc.py +++ b/daemon/tests/test_grpc.py @@ -257,6 +257,22 @@ class TestGrpc: # then assert response.output == output + def test_get_node_terminal(self, grpc_server): + # given + client = CoreGrpcClient() + session = grpc_server.coreemu.create_session() + session.set_state(EventTypes.CONFIGURATION_STATE) + node_options = NodeOptions(model="Host") + node = session.add_node(node_options=node_options) + session.instantiate() + + # then + with client.context_connect(): + response = client.get_node_terminal(session.id, node.objid) + + # then + assert response.terminal is not None + def test_get_hooks(self, grpc_server): # given client = CoreGrpcClient()