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

Side by Side Diff: appengine/cmd/milo/swarming/build.go

Issue 2109473005: Milo: Pending swarming builds (Closed) Base URL: https://chromium.googlesource.com/external/github.com/luci/luci-go@master
Patch Set: Created 4 years, 5 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 2015 The LUCI Authors. All rights reserved. 1 // Copyright 2015 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 swarming 5 package swarming
6 6
7 import ( 7 import (
8 "bytes" 8 "bytes"
9 "encoding/json" 9 "encoding/json"
10 "fmt" 10 "fmt"
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
107 *swarming.SwarmingRpcsTaskResult, error) { 107 *swarming.SwarmingRpcsTaskResult, error) {
108 108
109 trc := sc.Task.Result(taskID) 109 trc := sc.Task.Result(taskID)
110 srtr, err := trc.Do() 110 srtr, err := trc.Do()
111 if err != nil { 111 if err != nil {
112 return nil, err 112 return nil, err
113 } 113 }
114 return srtr, nil 114 return srtr, nil
115 } 115 }
116 116
117 // getSwarming fetches both the swarming task data and log data, and returns
118 // the task result, the log string, task error, and log error.
117 func getSwarming(c context.Context, server string, taskID string) ( 119 func getSwarming(c context.Context, server string, taskID string) (
118 » *swarming.SwarmingRpcsTaskResult, string, error) { 120 » *swarming.SwarmingRpcsTaskResult, string, error, error) {
119 121
120 var log string 122 var log string
121 var sr *swarming.SwarmingRpcsTaskResult 123 var sr *swarming.SwarmingRpcsTaskResult
122 var errLog, errRes error 124 var errLog, errRes error
123 125
124 // Detour: Return debugging results, useful for development. 126 // Detour: Return debugging results, useful for development.
125 if server == "debug" { 127 if server == "debug" {
126 sr, errRes = getDebugSwarmingResult(taskID) 128 sr, errRes = getDebugSwarmingResult(taskID)
127 log, errLog = getDebugTaskOutput(taskID) 129 log, errLog = getDebugTaskOutput(taskID)
128 » » if errLog != nil { 130 » » return sr, log, errRes, errLog
129 » » » return sr, log, errLog
130 » » }
131 » » return sr, log, errRes
132 } 131 }
133 132
134 sc, err := getSwarmingClient(c, server) 133 sc, err := getSwarmingClient(c, server)
135 if err != nil { 134 if err != nil {
136 » » return nil, "", err 135 » » return nil, "", err, nil
137 } 136 }
138 137
139 var wg sync.WaitGroup 138 var wg sync.WaitGroup
140 wg.Add(2) // Getting log and result can happen concurrently. Wait for b oth. 139 wg.Add(2) // Getting log and result can happen concurrently. Wait for b oth.
141 140
142 go func() { 141 go func() {
143 defer wg.Done() 142 defer wg.Done()
144 log, errLog = getTaskOutput(sc, taskID) 143 log, errLog = getTaskOutput(sc, taskID)
145 }() 144 }()
146 go func() { 145 go func() {
147 defer wg.Done() 146 defer wg.Done()
148 sr, errRes = getSwarmingResult(sc, taskID) 147 sr, errRes = getSwarmingResult(sc, taskID)
149 }() 148 }()
150 wg.Wait() 149 wg.Wait()
151 » if errRes != nil { 150 » return sr, log, errRes, errLog
152 » » return sr, log, errRes
153 » }
154 » return sr, log, errLog
155 } 151 }
156 152
157 func taskProperties(sr *swarming.SwarmingRpcsTaskResult) *resp.PropertyGroup { 153 func taskProperties(sr *swarming.SwarmingRpcsTaskResult) *resp.PropertyGroup {
158 props := &resp.PropertyGroup{GroupName: "Swarming"} 154 props := &resp.PropertyGroup{GroupName: "Swarming"}
159 if len(sr.CostsUsd) == 1 { 155 if len(sr.CostsUsd) == 1 {
160 props.Property = append(props.Property, &resp.Property{ 156 props.Property = append(props.Property, &resp.Property{
161 Key: "Cost of job (USD)", 157 Key: "Cost of job (USD)",
162 Value: fmt.Sprintf("$%.2f", sr.CostsUsd[0]), 158 Value: fmt.Sprintf("$%.2f", sr.CostsUsd[0]),
163 }) 159 })
164 } 160 }
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
285 // goroutine safe 281 // goroutine safe
286 if err := p.RunStreams([]*annotee.Stream{&is}); err != nil { 282 if err := p.RunStreams([]*annotee.Stream{&is}); err != nil {
287 return nil, err 283 return nil, err
288 } 284 }
289 p.Finish() 285 p.Finish()
290 return c.ToLogDogStreams() 286 return c.ToLogDogStreams()
291 } 287 }
292 288
293 func swarmingBuildImpl(c context.Context, URL string, server string, taskID stri ng) (*resp.MiloBuild, error) { 289 func swarmingBuildImpl(c context.Context, URL string, server string, taskID stri ng) (*resp.MiloBuild, error) {
294 // Fetch the data from Swarming 290 // Fetch the data from Swarming
295 » sr, body, err := getSwarming(c, server, taskID) 291 » sr, body, errRes, errLog := getSwarming(c, server, taskID)
296 » if err != nil { 292 » // Swarming result must come back.
297 » » return nil, err 293 » if errRes != nil {
294 » » return nil, errRes
295 » }
296 » switch sr.State {
297 » case TaskCompleted, TaskRunning, TaskCanceled:
298 » » if errLog != nil {
299 » » » // If the task is completed, running, or canceled, we'd expect a log.
300 » » » // If not, we don't necessarily expect the log to come b ack.
nodir 2016/06/28 20:36:49 I think getSwarming is a better place for this log
301 » » » return nil, errLog
302 » » }
298 } 303 }
299 304
300 allowMilo := false 305 allowMilo := false
301 for _, t := range sr.Tags { 306 for _, t := range sr.Tags {
302 if t == "allow_milo:1" { 307 if t == "allow_milo:1" {
303 allowMilo = true 308 allowMilo = true
304 break 309 break
305 } 310 }
306 } 311 }
307 if !allowMilo { 312 if !allowMilo {
308 return nil, fmt.Errorf("Not A Milo Job") 313 return nil, fmt.Errorf("Not A Milo Job")
309 } 314 }
310 315
311 build, err := taskToBuild(c, server, sr) 316 build, err := taskToBuild(c, server, sr)
312 if err != nil { 317 if err != nil {
313 return nil, err 318 return nil, err
314 } 319 }
315 320
316 // Decode the data using annotee. The logdog stream returned here is ass umed 321 // Decode the data using annotee. The logdog stream returned here is ass umed
317 // to be consistent, which is why the following block of code are not 322 // to be consistent, which is why the following block of code are not
318 // expected to ever err out. 323 // expected to ever err out.
319 » lds, err := streamsFromAnnotatedLog(c, body) 324 » if errLog != nil && body != "" {
320 » if err != nil { 325 » » lds, err := streamsFromAnnotatedLog(c, body)
321 » » build.Components = []*resp.BuildComponent{{ 326 » » if err != nil {
322 » » » Type: resp.Summary, 327 » » » build.Components = []*resp.BuildComponent{{
323 » » » Label: "Milo annotation parser", 328 » » » » Type: resp.Summary,
324 » » » Text: []string{err.Error()}, 329 » » » » Label: "Milo annotation parser",
325 » » » Status: resp.InfraFailure, 330 » » » » Text: []string{err.Error()},
326 » » » SubLink: []*resp.Link{{ 331 » » » » Status: resp.InfraFailure,
327 » » » » Label: "swarming task", 332 » » » » SubLink: []*resp.Link{{
328 » » » » URL: taskPageURL(server, taskID), 333 » » » » » Label: "swarming task",
329 » » » }}, 334 » » » » » URL: taskPageURL(server, taskID),
330 » » }} 335 » » » » }},
331 » } else { 336 » » » }}
332 » » logdog.AddLogDogToBuild(c, URL, lds, build) 337 » » } else {
338 » » » logdog.AddLogDogToBuild(c, URL, lds, build)
339 » » }
333 } 340 }
334 341
335 return build, nil 342 return build, nil
336 } 343 }
337 344
338 // taskPageURL returns a URL to a human-consumable page of a swarming task. 345 // taskPageURL returns a URL to a human-consumable page of a swarming task.
339 // Supports server aliases. 346 // Supports server aliases.
340 func taskPageURL(swarmingHostname, taskID string) string { 347 func taskPageURL(swarmingHostname, taskID string) string {
341 return fmt.Sprintf("https://%s/user/task/%s", resolveServer(swarmingHost name), taskID) 348 return fmt.Sprintf("https://%s/user/task/%s", resolveServer(swarmingHost name), taskID)
342 } 349 }
343 350
344 // botPageURL returns a URL to a human-consumable page of a swarming bot. 351 // botPageURL returns a URL to a human-consumable page of a swarming bot.
345 // Supports server aliases. 352 // Supports server aliases.
346 func botPageURL(swarmingHostname, botID string) string { 353 func botPageURL(swarmingHostname, botID string) string {
347 return fmt.Sprintf("https://%s/restricted/bot/%s", resolveServer(swarmin gHostname), botID) 354 return fmt.Sprintf("https://%s/restricted/bot/%s", resolveServer(swarmin gHostname), botID)
348 } 355 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698