Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(299)

Side by Side Diff: milo/appengine/buildbot/build.go

Issue 2271453002: Milo: Internal buildbot masters support (Closed) Base URL: https://chromium.googlesource.com/external/github.com/luci/luci-go@master
Patch Set: More places Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The LUCI Authors. All rights reserved. 1 // Copyright 2016 The LUCI Authors. All rights reserved.
2 // Use of this source code is governed under the Apache License, Version 2.0 2 // Use of this source code is governed under the Apache License, Version 2.0
3 // that can be found in the LICENSE file. 3 // that can be found in the LICENSE file.
4 4
5 package buildbot 5 package buildbot
6 6
7 import ( 7 import (
8 "encoding/json" 8 "encoding/json"
9 "fmt" 9 "fmt"
10 "io/ioutil" 10 "io/ioutil"
11 "net/http" 11 "net/http"
12 "os"
13 "path/filepath" 12 "path/filepath"
14 "regexp" 13 "regexp"
15 "sort" 14 "sort"
16 "strconv" 15 "strconv"
17 "strings" 16 "strings"
18 "time" 17 "time"
19 18
20 "github.com/luci/gae/service/datastore" 19 "github.com/luci/gae/service/datastore"
21 "github.com/luci/gae/service/memcache"
22 log "github.com/luci/luci-go/common/logging" 20 log "github.com/luci/luci-go/common/logging"
23 "github.com/luci/luci-go/milo/api/resp" 21 "github.com/luci/luci-go/milo/api/resp"
24 » "github.com/luci/luci-go/server/auth" 22 » "github.com/luci/luci-go/milo/appengine/settings"
23 » "github.com/luci/luci-go/milo/common/miloerror"
25 "golang.org/x/net/context" 24 "golang.org/x/net/context"
26 ) 25 )
27 26
28 func getURL(c context.Context, URL string) ([]byte, error) { 27 var errBuildNotFound = miloerror.Error{
29 » fmt.Fprintf(os.Stderr, "Fetching %s\n", URL) 28 » Message: "Build not found",
30 » tr, err := auth.GetRPCTransport(c, auth.NoAuth) 29 » Code: http.StatusNotFound,
31 » if err != nil {
32 » » return nil, err
33 » }
34 » client := http.Client{Transport: tr}
35 » resp, err := client.Get(URL)
36 » if err != nil {
37 » » return nil, err
38 » }
39 » if resp.StatusCode != 200 {
40 » » return nil, fmt.Errorf("Failed to fetch %s, status code %d", URL , resp.StatusCode)
41 » }
42 » defer resp.Body.Close()
43 » return ioutil.ReadAll(resp.Body)
44 } 30 }
45 31
46 // getBuild fetches a build from BuildBot. 32 // getBuild fetches a build from BuildBot.
Vadim Sh. 2016/08/23 18:53:06 ... and checks ACL.
Ryan Tseng 2016/08/23 22:00:15 Done.
47 func getBuild(c context.Context, master, builder, buildNum string) (*buildbotBui ld, error) { 33 func getBuild(c context.Context, master, builder, buildNum string) (*buildbotBui ld, error) {
48 result := &buildbotBuild{ 34 result := &buildbotBuild{
49 Master: master, 35 Master: master,
50 Buildername: builder, 36 Buildername: builder,
51 } 37 }
52 if num, err := strconv.Atoi(buildNum); err != nil { 38 if num, err := strconv.Atoi(buildNum); err != nil {
53 panic(fmt.Errorf("%s does not look like a number", buildNum)) 39 panic(fmt.Errorf("%s does not look like a number", buildNum))
54 } else { 40 } else {
55 result.Number = num 41 result.Number = num
56 } 42 }
57 // Check memcache first.
58 mc := memcache.Get(c)
59 if item, err := mc.Get(result.getID()); err == nil {
60 log.Debugf(c, "Found in Memcache!")
61 json.Unmarshal(item.Value(), result)
62 return result, nil
63 }
64 // Then check local datastore.
65 ds := datastore.Get(c) 43 ds := datastore.Get(c)
66 err := ds.Get(result) 44 err := ds.Get(result)
67 » if err == nil { 45 » if err != nil {
68 » » log.Debugf(c, "Found build in local cache!") 46 » » return nil, errBuildNotFound
Vadim Sh. 2016/08/23 18:53:06 It is important to distinguish transient errors fr
Ryan Tseng 2016/08/23 22:00:14 Done.
69 » » if result.Times[1] != nil { 47 » }
70 » » » bs, ierr := json.Marshal(result) 48 » // If the build is internal, check to see if the user has access. We us e
71 » » » if ierr == nil { 49 » // the magic project name "buildbot-internal" for membership check.
72 » » » » item := mc.NewItem(result.getID()).SetValue(bs) 50 » if result.Internal {
73 » » » » mc.Set(item) 51 » » allowed, err := settings.IsAllowed(c, "buildbot-internal")
Vadim Sh. 2016/08/23 18:53:06 since we are hardcoding magic name anyway, perhaps
Ryan Tseng 2016/08/23 22:00:14 Done.
74 » » » } 52 » » if err != nil {
53 » » » log.WithError(err).Errorf(c,
54 » » » » "Encountered error while checking buildbot membe rship, returning 404")
55 » » » return nil, errBuildNotFound
Vadim Sh. 2016/08/23 18:53:06 same here, it should be HTTP 500, not HTTP 404.
Ryan Tseng 2016/08/23 22:00:15 Done.
75 } 56 }
76 » » return result, nil 57 » » if !allowed {
77 » } 58 » » » return nil, errBuildNotFound
78 » log.Debugf(c, "Could not find log in local cache: %s", err.Error()) 59 » » }
79 » // Now check CBE.
80 » cbeURL := fmt.Sprintf(
81 » » "https://chrome-build-extract.appspot.com/p/%s/builders/%s/build s/%s?json=1",
82 » » master, builder, buildNum)
83 » if buf, err := getURL(c, cbeURL); err == nil {
84 » » return result, json.Unmarshal(buf, result)
85 » }
86 » // TODO(hinoka): Cache finished builds.
87 » url := fmt.Sprintf(
88 » » "https://build.chromium.org/p/%s/json/builders/%s/builds/%s", ma ster, builder, buildNum)
89 » buf, err := getURL(c, url)
90 » if err != nil {
91 » » return nil, err
92 } 60 }
93 61
94 » return result, json.Unmarshal(buf, result) 62 » return result, nil
95 } 63 }
96 64
97 // result2Status translates a buildbot result integer into a resp.Status. 65 // result2Status translates a buildbot result integer into a resp.Status.
98 func result2Status(s *int) (status resp.Status) { 66 func result2Status(s *int) (status resp.Status) {
99 if s == nil { 67 if s == nil {
100 return resp.Running 68 return resp.Running
101 } 69 }
102 switch *s { 70 switch *s {
103 case 0: 71 case 0:
104 status = resp.Success 72 status = resp.Success
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
145 // getBanner fetches the banner information about the bot that the build 113 // getBanner fetches the banner information about the bot that the build
146 // ran on. This is best effort and: 114 // ran on. This is best effort and:
147 // * Will return an empty list of banners if the master is not found. 115 // * Will return an empty list of banners if the master is not found.
148 // * May return incorrect data if the platform of the slave of the same name 116 // * May return incorrect data if the platform of the slave of the same name
149 // was changed recently, and this build was older than before the slave 117 // was changed recently, and this build was older than before the slave
150 // changed platforms. 118 // changed platforms.
151 func getBanner(c context.Context, b *buildbotBuild, m *buildbotMaster) *resp.Log oBanner { 119 func getBanner(c context.Context, b *buildbotBuild, m *buildbotMaster) *resp.Log oBanner {
152 logos := &resp.LogoBanner{} 120 logos := &resp.LogoBanner{}
153 // Fetch the master info from datastore if not provided. 121 // Fetch the master info from datastore if not provided.
154 if m == nil { 122 if m == nil {
155 » » m1, i, _, err := getMasterJSON(c, b.Master) 123 » » m1, _, _, err := getMasterJSON(c, b.Master)
156 m = m1 124 m = m1
157 if i {
158 // TODO(hinoka): Support internal masters.
159 return nil
160 }
161 if err != nil { 125 if err != nil {
162 log.Warningf(c, "Failed to fetch master information for banners on master %s", b.Master) 126 log.Warningf(c, "Failed to fetch master information for banners on master %s", b.Master)
163 return nil 127 return nil
164 } 128 }
165 } 129 }
166 130
167 s, ok := m.Slaves[b.Slave] 131 s, ok := m.Slaves[b.Slave]
168 if !ok { 132 if !ok {
169 log.Warningf(c, "Could not find slave %s in master %s", b.Slave, b.Master) 133 log.Warningf(c, "Could not find slave %s in master %s", b.Slave, b.Master)
170 return nil 134 return nil
(...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after
510 474
511 // TODO(hinoka): Do all fields concurrently. 475 // TODO(hinoka): Do all fields concurrently.
512 return &resp.MiloBuild{ 476 return &resp.MiloBuild{
513 SourceStamp: sourcestamp(c, b), 477 SourceStamp: sourcestamp(c, b),
514 Summary: summary(c, b), 478 Summary: summary(c, b),
515 Components: components(b), 479 Components: components(b),
516 PropertyGroup: properties(b), 480 PropertyGroup: properties(b),
517 Blame: blame(b), 481 Blame: blame(b),
518 }, nil 482 }, nil
519 } 483 }
OLDNEW
« no previous file with comments | « no previous file | milo/appengine/buildbot/build_test.go » ('j') | milo/appengine/buildbot/builder.go » ('J')

Powered by Google App Engine
This is Rietveld 408576698