OLD | NEW |
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 ChromiteApi(recipe_api.RecipeApi): | 11 class ChromiteApi(recipe_api.RecipeApi): |
12 chromite_url = 'https://chromium.googlesource.com/chromiumos/chromite.git' | 12 chromite_url = 'https://chromium.googlesource.com/chromiumos/chromite.git' |
13 manifest_url = 'https://chromium.googlesource.com/chromiumos/manifest.git' | 13 manifest_url = 'https://chromium.googlesource.com/chromiumos/manifest.git' |
14 repo_url = 'https://chromium.googlesource.com/external/repo.git' | 14 repo_url = 'https://chromium.googlesource.com/external/repo.git' |
15 chromite_subpath = 'chromite' | 15 chromite_subpath = 'chromite' |
16 | 16 |
17 # The number of Gitiles attempts to make before giving up. | 17 # The number of Gitiles attempts to make before giving up. |
18 _GITILES_ATTEMPTS = 10 | 18 _GITILES_ATTEMPTS = 10 |
19 | 19 |
20 _MANIFEST_CMD_RE = re.compile(r'Automatic:\s+Start\s+([^\s]+)\s+([^\s]+)') | 20 _MANIFEST_CMD_RE = re.compile(r'Automatic:\s+Start\s+([^\s]+)\s+([^\s]+)') |
21 _BUILD_ID_RE = re.compile(r'CrOS-Build-Id: (.+)') | 21 _BUILD_ID_RE = re.compile(r'CrOS-Build-Id: (.+)') |
22 | 22 |
| 23 def get_config_defaults(self): |
| 24 defaults = { |
| 25 'CBB_CONFIG': self.m.properties.get('cbb_config'), |
| 26 'CBB_BRANCH': self.m.properties.get('cbb_branch'), |
| 27 'CBB_DEBUG': self.m.properties.get('cbb_debug') is not None, |
| 28 'CBB_CLOBBER': 'clobber' in self.m.properties, |
| 29 } |
| 30 if 'buildnumber' in self.m.properties: |
| 31 defaults['CBB_BUILD_NUMBER'] = int(self.m.properties['buildnumber']) |
| 32 return defaults |
| 33 |
23 def check_repository(self, repo_type_key, value): | 34 def check_repository(self, repo_type_key, value): |
24 """Scans through registered repositories for a specified value. | 35 """Scans through registered repositories for a specified value. |
25 | 36 |
26 Args: | 37 Args: |
27 repo_type_key (str): The key in the 'repositories' config to scan through. | 38 repo_type_key (str): The key in the 'repositories' config to scan through. |
28 value (str): The value to scan for. | 39 value (str): The value to scan for. |
29 Returns (bool): True if the value was found. | 40 Returns (bool): True if the value was found. |
30 """ | 41 """ |
31 def remove_tail(v, tail): | 42 def remove_tail(v, tail): |
32 if v.endswith(tail): | 43 if v.endswith(tail): |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
114 # Build ID? | 125 # Build ID? |
115 match = self._BUILD_ID_RE.match(line) | 126 match = self._BUILD_ID_RE.match(line) |
116 if match: | 127 if match: |
117 self.c.cbb.build_id = match.group(1) | 128 self.c.cbb.build_id = match.group(1) |
118 loaded.append('Build ID: %s' % (self.c.cbb.build_id,)) | 129 loaded.append('Build ID: %s' % (self.c.cbb.build_id,)) |
119 continue | 130 continue |
120 if loaded: | 131 if loaded: |
121 loaded.insert(0, '') | 132 loaded.insert(0, '') |
122 result.presentation.step_text += '<br/>'.join(loaded) | 133 result.presentation.step_text += '<br/>'.join(loaded) |
123 | 134 |
| 135 @property |
124 def default_chromite_path(self): | 136 def default_chromite_path(self): |
125 """Returns: (Path) The default Chromite checkout path.""" | 137 """Returns: (Path) The default Chromite checkout path.""" |
126 return self.m.path['slave_build'].join(self.chromite_subpath) | 138 return self.m.path['slave_build'].join(self.chromite_subpath) |
127 | 139 |
128 def gclient_config(self): | 140 def gclient_config(self): |
129 """Generate a 'gclient' configuration to check out Chromite. | 141 """Generate a 'gclient' configuration to check out Chromite. |
130 | 142 |
131 Return: (config) A 'gclient' recipe module configuration. | 143 Return: (config) A 'gclient' recipe module configuration. |
132 """ | 144 """ |
133 cfg = self.m.gclient.make_config() | 145 cfg = self.m.gclient.make_config() |
134 soln = cfg.solutions.add() | 146 soln = cfg.solutions.add() |
135 soln.name = 'chromite' | 147 soln.name = 'chromite' |
136 soln.url = self.chromite_url | 148 soln.url = self.chromite_url |
137 # Set the revision using 'bot_update' remote branch:revision notation. | 149 # Set the revision using 'bot_update' remote branch:revision notation. |
138 # Omitting the revision uses HEAD. | 150 # Omitting the revision uses HEAD. |
139 soln.revision = '%s:' % (self.c.chromite_branch,) | 151 soln.revision = '%s:' % (self.c.chromite_branch,) |
140 return cfg | 152 return cfg |
141 | 153 |
142 def checkout(self, manifest_url=None, repo_url=None): | 154 def checkout(self, manifest_url=None, repo_url=None): |
143 manifest_url = manifest_url or self.manifest_url | 155 manifest_url = manifest_url or self.manifest_url |
144 repo_url = repo_url or self.repo_url | 156 repo_url = repo_url or self.repo_url |
145 | 157 |
146 self.m.repo.init(manifest_url, '--repo-url', repo_url) | 158 self.m.repo.init(manifest_url, '--repo-url', repo_url) |
147 self.m.repo.sync() | 159 self.m.repo.sync() |
148 | 160 |
| 161 @property |
| 162 def using_old_chromite_layout(self): |
| 163 """Returns (bool): True if we're using old Chromite checkout layout. |
| 164 """ |
| 165 return self.c.chromite_branch in self.c.old_chromite_branches |
| 166 |
149 def cbuildbot(self, name, config, args=None, chromite_path=None, **kwargs): | 167 def cbuildbot(self, name, config, args=None, chromite_path=None, **kwargs): |
150 """Runs the cbuildbot command defined by the arguments. | 168 """Runs the cbuildbot command defined by the arguments. |
151 | 169 |
152 Args: | 170 Args: |
153 name: (str) The name of the command step. | 171 name: (str) The name of the command step. |
154 config: (str) The name of the 'cbuildbot' configuration to invoke. | 172 config: (str) The name of the 'cbuildbot' configuration to invoke. |
155 args: (list) If not None, addition arguments to pass to 'cbuildbot'. | 173 args: (list) If not None, addition arguments to pass to 'cbuildbot'. |
156 chromite_path: (str) The path to the Chromite checkout; if None, the | 174 chromite_path: (str) The path to the Chromite checkout; if None, the |
157 'default_chromite_path()' will be used. | 175 'default_chromite_path' will be used. |
158 | 176 |
159 Returns: (Step) The step that was run. | 177 Returns: (Step) The step that was run. |
160 """ | 178 """ |
161 chromite_path = chromite_path or self.default_chromite_path() | 179 chromite_path = chromite_path or self.default_chromite_path |
162 args = (args or [])[:] | 180 args = (args or [])[:] |
163 args.append(config) | 181 args.append(config) |
164 | 182 |
165 cmd = [self.m.path.join(chromite_path, 'bin', 'cbuildbot')] + args | 183 bindir = 'bin' |
166 | 184 if self.using_old_chromite_layout: |
167 # TODO(petermayo): Wrap this nested annotation in a stabilizing wrapper. | 185 bindir = 'buildbot' |
| 186 cmd = [self.m.path.join(chromite_path, bindir, 'cbuildbot')] + args |
168 return self.m.step(name, cmd, allow_subannotations=True, **kwargs) | 187 return self.m.step(name, cmd, allow_subannotations=True, **kwargs) |
169 | 188 |
170 def cros_sdk(self, name, cmd, args=None, environ=None, chromite_path=None, | 189 def cros_sdk(self, name, cmd, args=None, environ=None, chromite_path=None, |
171 **kwargs): | 190 **kwargs): |
172 """Return a step to run a command inside the cros_sdk.""" | 191 """Return a step to run a command inside the cros_sdk.""" |
173 chromite_path = chromite_path or self.default_chromite_path() | 192 chromite_path = chromite_path or self.default_chromite_path |
174 | 193 |
175 chroot_cmd = self.m.path.join(chromite_path, 'bin', 'cros_sdk') | 194 chroot_cmd = self.m.path.join(chromite_path, 'bin', 'cros_sdk') |
176 | 195 |
177 arg_list = (args or [])[:] | 196 arg_list = (args or [])[:] |
178 for t in sorted((environ or {}).items()): | 197 for t in sorted((environ or {}).items()): |
179 arg_list.append('%s=%s' % t) | 198 arg_list.append('%s=%s' % t) |
180 arg_list.append('--') | 199 arg_list.append('--') |
181 arg_list.extend(cmd) | 200 arg_list.extend(cmd) |
182 | 201 |
183 self.m.python(name, chroot_cmd, arg_list, **kwargs) | 202 self.m.python(name, chroot_cmd, arg_list, **kwargs) |
(...skipping 25 matching lines...) Expand all Loading... |
209 master_config = config_map.get('master_config') | 228 master_config = config_map.get('master_config') |
210 assert master_config, ( | 229 assert master_config, ( |
211 "No 'master_config' configuration for '%s'" % (master,)) | 230 "No 'master_config' configuration for '%s'" % (master,)) |
212 self.set_config(master_config) | 231 self.set_config(master_config) |
213 | 232 |
214 # Apply any variant configurations. | 233 # Apply any variant configurations. |
215 if variant: | 234 if variant: |
216 for config_name in config_map.get('variants', {}).get(variant, ()): | 235 for config_name in config_map.get('variants', {}).get(variant, ()): |
217 self.apply_config(config_name) | 236 self.apply_config(config_name) |
218 | 237 |
219 # If a Chromite branch is supplied, use it to override the default Chromite | |
220 # checkout revision. | |
221 if properties.get('cbb_branch'): | |
222 self.c.chromite_branch = properties['cbb_branch'] | |
223 | |
224 # Set the build number if one is defined in the properties. | |
225 if self.m.properties.get('buildnumber') is not None: | |
226 # On a developer system, it's been noted that when the build number is | |
227 # zero, it's passed as an empty string in the properties JSON blob. | |
228 self.c.cbb.build_number = int(self.m.properties['buildnumber'] or 0) | |
229 | |
230 # Run a debug build if instructed. | |
231 if properties.get('cbb_debug'): | |
232 self.c.cbb.debug = True | |
233 | |
234 # If a clobber build was requested, set this builder to clobber. | |
235 if 'clobber' in properties: | |
236 self.c.cbb.clobber = True | |
237 | 238 |
238 # If a config repo was specified, use it. | 239 # If a config repo was specified, use it. |
239 if 'config_repo' in properties: | 240 if 'config_repo' in properties: |
240 self.c.cbb.config_repo = self.m.properties['config_repo'] | 241 self.c.cbb.config_repo = self.m.properties['config_repo'] |
241 | 242 |
242 def run_cbuildbot(self, config, tryjob=False): | 243 def run_cbuildbot(self, tryjob=False): |
243 """Runs a 'cbuildbot' checkout-and-build workflow. | 244 """Runs a 'cbuildbot' checkout-and-build workflow. |
244 | 245 |
245 This workflow uses the registered configuration dictionary to make master- | 246 This workflow uses the registered configuration dictionary to make master- |
246 and builder-specific changes to the standard workflow. | 247 and builder-specific changes to the standard workflow. |
247 | 248 |
248 The specific workflow paths that are taken are also influenced by several | 249 The specific workflow paths that are taken are also influenced by several |
249 build properties. | 250 build properties. |
250 | 251 |
251 TODO(dnj): When CrOS migrates away from BuildBot, replace property | 252 TODO(dnj): When CrOS migrates away from BuildBot, replace property |
252 inferences with command-line parameters. | 253 inferences with command-line parameters. |
253 | 254 |
254 This workflow: | 255 This workflow: |
255 - Checks out the specified 'cbuildbot' repository. | 256 - Checks out the specified 'cbuildbot' repository. |
256 - Pulls information based on the configured change's repository/revision | 257 - Pulls information based on the configured change's repository/revision |
257 to pass to 'cbuildbot'. | 258 to pass to 'cbuildbot'. |
258 - Executes the 'cbuildbot' command. | 259 - Executes the 'cbuildbot' command. |
259 | 260 |
260 Args: | 261 Args: |
261 config (str): The name of the 'cbuildbot' configuration target to build. | |
262 tryjob (bool): If True, load a tryjob description from the source | 262 tryjob (bool): If True, load a tryjob description from the source |
263 repository and augment the cbuildbot command-line with it. | 263 repository and augment the cbuildbot command-line with it. |
264 Returns: (Step) the 'cbuildbot' execution step. | 264 Returns: (Step) the 'cbuildbot' execution step. |
265 """ | 265 """ |
266 | |
267 # Assert correct configuration. | 266 # Assert correct configuration. |
268 assert config, 'An empty configuration was specified.' | 267 assert self.c.cbb.config, 'An empty configuration was specified.' |
269 assert self.c.cbb.builddir, 'A build directory name must be specified.' | 268 assert self.c.cbb.builddir, 'A build directory name must be specified.' |
270 | 269 |
271 # Load properties from the commit being processed. This requires both a | 270 # Load properties from the commit being processed. This requires both a |
272 # repository and revision to proceed. | 271 # repository and revision to proceed. |
273 repository = self.m.properties.get('repository') | 272 repository = self.m.properties.get('repository') |
274 revision = self.m.properties.get('revision') | 273 revision = self.m.properties.get('revision') |
275 tryjob_args = [] | 274 tryjob_args = [] |
276 if repository and revision: | 275 if repository and revision: |
277 if tryjob: | 276 if tryjob: |
278 assert self.check_repository('tryjob', repository), ( | 277 assert self.check_repository('tryjob', repository), ( |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
321 # Add tryjob args, if there are any. | 320 # Add tryjob args, if there are any. |
322 cbb_args.extend(tryjob_args) | 321 cbb_args.extend(tryjob_args) |
323 | 322 |
324 # Checkout Chromite. | 323 # Checkout Chromite. |
325 self.m.bot_update.ensure_checkout( | 324 self.m.bot_update.ensure_checkout( |
326 gclient_config=self.gclient_config(), | 325 gclient_config=self.gclient_config(), |
327 update_presentation=False, | 326 update_presentation=False, |
328 force=True) | 327 force=True) |
329 | 328 |
330 # Run cbuildbot. | 329 # Run cbuildbot. |
331 return self.cbuildbot(str('cbuildbot [%s]' % (config,)), | 330 return self.cbuildbot(str('cbuildbot [%s]' % (self.c.cbb.config,)), |
332 config, | 331 self.c.cbb.config, |
333 args=cbb_args, | 332 args=cbb_args, |
334 chromite_path=self.m.path['checkout'], | 333 chromite_path=self.m.path['checkout'], |
335 cwd=self.m.path['slave_root']) | 334 cwd=self.m.path['slave_root']) |
OLD | NEW |