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

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

Issue 1345143004: CrOS: Use local Chromite checkout for configs. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/build
Patch Set: Created 5 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 | Annotate | Revision Log
OLDNEW
1 # Copyright 2013 The Chromium Authors. All rights reserved. 1 # Copyright 2013 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 cgi 5 import cgi
6 import re 6 import re
7 7
8 from recipe_engine import recipe_api 8 from recipe_engine import recipe_api
9 9
10 10
11 class Config(object):
12 _NONE = object()
13
14 def __init__(self, name, *layers):
15 self.name = name
16 self.layers = layers
17
18 def get(self, key, d=None):
19 for l in self.layers:
20 v = l.get(key, self._NONE)
21 if v is not self._NONE:
22 return v
23 return d
24
25 def __getitem__(self, key):
26 v = self.get(key, self._NONE)
27 if v is not self._NONE:
28 return v
29 raise KeyError('Invalid configuration key: %s' % (key,))
30
31 def dict(self):
32 all_keys = set()
33 for l in self.layers:
34 all_keys.update(l.iterkeys())
35 return {k: self.get(k) for k in all_keys}
iannucci 2015/09/29 19:17:30 hm... this seems potentially much less efficient t
dnj 2015/09/29 19:28:40 Done.
36
37
11 class ChromiteApi(recipe_api.RecipeApi): 38 class ChromiteApi(recipe_api.RecipeApi):
12 chromite_url = 'https://chromium.googlesource.com/chromiumos/chromite.git' 39 chromite_url = 'https://chromium.googlesource.com/chromiumos/chromite.git'
13 manifest_url = 'https://chromium.googlesource.com/chromiumos/manifest.git' 40 manifest_url = 'https://chromium.googlesource.com/chromiumos/manifest.git'
14 repo_url = 'https://chromium.googlesource.com/external/repo.git' 41 repo_url = 'https://chromium.googlesource.com/external/repo.git'
15 chromite_subpath = 'chromite' 42
43 _chromite_subpath = 'chromite'
16 44
17 # The number of Gitiles attempts to make before giving up. 45 # The number of Gitiles attempts to make before giving up.
18 _GITILES_ATTEMPTS = 10 46 _GITILES_ATTEMPTS = 10
19 47
20 _MANIFEST_CMD_RE = re.compile(r'Automatic:\s+Start\s+([^\s]+)\s+([^\s]+)') 48 _MANIFEST_CMD_RE = re.compile(r'Automatic:\s+Start\s+([^\s]+)\s+([^\s]+)')
21 _BUILD_ID_RE = re.compile(r'CrOS-Build-Id: (.+)') 49 _BUILD_ID_RE = re.compile(r'CrOS-Build-Id: (.+)')
22 50
51 _cached_config = None
52
53 @property
54 def chromite_path(self):
55 v = self.m.path.c.dynamic_paths.get('chromite')
56 if v:
57 return v
58 return self.m.path['slave_build'].join(self._chromite_subpath)
59
60 def _set_chromite_path(self, path):
61 self.m.path.c.dynamic_paths['chromite'] = path
62
23 def get_config_defaults(self): 63 def get_config_defaults(self):
24 defaults = { 64 defaults = {
25 'CBB_CONFIG': self.m.properties.get('cbb_config'), 65 'CBB_CONFIG': self.m.properties.get('cbb_config'),
26 'CBB_BRANCH': self.m.properties.get('cbb_branch'), 66 'CBB_BRANCH': self.m.properties.get('cbb_branch'),
27 'CBB_DEBUG': self.m.properties.get('cbb_debug') is not None, 67 'CBB_DEBUG': self.m.properties.get('cbb_debug') is not None,
28 'CBB_CLOBBER': 'clobber' in self.m.properties, 68 'CBB_CLOBBER': 'clobber' in self.m.properties,
29 } 69 }
30 if 'buildnumber' in self.m.properties: 70 if 'buildnumber' in self.m.properties:
31 defaults['CBB_BUILD_NUMBER'] = int(self.m.properties['buildnumber']) 71 defaults['CBB_BUILD_NUMBER'] = int(self.m.properties['buildnumber'])
32 return defaults 72 return defaults
33 73
74 def _load_config_dump(self):
75 if not self._cached_config:
76 config_path = self.m.path.join(self.chromite_path,
77 'cbuildbot', 'config_dump.json')
78 step_result = self.m.json.read('read chromite config', config_path,
79 add_json_log=False)
80 self._cached_config = step_result.json.output
iannucci 2015/09/29 19:17:30 ugh, really? json.read should be changed to return
dnj 2015/09/29 19:28:40 Acknowledged.
81 return self._cached_config
82
83 def load_config(self, name):
84 c = self._load_config_dump()
85 conf = c.get(name)
86 if conf is None:
87 return None
88
89 layers = [conf]
90 template = conf.get('_template')
91 if template:
92 layers.append(c['_templates'][template])
93 default = c.get('_default')
94 if default:
95 layers.append(default)
96
97 config = Config(name, *layers)
98
99 presentation_dict = {name: config.dict()}
100 self.m.step.active_result.presentation.logs['config'] = [
101 self.m.json.dumps(presentation_dict, indent=2),
102 ]
103 return config
104
34 def check_repository(self, repo_type_key, value): 105 def check_repository(self, repo_type_key, value):
35 """Scans through registered repositories for a specified value. 106 """Scans through registered repositories for a specified value.
36 107
37 Args: 108 Args:
38 repo_type_key (str): The key in the 'repositories' config to scan through. 109 repo_type_key (str): The key in the 'repositories' config to scan through.
39 value (str): The value to scan for. 110 value (str): The value to scan for.
40 Returns (bool): True if the value was found. 111 Returns (bool): True if the value was found.
41 """ 112 """
42 def remove_tail(v, tail): 113 def remove_tail(v, tail):
43 if v.endswith(tail): 114 if v.endswith(tail):
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
83 # Build ID? 154 # Build ID?
84 match = self._BUILD_ID_RE.match(line) 155 match = self._BUILD_ID_RE.match(line)
85 if match: 156 if match:
86 self.c.cbb.build_id = match.group(1) 157 self.c.cbb.build_id = match.group(1)
87 loaded.append('Build ID: %s' % (self.c.cbb.build_id,)) 158 loaded.append('Build ID: %s' % (self.c.cbb.build_id,))
88 continue 159 continue
89 if loaded: 160 if loaded:
90 loaded.insert(0, '') 161 loaded.insert(0, '')
91 result.presentation.step_text += '<br/>'.join(loaded) 162 result.presentation.step_text += '<br/>'.join(loaded)
92 163
93 @property
94 def default_chromite_path(self):
95 """Returns: (Path) The default Chromite checkout path."""
96 return self.m.path['slave_build'].join(self.chromite_subpath)
97
98 def gclient_config(self): 164 def gclient_config(self):
99 """Generate a 'gclient' configuration to check out Chromite. 165 """Generate a 'gclient' configuration to check out Chromite.
100 166
101 Return: (config) A 'gclient' recipe module configuration. 167 Return: (config) A 'gclient' recipe module configuration.
102 """ 168 """
103 cfg = self.m.gclient.make_config() 169 cfg = self.m.gclient.make_config()
104 soln = cfg.solutions.add() 170 soln = cfg.solutions.add()
105 soln.name = 'chromite' 171 soln.name = 'chromite'
106 soln.url = self.chromite_url 172 soln.url = self.chromite_url
107 # Set the revision using 'bot_update' remote branch:revision notation. 173 # Set the revision using 'bot_update' remote branch:revision notation.
108 # Omitting the revision uses HEAD. 174 # Omitting the revision uses HEAD.
109 soln.revision = '%s:' % (self.c.chromite_branch,) 175 soln.revision = '%s:' % (self.c.chromite_branch,)
110 return cfg 176 return cfg
111 177
112 def checkout(self, manifest_url=None, repo_url=None): 178 def checkout(self, manifest_url=None, repo_url=None):
113 manifest_url = manifest_url or self.manifest_url 179 manifest_url = manifest_url or self.manifest_url
114 repo_url = repo_url or self.repo_url 180 repo_url = repo_url or self.repo_url
115 181
116 self.m.repo.init(manifest_url, '--repo-url', repo_url) 182 self.m.repo.init(manifest_url, '--repo-url', repo_url)
117 self.m.repo.sync() 183 self.m.repo.sync()
118 184
119 @property 185 @property
120 def using_old_chromite_layout(self): 186 def using_old_chromite_layout(self):
121 """Returns (bool): True if we're using old Chromite checkout layout. 187 """Returns (bool): True if we're using old Chromite checkout layout.
122 """ 188 """
123 return self.c.chromite_branch in self.c.old_chromite_branches 189 return self.c.chromite_branch in self.c.old_chromite_branches
124 190
125 def cbuildbot(self, name, config, args=None, chromite_path=None, **kwargs): 191 def cbuildbot(self, name, config, args=None, **kwargs):
126 """Runs the cbuildbot command defined by the arguments. 192 """Runs the cbuildbot command defined by the arguments.
127 193
128 Args: 194 Args:
129 name: (str) The name of the command step. 195 name: (str) The name of the command step.
130 config: (str) The name of the 'cbuildbot' configuration to invoke. 196 config: (str) The name of the 'cbuildbot' configuration to invoke.
131 args: (list) If not None, addition arguments to pass to 'cbuildbot'. 197 args: (list) If not None, addition arguments to pass to 'cbuildbot'.
132 chromite_path: (str) The path to the Chromite checkout; if None, the
133 'default_chromite_path' will be used.
134 198
135 Returns: (Step) The step that was run. 199 Returns: (Step) The step that was run.
136 """ 200 """
137 chromite_path = chromite_path or self.default_chromite_path
138 args = (args or [])[:] 201 args = (args or [])[:]
139 args.append(config) 202 args.append(config)
140 203
141 bindir = 'bin' 204 bindir = 'bin'
142 if self.using_old_chromite_layout: 205 if self.using_old_chromite_layout:
143 bindir = 'buildbot' 206 bindir = 'buildbot'
144 cmd = [self.m.path.join(chromite_path, bindir, 'cbuildbot')] + args 207 cmd = [self.chromite_path.join(bindir, 'cbuildbot')] + args
145 return self.m.step(name, cmd, allow_subannotations=True, **kwargs) 208 return self.m.step(name, cmd, allow_subannotations=True, **kwargs)
146 209
147 def cros_sdk(self, name, cmd, args=None, environ=None, chromite_path=None, 210 def cros_sdk(self, name, cmd, args=None, environ=None, **kwargs):
148 **kwargs):
149 """Return a step to run a command inside the cros_sdk.""" 211 """Return a step to run a command inside the cros_sdk."""
150 chromite_path = chromite_path or self.default_chromite_path 212 chroot_cmd = self.chromite_path.join('bin', 'cros_sdk')
151
152 chroot_cmd = self.m.path.join(chromite_path, 'bin', 'cros_sdk')
153 213
154 arg_list = (args or [])[:] 214 arg_list = (args or [])[:]
155 for t in sorted((environ or {}).items()): 215 for t in sorted((environ or {}).items()):
156 arg_list.append('%s=%s' % t) 216 arg_list.append('%s=%s' % t)
157 arg_list.append('--') 217 arg_list.append('--')
158 arg_list.extend(cmd) 218 arg_list.extend(cmd)
159 219
160 self.m.python(name, chroot_cmd, arg_list, **kwargs) 220 self.m.python(name, chroot_cmd, arg_list, **kwargs)
161 221
162 def setup_board(self, board, args=None, **kwargs): 222 def setup_board(self, board, args=None, **kwargs):
(...skipping 29 matching lines...) Expand all
192 if variant: 252 if variant:
193 for config_name in config_map.get('variants', {}).get(variant, ()): 253 for config_name in config_map.get('variants', {}).get(variant, ()):
194 self.apply_config(config_name) 254 self.apply_config(config_name)
195 255
196 256
197 # If a config repo was specified, use it. 257 # If a config repo was specified, use it.
198 if 'config_repo' in properties: 258 if 'config_repo' in properties:
199 self.c.cbb.config_repo = self.m.properties['config_repo'] 259 self.c.cbb.config_repo = self.m.properties['config_repo']
200 260
201 def run_cbuildbot(self, args=[]): 261 def run_cbuildbot(self, args=[]):
202 """Runs a 'cbuildbot' checkout-and-build workflow. 262 self.checkout_chromite()
263 self.run(args=args)
264
265 def checkout_chromite(self):
266 """Checks out the configured Chromite branch.
267 """
268 self.m.bot_update.ensure_checkout(
269 gclient_config=self.gclient_config(),
270 update_presentation=False,
271 force=True)
272
273 if self.c.chromite_branch and self.c.cbb.disable_bootstrap:
274 # Chromite auto-detects which branch to build for based on its current
275 # checkout. "bot_update" checks out remote branches, but Chromite requires
276 # a local branch.
277 #
278 # Normally we'd bootstrap, but if we're disabling bootstrapping, we have
279 # to checkout the local branch to let Chromite know which branch to build.
280 self.m.git('checkout', self.c.chromite_branch,
281 name=str('checkout chromite branch [%s]' % (self.c.chromite_branch)))
282 self._set_chromite_path(self.m.path['checkout'])
283 return self.chromite_path
284
285 def run(self, args=[]):
286 """Runs the configured 'cbuildbot' build.
203 287
204 This workflow uses the registered configuration dictionary to make master- 288 This workflow uses the registered configuration dictionary to make master-
205 and builder-specific changes to the standard workflow. 289 and builder-specific changes to the standard workflow.
206 290
207 The specific workflow paths that are taken are also influenced by several 291 The specific workflow paths that are taken are also influenced by several
208 build properties. 292 build properties.
209 293
210 TODO(dnj): When CrOS migrates away from BuildBot, replace property 294 TODO(dnj): When CrOS migrates away from BuildBot, replace property
211 inferences with command-line parameters. 295 inferences with command-line parameters.
212 296
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
264 if self.c.cbb.config_repo: 348 if self.c.cbb.config_repo:
265 cbb_args.extend(['--config_repo', self.c.cbb.config_repo]) 349 cbb_args.extend(['--config_repo', self.c.cbb.config_repo])
266 350
267 # Set the build ID, if specified. 351 # Set the build ID, if specified.
268 if self.c.cbb.build_id: 352 if self.c.cbb.build_id:
269 cbb_args.extend(['--master-build-id', self.c.cbb.build_id]) 353 cbb_args.extend(['--master-build-id', self.c.cbb.build_id])
270 354
271 # Add custom args, if there are any. 355 # Add custom args, if there are any.
272 cbb_args.extend(args) 356 cbb_args.extend(args)
273 357
274 # Checkout Chromite.
275 self.m.bot_update.ensure_checkout(
276 gclient_config=self.gclient_config(),
277 update_presentation=False,
278 force=True)
279 if self.c.chromite_branch and self.c.cbb.disable_bootstrap:
280 # Chromite auto-detects which branch to build for based on its current
281 # checkout. "bot_update" checks out remote branches, but Chromite requires
282 # a local branch.
283 #
284 # Normally we'd bootstrap, but if we're disabling bootstrapping, we have
285 # to checkout the local branch to let Chromite know which branch to build.
286 self.m.git('checkout', self.c.chromite_branch,
287 name=str('checkout chromite branch [%s]' % (self.c.chromite_branch)))
288
289 # Run cbuildbot. 358 # Run cbuildbot.
290 return self.cbuildbot(str('cbuildbot [%s]' % (self.c.cbb.config,)), 359 return self.cbuildbot(str('cbuildbot [%s]' % (self.c.cbb.config,)),
291 self.c.cbb.config, 360 self.c.cbb.config,
292 args=cbb_args, 361 args=cbb_args,
293 chromite_path=self.m.path['checkout'],
294 cwd=self.m.path['slave_root']) 362 cwd=self.m.path['slave_root'])
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698