go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/lucicfg/starlark/stdlib/internal/luci/rules/dynamic_builder_template.star (about) 1 # Copyright 2023 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 """Defines luci.dynamic_builder_template(...) rule.""" 16 17 load("@stdlib//internal/graph.star", "graph") 18 load("@stdlib//internal/lucicfg.star", "lucicfg") 19 load("@stdlib//internal/luci/common.star", "keys", "kinds") 20 load("@stdlib//internal/luci/rules/builder.star", "builderimpl") 21 22 def _dynamic_builder_template( 23 ctx, # @unused 24 *, 25 bucket = None, 26 executable = None, 27 28 # Execution environment parameters. 29 properties = None, 30 allowed_property_overrides = None, 31 service_account = None, 32 caches = None, 33 execution_timeout = None, 34 grace_period = None, 35 heartbeat_timeout = None, 36 37 # Scheduling parameters. 38 dimensions = None, 39 priority = None, 40 expiration_timeout = None, 41 retriable = None, 42 43 # Tweaks. 44 experiments = None, 45 46 # Results. 47 resultdb_settings = None, 48 test_presentation = None, 49 50 # TaskBackend. 51 backend = None, 52 backend_alt = None, 53 54 # Builder health indicators 55 contact_team_email = None): 56 """Defines a dynamic builder template for a dynamic bucket. 57 58 Args: 59 ctx: the implicit rule context, see lucicfg.rule(...). 60 bucket: a bucket the builder is in, see luci.bucket(...) rule. Required. 61 executable: an executable to run, e.g. a luci.recipe(...) or 62 luci.executable(...). 63 properties: a dict with string keys and JSON-serializable values, defining 64 properties to pass to the executable. Supports the module-scoped 65 defaults. They are merged (non-recursively) with the explicitly passed 66 properties. 67 allowed_property_overrides: a list of top-level property keys that can 68 be overridden by users calling the buildbucket ScheduleBuild RPC. If 69 this is set exactly to ['*'], ScheduleBuild is allowed to override 70 any properties. Only property keys which are populated via the `properties` 71 parameter here (or via the module-scoped defaults) are allowed. 72 service_account: an email of a service account to run the executable 73 under: the executable (and various tools it calls, e.g. gsutil) will be 74 able to make outbound HTTP calls that have an OAuth access token 75 belonging to this service account (provided it is registered with LUCI). 76 Supports the module-scoped default. 77 caches: a list of swarming.cache(...) objects describing Swarming named 78 caches that should be present on the bot. See swarming.cache(...) doc 79 for more details. Supports the module-scoped defaults. They are joined 80 with the explicitly passed caches. 81 execution_timeout: how long to wait for a running build to finish before 82 forcefully aborting it and marking the build as timed out. If None, 83 defer the decision to Buildbucket service. Supports the module-scoped 84 default. 85 grace_period: how long to wait after the expiration of `execution_timeout` 86 or after a Cancel event, before the build is forcefully shut down. Your 87 build can use this time as a 'last gasp' to do quick actions like 88 killing child processes, cleaning resources, etc. Supports the 89 module-scoped default. 90 heartbeat_timeout: How long Buildbucket should wait for a running build to 91 send any updates before forcefully fail it with `INFRA_FAILURE`. If 92 None, Buildbucket won't check the heartbeat timeout. This field only 93 takes effect for builds that don't have Buildbucket managing their 94 underlying backend tasks, namely the ones on TaskBackendLite. E.g. 95 builds running on Swarming don't need to set this. 96 97 dimensions: a dict with swarming dimensions, indicating requirements for 98 a bot to execute the build. Keys are strings (e.g. `os`), and values 99 are either strings (e.g. `Linux`), swarming.dimension(...) objects (for 100 defining expiring dimensions) or lists of thereof. Supports the 101 module-scoped defaults. They are merged (non-recursively) with the 102 explicitly passed dimensions. 103 priority: int [1-255] or None, indicating swarming task priority, lower is 104 more important. If None, defer the decision to Buildbucket service. 105 Supports the module-scoped default. 106 expiration_timeout: how long to wait for a build to be picked up by a 107 matching bot (based on `dimensions`) before canceling the build and 108 marking it as expired. If None, defer the decision to Buildbucket 109 service. Supports the module-scoped default. 110 retriable: control if the builds on the builder can be retried. Supports 111 the module-scoped default. 112 113 experiments: a dict that maps experiment name to percentage chance that it 114 will apply to builds generated from this builder. Keys are strings, 115 and values are integers from 0 to 100. This is unrelated to 116 lucicfg.enable_experiment(...). 117 118 resultdb_settings: A buildbucket_pb.BuilderConfig.ResultDB, such as one 119 created with resultdb.settings(...). A configuration that defines if 120 Buildbucket:ResultDB integration should be enabled for this builder and 121 which results to export to BigQuery. 122 test_presentation: A resultdb.test_presentation(...) struct. A 123 configuration that defines how tests should be rendered in the UI. 124 125 backend: the name of the task backend defined via luci.task_backend(...). 126 Supports the module-scoped default. 127 backend_alt: the name of the alternative task backend defined via 128 luci.task_backend(...). Supports the module-scoped default. 129 130 contact_team_email: the owning team's contact email. This team is responsible for fixing 131 any builder health issues (see BuilderConfig.ContactTeamEmail). 132 """ 133 134 bucket_key = keys.bucket(bucket) 135 136 props = builderimpl.generate_builder( 137 ctx, 138 name = None, 139 bucket = bucket, 140 properties = properties, 141 allowed_property_overrides = allowed_property_overrides, 142 service_account = service_account, 143 caches = caches, 144 execution_timeout = execution_timeout, 145 grace_period = grace_period, 146 heartbeat_timeout = heartbeat_timeout, 147 148 # Scheduling parameters. 149 dimensions = dimensions, 150 priority = priority, 151 expiration_timeout = expiration_timeout, 152 retriable = retriable, 153 experiments = experiments, 154 resultdb_settings = resultdb_settings, 155 test_presentation = test_presentation, 156 backend = backend, 157 backend_alt = backend_alt, 158 contact_team_email = contact_team_email, 159 dynamic = True, 160 ) 161 162 # Add a node that carries the full definition of the builder. 163 builder_key = keys.unique(kinds.DYNAMIC_BUILDER_TEMPLATE, keys.bucket(bucket).id) 164 graph.add_node(builder_key, props = props) 165 graph.add_edge(bucket_key, builder_key) 166 167 if executable != None: 168 executable_key = keys.executable(executable) 169 graph.add_edge(builder_key, executable_key) 170 171 if props["backend"]: 172 graph.add_edge(builder_key, props["backend"]) 173 if props["backend_alt"]: 174 graph.add_edge(builder_key, props["backend_alt"]) 175 176 return graph.keyset(builder_key) 177 178 dynamic_builder_template = lucicfg.rule( 179 impl = _dynamic_builder_template, 180 )