Index: milo/appengine/job_source/buildbot/grpc.go |
diff --git a/milo/appengine/job_source/buildbot/grpc.go b/milo/appengine/job_source/buildbot/grpc.go |
deleted file mode 100644 |
index 6523262ae326b1a921ff674364f60b7605563ff3..0000000000000000000000000000000000000000 |
--- a/milo/appengine/job_source/buildbot/grpc.go |
+++ /dev/null |
@@ -1,233 +0,0 @@ |
-// Copyright 2016 The LUCI Authors. All rights reserved. |
-// Use of this source code is governed under the Apache License, Version 2.0 |
-// that can be found in the LICENSE file. |
- |
-package buildbot |
- |
-import ( |
- "bytes" |
- "compress/gzip" |
- "encoding/json" |
- |
- "golang.org/x/net/context" |
- "google.golang.org/grpc" |
- "google.golang.org/grpc/codes" |
- |
- "github.com/golang/protobuf/ptypes/timestamp" |
- "github.com/luci/gae/service/datastore" |
- "github.com/luci/luci-go/common/iotools" |
- "github.com/luci/luci-go/common/logging" |
- milo "github.com/luci/luci-go/milo/api/proto" |
- "github.com/luci/luci-go/server/auth" |
-) |
- |
-// Service is a service implementation that displays BuildBot builds. |
-type Service struct{} |
- |
-var errNotFoundGRPC = grpc.Errorf(codes.NotFound, "Master Not Found") |
- |
-// GetBuildbotBuildJSON implements milo.BuildbotServer. |
-func (s *Service) GetBuildbotBuildJSON(c context.Context, req *milo.BuildbotBuildRequest) ( |
- *milo.BuildbotBuildJSON, error) { |
- |
- if req.Master == "" { |
- return nil, grpc.Errorf(codes.InvalidArgument, "No master specified") |
- } |
- if req.Builder == "" { |
- return nil, grpc.Errorf(codes.InvalidArgument, "No builder specified") |
- } |
- |
- cu := auth.CurrentUser(c) |
- logging.Debugf(c, "%s is requesting %s/%s/%d", |
- cu.Identity, req.Master, req.Builder, req.BuildNum) |
- |
- b, err := getBuild(c, req.Master, req.Builder, int(req.BuildNum)) |
- switch { |
- case err == errBuildNotFound: |
- return nil, grpc.Errorf(codes.NotFound, "Build not found") |
- case err == errNotAuth: |
- return nil, grpc.Errorf(codes.Unauthenticated, "Unauthenticated request") |
- case err != nil: |
- return nil, err |
- } |
- |
- updatePostProcessBuild(b) |
- bs, err := json.Marshal(b) |
- if err != nil { |
- return nil, err |
- } |
- |
- // Marshal the build back into JSON format. |
- return &milo.BuildbotBuildJSON{Data: bs}, nil |
-} |
- |
-// GetBuildbotBuildsJSON implements milo.BuildbotServer. |
-func (s *Service) GetBuildbotBuildsJSON(c context.Context, req *milo.BuildbotBuildsRequest) ( |
- *milo.BuildbotBuildsJSON, error) { |
- |
- if req.Master == "" { |
- return nil, grpc.Errorf(codes.InvalidArgument, "No master specified") |
- } |
- if req.Builder == "" { |
- return nil, grpc.Errorf(codes.InvalidArgument, "No builder specified") |
- } |
- |
- limit := req.Limit |
- if limit == 0 { |
- limit = 20 |
- } |
- |
- cu := auth.CurrentUser(c) |
- logging.Debugf(c, "%s is requesting %s/%s (limit %d, cursor %s)", |
- cu.Identity, req.Master, req.Builder, limit, req.Cursor) |
- |
- // Perform an ACL check by fetching the master. |
- _, err := getMasterEntry(c, req.Master) |
- switch { |
- case err == errMasterNotFound: |
- return nil, grpc.Errorf(codes.NotFound, "Master not found") |
- case err == errNotAuth: |
- return nil, grpc.Errorf(codes.Unauthenticated, "Unauthenticated request") |
- case err != nil: |
- return nil, err |
- } |
- |
- q := datastore.NewQuery("buildbotBuild") |
- q = q.Eq("master", req.Master). |
- Eq("builder", req.Builder). |
- Limit(limit). |
- Order("-number") |
- if req.IncludeCurrent == false { |
- q = q.Eq("finished", true) |
- } |
- // Insert the cursor or offset. |
- if req.Cursor != "" { |
- cursor, err := datastore.DecodeCursor(c, req.Cursor) |
- if err != nil { |
- return nil, grpc.Errorf(codes.InvalidArgument, "Invalid cursor: %s", err.Error()) |
- } |
- q = q.Start(cursor) |
- } |
- builds, nextCursor, err := runBuildsQuery(c, q, int32(req.Limit)) |
- if err != nil { |
- return nil, err |
- } |
- |
- results := make([]*milo.BuildbotBuildJSON, len(builds)) |
- for i, b := range builds { |
- updatePostProcessBuild(b) |
- |
- // In theory we could do this in parallel, but it doesn't actually go faster |
- // since AppEngine is single-cored. |
- bs, err := json.Marshal(b) |
- if err != nil { |
- return nil, err |
- } |
- results[i] = &milo.BuildbotBuildJSON{Data: bs} |
- } |
- buildsJSON := &milo.BuildbotBuildsJSON{ |
- Builds: results, |
- } |
- if nextCursor != nil { |
- buildsJSON.Cursor = (*nextCursor).String() |
- } |
- return buildsJSON, nil |
-} |
- |
-// GetCompressedMasterJSON assembles a CompressedMasterJSON object from the |
-// provided MasterRequest. |
-func (s *Service) GetCompressedMasterJSON(c context.Context, req *milo.MasterRequest) ( |
- *milo.CompressedMasterJSON, error) { |
- |
- if req.Name == "" { |
- return nil, grpc.Errorf(codes.InvalidArgument, "No master specified") |
- } |
- |
- cu := auth.CurrentUser(c) |
- logging.Debugf(c, "%s is making a master request for %s", cu.Identity, req.Name) |
- |
- entry, err := getMasterEntry(c, req.Name) |
- switch { |
- case err == errMasterNotFound: |
- return nil, errNotFoundGRPC |
- case err == errNotAuth: |
- return nil, grpc.Errorf(codes.Unauthenticated, "Unauthenticated request") |
- case err != nil: |
- return nil, err |
- } |
- // Decompress it so we can inject current build information. |
- master := &buildbotMaster{} |
- if err = decodeMasterEntry(c, entry, master); err != nil { |
- return nil, err |
- } |
- for _, slave := range master.Slaves { |
- numBuilds := 0 |
- for _, builds := range slave.RunningbuildsMap { |
- numBuilds += len(builds) |
- } |
- slave.Runningbuilds = make([]*buildbotBuild, 0, numBuilds) |
- for builderName, builds := range slave.RunningbuildsMap { |
- for _, buildNum := range builds { |
- slave.Runningbuilds = append(slave.Runningbuilds, &buildbotBuild{ |
- Master: req.Name, |
- Buildername: builderName, |
- Number: buildNum, |
- }) |
- } |
- } |
- if err := datastore.Get(c, slave.Runningbuilds); err != nil { |
- logging.WithError(err).Errorf(c, |
- "Encountered error while trying to fetch running builds for %s: %v", |
- master.Name, slave.Runningbuilds) |
- return nil, err |
- } |
- |
- for _, b := range slave.Runningbuilds { |
- updatePostProcessBuild(b) |
- } |
- } |
- |
- // Also inject cached builds information. |
- for builderName, builder := range master.Builders { |
- // Get the most recent 50 buildNums on the builder to simulate what the |
- // cachedBuilds field looks like from the real buildbot master json. |
- q := datastore.NewQuery("buildbotBuild"). |
- Eq("finished", true). |
- Eq("master", req.Name). |
- Eq("builder", builderName). |
- Limit(50). |
- Order("-number"). |
- KeysOnly(true) |
- var builds []*buildbotBuild |
- err := getBuildQueryBatcher(c).GetAll(c, q, &builds) |
- if err != nil { |
- return nil, err |
- } |
- builder.CachedBuilds = make([]int, len(builds)) |
- for i, b := range builds { |
- builder.CachedBuilds[i] = b.Number |
- } |
- } |
- |
- // And re-compress it. |
- gzbs := bytes.Buffer{} |
- gsw := gzip.NewWriter(&gzbs) |
- cw := iotools.CountingWriter{Writer: gsw} |
- e := json.NewEncoder(&cw) |
- if err := e.Encode(master); err != nil { |
- gsw.Close() |
- return nil, err |
- } |
- gsw.Close() |
- |
- logging.Infof(c, "Returning %d bytes", cw.Count) |
- |
- return &milo.CompressedMasterJSON{ |
- Internal: entry.Internal, |
- Modified: ×tamp.Timestamp{ |
- Seconds: entry.Modified.Unix(), |
- Nanos: int32(entry.Modified.Nanosecond()), |
- }, |
- Data: gzbs.Bytes(), |
- }, nil |
-} |