| 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" |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 184 // Extract OS and OS Family | 184 // Extract OS and OS Family |
| 185 if v, ok := hostInfo["os family"]; ok { | 185 if v, ok := hostInfo["os family"]; ok { |
| 186 family = v | 186 family = v |
| 187 } | 187 } |
| 188 if v, ok := hostInfo["os version"]; ok { | 188 if v, ok := hostInfo["os version"]; ok { |
| 189 version = v | 189 version = v |
| 190 } | 190 } |
| 191 return | 191 return |
| 192 } | 192 } |
| 193 | 193 |
| 194 // Marks a build as finished and expired. |
| 195 func expireBuild(c context.Context, b *buildbotBuild) error { |
| 196 finished := float64(clock.Now(c).Unix()) |
| 197 if b.TimeStamp != nil { |
| 198 finished = float64(*b.TimeStamp) |
| 199 } |
| 200 results := int(2) |
| 201 b.Times[1] = &finished |
| 202 b.Finished = true |
| 203 b.Results = &results |
| 204 return ds.Put(c, b) |
| 205 } |
| 206 |
| 207 func doMaster(c context.Context, master *buildbotMaster, internal bool) int { |
| 208 // Store the master json into the datastore. |
| 209 err := putDSMasterJSON(c, master, internal) |
| 210 if err != nil { |
| 211 logging.WithError(err).Errorf( |
| 212 c, "Could not save master in datastore %s", err) |
| 213 // This is transient, we do want PubSub to retry. |
| 214 return 500 |
| 215 } |
| 216 |
| 217 // Extract current builds data out of the master json, and use it to |
| 218 // clean up expired builds. |
| 219 q := ds.NewQuery("buildbotBuild"). |
| 220 Eq("finished", false). |
| 221 Eq("master", master.Name) |
| 222 builds := []*buildbotBuild{} |
| 223 err = ds.GetAll(c, q, &builds) |
| 224 if err != nil { |
| 225 logging.WithError(err).Errorf(c, "Could not load current builds
from master %s", |
| 226 master.Name) |
| 227 return 500 |
| 228 } |
| 229 for _, b := range builds { |
| 230 builder, ok := master.Builders[b.Buildername] |
| 231 if !ok { |
| 232 // Mark this build due to builder being removed. |
| 233 logging.Infof(c, "Expiring %s/%s/%d due to builder being
removed", |
| 234 master.Name, b.Buildername, b.Number) |
| 235 err = expireBuild(c, b) |
| 236 if err != nil { |
| 237 logging.WithError(err).Errorf(c, "Could not expi
re build") |
| 238 return 500 |
| 239 } |
| 240 } |
| 241 |
| 242 found := false |
| 243 for _, bnum := range builder.CurrentBuilds { |
| 244 if b.Number == bnum { |
| 245 found = true |
| 246 break |
| 247 } |
| 248 } |
| 249 if !found { |
| 250 // Mark this build due to build not current anymore. |
| 251 logging.Infof(c, "Expiring %s/%s/%d due to build not cur
rent", |
| 252 master.Name, b.Buildername, b.Number) |
| 253 err = expireBuild(c, b) |
| 254 if err != nil { |
| 255 logging.WithError(err).Errorf(c, "Could not expi
re build") |
| 256 return 500 |
| 257 } |
| 258 } |
| 259 } |
| 260 return 0 |
| 261 } |
| 262 |
| 194 // PubSubHandler is a webhook that stores the builds coming in from pubsub. | 263 // PubSubHandler is a webhook that stores the builds coming in from pubsub. |
| 195 func PubSubHandler(ctx *router.Context) { | 264 func PubSubHandler(ctx *router.Context) { |
| 196 c, h, r := ctx.Context, ctx.Writer, ctx.Request | 265 c, h, r := ctx.Context, ctx.Writer, ctx.Request |
| 197 | 266 |
| 198 msg := pubSubSubscription{} | 267 msg := pubSubSubscription{} |
| 199 defer r.Body.Close() | 268 defer r.Body.Close() |
| 200 dec := json.NewDecoder(r.Body) | 269 dec := json.NewDecoder(r.Body) |
| 201 if err := dec.Decode(&msg); err != nil { | 270 if err := dec.Decode(&msg); err != nil { |
| 202 logging.WithError(err).Errorf( | 271 logging.WithError(err).Errorf( |
| 203 c, "Could not decode message. %s", err) | 272 c, "Could not decode message. %s", err) |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 292 if buildExists { | 361 if buildExists { |
| 293 buildCounter.Add( | 362 buildCounter.Add( |
| 294 c, 1, false, build.Master, build.Buildername, bu
ild.Finished, "Replaced") | 363 c, 1, false, build.Master, build.Buildername, bu
ild.Finished, "Replaced") |
| 295 } else { | 364 } else { |
| 296 buildCounter.Add( | 365 buildCounter.Add( |
| 297 c, 1, false, build.Master, build.Buildername, bu
ild.Finished, "New") | 366 c, 1, false, build.Master, build.Buildername, bu
ild.Finished, "New") |
| 298 } | 367 } |
| 299 | 368 |
| 300 } | 369 } |
| 301 if master != nil { | 370 if master != nil { |
| 302 » » err = putDSMasterJSON(c, master, internal) | 371 » » code := doMaster(c, master, internal) |
| 303 » » if err != nil { | 372 » » if code != 0 { |
| 304 » » » logging.WithError(err).Errorf( | 373 » » » h.WriteHeader(code) |
| 305 » » » » c, "Could not save master in datastore %s", err) | |
| 306 » » » // This is transient, we do want PubSub to retry. | |
| 307 » » » h.WriteHeader(500) | |
| 308 return | 374 return |
| 309 } | 375 } |
| 310 } | 376 } |
| 311 h.WriteHeader(200) | 377 h.WriteHeader(200) |
| 312 } | 378 } |
| OLD | NEW |