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

Side by Side Diff: scheduler/appengine/catalog/catalog.go

Issue 2575383002: Add server/cache support to gaeconfig. (Closed)
Patch Set: Un-collapse. Created 3 years, 11 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/settings/config_test.go ('k') | scheduler/appengine/catalog/catalog_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
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 catalog implements a part that talks to luci-config service to fetch 5 // Package catalog implements a part that talks to luci-config service to fetch
6 // and parse job definitions. Catalog knows about all task types and can 6 // and parse job definitions. Catalog knows about all task types and can
7 // instantiate task.Manager's. 7 // instantiate task.Manager's.
8 package catalog 8 package catalog
9 9
10 import ( 10 import (
11 "fmt" 11 "fmt"
12 "net/url" 12 "net/url"
13 "reflect" 13 "reflect"
14 "regexp" 14 "regexp"
15 "strings" 15 "strings"
16 16
17 "github.com/golang/protobuf/proto" 17 "github.com/golang/protobuf/proto"
18 "golang.org/x/net/context" 18 "golang.org/x/net/context"
19 19
20 "github.com/luci/gae/service/info" 20 "github.com/luci/gae/service/info"
21 "github.com/luci/luci-go/common/config"
22 "github.com/luci/luci-go/common/logging" 21 "github.com/luci/luci-go/common/logging"
22 "github.com/luci/luci-go/luci_config/common/cfgtypes"
23 "github.com/luci/luci-go/luci_config/server/cfgclient"
24 "github.com/luci/luci-go/luci_config/server/cfgclient/textproto"
23 25
24 "github.com/luci/luci-go/scheduler/appengine/messages" 26 "github.com/luci/luci-go/scheduler/appengine/messages"
25 "github.com/luci/luci-go/scheduler/appengine/schedule" 27 "github.com/luci/luci-go/scheduler/appengine/schedule"
26 "github.com/luci/luci-go/scheduler/appengine/task" 28 "github.com/luci/luci-go/scheduler/appengine/task"
27 ) 29 )
28 30
29 var ( 31 var (
30 // jobIDRe is used to validate job ID field. 32 // jobIDRe is used to validate job ID field.
31 jobIDRe = regexp.MustCompile(`^[0-9A-Za-z_\-\.]{1,100}$`) 33 jobIDRe = regexp.MustCompile(`^[0-9A-Za-z_\-\.]{1,100}$`)
32 ) 34 )
(...skipping 21 matching lines...) Expand all
54 GetTaskManager(m proto.Message) task.Manager 56 GetTaskManager(m proto.Message) task.Manager
55 57
56 // UnmarshalTask takes a serialized task definition (as in Definition.Ta sk), 58 // UnmarshalTask takes a serialized task definition (as in Definition.Ta sk),
57 // unmarshals and validates it, and returns proto.Message that represent 59 // unmarshals and validates it, and returns proto.Message that represent
58 // the concrete task to run (e.g. SwarmingTask proto). It can be passed to 60 // the concrete task to run (e.g. SwarmingTask proto). It can be passed to
59 // corresponding task.Manager. 61 // corresponding task.Manager.
60 UnmarshalTask(task []byte) (proto.Message, error) 62 UnmarshalTask(task []byte) (proto.Message, error)
61 63
62 // GetAllProjects returns a list of all known project ids. 64 // GetAllProjects returns a list of all known project ids.
63 // 65 //
64 » // It assumes there's config.Interface implementation installed in 66 » // It assumes there's cfgclient implementation installed in
65 // the context, will panic if it's not there. 67 // the context, will panic if it's not there.
66 GetAllProjects(c context.Context) ([]string, error) 68 GetAllProjects(c context.Context) ([]string, error)
67 69
68 // GetProjectJobs returns a list of scheduler jobs defined within a proj ect or 70 // GetProjectJobs returns a list of scheduler jobs defined within a proj ect or
69 // empty list if no such project. 71 // empty list if no such project.
70 // 72 //
71 » // It assumes there's config.Interface implementation installed in 73 » // It assumes there's cfgclient implementation installed in
72 // the context, will panic if it's not there. 74 // the context, will panic if it's not there.
73 GetProjectJobs(c context.Context, projectID string) ([]Definition, error ) 75 GetProjectJobs(c context.Context, projectID string) ([]Definition, error )
74 } 76 }
75 77
76 // JobFlavor describes a category of jobs. 78 // JobFlavor describes a category of jobs.
77 type JobFlavor int 79 type JobFlavor int
78 80
79 const ( 81 const (
80 // JobFlavorPeriodic is a regular job (Swarming, Buildbucket) that runs on 82 // JobFlavorPeriodic is a regular job (Swarming, Buildbucket) that runs on
81 // a schedule or via a trigger. 83 // a schedule or via a trigger.
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
157 msg := messages.TaskDefWrapper{} 159 msg := messages.TaskDefWrapper{}
158 if err := proto.Unmarshal(task, &msg); err != nil { 160 if err := proto.Unmarshal(task, &msg); err != nil {
159 return nil, err 161 return nil, err
160 } 162 }
161 return cat.extractTaskProto(&msg) 163 return cat.extractTaskProto(&msg)
162 } 164 }
163 165
164 func (cat *catalog) GetAllProjects(c context.Context) ([]string, error) { 166 func (cat *catalog) GetAllProjects(c context.Context) ([]string, error) {
165 // Enumerate all projects that have <config>.cfg. Do not fetch actual co nfigs 167 // Enumerate all projects that have <config>.cfg. Do not fetch actual co nfigs
166 // yet. 168 // yet.
167 » cfgs, err := config.GetProjectConfigs(c, cat.configFile(c), true) 169 » var metas []*cfgclient.Meta
168 » if err != nil { 170 » if err := cfgclient.Projects(c, cfgclient.AsService, cat.configFile(c), nil, &metas); err != nil {
169 return nil, err 171 return nil, err
170 } 172 }
171 » out := make([]string, 0, len(cfgs)) 173
172 » for _, cfg := range cfgs { 174 » out := make([]string, 0, len(metas))
173 » » // ConfigSet must be "projects/<project-id>". Verify that. 175 » for _, meta := range metas {
174 » » chunks := strings.Split(cfg.ConfigSet, "/") 176 » » projectName, _, _ := meta.ConfigSet.SplitProject()
175 » » if len(chunks) != 2 || chunks[0] != "projects" { 177 » » if projectName == "" {
176 » » » logging.Warningf(c, "Unexpected ConfigSet: %s", cfg.Conf igSet) 178 » » » logging.Warningf(c, "Unexpected ConfigSet: %s", meta.Con figSet)
177 } else { 179 } else {
178 » » » out = append(out, chunks[1]) 180 » » » out = append(out, string(projectName))
179 } 181 }
180 } 182 }
181 return out, nil 183 return out, nil
182 } 184 }
183 185
184 func (cat *catalog) GetProjectJobs(c context.Context, projectID string) ([]Defin ition, error) { 186 func (cat *catalog) GetProjectJobs(c context.Context, projectID string) ([]Defin ition, error) {
185 » configSetURL, err := config.GetConfigSetLocation(c, "projects/"+projectI D) 187 » configSet := cfgtypes.ProjectConfigSet(cfgtypes.ProjectName(projectID))
188 » configSetURL, err := cfgclient.GetConfigSetURL(c, cfgclient.AsService, c onfigSet)
186 switch err { 189 switch err {
187 case nil: // Continue 190 case nil: // Continue
188 » case config.ErrNoConfig: 191 » case cfgclient.ErrNoConfig:
189 return nil, nil 192 return nil, nil
190 default: 193 default:
191 return nil, err 194 return nil, err
192 } 195 }
193 196
194 » rawCfg, err := config.GetConfig(c, "projects/"+projectID, cat.configFile (c), false) 197 » var (
195 » if err == config.ErrNoConfig { 198 » » cfg messages.ProjectConfig
199 » » meta cfgclient.Meta
200 » )
201 » switch err := cfgclient.Get(c, cfgclient.AsService, configSet, cat.confi gFile(c), textproto.Message(&cfg), &meta); err {
202 » case nil:
203 » » break
204 » case cfgclient.ErrNoConfig:
196 return nil, nil 205 return nil, nil
197 » } 206 » default:
198 » if err != nil {
199 return nil, err 207 return nil, err
200 } 208 }
201 » revisionURL := getRevisionURL(configSetURL, rawCfg.Revision, rawCfg.Path ) 209
210 » revisionURL := getRevisionURL(&configSetURL, meta.Revision, meta.Path)
202 if revisionURL != "" { 211 if revisionURL != "" {
203 logging.Infof(c, "Importing %s", revisionURL) 212 logging.Infof(c, "Importing %s", revisionURL)
204 } 213 }
205 cfg := messages.ProjectConfig{}
206 if err = proto.UnmarshalText(rawCfg.Content, &cfg); err != nil {
207 return nil, err
208 }
209 214
210 out := make([]Definition, 0, len(cfg.Job)+len(cfg.Trigger)) 215 out := make([]Definition, 0, len(cfg.Job)+len(cfg.Trigger))
211 216
212 // Regular jobs, triggered jobs. 217 // Regular jobs, triggered jobs.
213 for _, job := range cfg.Job { 218 for _, job := range cfg.Job {
214 if job.Disabled { 219 if job.Disabled {
215 continue 220 continue
216 } 221 }
217 id := "(empty)" 222 id := "(empty)"
218 if job.Id != "" { 223 if job.Id != "" {
(...skipping 13 matching lines...) Expand all
232 if schedule == "" { 237 if schedule == "" {
233 schedule = defaultJobSchedule 238 schedule = defaultJobSchedule
234 } 239 }
235 flavor := JobFlavorTriggered 240 flavor := JobFlavorTriggered
236 if schedule != "triggered" { 241 if schedule != "triggered" {
237 flavor = JobFlavorPeriodic 242 flavor = JobFlavorPeriodic
238 } 243 }
239 out = append(out, Definition{ 244 out = append(out, Definition{
240 JobID: fmt.Sprintf("%s/%s", projectID, job.Id), 245 JobID: fmt.Sprintf("%s/%s", projectID, job.Id),
241 Flavor: flavor, 246 Flavor: flavor,
242 » » » Revision: rawCfg.Revision, 247 » » » Revision: meta.Revision,
243 RevisionURL: revisionURL, 248 RevisionURL: revisionURL,
244 Schedule: schedule, 249 Schedule: schedule,
245 Task: packed, 250 Task: packed,
246 }) 251 })
247 } 252 }
248 253
249 // Triggering jobs. 254 // Triggering jobs.
250 for _, trigger := range cfg.Trigger { 255 for _, trigger := range cfg.Trigger {
251 if trigger.Disabled { 256 if trigger.Disabled {
252 continue 257 continue
(...skipping 12 matching lines...) Expand all
265 logging.Errorf(c, "Failed to marshal the task: %s/%s: %s ", projectID, id, err) 270 logging.Errorf(c, "Failed to marshal the task: %s/%s: %s ", projectID, id, err)
266 continue 271 continue
267 } 272 }
268 schedule := trigger.Schedule 273 schedule := trigger.Schedule
269 if schedule == "" { 274 if schedule == "" {
270 schedule = defaultTriggerSchedule 275 schedule = defaultTriggerSchedule
271 } 276 }
272 out = append(out, Definition{ 277 out = append(out, Definition{
273 JobID: fmt.Sprintf("%s/%s", projectID, trigger.Id) , 278 JobID: fmt.Sprintf("%s/%s", projectID, trigger.Id) ,
274 Flavor: JobFlavorTrigger, 279 Flavor: JobFlavorTrigger,
275 » » » Revision: rawCfg.Revision, 280 » » » Revision: meta.Revision,
276 RevisionURL: revisionURL, 281 RevisionURL: revisionURL,
277 Schedule: schedule, 282 Schedule: schedule,
278 Task: packed, 283 Task: packed,
279 }) 284 })
280 } 285 }
281 286
282 return out, nil 287 return out, nil
283 } 288 }
284 289
285 // configFile returns a name of *.cfg file (inside project's config set) with 290 // configFile returns a name of *.cfg file (inside project's config set) with
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
411 field := v.Field(i) 416 field := v.Field(i)
412 if field.Type() == taskType { 417 if field.Type() == taskType {
413 field.Set(reflect.ValueOf(task)) 418 field.Set(reflect.ValueOf(task))
414 return proto.Marshal(&wrapper) 419 return proto.Marshal(&wrapper)
415 } 420 }
416 } 421 }
417 // This can happen only if TaskDefWrapper wasn't updated when a new task type 422 // This can happen only if TaskDefWrapper wasn't updated when a new task type
418 // was added. This is a developer's mistake, not a config mistake. 423 // was added. This is a developer's mistake, not a config mistake.
419 return nil, fmt.Errorf("could not find a field of type %T in TaskDefWrap per", task) 424 return nil, fmt.Errorf("could not find a field of type %T in TaskDefWrap per", task)
420 } 425 }
OLDNEW
« no previous file with comments | « milo/appengine/settings/config_test.go ('k') | scheduler/appengine/catalog/catalog_test.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698