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

Side by Side Diff: milo/appengine/swarming/buildinfo.go

Issue 2667363002: milo: Add a build info Swarming implementation. (Closed)
Patch Set: Rebarse Created 3 years, 10 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
« no previous file with comments | « milo/appengine/swarming/build.go ('k') | milo/appengine/swarming/buildinfo_test.go » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2017 The LUCI Authors. All rights reserved.
2 // Use of this source code is governed under the Apache License, Version 2.0
3 // that can be found in the LICENSE file.
4
5 package swarming
6
7 import (
8 "strings"
9
10 swarming "github.com/luci/luci-go/common/api/swarming/swarming/v1"
11 "github.com/luci/luci-go/common/logging"
12 miloProto "github.com/luci/luci-go/common/proto/milo"
13 "github.com/luci/luci-go/grpc/grpcutil"
14 "github.com/luci/luci-go/logdog/client/coordinator"
15 "github.com/luci/luci-go/logdog/common/types"
16 "github.com/luci/luci-go/luci_config/common/cfgtypes"
17 milo "github.com/luci/luci-go/milo/api/proto"
18 "github.com/luci/luci-go/milo/appengine/logdog"
19
20 "golang.org/x/net/context"
21 )
22
23 // BuildInfoProvider is a configuration that provides build information.
hinoka 2017/02/07 20:07:24 s/configuration/service/ ?
dnj 2017/02/07 23:06:09 Done.
24 //
25 // In a production system, this will be completely defaults. For testing, the
26 // various services and data sources may be substituted for testing stubs.
27 type BuildInfoProvider struct {
28 // LogdogClientFunc returns a coordinator Client instance for the suppli ed
29 // parameters.
30 //
31 // If nil, a production client will be generated.
32 LogdogClientFunc func(c context.Context) (*coordinator.Client, error)
33
34 // swarmingServiceFunc returns a swarmingService instance for the suppli ed
35 // parameters.
36 //
37 // If nil, a production fetcher will be generated.
38 swarmingServiceFunc func(c context.Context, host string) (swarmingServic e, error)
39 }
40
41 func (p *BuildInfoProvider) newLogdogClient(c context.Context) (*coordinator.Cli ent, error) {
42 if p.LogdogClientFunc != nil {
43 return p.LogdogClientFunc(c)
44 }
45 return logdog.NewClient(c, "")
46 }
47
48 func (p *BuildInfoProvider) newSwarmingService(c context.Context, host string) ( swarmingService, error) {
49 fn := p.swarmingServiceFunc
50 if fn == nil {
51 fn = getSwarmingService
52 }
53 return fn(c, host)
54 }
55
56 // GetBuildInfo resolves a Milo protobuf Step for a given Swarming task.
57 func (p *BuildInfoProvider) GetBuildInfo(c context.Context, req *milo.BuildInfoR equest_Swarming,
58 projectHint cfgtypes.ProjectName) (*milo.BuildInfoResponse, error) {
59
60 // Load the Swarming task (no log content).
61 sf, err := p.newSwarmingService(c, req.Host)
62 if err != nil {
63 logging.WithError(err).Errorf(c, "Failed to create Swarming fetc her.")
64 return nil, grpcutil.Internal
65 }
66
67 // Use default Swarming host.
68 host := sf.getHost()
69 logging.Infof(c, "Loading build info for Swarming host %s, task %s.", ho st, req.Task)
70
71 fetchParams := swarmingFetchParams{
72 fetchReq: true,
73 fetchRes: true,
74 }
75 fr, err := swarmingFetch(c, sf, req.Task, fetchParams)
76 if err != nil {
77 if err == errNotMiloJob {
78 logging.Warningf(c, "User requested non-Milo task.")
79 return nil, grpcutil.NotFound
80 }
81
82 logging.WithError(err).Errorf(c, "Failed to load Swarming task." )
83 return nil, grpcutil.Internal
84 }
85
86 // Determine the LogDog annotation stream path for this Swarming task.
87 //
88 // On failure, will return a gRPC error.
89 as, err := getLogDogAnnotations(c, fr.req, projectHint, host, req.Task)
90 if err != nil {
91 logging.WithError(err).Warningf(c, "Failed to get annotation str eam parameters.")
92 return nil, err
93 }
94 if err := as.Normalize(); err != nil {
95 logging.WithError(err).Warningf(c, "Failed to normalize annotati on stream parameters.")
96 return nil, grpcutil.Internal
97 }
98
99 client, err := p.newLogdogClient(c)
100 if err != nil {
101 logging.WithError(err).Errorf(c, "Failed to create LogDog client .")
102 return nil, grpcutil.Internal
103 }
104
105 as.Client = client
106 step, err := as.Load(c)
hinoka 2017/02/07 20:07:24 This is an RPC call right? Add a comment here deno
dnj 2017/02/07 23:06:09 Done.
107 if err != nil {
108 logging.WithError(err).Warningf(c, "Failed to load annotation st ream.")
109 return nil, grpcutil.Internal
110 }
111
112 // Add Swarming task parameters to the Milo step.
113 if err := addTaskToMiloStep(c, sf.getHost(), fr.res, step); err != nil {
114 return nil, err
115 }
116
117 prefix, name := as.Path.Split()
118 return &milo.BuildInfoResponse{
119 Project: string(as.Project),
120 Step: step,
121 AnnotationStream: &miloProto.LogdogStream{
122 Server: client.Host,
123 Prefix: string(prefix),
124 Name: string(name),
125 },
126 }, nil
127 }
128
129 // getLogDogAnnotations returns a configured AnnotationStream given the input
130 // parameters.
131 //
132 // This will return a gRPC error on failure.
133 //
134 // This function is messy and implementation-specific. That's the point of this
135 // endpoint, though. All of the nastiness here should be replaced with something
136 // more elegant once that becomes available. In the meantime...
137 func getLogDogAnnotations(c context.Context, sr *swarming.SwarmingRpcsTaskReques t, projectHint cfgtypes.ProjectName,
hinoka 2017/02/07 20:07:24 I think "resolveLogDogAnnotations" is clearer
dnj 2017/02/07 23:06:09 Done.
138 host, taskID string) (*logdog.AnnotationStream, error) {
139
140 // If this is a Kitchen command, maybe we can infer our LogDog project f rom
141 // the command-line.
142 var as logdog.AnnotationStream
143 if sr.Properties == nil {
144 logging.Warningf(c, "No request properties, can't infer annotati on stream path.")
145 return nil, grpcutil.NotFound
146 }
147
148 var isKitchen bool
149 if as.Project, isKitchen = getLogDogProjectFromKitchen(sr.Properties.Com mand); !isKitchen {
150 logging.Warningf(c, "Not a Kitchen CLI, can't infer annotation s tream path.")
151 return nil, grpcutil.NotFound
152 }
153
154 if as.Project == "" {
155 as.Project = projectHint
156 }
157 if as.Project == "" {
158 logging.Warningf(c, "Don't know how to get annotation stream pat h.")
159 return nil, grpcutil.NotFound
160 }
161
162 // This is a Kitchen run, and it has a project! Construct the annotation
163 // stream path.
164 //
165 // This is an implementation of:
166 // https://chromium.googlesource.com/infra/infra/+/a7032e3e240d4b81a1912 bfaf29a20d02f665cc1/go/src/infra/tools/kitchen/cook_logdog.go#129
167 prefix, err := types.MakeStreamName("", "swarm", host, taskID)
168 if err != nil {
169 logging.WithError(err).Errorf(c, "Failed to generate Swarming pr efix.")
170 return nil, grpcutil.Internal
171 }
172 as.Path = prefix.Join("annotations")
173 return &as, nil
174 }
175
176 func getLogDogProjectFromKitchen(cmd []string) (proj cfgtypes.ProjectName, isKit chen bool) {
177 // Is this a Kitchen command?
178 switch {
179 case len(cmd) == 0:
180 return
181 case !strings.HasPrefix(cmd[0], "kitchen"):
182 return
183 }
184 isKitchen = true
185 cmd = cmd[1:]
186
187 // Scan through for the "-logdog-project" argument.
188 for i, arg := range cmd {
189 if arg == "-logdog-project" {
190 if i < len(cmd)-2 {
191 proj = cfgtypes.ProjectName(cmd[i+1])
192 return
193 }
194 break
195 }
196 }
197 return
198 }
OLDNEW
« no previous file with comments | « milo/appengine/swarming/build.go ('k') | milo/appengine/swarming/buildinfo_test.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698