1 // Copyright 2019 The Pigweed Authors
3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 // use this file except in compliance with the License. You may obtain a copy of
7 // https://www.apache.org/licenses/LICENSE-2.0
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 // License for the specific language governing permissions and limitations under
25 "google.golang.org/grpc"
26 "google.golang.org/grpc/codes"
27 "google.golang.org/grpc/status"
29 pb "pigweed.dev/proto/pw_target_runner/target_runner_pb"
32 // Client is a gRPC client that communicates with a TargetRunner service.
37 // NewClient creates a gRPC client which connects to a gRPC server hosted at the
39 func NewClient(host string, port int) (*Client, error) {
40 // The server currently only supports running locally over an insecure
42 // TODO(frolv): Investigate adding TLS support to the server and client.
43 opts := []grpc.DialOption{grpc.WithInsecure()}
45 conn, err := grpc.Dial(fmt.Sprintf("%s:%d", host, port), opts...)
50 return &Client{conn}, nil
53 // RunBinary sends a RunBinary RPC to the target runner service.
54 func (c *Client) RunBinary(path string) error {
55 abspath, err := filepath.Abs(path)
60 client := pb.NewTargetRunnerClient(c.conn)
61 req := &pb.RunBinaryRequest{FilePath: abspath}
63 res, err := client.RunBinary(context.Background(), req)
68 fmt.Printf("%s\n", path)
70 "Queued for %v, ran in %v\n\n",
71 time.Duration(res.QueueTimeNs),
72 time.Duration(res.RunTimeNs),
74 fmt.Println(string(res.Output))
76 if res.Result != pb.RunStatus_SUCCESS {
77 return errors.New("Binary run was unsuccessful")
84 hostPtr := flag.String("host", "localhost", "Server host")
85 portPtr := flag.Int("port", 8080, "Server port")
86 pathPtr := flag.String("binary", "", "Path to executable file")
91 log.Fatalf("Must provide -binary option")
94 cli, err := NewClient(*hostPtr, *portPtr)
96 log.Fatalf("Failed to create gRPC client: %v", err)
99 if err := cli.RunBinary(*pathPtr); err != nil {
100 log.Println("Failed to run executable on target:")
103 s, _ := status.FromError(err)
104 if s.Code() == codes.Unavailable {
105 log.Println(" No pw_target_runner_server is running.")
106 log.Println(" Check that a server has been started for your target.")
108 log.Printf(" %v\n", err)