| 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 "bytes" | 8 "bytes" |
| 9 "compress/gzip" | 9 "compress/gzip" |
| 10 "compress/zlib" | 10 "compress/zlib" |
| 11 "encoding/base64" | 11 "encoding/base64" |
| 12 "encoding/json" | 12 "encoding/json" |
| 13 "time" | 13 "time" |
| 14 | 14 |
| 15 "github.com/luci/gae/service/datastore" | 15 "github.com/luci/gae/service/datastore" |
| 16 "github.com/luci/luci-go/common/clock" | 16 "github.com/luci/luci-go/common/clock" |
| 17 "github.com/luci/luci-go/common/iotools" | 17 "github.com/luci/luci-go/common/iotools" |
| 18 log "github.com/luci/luci-go/common/logging" | 18 log "github.com/luci/luci-go/common/logging" |
| 19 "github.com/luci/luci-go/server/router" | 19 "github.com/luci/luci-go/server/router" |
| 20 | 20 |
| 21 "golang.org/x/net/context" | 21 "golang.org/x/net/context" |
| 22 | 22 |
| 23 "github.com/luci/luci-go/common/tsmon/field" | 23 "github.com/luci/luci-go/common/tsmon/field" |
| 24 "github.com/luci/luci-go/common/tsmon/metric" | 24 "github.com/luci/luci-go/common/tsmon/metric" |
| 25 "github.com/luci/luci-go/common/tsmon/types" | 25 "github.com/luci/luci-go/common/tsmon/types" |
| 26 ) | 26 ) |
| 27 | 27 |
| 28 var ( | 28 var ( |
| 29 » // subName is the name of the pubsub subscription that milo is expecting
. | 29 » // publicSubName is the name of the pubsub subscription that milo is exp
ecting. |
| 30 // TODO(hinoka): This should be read from luci-config. | 30 // TODO(hinoka): This should be read from luci-config. |
| 31 » subName = "projects/luci-milo/subscriptions/buildbot-public" | 31 » publicSubName = "projects/luci-milo/subscriptions/buildbot-public" |
| 32 » internalSubName = "projects/luci-milo/subscriptions/buildbot-private" |
| 32 | 33 |
| 33 // Metrics | 34 // Metrics |
| 34 buildCounter = metric.NewCounter( | 35 buildCounter = metric.NewCounter( |
| 35 "luci/milo/buildbot_pubsub/builds", | 36 "luci/milo/buildbot_pubsub/builds", |
| 36 "The number of buildbot builds received by Milo from PubSub", | 37 "The number of buildbot builds received by Milo from PubSub", |
| 37 types.MetricMetadata{}, | 38 types.MetricMetadata{}, |
| 38 field.Bool("internal"), | 39 field.Bool("internal"), |
| 39 field.String("master"), | 40 field.String("master"), |
| 40 field.String("builder"), | 41 field.String("builder"), |
| 41 field.Bool("finished"), | 42 field.Bool("finished"), |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 138 | 139 |
| 139 msg := pubSubSubscription{} | 140 msg := pubSubSubscription{} |
| 140 defer r.Body.Close() | 141 defer r.Body.Close() |
| 141 dec := json.NewDecoder(r.Body) | 142 dec := json.NewDecoder(r.Body) |
| 142 if err := dec.Decode(&msg); err != nil { | 143 if err := dec.Decode(&msg); err != nil { |
| 143 log.WithError(err).Errorf( | 144 log.WithError(err).Errorf( |
| 144 c, "Could not decode message. %s", err) | 145 c, "Could not decode message. %s", err) |
| 145 h.WriteHeader(200) // This is a hard failure, we don't want PubS
ub to retry. | 146 h.WriteHeader(200) // This is a hard failure, we don't want PubS
ub to retry. |
| 146 return | 147 return |
| 147 } | 148 } |
| 148 » if msg.Subscription != subName { | 149 » internal := true |
| 150 » switch msg.Subscription { |
| 151 » case publicSubName: |
| 152 » » internal = false |
| 153 » case internalSubName: |
| 154 » » // internal = true, but that's already set. |
| 155 » default: |
| 149 log.Errorf( | 156 log.Errorf( |
| 150 » » » c, "Subscription name %s does not match %s", msg.Subscri
ption, subName) | 157 » » » c, "Subscription name %s does not match %s or %s", |
| 158 » » » msg.Subscription, publicSubName, internalSubName) |
| 151 h.WriteHeader(200) | 159 h.WriteHeader(200) |
| 152 return | 160 return |
| 153 } | 161 } |
| 154 bbMsg, err := msg.GetData() | 162 bbMsg, err := msg.GetData() |
| 155 if err != nil { | 163 if err != nil { |
| 156 log.WithError(err).Errorf(c, "Could not base64 decode message %s
", err) | 164 log.WithError(err).Errorf(c, "Could not base64 decode message %s
", err) |
| 157 h.WriteHeader(200) | 165 h.WriteHeader(200) |
| 158 return | 166 return |
| 159 } | 167 } |
| 160 builds, master, err := unmarshal(c, bbMsg) | 168 builds, master, err := unmarshal(c, bbMsg) |
| (...skipping 23 matching lines...) Expand all Loading... |
| 184 if existingBuild.Finished { | 192 if existingBuild.Finished { |
| 185 // Never replace a completed build. | 193 // Never replace a completed build. |
| 186 buildCounter.Add( | 194 buildCounter.Add( |
| 187 c, 1, false, build.Master, build.Builder
name, false, "Rejected") | 195 c, 1, false, build.Master, build.Builder
name, false, "Rejected") |
| 188 log.Debugf( | 196 log.Debugf( |
| 189 c, "Found build %s/%s/%d and it's finish
ed, skipping", build.Master, build.Buildername, build.Number) | 197 c, "Found build %s/%s/%d and it's finish
ed, skipping", build.Master, build.Buildername, build.Number) |
| 190 continue | 198 continue |
| 191 } | 199 } |
| 192 buildExists = true | 200 buildExists = true |
| 193 } | 201 } |
| 194 » » // Also set the finished bit. | 202 » » // Also set the finished and internal bit. |
| 195 build.Finished = false | 203 build.Finished = false |
| 196 if len(build.Times) == 2 && build.Times[1] != nil { | 204 if len(build.Times) == 2 && build.Times[1] != nil { |
| 197 build.Finished = true | 205 build.Finished = true |
| 198 } | 206 } |
| 207 build.Internal = internal |
| 199 err = ds.Put(&build) | 208 err = ds.Put(&build) |
| 200 if err != nil { | 209 if err != nil { |
| 201 switch err { | 210 switch err { |
| 202 case errTooBig: | 211 case errTooBig: |
| 203 // This will never work, we don't want PubSub to
retry. | 212 // This will never work, we don't want PubSub to
retry. |
| 204 log.WithError(err).Errorf( | 213 log.WithError(err).Errorf( |
| 205 c, "Could not save build to datastore, f
ailing permanently") | 214 c, "Could not save build to datastore, f
ailing permanently") |
| 206 h.WriteHeader(200) | 215 h.WriteHeader(200) |
| 207 default: | 216 default: |
| 208 // This is transient, we do want PubSub to retry
. | 217 // This is transient, we do want PubSub to retry
. |
| 209 log.WithError(err).Errorf(c, "Could not save bui
ld in datastore") | 218 log.WithError(err).Errorf(c, "Could not save bui
ld in datastore") |
| 210 h.WriteHeader(500) | 219 h.WriteHeader(500) |
| 211 } | 220 } |
| 212 return | 221 return |
| 213 } | 222 } |
| 214 log.Debugf( | 223 log.Debugf( |
| 215 c, "Saved build %s/%s/%d, it is %s", | 224 c, "Saved build %s/%s/%d, it is %s", |
| 216 build.Master, build.Buildername, build.Number, build.Fin
ished) | 225 build.Master, build.Buildername, build.Number, build.Fin
ished) |
| 217 if buildExists { | 226 if buildExists { |
| 218 buildCounter.Add( | 227 buildCounter.Add( |
| 219 c, 1, false, build.Master, build.Buildername, bu
ild.Finished, "Replaced") | 228 c, 1, false, build.Master, build.Buildername, bu
ild.Finished, "Replaced") |
| 220 } else { | 229 } else { |
| 221 buildCounter.Add( | 230 buildCounter.Add( |
| 222 c, 1, false, build.Master, build.Buildername, bu
ild.Finished, "New") | 231 c, 1, false, build.Master, build.Buildername, bu
ild.Finished, "New") |
| 223 } | 232 } |
| 224 | 233 |
| 225 } | 234 } |
| 226 if master != nil { | 235 if master != nil { |
| 227 » » // TODO(hinoka): Internal builds. | 236 » » err = putDSMasterJSON(c, master, internal) |
| 228 » » err = putDSMasterJSON(c, master, false) | |
| 229 if err != nil { | 237 if err != nil { |
| 230 log.WithError(err).Errorf( | 238 log.WithError(err).Errorf( |
| 231 c, "Could not save master in datastore %s", err) | 239 c, "Could not save master in datastore %s", err) |
| 232 // This is transient, we do want PubSub to retry. | 240 // This is transient, we do want PubSub to retry. |
| 233 h.WriteHeader(500) | 241 h.WriteHeader(500) |
| 234 return | 242 return |
| 235 } | 243 } |
| 236 } | 244 } |
| 237 h.WriteHeader(200) | 245 h.WriteHeader(200) |
| 238 } | 246 } |
| OLD | NEW |