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

Side by Side Diff: appengine/cr-buildbucket/swarming/swarmingcfg.py

Issue 2213723002: swarmbucket: allow overriding config (Closed) Base URL: https://chromium.googlesource.com/infra/infra.git@sb-cfg-refactoring
Patch Set: security warning Created 4 years, 4 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
OLDNEW
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 import copy 5 import copy
6 import json 6 import json
7 import re 7 import re
8 8
9 from components.config import validation 9 from components.config import validation
10 10
11 from proto import project_config_pb2 11 from proto import project_config_pb2
12 12
13 13
14 DIMENSION_KEY_RGX = re.compile(r'^[a-zA-Z\_\-]+$') 14 DIMENSION_KEY_RGX = re.compile(r'^[a-zA-Z\_\-]+$')
15 NO_PROPERTY = object()
16 15
17 16
18 def read_properties(recipe): 17 def read_properties(recipe):
19 """Parses build properties from the recipe message. 18 """Parses build properties from the recipe message.
20 19
21 Expects the message to be valid. 20 Expects the message to be valid.
22 21
23 Uses NO_PROPERTY for empty values. 22 Uses NO_PROPERTY for empty values.
24 """ 23 """
25 result = dict(p.split(':', 1) for p in recipe.properties) 24 result = dict(p.split(':', 1) for p in recipe.properties)
26 for p in recipe.properties_j: 25 for p in recipe.properties_j:
27 k, v = p.split(':', 1) 26 k, v = p.split(':', 1)
28 if not v: 27 parsed = json.loads(v)
29 parsed = NO_PROPERTY
30 else:
31 parsed = json.loads(v)
32 result[k] = parsed 28 result[k] = parsed
33 return result 29 return result
34 30
35 31
36 def merge_recipe(r1, r2): 32 def merge_recipe(r1, r2):
37 """Merges Recipe message r2 into r1. 33 """Merges Recipe message r2 into r1.
38 34
39 Expects messages to be valid. 35 Expects messages to be valid.
40 36
41 All properties are converted to properties_j. 37 All properties are converted to properties_j.
42 """ 38 """
43 props = read_properties(r1) 39 props = read_properties(r1)
44 props.update(read_properties(r2)) 40 props.update(read_properties(r2))
45 41
46 r1.MergeFrom(r2) 42 r1.MergeFrom(r2)
47 r1.properties[:] = [] 43 r1.properties[:] = []
48 r1.properties_j[:] = [ 44 r1.properties_j[:] = [
49 '%s:%s' % (k, json.dumps(v)) 45 '%s:%s' % (k, json.dumps(v))
50 for k, v in sorted(props.iteritems()) 46 for k, v in sorted(props.iteritems())
51 if v is not NO_PROPERTY 47 if v is not None
52 ] 48 ]
53 49
54 50
55 def merge_dimensions(d1, d2): 51 def merge_dimensions(d1, d2):
56 """Merges dimensions. Values in d2 overwrite values in d1. 52 """Merges dimensions. Values in d2 overwrite values in d1.
57 53
58 Expects dimensions to be valid. 54 Expects dimensions to be valid.
59 55
60 If a dimensions value in d2 is empty, it is excluded from the result. 56 If a dimensions value in d2 is empty, it is excluded from the result.
61 """ 57 """
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
163 keys.add(key) 159 keys.add(key)
164 160
165 for i, p in enumerate(properties_j): 161 for i, p in enumerate(properties_j):
166 with ctx.prefix('properties_j #%d: ', i + 1): 162 with ctx.prefix('properties_j #%d: ', i + 1):
167 if ':' not in p: 163 if ':' not in p:
168 ctx.error('does not have colon') 164 ctx.error('does not have colon')
169 else: 165 else:
170 key, value = p.split(':', 1) 166 key, value = p.split(':', 1)
171 validate_key(key) 167 validate_key(key)
172 keys.add(key) 168 keys.add(key)
173 if value: 169 try:
174 try: 170 json.loads(value)
175 json.loads(value) 171 except ValueError as ex:
176 except ValueError as ex: 172 ctx.error(ex)
177 ctx.error(ex)
178 173
179 174
180 def validate_builder_cfg(builder, ctx, final=True): 175 def validate_builder_cfg(builder, ctx, final=True):
181 """Validates a Builder message. 176 """Validates a Builder message.
182 177
183 If final is False, does not validate for completeness. 178 If final is False, does not validate for completeness.
184 """ 179 """
185 if final and not builder.name: 180 if final and not builder.name:
186 ctx.error('name unspecified') 181 ctx.error('name unspecified')
187 182
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
229 # Do no try to merge invalid configs. 224 # Do no try to merge invalid configs.
230 continue 225 continue
231 226
232 merged = copy.deepcopy(swarming.builder_defaults) 227 merged = copy.deepcopy(swarming.builder_defaults)
233 merge_builder(merged, b) 228 merge_builder(merged, b)
234 validate_builder_cfg(merged, ctx) 229 validate_builder_cfg(merged, ctx)
235 230
236 231
237 def has_pool_dimension(dimensions): 232 def has_pool_dimension(dimensions):
238 return any(d.startswith('pool:') for d in dimensions) 233 return any(d.startswith('pool:') for d in dimensions)
OLDNEW
« no previous file with comments | « appengine/cr-buildbucket/swarming/swarming.py ('k') | appengine/cr-buildbucket/swarming/test/swarming_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698