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

Side by Side Diff: scripts/slave/recipe_modules/buildbucket/api.py

Issue 2324733005: BuildBucket recipe module can expose properties. (Closed)
Patch Set: Created 4 years, 3 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
« no previous file with comments | « no previous file | scripts/slave/recipe_modules/buildbucket/example.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # Copyright 2016 The Chromium Authors. All rights reserved. 1 # Copyright 2016 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 """API for interacting with the buildbucket service directly. 5 """API for interacting with the buildbucket service directly.
6 6
7 Instead of triggering jobs by emitting annotations then handled by the master, 7 Instead of triggering jobs by emitting annotations then handled by the master,
8 this module allows slaves to directly post requests to buildbucket. 8 this module allows slaves to directly post requests to buildbucket.
9 """ 9 """
10 10
11 import json 11 import json
12 import os 12 import os
13 import uuid 13 import uuid
14 14
15 from recipe_engine import recipe_api 15 from recipe_engine import recipe_api, types
nxia1 2016/09/09 18:41:47 is the 'types' used here?
dnj 2016/09/09 18:50:54 oops, nope
16 16
17 17
18 class BuildbucketApi(recipe_api.RecipeApi): 18 class BuildbucketApi(recipe_api.RecipeApi):
19 """A module for interacting with buildbucket.""" 19 """A module for interacting with buildbucket."""
20 20
21 def __init__(self, *args, **kwargs):
22 super(BuildbucketApi, self).__init__(*args, **kwargs)
23 self._properties = None
24
21 def get_config_defaults(self): 25 def get_config_defaults(self):
22 if self.m.platform.is_win: 26 if self.m.platform.is_win:
23 return {'PLATFORM': 'win'} 27 return {'PLATFORM': 'win'}
24 return {'PLATFORM': 'default'} 28 return {'PLATFORM': 'default'}
25 29
26 def _configure_defaults(self): 30 def _configure_defaults(self):
27 """Apply default configuration if no configuration has been set. 31 """Apply default configuration if no configuration has been set.
28 32
29 Ideally whoever uses this api will explicitly set the configuration by 33 Ideally whoever uses this api will explicitly set the configuration by
30 doing `api.buildbucket.set_config('production_buildbucket')`, but to make 34 doing `api.buildbucket.set_config('production_buildbucket')`, but to make
31 this module usable even in case they don't configure it, we set the default 35 this module usable even in case they don't configure it, we set the default
32 to the production instance of buildbucket.""" 36 to the production instance of buildbucket."""
33 # There's only two items in this module's configuration, the path to the 37 # There's only two items in this module's configuration, the path to the
34 # buildbucket cli client binary and the buildbucket hostname, this default 38 # buildbucket cli client binary and the buildbucket hostname, this default
35 # configuration will override them. 39 # configuration will override them.
36 if not self.c or not self.c.complete(): 40 if not self.c or not self.c.complete():
37 self.set_config('production_buildbucket') 41 self.set_config('production_buildbucket')
38 42
39 def _tags_for_build(self, bucket, parameters, override_tags=None): 43 def _tags_for_build(self, bucket, parameters, override_tags=None):
40 buildbucket_info = self.m.properties.get('buildbucket', {}) 44 buildbucket_info = (self.properties or {})
41 if isinstance(buildbucket_info, basestring): # pragma: no cover
42 buildbucket_info = json.loads(buildbucket_info)
43 original_tags_list = buildbucket_info.get('build', {}).get('tags', []) 45 original_tags_list = buildbucket_info.get('build', {}).get('tags', [])
44 46
45 original_tags = dict(t.split(':', 1) for t in original_tags_list) 47 original_tags = dict(t.split(':', 1) for t in original_tags_list)
46 new_tags = {'user_agent': 'recipe'} 48 new_tags = {'user_agent': 'recipe'}
47 49
48 if 'buildset' in original_tags: 50 if 'buildset' in original_tags:
49 new_tags['buildset'] = original_tags['buildset'] 51 new_tags['buildset'] = original_tags['buildset']
50 builder_name = parameters.get('builder_name') 52 builder_name = parameters.get('builder_name')
51 if builder_name: 53 if builder_name:
52 new_tags['builder'] = builder_name 54 new_tags['builder'] = builder_name
53 if bucket.startswith('master.'): 55 if bucket.startswith('master.'):
54 new_tags['master'] = bucket[7:] 56 new_tags['master'] = bucket[7:]
55 57
56 new_tags.update(override_tags or {}) 58 new_tags.update(override_tags or {})
57 return sorted([':'.join((x, y)) for x, y in new_tags.iteritems()]) 59 return sorted([':'.join((x, y)) for x, y in new_tags.iteritems()])
58 60
61 @property
62 def properties(self):
63 """Returns (dict-like or None): The BuildBucket properties, if present."""
64 if self._properties is None:
65 # Not cached, load and deserialize from properties.
66 props = self.m.properties.get('buildbucket')
67 if props is not None:
nxia1 2016/09/09 18:41:48 set _properties to {} if props is None?
dnj 2016/09/09 18:50:54 I want it to return None to differentiate "no prop
68 if isinstance(props, basestring):
69 props = json.loads(props)
70 self._properties = props
71 return self._properties
59 72
60 def put(self, builds, service_account=None, **kwargs): 73 def put(self, builds, service_account=None, **kwargs):
61 """Puts a batch of builds. 74 """Puts a batch of builds.
62 75
63 Args: 76 Args:
64 builds (list): A list of dicts, where keys are: 77 builds (list): A list of dicts, where keys are:
65 'bucket': (required) name of the bucket for the request. 78 'bucket': (required) name of the bucket for the request.
66 'parameters' (dict): (required) arbitrary json-able parameters that a 79 'parameters' (dict): (required) arbitrary json-able parameters that a
67 build system would be able to interpret. 80 build system would be able to interpret.
68 'tags': (optional) a dict(str->str) of tags for the build. These will 81 'tags': (optional) a dict(str->str) of tags for the build. These will
(...skipping 30 matching lines...) Expand all
99 def _call_service(self, command, args, service_account=None, **kwargs): 112 def _call_service(self, command, args, service_account=None, **kwargs):
100 # TODO: Deploy buildbucket client using cipd. 113 # TODO: Deploy buildbucket client using cipd.
101 self._configure_defaults() 114 self._configure_defaults()
102 step_name = kwargs.pop('name', 'buildbucket.' + command) 115 step_name = kwargs.pop('name', 'buildbucket.' + command)
103 if service_account: 116 if service_account:
104 args = ['--service-account-json', service_account] + args 117 args = ['--service-account-json', service_account] + args
105 args = [str(self.c.buildbucket_client_path), command, '--host', 118 args = [str(self.c.buildbucket_client_path), command, '--host',
106 self.c.buildbucket_host] + args 119 self.c.buildbucket_host] + args
107 return self.m.step( 120 return self.m.step(
108 step_name, args, stdout=self.m.json.output(), **kwargs) 121 step_name, args, stdout=self.m.json.output(), **kwargs)
OLDNEW
« no previous file with comments | « no previous file | scripts/slave/recipe_modules/buildbucket/example.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698