| OLD | NEW |
| 1 // Copyright 2015 The LUCI Authors. | 1 // Copyright 2015 The LUCI Authors. |
| 2 // | 2 // |
| 3 // Licensed under the Apache License, Version 2.0 (the "License"); | 3 // Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 // you may not use this file except in compliance with the License. | 4 // you may not use this file except in compliance with the License. |
| 5 // You may obtain a copy of the License at | 5 // You may obtain a copy of the License at |
| 6 // | 6 // |
| 7 // http://www.apache.org/licenses/LICENSE-2.0 | 7 // http://www.apache.org/licenses/LICENSE-2.0 |
| 8 // | 8 // |
| 9 // Unless required by applicable law or agreed to in writing, software | 9 // Unless required by applicable law or agreed to in writing, software |
| 10 // distributed under the License is distributed on an "AS IS" BASIS, | 10 // distributed under the License is distributed on an "AS IS" BASIS, |
| (...skipping 15 matching lines...) Expand all Loading... |
| 26 | 26 |
| 27 "github.com/golang/protobuf/proto" | 27 "github.com/golang/protobuf/proto" |
| 28 "golang.org/x/net/context" | 28 "golang.org/x/net/context" |
| 29 | 29 |
| 30 "github.com/luci/gae/service/info" | 30 "github.com/luci/gae/service/info" |
| 31 "github.com/luci/luci-go/common/logging" | 31 "github.com/luci/luci-go/common/logging" |
| 32 "github.com/luci/luci-go/luci_config/common/cfgtypes" | 32 "github.com/luci/luci-go/luci_config/common/cfgtypes" |
| 33 "github.com/luci/luci-go/luci_config/server/cfgclient" | 33 "github.com/luci/luci-go/luci_config/server/cfgclient" |
| 34 "github.com/luci/luci-go/luci_config/server/cfgclient/textproto" | 34 "github.com/luci/luci-go/luci_config/server/cfgclient/textproto" |
| 35 | 35 |
| 36 "github.com/luci/luci-go/common/errors" |
| 37 "github.com/luci/luci-go/scheduler/appengine/acl" |
| 36 "github.com/luci/luci-go/scheduler/appengine/messages" | 38 "github.com/luci/luci-go/scheduler/appengine/messages" |
| 37 "github.com/luci/luci-go/scheduler/appengine/schedule" | 39 "github.com/luci/luci-go/scheduler/appengine/schedule" |
| 38 "github.com/luci/luci-go/scheduler/appengine/task" | 40 "github.com/luci/luci-go/scheduler/appengine/task" |
| 39 ) | 41 ) |
| 40 | 42 |
| 41 var ( | 43 var ( |
| 42 // jobIDRe is used to validate job ID field. | 44 // jobIDRe is used to validate job ID field. |
| 43 jobIDRe = regexp.MustCompile(`^[0-9A-Za-z_\-\.]{1,100}$`) | 45 jobIDRe = regexp.MustCompile(`^[0-9A-Za-z_\-\.]{1,100}$`) |
| 44 ) | 46 ) |
| 45 | 47 |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 105 // | 107 // |
| 106 // Defined via 'trigger {...}' config stanza. | 108 // Defined via 'trigger {...}' config stanza. |
| 107 JobFlavorTrigger | 109 JobFlavorTrigger |
| 108 ) | 110 ) |
| 109 | 111 |
| 110 // Definition wraps definition of a scheduler job fetched from the config. | 112 // Definition wraps definition of a scheduler job fetched from the config. |
| 111 type Definition struct { | 113 type Definition struct { |
| 112 // JobID is globally unique job identifier: "<ProjectID>/<JobName>". | 114 // JobID is globally unique job identifier: "<ProjectID>/<JobName>". |
| 113 JobID string | 115 JobID string |
| 114 | 116 |
| 117 // Acls describes who can read and who owns this job. |
| 118 Acls acl.GrantsByRole |
| 119 |
| 115 // Flavor describes what category of jobs this is, see the enum. | 120 // Flavor describes what category of jobs this is, see the enum. |
| 116 Flavor JobFlavor | 121 Flavor JobFlavor |
| 117 | 122 |
| 118 // Revision is config revision this definition was fetched from. | 123 // Revision is config revision this definition was fetched from. |
| 119 Revision string | 124 Revision string |
| 120 | 125 |
| 121 // RevisionURL is URL to human readable page with config file. | 126 // RevisionURL is URL to human readable page with config file. |
| 122 RevisionURL string | 127 RevisionURL string |
| 123 | 128 |
| 124 // Schedule is job's schedule in regular cron expression format. | 129 // Schedule is job's schedule in regular cron expression format. |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 187 if projectName == "" { | 192 if projectName == "" { |
| 188 logging.Warningf(c, "Unexpected ConfigSet: %s", meta.Con
figSet) | 193 logging.Warningf(c, "Unexpected ConfigSet: %s", meta.Con
figSet) |
| 189 } else { | 194 } else { |
| 190 out = append(out, string(projectName)) | 195 out = append(out, string(projectName)) |
| 191 } | 196 } |
| 192 } | 197 } |
| 193 return out, nil | 198 return out, nil |
| 194 } | 199 } |
| 195 | 200 |
| 196 func (cat *catalog) GetProjectJobs(c context.Context, projectID string) ([]Defin
ition, error) { | 201 func (cat *catalog) GetProjectJobs(c context.Context, projectID string) ([]Defin
ition, error) { |
| 197 » // TODO(vadimsh): This is a workaround for crbug.com/710619. Remove it o
nce | 202 » // TODO(vadimsh): This is a workaround for http://crbug.com/710619. Remo
ve it |
| 198 » // the bug is fixed. | 203 » // once the bug is fixed. |
| 199 projects, err := cat.GetAllProjects(c) | 204 projects, err := cat.GetAllProjects(c) |
| 200 if err != nil { | 205 if err != nil { |
| 201 return nil, err | 206 return nil, err |
| 202 } | 207 } |
| 203 found := false | 208 found := false |
| 204 for _, p := range projects { | 209 for _, p := range projects { |
| 205 if p == projectID { | 210 if p == projectID { |
| 206 found = true | 211 found = true |
| 207 } | 212 } |
| 208 } | 213 } |
| (...skipping 21 matching lines...) Expand all Loading... |
| 230 case cfgclient.ErrNoConfig: | 235 case cfgclient.ErrNoConfig: |
| 231 return nil, nil | 236 return nil, nil |
| 232 default: | 237 default: |
| 233 return nil, err | 238 return nil, err |
| 234 } | 239 } |
| 235 | 240 |
| 236 revisionURL := getRevisionURL(&configSetURL, meta.Revision, meta.Path) | 241 revisionURL := getRevisionURL(&configSetURL, meta.Revision, meta.Path) |
| 237 if revisionURL != "" { | 242 if revisionURL != "" { |
| 238 logging.Infof(c, "Importing %s", revisionURL) | 243 logging.Infof(c, "Importing %s", revisionURL) |
| 239 } | 244 } |
| 245 // TODO(tandrii): make use of https://godoc.org/github.com/luci/luci-go/
common/config/validation |
| 246 knownAclSets, err := acl.ValidateAclSets(cfg.GetAclSets()) |
| 247 if err != nil { |
| 248 logging.Errorf(c, "Invalid aclsets definition %s: %s", projectID
, err) |
| 249 return nil, errors.Annotate(err, "invalid aclsets in a project %
s", projectID).Err() |
| 250 } |
| 240 | 251 |
| 241 out := make([]Definition, 0, len(cfg.Job)+len(cfg.Trigger)) | 252 out := make([]Definition, 0, len(cfg.Job)+len(cfg.Trigger)) |
| 242 | 253 |
| 243 // Regular jobs, triggered jobs. | 254 // Regular jobs, triggered jobs. |
| 244 for _, job := range cfg.Job { | 255 for _, job := range cfg.Job { |
| 245 if job.Disabled { | 256 if job.Disabled { |
| 246 continue | 257 continue |
| 247 } | 258 } |
| 248 id := "(empty)" | 259 id := "(empty)" |
| 249 if job.Id != "" { | 260 if job.Id != "" { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 260 continue | 271 continue |
| 261 } | 272 } |
| 262 schedule := job.Schedule | 273 schedule := job.Schedule |
| 263 if schedule == "" { | 274 if schedule == "" { |
| 264 schedule = defaultJobSchedule | 275 schedule = defaultJobSchedule |
| 265 } | 276 } |
| 266 flavor := JobFlavorTriggered | 277 flavor := JobFlavorTriggered |
| 267 if schedule != "triggered" { | 278 if schedule != "triggered" { |
| 268 flavor = JobFlavorPeriodic | 279 flavor = JobFlavorPeriodic |
| 269 } | 280 } |
| 281 acls, err := acl.ValidateTaskAcls(knownAclSets, job.GetAclSets()
, job.GetAcls()) |
| 282 if err != nil { |
| 283 logging.Errorf(c, "Failed to compute task ACLs: %s/%s: %
s", projectID, id, err) |
| 284 continue |
| 285 } |
| 270 out = append(out, Definition{ | 286 out = append(out, Definition{ |
| 271 JobID: fmt.Sprintf("%s/%s", projectID, job.Id), | 287 JobID: fmt.Sprintf("%s/%s", projectID, job.Id), |
| 288 Acls: *acls, |
| 272 Flavor: flavor, | 289 Flavor: flavor, |
| 273 Revision: meta.Revision, | 290 Revision: meta.Revision, |
| 274 RevisionURL: revisionURL, | 291 RevisionURL: revisionURL, |
| 275 Schedule: schedule, | 292 Schedule: schedule, |
| 276 Task: packed, | 293 Task: packed, |
| 277 }) | 294 }) |
| 278 } | 295 } |
| 279 | 296 |
| 280 // Triggering jobs. | 297 // Triggering jobs. |
| 281 for _, trigger := range cfg.Trigger { | 298 for _, trigger := range cfg.Trigger { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 293 } | 310 } |
| 294 packed, err := cat.marshalTask(task) | 311 packed, err := cat.marshalTask(task) |
| 295 if err != nil { | 312 if err != nil { |
| 296 logging.Errorf(c, "Failed to marshal the task: %s/%s: %s
", projectID, id, err) | 313 logging.Errorf(c, "Failed to marshal the task: %s/%s: %s
", projectID, id, err) |
| 297 continue | 314 continue |
| 298 } | 315 } |
| 299 schedule := trigger.Schedule | 316 schedule := trigger.Schedule |
| 300 if schedule == "" { | 317 if schedule == "" { |
| 301 schedule = defaultTriggerSchedule | 318 schedule = defaultTriggerSchedule |
| 302 } | 319 } |
| 320 acls, err := acl.ValidateTaskAcls(knownAclSets, trigger.GetAclSe
ts(), trigger.GetAcls()) |
| 321 if err != nil { |
| 322 logging.Errorf(c, "Failed to compute task ACLs: %s/%s: %
s", projectID, id, err) |
| 323 continue |
| 324 } |
| 303 out = append(out, Definition{ | 325 out = append(out, Definition{ |
| 304 JobID: fmt.Sprintf("%s/%s", projectID, trigger.Id)
, | 326 JobID: fmt.Sprintf("%s/%s", projectID, trigger.Id)
, |
| 327 Acls: *acls, |
| 305 Flavor: JobFlavorTrigger, | 328 Flavor: JobFlavorTrigger, |
| 306 Revision: meta.Revision, | 329 Revision: meta.Revision, |
| 307 RevisionURL: revisionURL, | 330 RevisionURL: revisionURL, |
| 308 Schedule: schedule, | 331 Schedule: schedule, |
| 309 Task: packed, | 332 Task: packed, |
| 310 }) | 333 }) |
| 311 } | 334 } |
| 312 | 335 |
| 313 return out, nil | 336 return out, nil |
| 314 } | 337 } |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 442 field := v.Field(i) | 465 field := v.Field(i) |
| 443 if field.Type() == taskType { | 466 if field.Type() == taskType { |
| 444 field.Set(reflect.ValueOf(task)) | 467 field.Set(reflect.ValueOf(task)) |
| 445 return proto.Marshal(&wrapper) | 468 return proto.Marshal(&wrapper) |
| 446 } | 469 } |
| 447 } | 470 } |
| 448 // This can happen only if TaskDefWrapper wasn't updated when a new task
type | 471 // This can happen only if TaskDefWrapper wasn't updated when a new task
type |
| 449 // was added. This is a developer's mistake, not a config mistake. | 472 // was added. This is a developer's mistake, not a config mistake. |
| 450 return nil, fmt.Errorf("could not find a field of type %T in TaskDefWrap
per", task) | 473 return nil, fmt.Errorf("could not find a field of type %T in TaskDefWrap
per", task) |
| 451 } | 474 } |
| OLD | NEW |