Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 163 } | 163 } |
| 164 if sr.State == TaskCompleted || sr.State == TaskTimedOut { | 164 if sr.State == TaskCompleted || sr.State == TaskTimedOut { |
| 165 props.Property = append(props.Property, &resp.Property{ | 165 props.Property = append(props.Property, &resp.Property{ |
| 166 Key: "Exit Code", | 166 Key: "Exit Code", |
| 167 Value: fmt.Sprintf("%d", sr.ExitCode), | 167 Value: fmt.Sprintf("%d", sr.ExitCode), |
| 168 }) | 168 }) |
| 169 } | 169 } |
| 170 return props | 170 return props |
| 171 } | 171 } |
| 172 | 172 |
| 173 func tagsToProperties(tags []string) *resp.PropertyGroup { | 173 func tagsToMap(tags []string) map[string]string { |
| 174 » props := &resp.PropertyGroup{GroupName: "Swarming Tags"} | 174 » result := map[string]string{} |
| 175 for _, t := range tags { | 175 for _, t := range tags { |
| 176 if t == "" { | 176 if t == "" { |
| 177 continue | 177 continue |
| 178 } | 178 } |
| 179 parts := strings.SplitN(t, ":", 2) | 179 parts := strings.SplitN(t, ":", 2) |
| 180 p := &resp.Property{ | |
| 181 Key: parts[0], | |
| 182 } | |
| 183 if len(parts) == 2 { | 180 if len(parts) == 2 { |
| 184 » » » p.Value = parts[1] | 181 » » » result[parts[0]] = parts[1] |
|
nodir
2017/02/07 21:56:29
are you sure tag keys are unique? add a func comme
hinoka
2017/02/24 00:56:22
Tags keys are supposed to be unique. If a second
| |
| 185 » » } | |
| 186 » » props.Property = append(props.Property, p) | |
| 187 » } | |
| 188 » return props | |
| 189 } | |
| 190 | |
| 191 // tagValue returns a value of the first tag matching the tag key. If not found | |
| 192 // returns "". | |
| 193 func tagValue(tags []string, key string) string { | |
| 194 » prefix := key + ":" | |
| 195 » for _, t := range tags { | |
| 196 » » if strings.HasPrefix(t, prefix) { | |
| 197 » » » return strings.TrimPrefix(t, prefix) | |
| 198 } | 182 } |
| 199 } | 183 } |
| 200 » return "" | 184 » return result |
| 201 } | 185 } |
| 202 | 186 |
| 203 // addBuilderLink adds a link to the buildbucket builder view. | 187 // addBuilderLink adds a link to the buildbucket builder view. |
| 204 func addBuilderLink(c context.Context, build *resp.MiloBuild, swarmingHostname s tring, sr *swarming.SwarmingRpcsTaskResult) { | 188 func addBuilderLink(c context.Context, build *resp.MiloBuild, selfURL string, pr ops map[string]string) { |
|
nodir
2017/02/07 21:56:30
it is not obvious what "self" means here. Task? Co
nodir
2017/02/07 21:56:30
s/props/tags/
in swarming land, properties mean s
hinoka
2017/02/24 00:56:22
Actually I just removed this entirely. No need to
hinoka
2017/02/24 00:56:22
Done.
| |
| 205 » bbHost := tagValue(sr.Tags, "buildbucket_hostname") | 189 » bbHost := props["buildbucket_hostname"] |
| 206 » bucket := tagValue(sr.Tags, "buildbucket_bucket") | 190 » bucket := props["buildbucket_bucket"] |
| 207 » builder := tagValue(sr.Tags, "builder") | 191 » builder := props["builder"] |
| 208 if bucket == "" { | 192 if bucket == "" { |
| 209 logging.Errorf( | 193 logging.Errorf( |
| 210 » » » c, "Could not extract buidlbucket bucket from task %s", | 194 » » » c, "Could not extract buidlbucket bucket from task %s", selfURL) |
| 211 » » » taskPageURL(swarmingHostname, sr.TaskId)) | |
| 212 } | 195 } |
| 213 if builder == "" { | 196 if builder == "" { |
| 214 logging.Errorf( | 197 logging.Errorf( |
| 215 » » » c, "Could not extract builder name from task %s", | 198 » » » c, "Could not extract builder name from task %s", selfUR L) |
| 216 » » » taskPageURL(swarmingHostname, sr.TaskId)) | |
| 217 } | 199 } |
| 218 if bucket != "" && builder != "" { | 200 if bucket != "" && builder != "" { |
| 219 build.Summary.ParentLabel = &resp.Link{ | 201 build.Summary.ParentLabel = &resp.Link{ |
| 220 Label: builder, | 202 Label: builder, |
| 221 URL: fmt.Sprintf("/buildbucket/%s/%s?server=%s", bucke t, builder, bbHost), | 203 URL: fmt.Sprintf("/buildbucket/%s/%s?server=%s", bucke t, builder, bbHost), |
| 222 } | 204 } |
| 223 } | 205 } |
| 224 } | 206 } |
| 225 | 207 |
| 226 // addBanner adds an OS banner derived from "os" swarming tag, if present. | 208 // addBanner adds an OS banner derived from "os" swarming tag, if present. |
| 227 func addBanner(build *resp.MiloBuild, sr *swarming.SwarmingRpcsTaskResult) { | 209 func addBanner(build *resp.MiloBuild, props map[string]string) { |
|
nodir
2017/02/07 21:56:29
s/props/tags/
hinoka
2017/02/24 00:56:22
Done.
| |
| 228 » var os, ver string | 210 » os := props["os"] |
| 229 » for _, t := range sr.Tags { | 211 » var ver string |
| 230 » » value := strings.TrimPrefix(t, "os:") | 212 » parts := strings.SplitN(os, "-", 2) |
| 231 » » if value == t { | 213 » if len(parts) == 2 { |
| 232 » » » // t does not have the prefix | 214 » » os = parts[0] |
| 233 » » » continue | 215 » » ver = parts[1] |
| 234 » » } | |
| 235 » » parts := strings.SplitN(value, "-", 2) | |
| 236 » » if len(parts) == 2 { | |
| 237 » » » os = parts[0] | |
| 238 » » » ver = parts[1] | |
| 239 » » » break | |
| 240 » » } | |
| 241 } | 216 } |
| 242 | 217 |
| 243 var base resp.LogoBase | 218 var base resp.LogoBase |
| 244 switch os { | 219 switch os { |
| 245 case "Ubuntu": | 220 case "Ubuntu": |
| 246 base = resp.Ubuntu | 221 base = resp.Ubuntu |
| 247 case "Windows": | 222 case "Windows": |
| 248 base = resp.Windows | 223 base = resp.Windows |
| 249 case "Mac": | 224 case "Mac": |
| 250 base = resp.OSX | 225 base = resp.OSX |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 341 ts, err := time.Parse(SwarmingTimeLayout, sr.CompletedTs) | 316 ts, err := time.Parse(SwarmingTimeLayout, sr.CompletedTs) |
| 342 if err != nil { | 317 if err != nil { |
| 343 return fmt.Errorf("invalid task CompletedTs: %s", err) | 318 return fmt.Errorf("invalid task CompletedTs: %s", err) |
| 344 } | 319 } |
| 345 step.Ended = google.NewTimestamp(ts) | 320 step.Ended = google.NewTimestamp(ts) |
| 346 } | 321 } |
| 347 | 322 |
| 348 return nil | 323 return nil |
| 349 } | 324 } |
| 350 | 325 |
| 326 func addBuildsetInfo(build *resp.MiloBuild, props map[string]string) { | |
|
nodir
2017/02/07 21:56:29
s/props/tags/
hinoka
2017/02/24 00:56:22
Done.
| |
| 327 buildset := props["buildset"] | |
| 328 if strings.HasPrefix(buildset, "patch/") { | |
| 329 if build.SourceStamp == nil { | |
|
nodir
2017/02/07 21:56:29
ah, this is why an empty SourceStamp section appea
hinoka
2017/02/24 00:56:22
Done.
| |
| 330 build.SourceStamp = &resp.SourceStamp{} | |
| 331 } | |
| 332 patchset := strings.TrimLeft(buildset, "patch/") | |
| 333 if strings.HasPrefix(patchset, "gerrit/") { | |
| 334 gerritset := strings.TrimLeft(patchset, "gerrit/") | |
|
nodir
2017/02/07 21:56:30
gerritPatchset?
hinoka
2017/02/24 00:56:22
Done.
| |
| 335 parts := strings.Split(gerritset, "/") | |
| 336 if len(parts) == 3 { | |
| 337 build.SourceStamp.Changelist = &resp.Link{ | |
| 338 Label: "Gerrit CL", | |
| 339 URL: fmt.Sprintf("https://%s/r/%s/%s", parts[0], parts[1], parts[2]), | |
|
nodir
2017/02/07 21:56:30
never saw /r/ before.
did you mean c?
hinoka
2017/02/24 00:56:22
Oops fixed.
| |
| 340 } | |
| 341 } | |
| 342 } | |
| 343 } | |
| 344 } | |
| 345 | |
| 346 func addRecipeLink(build *resp.MiloBuild, props map[string]string) { | |
|
nodir
2017/02/07 21:56:30
tags
hinoka
2017/02/24 00:56:22
Done.
| |
| 347 name := props["recipe_name"] | |
| 348 repo := props["recipe_repository"] | |
| 349 revision := props["recipe_revision"] | |
| 350 if name != "" && repo != "" { | |
| 351 subpath := "/+/" | |
|
nodir
2017/02/07 21:56:30
move /+/ to the format string
hinoka
2017/03/01 22:53:10
Done.
| |
| 352 if revision != "" { | |
| 353 subpath += revision + "/" | |
| 354 } else { | |
| 355 subpath += "master/" | |
| 356 } | |
| 357 if repo == "https://chromium.googlesource.com/chromium/tools/bui ld" { | |
| 358 subpath += "scripts/slave/recipes/" | |
|
nodir
2017/02/07 21:56:29
this isn't right
we should fetch recipes.cfg (htt
hinoka
2017/03/01 22:53:10
That won't work, removing sutpath alltogether
| |
| 359 } | |
|
nodir
2017/02/07 21:56:30
this will not work for any other repos?
for https
hinoka
2017/03/01 22:53:10
Acknowledged.
| |
| 360 build.Summary.Recipe = &resp.Link{ | |
| 361 Label: name, | |
| 362 URL: fmt.Sprintf("%s%s%s.py", repo, subpath, name), | |
| 363 } | |
| 364 } | |
| 365 } | |
| 366 | |
| 351 func addTaskToBuild(c context.Context, server string, sr *swarming.SwarmingRpcsT askResult, build *resp.MiloBuild) error { | 367 func addTaskToBuild(c context.Context, server string, sr *swarming.SwarmingRpcsT askResult, build *resp.MiloBuild) error { |
| 368 selfURL := taskPageURL(server, sr.TaskId) | |
| 352 build.Summary.Label = sr.TaskId | 369 build.Summary.Label = sr.TaskId |
| 353 build.Summary.Type = resp.Recipe | 370 build.Summary.Type = resp.Recipe |
| 354 build.Summary.Source = &resp.Link{ | 371 build.Summary.Source = &resp.Link{ |
| 355 Label: "Task " + sr.TaskId, | 372 Label: "Task " + sr.TaskId, |
| 356 » » URL: taskPageURL(server, sr.TaskId), | 373 » » URL: selfURL, |
| 357 } | 374 } |
| 358 | 375 |
| 359 // Extract more swarming specific information into the properties. | 376 // Extract more swarming specific information into the properties. |
| 360 if props := taskProperties(sr); len(props.Property) > 0 { | 377 if props := taskProperties(sr); len(props.Property) > 0 { |
| 361 build.PropertyGroup = append(build.PropertyGroup, props) | 378 build.PropertyGroup = append(build.PropertyGroup, props) |
| 362 } | 379 } |
| 363 » if props := tagsToProperties(sr.Tags); len(props.Property) > 0 { | 380 » props := tagsToMap(sr.Tags) |
|
nodir
2017/02/07 21:56:30
tags
hinoka
2017/03/01 22:53:10
Done.
| |
| 364 » » build.PropertyGroup = append(build.PropertyGroup, props) | |
| 365 » } | |
| 366 | 381 |
| 367 » addBuilderLink(c, build, server, sr) | 382 » addBuildsetInfo(build, props) |
| 368 » addBanner(build, sr) | 383 » addBanner(build, props) |
| 384 » addBuilderLink(c, build, selfURL, props) | |
| 385 » addRecipeLink(build, props) | |
| 369 | 386 |
| 370 // Add a link to the bot. | 387 // Add a link to the bot. |
| 371 if sr.BotId != "" { | 388 if sr.BotId != "" { |
| 372 build.Summary.Bot = &resp.Link{ | 389 build.Summary.Bot = &resp.Link{ |
| 373 Label: sr.BotId, | 390 Label: sr.BotId, |
| 374 URL: botPageURL(server, sr.BotId), | 391 URL: botPageURL(server, sr.BotId), |
| 375 } | 392 } |
| 376 } | 393 } |
| 377 | 394 |
| 378 return nil | 395 return nil |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 508 case *miloProto.Link_Url: | 525 case *miloProto.Link_Url: |
| 509 return &resp.Link{ | 526 return &resp.Link{ |
| 510 Label: l.Label, | 527 Label: l.Label, |
| 511 URL: t.Url, | 528 URL: t.Url, |
| 512 } | 529 } |
| 513 | 530 |
| 514 default: | 531 default: |
| 515 return nil | 532 return nil |
| 516 } | 533 } |
| 517 } | 534 } |
| OLD | NEW |