go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/scheduler/appengine/messages/config.proto (about) 1 // Copyright 2015 The LUCI Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (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 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 syntax = "proto3"; 16 17 package scheduler.config; 18 19 option go_package = "go.chromium.org/luci/scheduler/appengine/messages"; 20 21 import "go.chromium.org/luci/common/proto/options.proto"; 22 import "google/protobuf/duration.proto"; 23 24 option (luci.file_metadata) = { 25 doc_url: "https://config.luci.app/schemas/projects:luci-scheduler.cfg"; 26 }; 27 28 29 // ProjectConfig defines a schema for a config file that describe jobs belonging 30 // to some project. 31 message ProjectConfig { 32 reserved 4; 33 reserved "security_options"; 34 35 // Job is a set of jobs defined in the project. 36 repeated Job job = 1; 37 // Trigger is a set of triggering jobs defined in the project. 38 repeated Trigger trigger = 2; 39 // Deprecated and unused. Use realms permissions instead. 40 repeated AclSet acl_sets = 3 [deprecated = true]; 41 } 42 43 44 // Deprecated in favor of LUCI Realms. This proto is totally unused now, exists 45 // only to not break older configs that still may have deprecated fields 46 // populated. 47 message Acl { 48 enum Role { 49 READER = 0; 50 TRIGGERER = 2; 51 OWNER = 1; 52 } 53 Role role = 1 [deprecated = true]; 54 string granted_to = 2 [deprecated = true]; 55 } 56 57 58 // Deprecated in favor of LUCI Realms. This proto is totally unused now, exists 59 // only to not break older configs that still may have deprecated fields 60 // populated. 61 message AclSet { 62 string name = 1 [deprecated = true]; 63 repeated Acl acls = 2 [deprecated = true]; 64 } 65 66 67 // TriggeringPolicy defines a function that decides when and how to launch a 68 // job invocation, given the job's current state and a set of pending triggers. 69 message TriggeringPolicy { 70 enum Kind { 71 // A placeholder for unrecognized policy kind. 72 UNDEFINED = 0; 73 74 // A greedy triggering function that takes all pending triggers (up to 75 // max_batch_size limit) and collapses them into one new invocation, 76 // deriving its properties from the most recent trigger alone. It doesn't 77 // wait for a full batch, nor tries to batch evenly. 78 GREEDY_BATCHING = 1; 79 80 // A logarithmic triggering function that takes floor(log(base,N)) pending 81 // triggers (at least 1 and up to max_batch_size limit) and collapses them 82 // into one new invocation, deriving its properties from the most recent 83 // trigger alone, where N is the total number of pending triggers and k is 84 // specified by the log_base field below. 85 LOGARITHMIC_BATCHING = 2; 86 87 // A triggering function that prioritizes the most recent pending triggers. 88 // Triggers stay pending until they either become the most recent pending 89 // trigger or expire. The timeout for pending triggers is specified by the 90 // pending_timeout field below. 91 NEWEST_FIRST = 3; 92 } 93 94 // Defines an algorithm to use for the triggering decisions. 95 // 96 // See comments for Kind enum field. 97 // 98 // Default is GREEDY_BATCHING. 99 Kind kind = 1; 100 101 // Limits number of job invocations running at the same time. 102 // 103 // If the number of current active invocations is more or equal to this 104 // setting, the triggering function will be skipped completely, since it isn't 105 // allowed to trigger anything anyway. 106 // 107 // Default is 1. 108 int64 max_concurrent_invocations = 2; 109 110 // Limits how many triggers can be put into one invocation request. 111 // 112 // For example, setting this to 1 will make each trigger launch its own 113 // invocation. This value is ignore dby NEWEST_FIRST, since batching 114 // isn't well-defined in that policy kind. 115 // 116 // Default is 1000 (which is ~= unlimited). 117 int64 max_batch_size = 3; 118 119 // Base of the logarithm operation during logarithmic batching. 120 // 121 // For example, setting this to 2, will cause 3 out of 8 pending triggers to 122 // be combined into a single invocation with LOGARITHMIC_BATCHING kind. This 123 // value is ignored by other policy kinds. Must be larger or equal to 1.0001 124 // for numerical stability reasons. 125 // 126 // Required. 127 float log_base = 4; 128 129 // How long until a pending trigger is discarded. 130 // 131 // For example, setting this to 1 day will cause triggers that stay pending 132 // for at least 1 day to be removed from consideration. This value is ignored 133 // by policy kinds other than NEWEST_FIRST, which can starve old triggers and 134 // cause the pending triggers list to grow without bound. 135 // 136 // Default is 7 days. 137 google.protobuf.Duration pending_timeout = 5; 138 } 139 140 141 // Job specifies a single regular job belonging to a project. 142 // 143 // Such jobs runs on a schedule or can be triggered by some trigger. 144 message Job { 145 reserved 4; 146 reserved 102; 147 148 // Id is a name of the job (unique for the project). 149 // 150 // Must match '^[0-9A-Za-z_\-\. \)\(]{1,100}$'. 151 string id = 1; 152 153 // Realm is a name of a LUCI realm within the project to use for ACLs. 154 // 155 // Must match `^[a-z0-9_\.\-/]{1,400}$` or be literals "@root" or "@legacy". 156 // If not set, defaults to "@legacy". 157 // 158 // ACLs associated with a realm are defined separately in realms.cfg file. 159 // That way they can be shared by multiple services. 160 string realm = 8; 161 162 // Schedule describes when to run the job. 163 // 164 // A job with a schedule can still be triggered by other triggering jobs 165 // and via "Trigger" button in UI. 166 // 167 // Supported kinds of schedules (illustrated by examples): 168 // - "* 0 * * * *": cron-like expression, in a syntax supported by 169 // https://github.com/gorhill/cronexpr (see its docs for full reference). 170 // The cron engine will attempt to start a job at specified moments in 171 // time (based on UTC clock). If when triggering a job, previous 172 // invocation is still running, an overrun will be recorded (and next 173 // attempt to start a job happens based on the schedule, not when the 174 // previous invocation finishes). Some examples: 175 // "0 */3 * * * *" - each 3 hours: at 12:00 AM UTC, 3:00 AM UTC, ... 176 // "0 */3 * * *" - exact same thing (last field is optional) 177 // "0 1/3 * * *" - each 3 hours but starting 1:00 AM UTC 178 // "0 2,10,18 * * *" - at 2 AM UTC, 10 AM UTC, 6 PM UTC 179 // "0 7 * * *" - at 7 AM UTC, once a day. 180 // - "with 10s interval": runs invocations in a loop, waiting 10s after 181 // finishing invocation before starting a new one. Overruns are not 182 // possible. 183 // - "continuously" is alias for "with 0s interval", meaning the job will 184 // run in a loop without any pauses. 185 // - "triggered" schedule indicates that job is only started via a trigger. 186 // 187 // Default is "triggered". 188 string schedule = 2; 189 190 // Disabled is true to disable this job. 191 // 192 // Disabled job is equivalent to a deleted job: it can't be triggered, it 193 // can't be referenced by other jobs and it doesn't show up in UI or API. 194 // 195 // Use this instead of commenting out the definition in case you want to 196 // temporarily git rid of the job. 197 bool disabled = 3; 198 199 // Deprecated and unused. Use realms permissions instead. 200 repeated Acl acls = 5 [deprecated = true]; 201 // Deprecated and unused. Use realms permissions instead. 202 repeated string acl_sets = 6 [deprecated = true]; 203 204 // TriggeringPolicy defines how job handles incoming triggering events. 205 // 206 // If not specified defaults to GREEDY_BATCHING with 1 max concurrent 207 // invocation. See comments in TriggeringPolicy for more details. 208 TriggeringPolicy triggering_policy = 7; 209 210 // One and only one field below must be set. It defines what this job does. 211 212 // Noop is used for testing. It is "do nothing" task. 213 NoopTask noop = 100; 214 // UrlFetch can be used to make a simple HTTP call. 215 UrlFetchTask url_fetch = 101; 216 // BuildbucketTask can be used to schedule buildbucket job. 217 BuildbucketTask buildbucket = 103; 218 } 219 220 221 // Trigger specifies a job that triggers other jobs. 222 // 223 // It is a special kind of a job that periodically checks the state of the world 224 // and triggers other jobs. 225 message Trigger { 226 // Id is a name of the job (unique for the project). 227 // 228 // Must match '^[0-9A-Za-z_\-\. \)\(]{1,100}$'. It's in the same namespace as 229 // regular jobs. 230 string id = 1; 231 232 // Realm is a name of a LUCI realm within the project to use for ACLs. 233 // 234 // Must match `^[a-z0-9_\.\-/]{1,400}$` or be literals "@root" or "@legacy". 235 // If not set, defaults to "@legacy". 236 // 237 // ACLs associated with a realm are defined separately in realms.cfg file. 238 // That way they can be shared by multiple services. 239 string realm = 7; 240 241 // Schedule describes when to run this triggering job. 242 // 243 // See Job.schedule for more info. Default is "with 30s interval". 244 string schedule = 2; 245 246 // Disabled is true to disable this job. 247 // 248 // Se Job.disabled for more info. 249 bool disabled = 3; 250 251 // Deprecated and unused. Use realms permissions instead. 252 repeated Acl acls = 4 [deprecated = true]; 253 // Deprecated and unused. Use realms permissions instead. 254 repeated string acl_sets = 5 [deprecated = true]; 255 256 // TriggeringPolicy defines how job handles incoming triggering events. 257 // 258 // It is rare for a trigger itself to have a non-default triggering policy, 259 // so most likely you should not touch this field. 260 TriggeringPolicy triggering_policy = 6; 261 262 // Triggers are IDs of jobs triggered by this trigger. 263 repeated string triggers = 200; 264 265 // One and only one field below must be set. It defines what this trigger 266 // polls. 267 268 // Noop is used for testing. It is "do nothing" trigger. 269 NoopTask noop = 100; 270 // Gitiles is used to trigger jobs for new commits on Gitiles. 271 GitilesTask gitiles = 101; 272 } 273 274 275 // NoopTask is used for testing. It is a "do nothing" task that can emit fake 276 // triggers. 277 message NoopTask { 278 int64 sleep_ms = 1; 279 int64 triggers_count = 2; 280 } 281 282 283 // GitilesTask specifies parameters of what repo and which refs to watch for new 284 // commits. 285 // 286 // GitilesTask will trigger other jobs if either: 287 // * ref's tip has changed (e.g. new commit landed on a ref), 288 // * a ref has just been created from Scheduler point of view, which is 289 // treated as a single new commit. 290 // For example, if you configure new GitilesTask or add a ref not previously 291 // watched to the existing GitilesTask, then Scheduler will "discover" this 292 // ref as newly created and emit exactly 1 trigger for the ref's current 293 // tip. 294 // 295 // 296 // LIMITATIONS: 297 // 298 // 1. Per each fast-forward ref's tip change as observed by scheduler, 299 // no more than 50 latest (according to gitiles default ordering) commits 300 // will result in emitted triggers. 301 // This is a safeguard against mistaken or deliberate but unusual git push 302 // actions, which typically don't have intent of triggering a build for each 303 // such commit. 304 // If you absolutely need to act on every new commit even in such cases, 305 // you will need to roll your own implementation, though you may still find 306 // Scheduler GitilesTask useful to trigger your code on new changes. 307 // 308 // 2. No hard latency guarantee. A single invocation of GitilesTask may not be 309 // able to process all the backlog. This is particularly true after a config 310 // change changes the set of watched ref. However, GitilesTask is designed 311 // to make continuous progress with each invocation. 312 message GitilesTask { 313 // Repo is the URL of the Gitiles repository. 314 string repo = 1; 315 316 // Refs is a list of Git references to track. 317 // 318 // Each ref can be either: 319 // * a fully qualified ref like "refs/heads/master" or "refs/tags/v1.2.3" 320 // * a regular expression with "regexp:" prefix to match multiple refs, e.g. 321 // "regexp:refs/heads/[^/]+" or "regexp:refs/branch-heads/\d+\.\d+", but 322 // the regular expression should have a literal prefix with at least two 323 // slashes present, e.g. "refs/release-\d+/foobar" is not allowed, because 324 // the literal prefix "refs/release-" contains only one slash. The regexp 325 // should not start with ^ or end with $ as they will be added 326 // automatically. 327 // 328 // Each tracked ref, either fully qualified or regexp, must match at least 1 329 // ref in gitiles output. 330 repeated string refs = 2; 331 332 // Optional path_regexps and path_regexps_exclude are lists of regular 333 // expressions limiting emitted triggers only to commits whose tree diff 334 // touches relevant files. 335 // 336 // If neither path_regexps nor path_regexps_exclude is specified (default), 337 // emits triggers for any commit. 338 // Specifying just path_regexps_exclude is not allowed. 339 // 340 // path_regexps and path_regexps_exclude rules apply on each individual commit 341 // independently. For each commit, a set of all filepaths referenced in Git 342 // commit diff is used for matching. On top of simple file additions and file 343 // modifications, this also includes: file removals, file moves (old and new 344 // path is considered), and changing of file metadata (e.g., chmod +x). This 345 // doesn't include directories (git doesn't track them explicitly). 346 // 347 // Triggers are emitted for a commit if only if at least 1 touched filepath 348 // 1. is not matched by any path_regexps_exclude, 349 // 2. AND is matched at least 1 path_regexps 350 // **subject to caveats below** for exceptional cases. 351 // 352 // Each path_regexps and path_regexps_exclude is a regular expression 353 // "a/b/c/.+". It should not start with ^ or end with $ as they will be added 354 // automatically. 355 // 356 // CAVEATS: 357 // 1. path_regexps: ".+" 358 // will NOT match commits which modify no files (aka empty commits) and 359 // as such differs from default case of not specifying any `path_regexps`. 360 // 2. Per GitilesTask doc, if a ref fast-forwards >=50 commits, only the last 361 // 50 commits are checked. If none of them matches any path specified here, 362 // no trigger is emitted, even if there is an unexamined commit which 363 // matches the path. 364 // TODO(tandrii): it's possible to improve this by examining diff 365 // between ref's last and new tips, but one has to worry about gitiles 366 // taking potentially very long time to compute it. 367 // 368 repeated string path_regexps = 3; 369 repeated string path_regexps_exclude = 4; 370 } 371 372 373 // UrlFetchTask specifies parameters for simple HTTP call. 374 message UrlFetchTask { 375 // Method is HTTP method to use, such as "GET" or "POST". Default is "GET". 376 string method = 1; 377 // Url to send the request to. 378 string url = 2; 379 // Timeout is how long to wait for request to complete. Default is 60 sec. 380 int32 timeout_sec = 3; 381 // TODO: add more. 382 } 383 384 385 // BuildbucketTask specifies parameters of Buildbucket-based jobs. 386 message BuildbucketTask { 387 // Server is hostname of the buildbucket service to use. 388 // 389 // Typically, "cr-buildbucket.appspot.com". 390 string server = 1; 391 392 // Bucket defines what bucket to add the task to. 393 // 394 // Supported formats are: 395 // * "<bucket>" - for a bucket in the current project. 396 // * "<project>:<bucket>" - for a bucket in another project. 397 // * "luci.<project>.<bucket>" - legacy v1 bucket name. 398 // 399 // If empty, defaults to `realm` field in the parent Job message. 400 string bucket = 2; 401 402 // Builder defines what builder within the bucket to launch. 403 string builder = 3; 404 405 // Properties is arbitrary "key:value" pairs describing the task. 406 // TODO(tandrii): which properties will be overridden if triggered? 407 repeated string properties = 4; 408 409 // Tags is a list of tags (as "key:value" pairs) to assign to the task. 410 repeated string tags = 5; 411 } 412 413 414 //////////////////////////////////////////////////////////////////////////////// 415 // Internal stuff. 416 417 // TaskDefWrapper is a union type of all possible tasks known to the scheduler. 418 // 419 // It is used internally when storing jobs in the datastore. 420 message TaskDefWrapper { 421 reserved 3; 422 423 NoopTask noop = 1; 424 UrlFetchTask url_fetch = 2; 425 BuildbucketTask buildbucket = 4; 426 GitilesTask gitiles = 5; 427 }