| OLD | NEW |
| 1 # Copyright 2014 The Chromium Authors. All rights reserved. | 1 # Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
| 4 | 4 |
| 5 """This module integrates buildbucket with swarming. | 5 """This module integrates buildbucket with swarming. |
| 6 | 6 |
| 7 A bucket config may have "swarming" field that specifies how a builder | 7 A bucket config may have "swarming" field that specifies how a builder |
| 8 is mapped to a recipe. If build is scheduled for a bucket/builder | 8 is mapped to a recipe. If build is scheduled for a bucket/builder |
| 9 with swarming configuration, the integration overrides the default behavior. | 9 with swarming configuration, the integration overrides the default behavior. |
| 10 | 10 |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 44 | 44 |
| 45 import config | 45 import config |
| 46 import errors | 46 import errors |
| 47 import model | 47 import model |
| 48 import notifications | 48 import notifications |
| 49 | 49 |
| 50 PUBSUB_TOPIC = 'swarming' | 50 PUBSUB_TOPIC = 'swarming' |
| 51 BUILDER_PARAMETER = 'builder_name' | 51 BUILDER_PARAMETER = 'builder_name' |
| 52 PARAM_PROPERTIES = 'properties' | 52 PARAM_PROPERTIES = 'properties' |
| 53 PARAM_SWARMING = 'swarming' | 53 PARAM_SWARMING = 'swarming' |
| 54 PARAM_CHANGES = 'changes' |
| 54 DEFAULT_URL_FORMAT = 'https://{swarming_hostname}/user/task/{task_id}' | 55 DEFAULT_URL_FORMAT = 'https://{swarming_hostname}/user/task/{task_id}' |
| 55 | 56 |
| 56 | 57 |
| 57 ################################################################################ | 58 ################################################################################ |
| 58 # Creation/cancellation of tasks. | 59 # Creation/cancellation of tasks. |
| 59 | 60 |
| 60 | 61 |
| 61 @ndb.tasklet | 62 @ndb.tasklet |
| 62 def get_task_template_async(): | 63 def get_task_template_async(): |
| 63 """Returns a task template (dict) if it exists, otherwise None. | 64 """Returns a task template (dict) if it exists, otherwise None. |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 125 'Unrecognized keys in swarming.recipe: %r' % recipe) | 126 'Unrecognized keys in swarming.recipe: %r' % recipe) |
| 126 | 127 |
| 127 if swarming: | 128 if swarming: |
| 128 raise errors.InvalidInputError('Unrecognized keys: %r', swarming) | 129 raise errors.InvalidInputError('Unrecognized keys: %r', swarming) |
| 129 | 130 |
| 130 | 131 |
| 131 @ndb.tasklet | 132 @ndb.tasklet |
| 132 def create_task_def_async(swarming_cfg, builder_cfg, build): | 133 def create_task_def_async(swarming_cfg, builder_cfg, build): |
| 133 """Creates a swarming task definition for the |build|. | 134 """Creates a swarming task definition for the |build|. |
| 134 | 135 |
| 136 Supports build properties that are supported by Buildbot-Buildbucket |
| 137 integration. See |
| 138 https://chromium.googlesource.com/chromium/tools/build/+/eff4ceb/scripts/maste
r/buildbucket/README.md#Build-parameters |
| 139 |
| 135 Raises: | 140 Raises: |
| 136 errors.InvalidInputError if build.parameters are invalid. | 141 errors.InvalidInputError if build.parameters are invalid. |
| 137 """ | 142 """ |
| 138 params = build.parameters or {} | 143 params = build.parameters or {} |
| 139 validate_build_parameters(builder_cfg.name, params) | 144 validate_build_parameters(builder_cfg.name, params) |
| 140 swarming_param = params.get(PARAM_SWARMING) or {} | 145 swarming_param = params.get(PARAM_SWARMING) or {} |
| 141 | 146 |
| 142 # Render task template. | 147 # Render task template. |
| 143 task_template = yield get_task_template_async() | 148 task_template = yield get_task_template_async() |
| 144 task_template_params = { | 149 task_template_params = { |
| 145 'bucket': build.bucket, | 150 'bucket': build.bucket, |
| 146 'builder': builder_cfg.name, | 151 'builder': builder_cfg.name, |
| 147 } | 152 } |
| 148 | 153 |
| 149 is_recipe = builder_cfg.HasField('recipe') | 154 is_recipe = builder_cfg.HasField('recipe') |
| 150 if is_recipe: # pragma: no branch | 155 if is_recipe: # pragma: no branch |
| 151 recipe = builder_cfg.recipe | 156 recipe = builder_cfg.recipe |
| 152 revision = swarming_param.get('recipe', {}).get('revision') or '' | 157 revision = swarming_param.get('recipe', {}).get('revision') or '' |
| 153 | 158 |
| 154 build_properties = dict( | 159 build_properties = dict( |
| 155 p.split(':', 1) for p in builder_cfg.recipe.properties or []) | 160 p.split(':', 1) for p in builder_cfg.recipe.properties or []) |
| 156 build_properties.update(build.parameters.get(PARAM_PROPERTIES) or {}) | 161 build_properties.update(build.parameters.get(PARAM_PROPERTIES) or {}) |
| 157 build_properties['buildername'] = builder_cfg.name | 162 build_properties['buildername'] = builder_cfg.name |
| 158 | 163 |
| 164 # Convert changes in build to blamelist property, like Buildbot-Buildbucket |
| 165 # integration. In Buildbot the property value is a list of emails. |
| 166 changes = params.get(PARAM_CHANGES) |
| 167 if changes: # pragma: no branch |
| 168 emails = [c.get('author', {}).get('email') for c in changes] |
| 169 build_properties['blamelist'] = filter(None, emails) |
| 170 |
| 159 task_template_params.update({ | 171 task_template_params.update({ |
| 160 'repository': recipe.repository, | 172 'repository': recipe.repository, |
| 161 'revision': revision, | 173 'revision': revision, |
| 162 'recipe': recipe.name, | 174 'recipe': recipe.name, |
| 163 'properties_json': json.dumps(build_properties, sort_keys=True), | 175 'properties_json': json.dumps(build_properties, sort_keys=True), |
| 164 }) | 176 }) |
| 165 | 177 |
| 166 task_template_params = { | 178 task_template_params = { |
| 167 k: v or '' for k, v in task_template_params.iteritems()} | 179 k: v or '' for k, v in task_template_params.iteritems()} |
| 168 task = format_obj(task_template, task_template_params) | 180 task = format_obj(task_template, task_template_params) |
| (...skipping 416 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 585 def _extend_unique(target, items): | 597 def _extend_unique(target, items): |
| 586 for x in items: | 598 for x in items: |
| 587 if x not in target: # pragma: no branch | 599 if x not in target: # pragma: no branch |
| 588 target.append(x) | 600 target.append(x) |
| 589 | 601 |
| 590 | 602 |
| 591 class TaskToken(tokens.TokenKind): | 603 class TaskToken(tokens.TokenKind): |
| 592 expiration_sec = 60 * 60 * 24 # 24 hours. | 604 expiration_sec = 60 * 60 * 24 # 24 hours. |
| 593 secret_key = auth.SecretKey('swarming_task_token', scope='local') | 605 secret_key = auth.SecretKey('swarming_task_token', scope='local') |
| 594 version = 1 | 606 version = 1 |
| OLD | NEW |