Adding publishing service (part 2)
Implementation Skeleton
BUG=None
TEST=None
Cq-Depend: chromium:3098708
Change-Id: Ic2b003bec8a7ebe5a682bce4a450d17d89e4f347
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/dev-util/+/3098519
Tested-by: Jaques Clapauch <jaquesc@google.com>
Auto-Submit: Jaques Clapauch <jaquesc@google.com>
Commit-Queue: Jaques Clapauch <jaquesc@google.com>
Reviewed-by: Andrew Lamb <andrewlamb@chromium.org>
diff --git a/src/chromiumos/test/publish/cmd/main.go b/src/chromiumos/test/publish/cmd/main.go
new file mode 100644
index 0000000..b5bb090
--- /dev/null
+++ b/src/chromiumos/test/publish/cmd/main.go
@@ -0,0 +1,78 @@
+// Copyright 2021 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package main
+
+import (
+ "flag"
+ "fmt"
+ "io"
+ "log"
+ "net"
+ "os"
+ "path/filepath"
+ "time"
+)
+
+// Version is the version info of this command. It is filled in during emerge.
+var Version = "<unknown>"
+
+// createLogFile creates a file and its parent directory for logging purpose.
+func createLogFile() (*os.File, error) {
+ t := time.Now()
+ fullPath := filepath.Join("/tmp/publishserver/", t.Format("20060102-150405"))
+ if err := os.MkdirAll(fullPath, 0755); err != nil {
+ return nil, fmt.Errorf("failed to create directory %v: %v", fullPath, err)
+ }
+
+ logFullPathName := filepath.Join(fullPath, "log.txt")
+
+ // Log the full output of the command to disk.
+ logFile, err := os.Create(logFullPathName)
+ if err != nil {
+ return nil, fmt.Errorf("failed to create file %v: %v", fullPath, err)
+ }
+ return logFile, nil
+}
+
+// newLogger creates a logger. Using go default logger for now.
+func newLogger(logFile *os.File) *log.Logger {
+ mw := io.MultiWriter(logFile, os.Stderr)
+ return log.New(mw, "", log.LstdFlags|log.LUTC)
+}
+
+func main() {
+ os.Exit(func() int {
+ flag.NewFlagSet("version", flag.ExitOnError)
+ flag.Parse()
+
+ if os.Args[1] == "version" {
+ fmt.Println("publishservice version ", Version)
+ return 0
+ }
+
+ logFile, err := createLogFile()
+ if err != nil {
+ log.Fatalln("Failed to create log file: ", err)
+ }
+ defer logFile.Close()
+
+ logger := newLogger(logFile)
+ logger.Println("Starting publishservice version ", Version)
+ l, err := net.Listen("tcp", ":0")
+ if err != nil {
+ logger.Fatalln("Failed to create a net listener: ", err)
+ return 2
+ }
+
+ server, destructor := newPublishServiceServer(l, logger)
+ defer destructor()
+
+ err = server.Serve(l)
+ if err != nil {
+ logger.Fatalln("Failed to initialize server: ", err)
+ }
+ return 0
+ }())
+}
diff --git a/src/chromiumos/test/publish/cmd/publishserver.go b/src/chromiumos/test/publish/cmd/publishserver.go
new file mode 100644
index 0000000..33f5e53
--- /dev/null
+++ b/src/chromiumos/test/publish/cmd/publishserver.go
@@ -0,0 +1,52 @@
+// Copyright 2021 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Implements publish_service.proto (see proto for details)
+package main
+
+import (
+ "chromiumos/lro"
+ "context"
+ "log"
+ "net"
+
+ "go.chromium.org/chromiumos/config/go/longrunning"
+ "go.chromium.org/chromiumos/config/go/test/api"
+ "google.golang.org/grpc"
+)
+
+// PublishServiceServer implementation of publish_service.proto
+type PublishServiceServer struct {
+ manager *lro.Manager
+ logger *log.Logger
+}
+
+// newPublishServiceServer creates a new publish service server to listen to rpc requests.
+func newPublishServiceServer(l net.Listener, logger *log.Logger) (*grpc.Server, func()) {
+ s := &PublishServiceServer{
+ manager: lro.New(),
+ logger: logger,
+ }
+
+ server := grpc.NewServer()
+ destructor := func() {
+ s.manager.Close()
+ }
+
+ api.RegisterPublishServiceServer(server, s)
+ logger.Println("publishservice listen to request at ", l.Addr().String())
+ return server, destructor
+}
+
+// UploadToGS uploads the designated folder to the provided Google Cloud Storage
+// bucket/object
+//
+// TODO(jaquesc): Implement this
+func (s *PublishServiceServer) UploadToGS(ctx context.Context, req *api.UploadToGSRequest) (*longrunning.Operation, error) {
+ s.logger.Println("Received api.UploadToGSRequest: ", *req)
+ s.logger.Println("TODO(jaquesc): Implement")
+ op := s.manager.NewOperation()
+ s.manager.SetResult(op.Name, &api.UploadToGSResponse{})
+ return op, nil
+}