| OLD | NEW |
| 1 // Copyright 2017 The LUCI Authors. All rights reserved. | 1 // Copyright 2017 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 "strconv" | 8 "strconv" |
| 9 "strings" | 9 "strings" |
| 10 "unicode/utf8" | 10 "unicode/utf8" |
| 11 | 11 |
| 12 swarming "github.com/luci/luci-go/common/api/swarming/swarming/v1" | 12 swarming "github.com/luci/luci-go/common/api/swarming/swarming/v1" |
| 13 "github.com/luci/luci-go/common/errors" | 13 "github.com/luci/luci-go/common/errors" |
| 14 "github.com/luci/luci-go/common/logging" | 14 "github.com/luci/luci-go/common/logging" |
| 15 miloProto "github.com/luci/luci-go/common/proto/milo" | 15 miloProto "github.com/luci/luci-go/common/proto/milo" |
| 16 "github.com/luci/luci-go/grpc/grpcutil" | 16 "github.com/luci/luci-go/grpc/grpcutil" |
| 17 "github.com/luci/luci-go/logdog/common/types" | 17 "github.com/luci/luci-go/logdog/common/types" |
| 18 "github.com/luci/luci-go/luci_config/common/cfgtypes" | 18 "github.com/luci/luci-go/luci_config/common/cfgtypes" |
| 19 milo "github.com/luci/luci-go/milo/api/proto" | 19 milo "github.com/luci/luci-go/milo/api/proto" |
| 20 "github.com/luci/luci-go/swarming/tasktemplate" |
| 20 | 21 |
| 21 "golang.org/x/net/context" | 22 "golang.org/x/net/context" |
| 22 ) | 23 ) |
| 23 | 24 |
| 24 // BuildInfoProvider provides build information. | 25 // BuildInfoProvider provides build information. |
| 25 // | 26 // |
| 26 // In a production system, this will be completely defaults. For testing, the | 27 // In a production system, this will be completely defaults. For testing, the |
| 27 // various services and data sources may be substituted for testing stubs. | 28 // various services and data sources may be substituted for testing stubs. |
| 28 type BuildInfoProvider struct { | 29 type BuildInfoProvider struct { |
| 29 bl buildLoader | 30 bl buildLoader |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 124 // This will return a gRPC error on failure. | 125 // This will return a gRPC error on failure. |
| 125 // | 126 // |
| 126 // This function is messy and implementation-specific. That's the point of this | 127 // This function is messy and implementation-specific. That's the point of this |
| 127 // endpoint, though. All of the nastiness here should be replaced with something | 128 // endpoint, though. All of the nastiness here should be replaced with something |
| 128 // more elegant once that becomes available. In the meantime... | 129 // more elegant once that becomes available. In the meantime... |
| 129 func resolveLogDogAnnotations(c context.Context, sr *swarming.SwarmingRpcsTaskRe
quest, projectHint cfgtypes.ProjectName, | 130 func resolveLogDogAnnotations(c context.Context, sr *swarming.SwarmingRpcsTaskRe
quest, projectHint cfgtypes.ProjectName, |
| 130 host, taskID string, tryNumber int64) (*types.StreamAddr, error) { | 131 host, taskID string, tryNumber int64) (*types.StreamAddr, error) { |
| 131 | 132 |
| 132 // Try and resolve from explicit tags (preferred). | 133 // Try and resolve from explicit tags (preferred). |
| 133 tags := swarmingTags(sr.Tags) | 134 tags := swarmingTags(sr.Tags) |
| 134 » addr, err := resolveLogDogStreamAddrFromTags(tags) | 135 » addr, err := resolveLogDogStreamAddrFromTags(tags, taskID, tryNumber) |
| 135 if err == nil { | 136 if err == nil { |
| 136 return addr, nil | 137 return addr, nil |
| 137 } | 138 } |
| 138 logging.WithError(err).Debugf(c, "Could not resolve stream address from
tags.") | 139 logging.WithError(err).Debugf(c, "Could not resolve stream address from
tags.") |
| 139 | 140 |
| 140 // If this is a Kitchen command, maybe we can infer our LogDog project f
rom | 141 // If this is a Kitchen command, maybe we can infer our LogDog project f
rom |
| 141 // the command-line. | 142 // the command-line. |
| 142 if sr.Properties == nil { | 143 if sr.Properties == nil { |
| 143 logging.Warningf(c, "No request properties, can't infer annotati
on stream path.") | 144 logging.Warningf(c, "No request properties, can't infer annotati
on stream path.") |
| 144 return nil, grpcutil.NotFound | 145 return nil, grpcutil.NotFound |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 200 if i < len(cmd)-2 { | 201 if i < len(cmd)-2 { |
| 201 proj = cfgtypes.ProjectName(cmd[i+1]) | 202 proj = cfgtypes.ProjectName(cmd[i+1]) |
| 202 return | 203 return |
| 203 } | 204 } |
| 204 break | 205 break |
| 205 } | 206 } |
| 206 } | 207 } |
| 207 return | 208 return |
| 208 } | 209 } |
| 209 | 210 |
| 210 func resolveLogDogStreamAddrFromTags(tags map[string]string) (*types.StreamAddr,
error) { | 211 func resolveLogDogStreamAddrFromTags(tags map[string]string, taskID string, tryN
umber int64) (*types.StreamAddr, error) { |
| 211 // If we don't have a LUCI project, abort. | 212 // If we don't have a LUCI project, abort. |
| 212 luciProject, logLocation := tags["luci_project"], tags["log_location"] | 213 luciProject, logLocation := tags["luci_project"], tags["log_location"] |
| 213 switch { | 214 switch { |
| 214 case luciProject == "": | 215 case luciProject == "": |
| 215 return nil, errors.New("no 'luci_project' tag") | 216 return nil, errors.New("no 'luci_project' tag") |
| 216 case logLocation == "": | 217 case logLocation == "": |
| 217 return nil, errors.New("no 'log_location' tag") | 218 return nil, errors.New("no 'log_location' tag") |
| 218 } | 219 } |
| 219 | 220 |
| 221 // Gather our Swarming task template parameters and perform a substituti
on. |
| 222 runID, err := getRunID(taskID, tryNumber) |
| 223 if err != nil { |
| 224 return nil, errors.Annotate(err).Err() |
| 225 } |
| 226 p := tasktemplate.Params{ |
| 227 SwarmingRunID: runID, |
| 228 } |
| 229 if logLocation, err = p.Resolve(logLocation); err != nil { |
| 230 return nil, errors.Annotate(err).Reason("failed to resolve swarm
ing task templating in 'log_location'").Err() |
| 231 } |
| 232 |
| 220 addr, err := types.ParseURL(logLocation) | 233 addr, err := types.ParseURL(logLocation) |
| 221 if err != nil { | 234 if err != nil { |
| 222 return nil, errors.Annotate(err).Reason("could not parse LogDog
stream from location").Err() | 235 return nil, errors.Annotate(err).Reason("could not parse LogDog
stream from location").Err() |
| 223 } | 236 } |
| 224 | 237 |
| 225 // The LogDog stream's project should match the LUCI project. | 238 // The LogDog stream's project should match the LUCI project. |
| 226 if string(addr.Project) != luciProject { | 239 if string(addr.Project) != luciProject { |
| 227 return nil, errors.Reason("stream project %(streamProject)q does
n't match LUCI project %(luciProject)q"). | 240 return nil, errors.Reason("stream project %(streamProject)q does
n't match LUCI project %(luciProject)q"). |
| 228 D("luciProject", luciProject). | 241 D("luciProject", luciProject). |
| 229 D("streamProject", addr.Project). | 242 D("streamProject", addr.Project). |
| (...skipping 25 matching lines...) Expand all Loading... |
| 255 lastChar, lastCharSize := utf8.DecodeLastRuneInString(taskID) | 268 lastChar, lastCharSize := utf8.DecodeLastRuneInString(taskID) |
| 256 v, err := strconv.ParseUint(string(lastChar), 16, 8) | 269 v, err := strconv.ParseUint(string(lastChar), 16, 8) |
| 257 if err != nil { | 270 if err != nil { |
| 258 return "", errors.Annotate(err).Reason("failed to parse hex from
rune: %(rune)r"). | 271 return "", errors.Annotate(err).Reason("failed to parse hex from
rune: %(rune)r"). |
| 259 D("rune", lastChar). | 272 D("rune", lastChar). |
| 260 Err() | 273 Err() |
| 261 } | 274 } |
| 262 | 275 |
| 263 return taskID[:len(taskID)-lastCharSize] + strconv.FormatUint((v|uint64(
tryNumber)), 16), nil | 276 return taskID[:len(taskID)-lastCharSize] + strconv.FormatUint((v|uint64(
tryNumber)), 16), nil |
| 264 } | 277 } |
| OLD | NEW |