// Copyright 2019 The Pigweed Authors // // Licensed under the Apache License, Version 2.0 (the "License"); you may not // use this file except in compliance with the License. You may obtain a copy of // the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the // License for the specific language governing permissions and limitations under // the License. package main import ( "errors" "flag" "fmt" "io/ioutil" "log" "google.golang.org/protobuf/encoding/prototext" "pigweed/pw_target_runner" pb "pigweed/proto/pw_target_runner/exec_server_config_pb" ) // ServerOptions contains command-line options for the server. type ServerOptions struct { // Path to a server configuration file. config string // Port on which to run. port int } // configureServerFromFile sets up the server with workers specified in a // config file. The file contains a pw.target_runner.ServerConfig protobuf // message in canonical protobuf text format. func configureServerFromFile(s *pw_target_runner.Server, filepath string) error { content, err := ioutil.ReadFile(filepath) if err != nil { return err } var config pb.ServerConfig if err := prototext.Unmarshal(content, &config); err != nil { return err } log.Printf("Parsed server configuration from %s\n", filepath) runners := config.GetRunner() if runners == nil { return nil } // Create an exec worker for each of the runner messages listed in the // config and register them with the server. for i, runner := range runners { // Build the complete command for the worker from its "command" // and "args" fields in the proto message. The command is // required; arguments are optional. cmd := []string{runner.GetCommand()} if cmd[0] == "" { msg := fmt.Sprintf( "ServerConfig.runner[%d] does not specify a command; skipping\n", i) return errors.New(msg) } if args := runner.GetArgs(); args != nil { cmd = append(cmd, args...) } worker := pw_target_runner.NewExecDeviceRunner(i, cmd) s.RegisterWorker(worker) log.Printf( "Registered ExecDeviceRunner %s with args %v\n", cmd[0], cmd[1:]) } return nil } func main() { configPtr := flag.String("config", "", "Path to server configuration file") portPtr := flag.Int("port", 8080, "Server port") flag.Parse() server := pw_target_runner.NewServer() if *configPtr != "" { if err := configureServerFromFile(server, *configPtr); err != nil { log.Fatalf("Failed to parse config file %s: %v", *configPtr, err) } } if err := server.Bind(*portPtr); err != nil { log.Fatal(err) } if err := server.Serve(); err != nil { log.Fatalf("Failed to start server: %v", err) } }