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

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

Issue 2271453002: Milo: Internal buildbot masters support (Closed) Base URL: https://chromium.googlesource.com/external/github.com/luci/luci-go@master
Patch Set: nit fix 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
« no previous file with comments | « milo/appengine/buildbot/build_test.go ('k') | milo/appengine/buildbot/master.go » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 "net/http"
10 "os" 11 "os"
11 "sort" 12 "sort"
12 "strings" 13 "strings"
13 "time" 14 "time"
14 15
15 "github.com/luci/gae/service/datastore" 16 "github.com/luci/gae/service/datastore"
16 17
17 "github.com/luci/luci-go/common/clock" 18 "github.com/luci/luci-go/common/clock"
18 » log "github.com/luci/luci-go/common/logging" 19 » "github.com/luci/luci-go/common/logging"
19 "github.com/luci/luci-go/milo/api/resp" 20 "github.com/luci/luci-go/milo/api/resp"
21 "github.com/luci/luci-go/milo/appengine/settings"
22 "github.com/luci/luci-go/milo/common/miloerror"
20 "golang.org/x/net/context" 23 "golang.org/x/net/context"
21 ) 24 )
22 25
23 // builderRef is used for keying specific builds in a master json. 26 // builderRef is used for keying specific builds in a master json.
24 type builderRef struct { 27 type builderRef struct {
25 builder string 28 builder string
26 buildNum int 29 buildNum int
27 } 30 }
28 31
29 // buildMap contains all of the current build within a master json. We use this 32 // buildMap contains all of the current build within a master json. We use this
(...skipping 25 matching lines...) Expand all
55 Started: started, 58 Started: started,
56 Finished: finished, 59 Finished: finished,
57 Duration: duration, 60 Duration: duration,
58 }, 61 },
59 Text: b.Text, 62 Text: b.Text,
60 Blame: blame(b), 63 Blame: blame(b),
61 Revision: b.Sourcestamp.Revision, 64 Revision: b.Sourcestamp.Revision,
62 } 65 }
63 } 66 }
64 67
65 // getBuilds fetches all of the recent builds from the datastore. 68 // getBuilds fetches all of the recent builds from the datastore. Note that
69 // getBuilds() does not perform ACL checks.
66 func getBuilds(c context.Context, masterName, builderName string, finished bool) ([]*resp.BuildSummary, error) { 70 func getBuilds(c context.Context, masterName, builderName string, finished bool) ([]*resp.BuildSummary, error) {
67 // TODO(hinoka): Builder specific structs. 71 // TODO(hinoka): Builder specific structs.
68 result := []*resp.BuildSummary{} 72 result := []*resp.BuildSummary{}
69 ds := datastore.Get(c) 73 ds := datastore.Get(c)
70 q := datastore.NewQuery("buildbotBuild") 74 q := datastore.NewQuery("buildbotBuild")
71 q = q.Eq("finished", finished) 75 q = q.Eq("finished", finished)
72 q = q.Eq("master", masterName) 76 q = q.Eq("master", masterName)
73 q = q.Eq("builder", builderName) 77 q = q.Eq("builder", builderName)
74 q = q.Limit(25) // TODO(hinoka): This should be adjustable 78 q = q.Limit(25) // TODO(hinoka): This should be adjustable
75 q = q.Order("-number") 79 q = q.Order("-number")
76 buildbots := []*buildbotBuild{} 80 buildbots := []*buildbotBuild{}
77 err := ds.GetAll(q, &buildbots) 81 err := ds.GetAll(q, &buildbots)
78 if err != nil { 82 if err != nil {
79 return nil, err 83 return nil, err
80 } 84 }
81 for _, b := range buildbots { 85 for _, b := range buildbots {
82 result = append(result, getBuildSummary(b)) 86 result = append(result, getBuildSummary(b))
83 } 87 }
84 return result, nil 88 return result, nil
85 } 89 }
86 90
87 // getCurrentBuild extracts a build from a map of current builds, and translates 91 // getCurrentBuild extracts a build from a map of current builds, and translates
88 // it into the milo version of the build. 92 // it into the milo version of the build.
89 func getCurrentBuild(c context.Context, bMap buildMap, builder string, buildNum int) *resp.BuildSummary { 93 func getCurrentBuild(c context.Context, bMap buildMap, builder string, buildNum int) *resp.BuildSummary {
90 b, ok := bMap[builderRef{builder, buildNum}] 94 b, ok := bMap[builderRef{builder, buildNum}]
91 if !ok { 95 if !ok {
92 » » log.Warningf(c, "Could not find %s/%d in builder map:\n %s", bui lder, buildNum, bMap) 96 » » logging.Warningf(c, "Could not find %s/%d in builder map:\n %s", builder, buildNum, bMap)
93 return nil 97 return nil
94 } 98 }
95 return getBuildSummary(b) 99 return getBuildSummary(b)
96 } 100 }
97 101
98 // getCurrentBuilds extracts the list of all the current builds from a master js on 102 // getCurrentBuilds extracts the list of all the current builds from a master js on
99 // from the slaves' runningBuilds portion. 103 // from the slaves' runningBuilds portion.
100 func getCurrentBuilds(c context.Context, master *buildbotMaster, builderName str ing) []*resp.BuildSummary { 104 func getCurrentBuilds(c context.Context, master *buildbotMaster, builderName str ing) []*resp.BuildSummary {
101 b := master.Builders[builderName] 105 b := master.Builders[builderName]
102 results := []*resp.BuildSummary{} 106 results := []*resp.BuildSummary{}
103 bMap := createRunningBuildMap(master) 107 bMap := createRunningBuildMap(master)
104 for _, bn := range b.Currentbuilds { 108 for _, bn := range b.Currentbuilds {
105 cb := getCurrentBuild(c, bMap, builderName, bn) 109 cb := getCurrentBuild(c, bMap, builderName, bn)
106 if cb != nil { 110 if cb != nil {
107 results = append(results, cb) 111 results = append(results, cb)
108 } 112 }
109 } 113 }
110 return results 114 return results
111 } 115 }
112 116
117 var errMasterNotFound = miloerror.Error{
118 Message: "Master not found",
119 Code: http.StatusNotFound,
120 }
121
113 // builderImpl is the implementation for getting a milo builder page from buildb ot. 122 // builderImpl is the implementation for getting a milo builder page from buildb ot.
114 // This gets: 123 // This gets:
115 // * Current Builds from querying the master json from the datastore. 124 // * Current Builds from querying the master json from the datastore.
116 // * Recent Builds from a cron job that backfills the recent builds. 125 // * Recent Builds from a cron job that backfills the recent builds.
117 func builderImpl(c context.Context, masterName, builderName string) (*resp.Build er, error) { 126 func builderImpl(c context.Context, masterName, builderName string) (*resp.Build er, error) {
118 result := &resp.Builder{} 127 result := &resp.Builder{}
119 master, internal, t, err := getMasterJSON(c, masterName) 128 master, internal, t, err := getMasterJSON(c, masterName)
120 if internal { 129 if internal {
121 » » // TODO(hinoka): Implement ACL support and remove this. 130 » » allowed, err := settings.IsAllowedInternal(c)
122 » » return nil, fmt.Errorf("Internal masters are not yet supported." ) 131 » » if err != nil {
132 » » » return nil, err
133 » » }
134 » » if !allowed {
135 » » » return nil, errMasterNotFound
136 » » }
123 } 137 }
124 if err != nil { 138 if err != nil {
125 return nil, fmt.Errorf("Cannot find master %s\n%s", masterName, err.Error()) 139 return nil, fmt.Errorf("Cannot find master %s\n%s", masterName, err.Error())
126 } 140 }
127 if clock.Now(c).Sub(t) > 2*time.Minute { 141 if clock.Now(c).Sub(t) > 2*time.Minute {
128 warning := fmt.Sprintf( 142 warning := fmt.Sprintf(
129 "WARNING: Master data is stale (last updated %s)", t) 143 "WARNING: Master data is stale (last updated %s)", t)
130 » » log.Warningf(c, warning) 144 » » logging.Warningf(c, warning)
131 result.Warning = warning 145 result.Warning = warning
132 } 146 }
133 147
134 s, _ := json.Marshal(master) 148 s, _ := json.Marshal(master)
135 » log.Debugf(c, "Master: %s", s) 149 » logging.Debugf(c, "Master: %s", s)
136 150
137 _, ok := master.Builders[builderName] 151 _, ok := master.Builders[builderName]
138 if !ok { 152 if !ok {
139 // This long block is just to return a good error message when a n invalid 153 // This long block is just to return a good error message when a n invalid
140 // buildbot builder is specified. 154 // buildbot builder is specified.
141 keys := make([]string, 0, len(master.Builders)) 155 keys := make([]string, 0, len(master.Builders))
142 for k := range master.Builders { 156 for k := range master.Builders {
143 keys = append(keys, k) 157 keys = append(keys, k)
144 } 158 }
145 sort.Strings(keys) 159 sort.Strings(keys)
(...skipping 12 matching lines...) Expand all
158 result.CurrentBuilds = currentBuilds 172 result.CurrentBuilds = currentBuilds
159 for _, fb := range recentBuilds { 173 for _, fb := range recentBuilds {
160 // Yes recent builds is synonymous with finished builds. 174 // Yes recent builds is synonymous with finished builds.
161 // TODO(hinoka): Implement limits. 175 // TODO(hinoka): Implement limits.
162 if fb != nil { 176 if fb != nil {
163 result.FinishedBuilds = append(result.FinishedBuilds, fb ) 177 result.FinishedBuilds = append(result.FinishedBuilds, fb )
164 } 178 }
165 } 179 }
166 return result, nil 180 return result, nil
167 } 181 }
OLDNEW
« no previous file with comments | « milo/appengine/buildbot/build_test.go ('k') | milo/appengine/buildbot/master.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698