blob: d8b2cb3d8114a6e2be6d1cdb23b8e562c898d9f7 [file] [log] [blame]
Mike Frysingere58c0e22017-10-04 15:43:30 -04001# -*- coding: utf-8 -*-
Don Garrettc4114cc2016-11-01 20:04:06 -07002# Copyright 2016 The Chromium OS Authors. All rights reserved.
3# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5
6"""Bootstrap for cbuildbot.
7
8This script is intended to checkout chromite on the branch specified by -b or
9--branch (as normally accepted by cbuildbot), and then invoke cbuildbot. Most
10arguments are not parsed, only passed along. If a branch is not specified, this
11script will use 'master'.
12
13Among other things, this allows us to invoke build configs that exist on a given
14branch, but not on TOT.
15"""
16
17from __future__ import print_function
18
Don Garrett125d4dc2017-04-25 16:26:03 -070019import functools
Don Garrettc4114cc2016-11-01 20:04:06 -070020import os
21
22from chromite.cbuildbot import repository
Don Garrett597ddff2017-02-17 18:29:37 -080023from chromite.cbuildbot.stages import sync_stages
Don Garrett86881cb2017-02-15 15:41:55 -080024from chromite.lib import config_lib
Don Garretta50bf492017-09-28 18:33:02 -070025from chromite.lib import constants
Don Garrettc4114cc2016-11-01 20:04:06 -070026from chromite.lib import cros_build_lib
27from chromite.lib import cros_logging as logging
Don Garrettacbb2392017-05-11 18:27:41 -070028from chromite.lib import metrics
Don Garrettc4114cc2016-11-01 20:04:06 -070029from chromite.lib import osutils
Don Garrettacbb2392017-05-11 18:27:41 -070030from chromite.lib import ts_mon_config
Don Garrett86881cb2017-02-15 15:41:55 -080031from chromite.scripts import cbuildbot
Don Garrettc4114cc2016-11-01 20:04:06 -070032
Don Garrett597ddff2017-02-17 18:29:37 -080033
Don Garrett60967922017-04-12 18:51:44 -070034# This number should be incremented when we change the layout of the buildroot
35# in a non-backwards compatible way. This wipes all buildroots.
Don Garrettbf90cdf2017-05-19 15:54:02 -070036BUILDROOT_BUILDROOT_LAYOUT = 2
Don Garrett60967922017-04-12 18:51:44 -070037
Don Garrettacbb2392017-05-11 18:27:41 -070038# Metrics reported to Monarch.
Don Garrett45e77412017-06-14 16:57:55 -070039METRIC_ACTIVE = 'chromeos/chromite/cbuildbot_launch/active'
Don Garrettacbb2392017-05-11 18:27:41 -070040METRIC_INVOKED = 'chromeos/chromite/cbuildbot_launch/invoked'
41METRIC_COMPLETED = 'chromeos/chromite/cbuildbot_launch/completed'
42METRIC_PREP = 'chromeos/chromite/cbuildbot_launch/prep_completed'
43METRIC_CLEAN = 'chromeos/chromite/cbuildbot_launch/clean_buildroot_durations'
44METRIC_INITIAL = 'chromeos/chromite/cbuildbot_launch/initial_checkout_durations'
45METRIC_CBUILDBOT = 'chromeos/chromite/cbuildbot_launch/cbuildbot_durations'
46METRIC_CLOBBER = 'chromeos/chromite/cbuildbot_launch/clobber'
47METRIC_BRANCH_CLEANUP = 'chromeos/chromite/cbuildbot_launch/branch_cleanup'
Don Garrett066e6f52017-09-28 19:14:01 -070048METRIC_DEPOT_TOOLS = 'chromeos/chromite/cbuildbot_launch/depot_tools_prep'
Don Garrettacbb2392017-05-11 18:27:41 -070049
Don Garrett60967922017-04-12 18:51:44 -070050
Don Garrett125d4dc2017-04-25 16:26:03 -070051def StageDecorator(functor):
52 """A Decorator that adds buildbot stage tags around a method.
53
Don Garrettacbb2392017-05-11 18:27:41 -070054 It uses the method name as the stage name, and assumes failure on a true
55 return value, or an exception.
Don Garrett125d4dc2017-04-25 16:26:03 -070056 """
57 @functools.wraps(functor)
58 def wrapped_functor(*args, **kwargs):
59 try:
60 logging.PrintBuildbotStepName(functor.__name__)
Don Garrettacbb2392017-05-11 18:27:41 -070061 result = functor(*args, **kwargs)
Don Garrett125d4dc2017-04-25 16:26:03 -070062 except Exception:
63 logging.PrintBuildbotStepFailure()
64 raise
65
Don Garrettacbb2392017-05-11 18:27:41 -070066 if result:
67 logging.PrintBuildbotStepFailure()
68 return result
69
Don Garrett125d4dc2017-04-25 16:26:03 -070070 return wrapped_functor
71
72
Don Garrettacbb2392017-05-11 18:27:41 -070073def field(fields, **kwargs):
74 """Helper for inserting more fields into a metrics fields dictionary.
75
76 Args:
77 fields: Dictionary of metrics fields.
78 kwargs: Each argument is a key/value pair to insert into dict.
79
80 Returns:
81 Copy of original dictionary with kwargs set as fields.
82 """
83 f = fields.copy()
84 f.update(kwargs)
85 return f
86
Don Garretta50bf492017-09-28 18:33:02 -070087
88def PrependPath(prepend):
89 """Generate path with new directory at the beginning.
90
91 Args:
92 prepend: Directory to add at the beginning of the path.
93
94 Returns:
95 Extended path as a string.
96 """
97 return os.pathsep.join([prepend, os.environ.get('PATH', os.defpath)])
98
99
Don Garrett86881cb2017-02-15 15:41:55 -0800100def PreParseArguments(argv):
Don Garrettc4114cc2016-11-01 20:04:06 -0700101 """Extract the branch name from cbuildbot command line arguments.
102
Don Garrettc4114cc2016-11-01 20:04:06 -0700103 Args:
104 argv: The command line arguments to parse.
105
106 Returns:
107 Branch as a string ('master' if nothing is specified).
108 """
Don Garrett86881cb2017-02-15 15:41:55 -0800109 parser = cbuildbot.CreateParser()
Mike Frysinger80bba8a2017-08-18 15:28:36 -0400110 options = cbuildbot.ParseCommandLine(parser, argv)
Don Garrettd1d90dd2017-06-13 17:35:52 -0700111 options.Freeze()
Don Garrett86881cb2017-02-15 15:41:55 -0800112
113 # This option isn't required for cbuildbot, but is for us.
114 if not options.buildroot:
115 cros_build_lib.Die('--buildroot is a required option.')
116
Don Garrettd1d90dd2017-06-13 17:35:52 -0700117 if len(options.build_targets) != 1:
118 cros_build_lib.Die('Exactly one build target required, got: %s',
119 ', '.join(options.build_targets) or 'None')
Don Garrett597ddff2017-02-17 18:29:37 -0800120
Don Garrett86881cb2017-02-15 15:41:55 -0800121 return options
Don Garrettc4114cc2016-11-01 20:04:06 -0700122
123
Don Garrettbf90cdf2017-05-19 15:54:02 -0700124def GetState(root):
125 """Fetch the current state of our working directory.
126
127 Will return with a default result if there is no known state.
128
129 Args:
130 root: Root of the working directory tree as a string.
131
132 Returns:
133 Layout version as an integer (0 for unknown).
134 Previous branch as a string ('' for unknown).
135 """
136 state_file = os.path.join(root, '.cbuildbot_launch_state')
Don Garrett60967922017-04-12 18:51:44 -0700137
138 try:
139 state = osutils.ReadFile(state_file)
140 buildroot_layout, branchname = state.split()
141 buildroot_layout = int(buildroot_layout)
142 return buildroot_layout, branchname
143 except (IOError, ValueError):
144 # If we are unable to either read or parse the state file, we get here.
145 return 0, ''
146
147
Don Garrettbf90cdf2017-05-19 15:54:02 -0700148def SetState(branchname, root):
149 """Save the current state of our working directory.
150
151 Args:
152 branchname: Name of branch we prepped for as a string.
153 root: Root of the working directory tree as a string.
154 """
Don Garrett60967922017-04-12 18:51:44 -0700155 assert branchname
Don Garrettbf90cdf2017-05-19 15:54:02 -0700156 state_file = os.path.join(root, '.cbuildbot_launch_state')
Don Garrett60967922017-04-12 18:51:44 -0700157 new_state = '%d %s' % (BUILDROOT_BUILDROOT_LAYOUT, branchname)
158 osutils.WriteFile(state_file, new_state)
159
160
Don Garrett125d4dc2017-04-25 16:26:03 -0700161@StageDecorator
Don Garrettbf90cdf2017-05-19 15:54:02 -0700162def CleanBuildRoot(root, repo, metrics_fields):
Don Garrett7ade05a2017-02-17 13:31:47 -0800163 """Some kinds of branch transitions break builds.
164
Don Garrettbf90cdf2017-05-19 15:54:02 -0700165 This method ensures that cbuildbot's buildroot is a clean checkout on the
166 given branch when it starts. If necessary (a branch transition) it will wipe
167 assorted state that cannot be safely reused from the previous build.
Don Garrett7ade05a2017-02-17 13:31:47 -0800168
Don Garrett7ade05a2017-02-17 13:31:47 -0800169 Args:
Don Garrettbf90cdf2017-05-19 15:54:02 -0700170 root: Root directory owned by cbuildbot_launch.
Don Garrettf324bc32017-05-23 14:00:53 -0700171 repo: repository.RepoRepository instance.
Don Garrettacbb2392017-05-11 18:27:41 -0700172 metrics_fields: Dictionary of fields to include in metrics.
Don Garrett7ade05a2017-02-17 13:31:47 -0800173 """
Don Garrettbf90cdf2017-05-19 15:54:02 -0700174 old_buildroot_layout, old_branch = GetState(root)
Don Garrette17e1d92017-04-12 15:28:19 -0700175
Don Garrett60967922017-04-12 18:51:44 -0700176 if old_buildroot_layout != BUILDROOT_BUILDROOT_LAYOUT:
Don Garrett125d4dc2017-04-25 16:26:03 -0700177 logging.PrintBuildbotStepText('Unknown layout: Wiping buildroot.')
Don Garrettacbb2392017-05-11 18:27:41 -0700178 metrics.Counter(METRIC_CLOBBER).increment(
179 field(metrics_fields, reason='layout_change'))
Benjamin Gordon59ba2f82017-08-28 15:31:06 -0600180 chroot_dir = os.path.join(root, 'chroot')
181 if os.path.exists(chroot_dir) or os.path.exists(chroot_dir + '.img'):
182 cros_build_lib.CleanupChrootMount(chroot_dir, delete_image=True)
Don Garrettbf90cdf2017-05-19 15:54:02 -0700183 osutils.RmDir(root, ignore_missing=True, sudo=True)
Don Garrettf324bc32017-05-23 14:00:53 -0700184 else:
185 if old_branch != repo.branch:
186 logging.PrintBuildbotStepText('Branch change: Cleaning buildroot.')
187 logging.info('Unmatched branch: %s -> %s', old_branch, repo.branch)
Don Garrettacbb2392017-05-11 18:27:41 -0700188 metrics.Counter(METRIC_BRANCH_CLEANUP).increment(
189 field(metrics_fields, old_branch=old_branch))
Don Garrett39963602017-02-27 14:41:58 -0800190
Don Garrettf324bc32017-05-23 14:00:53 -0700191 logging.info('Remove Chroot.')
Benjamin Gordon59ba2f82017-08-28 15:31:06 -0600192 chroot_dir = os.path.join(repo.directory, 'chroot')
193 if os.path.exists(chroot_dir) or os.path.exists(chroot_dir + '.img'):
194 cros_build_lib.CleanupChrootMount(chroot_dir, delete_image=True)
195 osutils.RmDir(chroot_dir, ignore_missing=True, sudo=True)
Don Garrett7ade05a2017-02-17 13:31:47 -0800196
Don Garrettf324bc32017-05-23 14:00:53 -0700197 logging.info('Remove Chrome checkout.')
Don Garrettbf90cdf2017-05-19 15:54:02 -0700198 osutils.RmDir(os.path.join(repo.directory, '.cache', 'distfiles'),
Don Garrettf324bc32017-05-23 14:00:53 -0700199 ignore_missing=True, sudo=True)
200
201 try:
202 # If there is any failure doing the cleanup, wipe everything.
203 repo.BuildRootGitCleanup(prune_all=True)
204 except Exception:
205 logging.info('Checkout cleanup failed, wiping buildroot:', exc_info=True)
Don Garrettacbb2392017-05-11 18:27:41 -0700206 metrics.Counter(METRIC_CLOBBER).increment(
207 field(metrics_fields, reason='repo_cleanup_failure'))
Don Garrettbf90cdf2017-05-19 15:54:02 -0700208 repository.ClearBuildRoot(repo.directory)
Don Garrett39963602017-02-27 14:41:58 -0800209
Don Garrettbf90cdf2017-05-19 15:54:02 -0700210 # Ensure buildroot exists. Save the state we are prepped for.
211 osutils.SafeMakedirs(repo.directory)
212 SetState(repo.branch, root)
Don Garrett7ade05a2017-02-17 13:31:47 -0800213
214
Don Garrett125d4dc2017-04-25 16:26:03 -0700215@StageDecorator
Don Garrettf324bc32017-05-23 14:00:53 -0700216def InitialCheckout(repo):
Don Garrett86881cb2017-02-15 15:41:55 -0800217 """Preliminary ChromeOS checkout.
218
219 Perform a complete checkout of ChromeOS on the specified branch. This does NOT
220 match what the build needs, but ensures the buildroot both has a 'hot'
221 checkout, and is close enough that the branched cbuildbot can successfully get
222 the right checkout.
223
224 This checks out full ChromeOS, even if a ChromiumOS build is going to be
225 performed. This is because we have no knowledge of the build config to be
226 used.
Don Garrettc4114cc2016-11-01 20:04:06 -0700227
228 Args:
Don Garrettf324bc32017-05-23 14:00:53 -0700229 repo: repository.RepoRepository instance.
Don Garrettc4114cc2016-11-01 20:04:06 -0700230 """
Don Garrettf324bc32017-05-23 14:00:53 -0700231 logging.PrintBuildbotStepText('Branch: %s' % repo.branch)
Don Garrett7ade05a2017-02-17 13:31:47 -0800232 logging.info('Bootstrap script starting initial sync on branch: %s',
Don Garrettf324bc32017-05-23 14:00:53 -0700233 repo.branch)
Don Garrett76496912017-05-11 16:59:11 -0700234 repo.Sync(detach=True)
Don Garrettc4114cc2016-11-01 20:04:06 -0700235
236
Don Garrett125d4dc2017-04-25 16:26:03 -0700237@StageDecorator
Don Garrett066e6f52017-09-28 19:14:01 -0700238def DepotToolsEnsureBootstrap(depot_tools_path):
239 """Start cbuildbot in specified directory with all arguments.
240
241 Args:
242 buildroot: Directory to be passed to cbuildbot with --buildroot.
243 depot_tools_path: Directory for depot_tools to be used by cbuildbot.
244 argv: Command line options passed to cbuildbot_launch.
245
246 Returns:
247 Return code of cbuildbot as an integer.
248 """
249 ensure_bootstrap_script = os.path.join(depot_tools_path, 'ensure_bootstrap')
250 if os.path.exists(ensure_bootstrap_script):
251 extra_env = {'PATH': PrependPath(depot_tools_path)}
252 cros_build_lib.RunCommand(
253 [ensure_bootstrap_script], extra_env=extra_env, cwd=depot_tools_path)
254 else:
255 # This is normal when checking out branches older than this script.
256 logging.warn('ensure_bootstrap not found, skipping: %s',
257 ensure_bootstrap_script)
258
259
260@StageDecorator
Don Garretta50bf492017-09-28 18:33:02 -0700261def RunCbuildbot(buildroot, depot_tools_path, argv):
Don Garrettc4114cc2016-11-01 20:04:06 -0700262 """Start cbuildbot in specified directory with all arguments.
263
264 Args:
Don Garrettbf90cdf2017-05-19 15:54:02 -0700265 buildroot: Directory to be passed to cbuildbot with --buildroot.
Don Garretta50bf492017-09-28 18:33:02 -0700266 depot_tools_path: Directory for depot_tools to be used by cbuildbot.
Don Garrettd1d90dd2017-06-13 17:35:52 -0700267 argv: Command line options passed to cbuildbot_launch.
Don Garrettc4114cc2016-11-01 20:04:06 -0700268
269 Returns:
270 Return code of cbuildbot as an integer.
271 """
Don Garrettbf90cdf2017-05-19 15:54:02 -0700272 logging.info('Bootstrap cbuildbot in: %s', buildroot)
Don Garrettbf90cdf2017-05-19 15:54:02 -0700273
Don Garrettd1d90dd2017-06-13 17:35:52 -0700274 # Fixup buildroot parameter.
275 argv = argv[:]
276 for i in xrange(len(argv)):
277 if argv[i] in ('-r', '--buildroot'):
278 argv[i+1] = buildroot
Don Garrett597ddff2017-02-17 18:29:37 -0800279
Don Garrettd1d90dd2017-06-13 17:35:52 -0700280 # This filters out command line arguments not supported by older versions
281 # of cbuildbot.
282 parser = cbuildbot.CreateParser()
Mike Frysinger80bba8a2017-08-18 15:28:36 -0400283 options = cbuildbot.ParseCommandLine(parser, argv)
Don Garrettd1d90dd2017-06-13 17:35:52 -0700284 cbuildbot_path = os.path.join(buildroot, 'chromite', 'bin', 'cbuildbot')
Don Garrett597ddff2017-02-17 18:29:37 -0800285 cmd = sync_stages.BootstrapStage.FilterArgsForTargetCbuildbot(
Don Garrettbf90cdf2017-05-19 15:54:02 -0700286 buildroot, cbuildbot_path, options)
Don Garrett597ddff2017-02-17 18:29:37 -0800287
Don Garretta50bf492017-09-28 18:33:02 -0700288 # We want cbuildbot to use branched depot_tools scripts from our manifest,
289 # so that depot_tools is branched to match cbuildbot.
290 logging.info('Adding depot_tools into PATH: %s', depot_tools_path)
291 extra_env = {'PATH': PrependPath(depot_tools_path)}
292
293 result = cros_build_lib.RunCommand(
294 cmd, extra_env=extra_env, error_code_ok=True, cwd=buildroot)
Don Garrettacbb2392017-05-11 18:27:41 -0700295 return result.returncode
Don Garrettc4114cc2016-11-01 20:04:06 -0700296
Don Garrett60967922017-04-12 18:51:44 -0700297
Don Garrett90c9da22017-09-12 16:45:40 -0700298def _InstallSystemCrcmodIfNeeded():
299 """Install Crcmod binary extension if needed.
300
301 If the build host has python-crcmod installed without the binary extension,
302 that breaks some versions of gsutil. In that case, this function installs
303 a new copy of the module with the extension.
304
305 Newer branches workaround this in gs.py, and hopefully future versions of
306 gsutil will work around this in gsutil, however, older branches will always
307 have this problem.
308
309 So... this method will always be required unless/until we chose to solve this
310 through configuration management of hosts.
311
312 http://crbug.com/763438 covers this in detail.
313 """
314 try:
315 import crcmod
316 # If crcmod exists on the system, but doesn't have the binary extension,
317 # gsutil behaves badly. Override the system module with one that contains
318 # the binary extension. This depends on /usr/local/lib overridding /usr/lib.
319 if not (getattr(crcmod, 'crcmod', None) and
320 getattr(crcmod.crcmod, '_usingExtension', None)):
321 logging.warn('FORCING CRCMOD INSTALL to workaround crbug.com/763438.')
322 cmd = ['pip', 'install', '--ignore-installed', 'crcmod']
323 result = cros_build_lib.SudoRunCommand(
324 cmd, error_code_ok=True, mute_output=True)
325 logging.warn('CRCMOD INSTALL RETURNED :%d', result.returncode)
326 except ImportError:
327 # If crcmod doesn't exist on the system, gs.py will properly use its
328 # version in the cache.
329 pass
330
331
Don Garrettf15d65b2017-04-12 12:39:55 -0700332def ConfigureGlobalEnvironment():
333 """Setup process wide environmental changes."""
Don Garrettf15d65b2017-04-12 12:39:55 -0700334 # Set umask to 022 so files created by buildbot are readable.
335 os.umask(0o22)
336
Don Garrett86fec482017-05-17 18:13:33 -0700337 # These variables can interfere with LANG / locale behavior.
338 unwanted_local_vars = [
339 'LC_ALL', 'LC_CTYPE', 'LC_COLLATE', 'LC_TIME', 'LC_NUMERIC',
340 'LC_MONETARY', 'LC_MESSAGES', 'LC_PAPER', 'LC_NAME', 'LC_ADDRESS',
341 'LC_TELEPHONE', 'LC_MEASUREMENT', 'LC_IDENTIFICATION',
342 ]
343 for v in unwanted_local_vars:
344 os.environ.pop(v, None)
345
346 # This variable is required for repo sync's to work in all cases.
347 os.environ['LANG'] = 'en_US.UTF-8'
348
Don Garrett90c9da22017-09-12 16:45:40 -0700349 _InstallSystemCrcmodIfNeeded()
Don Garrett90f5e7d2017-09-08 17:42:46 -0700350
Don Garrettc4114cc2016-11-01 20:04:06 -0700351
Don Garrettacbb2392017-05-11 18:27:41 -0700352def _main(argv):
Don Garrettc4114cc2016-11-01 20:04:06 -0700353 """main method of script.
354
355 Args:
356 argv: All command line arguments to pass as list of strings.
357
358 Returns:
359 Return code of cbuildbot as an integer.
360 """
Don Garrettd1d90dd2017-06-13 17:35:52 -0700361 options = PreParseArguments(argv)
362
363 branchname = options.branch or 'master'
364 root = options.buildroot
365 buildroot = os.path.join(root, 'repository')
Don Garretta50bf492017-09-28 18:33:02 -0700366 depot_tools_path = os.path.join(buildroot, constants.DEPOT_TOOLS_SUBPATH)
Don Garrettd1d90dd2017-06-13 17:35:52 -0700367 build_config = options.build_targets[0]
368
369 metrics_fields = {
370 'branch_name': branchname,
371 'build_config': build_config,
372 'tryjob': options.remote_trybot,
373 }
Don Garrettf15d65b2017-04-12 12:39:55 -0700374
Don Garrettacbb2392017-05-11 18:27:41 -0700375 # Does the entire build pass or fail.
Don Garrett45e77412017-06-14 16:57:55 -0700376 with metrics.Presence(METRIC_ACTIVE, metrics_fields), \
377 metrics.SuccessCounter(METRIC_COMPLETED, metrics_fields) as s_fields:
Don Garrettc4114cc2016-11-01 20:04:06 -0700378
Don Garrettacbb2392017-05-11 18:27:41 -0700379 # Preliminary set, mostly command line parsing.
Don Garrettd1d90dd2017-06-13 17:35:52 -0700380 with metrics.SuccessCounter(METRIC_INVOKED, metrics_fields):
Don Garrettfbbccec2017-09-20 14:04:48 -0700381 if options.enable_buildbot_tags:
382 logging.EnableBuildbotMarkers()
Don Garrettacbb2392017-05-11 18:27:41 -0700383 ConfigureGlobalEnvironment()
Don Garrett86881cb2017-02-15 15:41:55 -0800384
Don Garrettacbb2392017-05-11 18:27:41 -0700385 # Prepare the buildroot with source for the build.
386 with metrics.SuccessCounter(METRIC_PREP, metrics_fields):
387 site_config = config_lib.GetConfig()
388 manifest_url = site_config.params['MANIFEST_INT_URL']
389 repo = repository.RepoRepository(manifest_url, buildroot,
390 branch=branchname,
Don Garrettd1d90dd2017-06-13 17:35:52 -0700391 git_cache_dir=options.git_cache_dir)
Don Garrett86881cb2017-02-15 15:41:55 -0800392
Don Garrettacbb2392017-05-11 18:27:41 -0700393 # Clean up the buildroot to a safe state.
394 with metrics.SecondsTimer(METRIC_CLEAN, fields=metrics_fields):
Don Garrettbf90cdf2017-05-19 15:54:02 -0700395 CleanBuildRoot(root, repo, metrics_fields)
Don Garrettacbb2392017-05-11 18:27:41 -0700396
Don Garretta50bf492017-09-28 18:33:02 -0700397 # Get a checkout close enough to the branch that cbuildbot can handle it.
Don Garrettacbb2392017-05-11 18:27:41 -0700398 with metrics.SecondsTimer(METRIC_INITIAL, fields=metrics_fields):
399 InitialCheckout(repo)
400
Don Garrett066e6f52017-09-28 19:14:01 -0700401 # Get a checkout close enough to the branch that cbuildbot can handle it.
402 with metrics.SecondsTimer(METRIC_DEPOT_TOOLS, fields=metrics_fields):
403 DepotToolsEnsureBootstrap(depot_tools_path)
404
Don Garrettacbb2392017-05-11 18:27:41 -0700405 # Run cbuildbot inside the full ChromeOS checkout, on the specified branch.
406 with metrics.SecondsTimer(METRIC_CBUILDBOT, fields=metrics_fields):
Don Garretta50bf492017-09-28 18:33:02 -0700407 result = RunCbuildbot(buildroot, depot_tools_path, argv)
Don Garrettd1d90dd2017-06-13 17:35:52 -0700408 s_fields['success'] = (result == 0)
Don Garrettacbb2392017-05-11 18:27:41 -0700409 return result
410
411
412def main(argv):
413 # Enable Monarch metrics gathering.
414 with ts_mon_config.SetupTsMonGlobalState('cbuildbot_launch', indirect=True):
415 return _main(argv)