Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 log "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 Loading... | |
| 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") |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 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.IsAllowed(c, "buildbot-internal") |
| 122 » » return nil, fmt.Errorf("Internal masters are not yet supported." ) | 131 » » if err != nil { |
| 132 » » » log.WithError(err).Errorf(c, | |
| 133 » » » » "Encountered error while checking buildbot membe rship, returning 404") | |
| 134 » » » return nil, errMasterNotFound | |
|
Vadim Sh.
2016/08/23 18:53:06
same here
Ryan Tseng
2016/08/23 22:00:15
Done.
| |
| 135 » » } | |
| 136 » » if !allowed { | |
| 137 » » » return nil, errMasterNotFound | |
| 138 » » } | |
| 123 } | 139 } |
| 124 if err != nil { | 140 if err != nil { |
| 125 return nil, fmt.Errorf("Cannot find master %s\n%s", masterName, err.Error()) | 141 return nil, fmt.Errorf("Cannot find master %s\n%s", masterName, err.Error()) |
| 126 } | 142 } |
| 127 if clock.Now(c).Sub(t) > 2*time.Minute { | 143 if clock.Now(c).Sub(t) > 2*time.Minute { |
| 128 warning := fmt.Sprintf( | 144 warning := fmt.Sprintf( |
| 129 "WARNING: Master data is stale (last updated %s)", t) | 145 "WARNING: Master data is stale (last updated %s)", t) |
| 130 log.Warningf(c, warning) | 146 log.Warningf(c, warning) |
| 131 result.Warning = warning | 147 result.Warning = warning |
| 132 } | 148 } |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 158 result.CurrentBuilds = currentBuilds | 174 result.CurrentBuilds = currentBuilds |
| 159 for _, fb := range recentBuilds { | 175 for _, fb := range recentBuilds { |
| 160 // Yes recent builds is synonymous with finished builds. | 176 // Yes recent builds is synonymous with finished builds. |
| 161 // TODO(hinoka): Implement limits. | 177 // TODO(hinoka): Implement limits. |
| 162 if fb != nil { | 178 if fb != nil { |
| 163 result.FinishedBuilds = append(result.FinishedBuilds, fb ) | 179 result.FinishedBuilds = append(result.FinishedBuilds, fb ) |
| 164 } | 180 } |
| 165 } | 181 } |
| 166 return result, nil | 182 return result, nil |
| 167 } | 183 } |
| OLD | NEW |