blob: 63cef924d71a73e3923bb1cb9d806821f0ee78f0 [file] [log] [blame]
Don Garrettc4114cc2016-11-01 20:04:06 -07001# Copyright 2016 The Chromium OS Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5"""Bootstrap for cbuildbot.
6
7This script is intended to checkout chromite on the branch specified by -b or
8--branch (as normally accepted by cbuildbot), and then invoke cbuildbot. Most
9arguments are not parsed, only passed along. If a branch is not specified, this
10script will use 'master'.
11
12Among other things, this allows us to invoke build configs that exist on a given
13branch, but not on TOT.
14"""
15
16from __future__ import print_function
17
Don Garrett125d4dc2017-04-25 16:26:03 -070018import functools
Don Garrettc4114cc2016-11-01 20:04:06 -070019import os
20
21from chromite.cbuildbot import repository
Don Garrett597ddff2017-02-17 18:29:37 -080022from chromite.cbuildbot.stages import sync_stages
Don Garrett86881cb2017-02-15 15:41:55 -080023from chromite.lib import config_lib
Don Garretta50bf492017-09-28 18:33:02 -070024from chromite.lib import constants
Don Garrettc4114cc2016-11-01 20:04:06 -070025from chromite.lib import cros_build_lib
26from chromite.lib import cros_logging as logging
Don Garrettacbb2392017-05-11 18:27:41 -070027from chromite.lib import metrics
Don Garrettc4114cc2016-11-01 20:04:06 -070028from chromite.lib import osutils
Don Garrettacbb2392017-05-11 18:27:41 -070029from chromite.lib import ts_mon_config
Don Garrett86881cb2017-02-15 15:41:55 -080030from chromite.scripts import cbuildbot
Don Garrettc4114cc2016-11-01 20:04:06 -070031
Don Garrett597ddff2017-02-17 18:29:37 -080032
Don Garrett60967922017-04-12 18:51:44 -070033# This number should be incremented when we change the layout of the buildroot
34# in a non-backwards compatible way. This wipes all buildroots.
Don Garrettbf90cdf2017-05-19 15:54:02 -070035BUILDROOT_BUILDROOT_LAYOUT = 2
Don Garrett60967922017-04-12 18:51:44 -070036
Don Garrettacbb2392017-05-11 18:27:41 -070037# Metrics reported to Monarch.
Don Garrett45e77412017-06-14 16:57:55 -070038METRIC_ACTIVE = 'chromeos/chromite/cbuildbot_launch/active'
Don Garrettacbb2392017-05-11 18:27:41 -070039METRIC_INVOKED = 'chromeos/chromite/cbuildbot_launch/invoked'
40METRIC_COMPLETED = 'chromeos/chromite/cbuildbot_launch/completed'
41METRIC_PREP = 'chromeos/chromite/cbuildbot_launch/prep_completed'
42METRIC_CLEAN = 'chromeos/chromite/cbuildbot_launch/clean_buildroot_durations'
43METRIC_INITIAL = 'chromeos/chromite/cbuildbot_launch/initial_checkout_durations'
44METRIC_CBUILDBOT = 'chromeos/chromite/cbuildbot_launch/cbuildbot_durations'
45METRIC_CLOBBER = 'chromeos/chromite/cbuildbot_launch/clobber'
46METRIC_BRANCH_CLEANUP = 'chromeos/chromite/cbuildbot_launch/branch_cleanup'
Don Garrett066e6f52017-09-28 19:14:01 -070047METRIC_DEPOT_TOOLS = 'chromeos/chromite/cbuildbot_launch/depot_tools_prep'
Don Garrettacbb2392017-05-11 18:27:41 -070048
Don Garrett60967922017-04-12 18:51:44 -070049
Don Garrett125d4dc2017-04-25 16:26:03 -070050def StageDecorator(functor):
51 """A Decorator that adds buildbot stage tags around a method.
52
Don Garrettacbb2392017-05-11 18:27:41 -070053 It uses the method name as the stage name, and assumes failure on a true
54 return value, or an exception.
Don Garrett125d4dc2017-04-25 16:26:03 -070055 """
56 @functools.wraps(functor)
57 def wrapped_functor(*args, **kwargs):
58 try:
59 logging.PrintBuildbotStepName(functor.__name__)
Don Garrettacbb2392017-05-11 18:27:41 -070060 result = functor(*args, **kwargs)
Don Garrett125d4dc2017-04-25 16:26:03 -070061 except Exception:
62 logging.PrintBuildbotStepFailure()
63 raise
64
Don Garrettacbb2392017-05-11 18:27:41 -070065 if result:
66 logging.PrintBuildbotStepFailure()
67 return result
68
Don Garrett125d4dc2017-04-25 16:26:03 -070069 return wrapped_functor
70
71
Don Garrettacbb2392017-05-11 18:27:41 -070072def field(fields, **kwargs):
73 """Helper for inserting more fields into a metrics fields dictionary.
74
75 Args:
76 fields: Dictionary of metrics fields.
77 kwargs: Each argument is a key/value pair to insert into dict.
78
79 Returns:
80 Copy of original dictionary with kwargs set as fields.
81 """
82 f = fields.copy()
83 f.update(kwargs)
84 return f
85
Don Garretta50bf492017-09-28 18:33:02 -070086
87def PrependPath(prepend):
88 """Generate path with new directory at the beginning.
89
90 Args:
91 prepend: Directory to add at the beginning of the path.
92
93 Returns:
94 Extended path as a string.
95 """
96 return os.pathsep.join([prepend, os.environ.get('PATH', os.defpath)])
97
98
Don Garrett86881cb2017-02-15 15:41:55 -080099def PreParseArguments(argv):
Don Garrettc4114cc2016-11-01 20:04:06 -0700100 """Extract the branch name from cbuildbot command line arguments.
101
Don Garrettc4114cc2016-11-01 20:04:06 -0700102 Args:
103 argv: The command line arguments to parse.
104
105 Returns:
106 Branch as a string ('master' if nothing is specified).
107 """
Don Garrett86881cb2017-02-15 15:41:55 -0800108 parser = cbuildbot.CreateParser()
Mike Frysinger80bba8a2017-08-18 15:28:36 -0400109 options = cbuildbot.ParseCommandLine(parser, argv)
Don Garrettd1d90dd2017-06-13 17:35:52 -0700110 options.Freeze()
Don Garrett86881cb2017-02-15 15:41:55 -0800111
112 # This option isn't required for cbuildbot, but is for us.
113 if not options.buildroot:
114 cros_build_lib.Die('--buildroot is a required option.')
115
Don Garrettd1d90dd2017-06-13 17:35:52 -0700116 if len(options.build_targets) != 1:
117 cros_build_lib.Die('Exactly one build target required, got: %s',
118 ', '.join(options.build_targets) or 'None')
Don Garrett597ddff2017-02-17 18:29:37 -0800119
Don Garrett86881cb2017-02-15 15:41:55 -0800120 return options
Don Garrettc4114cc2016-11-01 20:04:06 -0700121
122
Don Garrettbf90cdf2017-05-19 15:54:02 -0700123def GetState(root):
124 """Fetch the current state of our working directory.
125
126 Will return with a default result if there is no known state.
127
128 Args:
129 root: Root of the working directory tree as a string.
130
131 Returns:
132 Layout version as an integer (0 for unknown).
133 Previous branch as a string ('' for unknown).
134 """
135 state_file = os.path.join(root, '.cbuildbot_launch_state')
Don Garrett60967922017-04-12 18:51:44 -0700136
137 try:
138 state = osutils.ReadFile(state_file)
139 buildroot_layout, branchname = state.split()
140 buildroot_layout = int(buildroot_layout)
141 return buildroot_layout, branchname
142 except (IOError, ValueError):
143 # If we are unable to either read or parse the state file, we get here.
144 return 0, ''
145
146
Don Garrettbf90cdf2017-05-19 15:54:02 -0700147def SetState(branchname, root):
148 """Save the current state of our working directory.
149
150 Args:
151 branchname: Name of branch we prepped for as a string.
152 root: Root of the working directory tree as a string.
153 """
Don Garrett60967922017-04-12 18:51:44 -0700154 assert branchname
Don Garrettbf90cdf2017-05-19 15:54:02 -0700155 state_file = os.path.join(root, '.cbuildbot_launch_state')
Don Garrett60967922017-04-12 18:51:44 -0700156 new_state = '%d %s' % (BUILDROOT_BUILDROOT_LAYOUT, branchname)
157 osutils.WriteFile(state_file, new_state)
158
159
Don Garrett125d4dc2017-04-25 16:26:03 -0700160@StageDecorator
Don Garrettbf90cdf2017-05-19 15:54:02 -0700161def CleanBuildRoot(root, repo, metrics_fields):
Don Garrett7ade05a2017-02-17 13:31:47 -0800162 """Some kinds of branch transitions break builds.
163
Don Garrettbf90cdf2017-05-19 15:54:02 -0700164 This method ensures that cbuildbot's buildroot is a clean checkout on the
165 given branch when it starts. If necessary (a branch transition) it will wipe
166 assorted state that cannot be safely reused from the previous build.
Don Garrett7ade05a2017-02-17 13:31:47 -0800167
Don Garrett7ade05a2017-02-17 13:31:47 -0800168 Args:
Don Garrettbf90cdf2017-05-19 15:54:02 -0700169 root: Root directory owned by cbuildbot_launch.
Don Garrettf324bc32017-05-23 14:00:53 -0700170 repo: repository.RepoRepository instance.
Don Garrettacbb2392017-05-11 18:27:41 -0700171 metrics_fields: Dictionary of fields to include in metrics.
Don Garrett7ade05a2017-02-17 13:31:47 -0800172 """
Don Garrettbf90cdf2017-05-19 15:54:02 -0700173 old_buildroot_layout, old_branch = GetState(root)
Don Garrette17e1d92017-04-12 15:28:19 -0700174
Don Garrett60967922017-04-12 18:51:44 -0700175 if old_buildroot_layout != BUILDROOT_BUILDROOT_LAYOUT:
Don Garrett125d4dc2017-04-25 16:26:03 -0700176 logging.PrintBuildbotStepText('Unknown layout: Wiping buildroot.')
Don Garrettacbb2392017-05-11 18:27:41 -0700177 metrics.Counter(METRIC_CLOBBER).increment(
178 field(metrics_fields, reason='layout_change'))
Benjamin Gordon59ba2f82017-08-28 15:31:06 -0600179 chroot_dir = os.path.join(root, 'chroot')
180 if os.path.exists(chroot_dir) or os.path.exists(chroot_dir + '.img'):
181 cros_build_lib.CleanupChrootMount(chroot_dir, delete_image=True)
Don Garrettbf90cdf2017-05-19 15:54:02 -0700182 osutils.RmDir(root, ignore_missing=True, sudo=True)
Don Garrettf324bc32017-05-23 14:00:53 -0700183 else:
184 if old_branch != repo.branch:
185 logging.PrintBuildbotStepText('Branch change: Cleaning buildroot.')
186 logging.info('Unmatched branch: %s -> %s', old_branch, repo.branch)
Don Garrettacbb2392017-05-11 18:27:41 -0700187 metrics.Counter(METRIC_BRANCH_CLEANUP).increment(
188 field(metrics_fields, old_branch=old_branch))
Don Garrett39963602017-02-27 14:41:58 -0800189
Don Garrettf324bc32017-05-23 14:00:53 -0700190 logging.info('Remove Chroot.')
Benjamin Gordon59ba2f82017-08-28 15:31:06 -0600191 chroot_dir = os.path.join(repo.directory, 'chroot')
192 if os.path.exists(chroot_dir) or os.path.exists(chroot_dir + '.img'):
193 cros_build_lib.CleanupChrootMount(chroot_dir, delete_image=True)
194 osutils.RmDir(chroot_dir, ignore_missing=True, sudo=True)
Don Garrett7ade05a2017-02-17 13:31:47 -0800195
Don Garrettf324bc32017-05-23 14:00:53 -0700196 logging.info('Remove Chrome checkout.')
Don Garrettbf90cdf2017-05-19 15:54:02 -0700197 osutils.RmDir(os.path.join(repo.directory, '.cache', 'distfiles'),
Don Garrettf324bc32017-05-23 14:00:53 -0700198 ignore_missing=True, sudo=True)
199
200 try:
201 # If there is any failure doing the cleanup, wipe everything.
202 repo.BuildRootGitCleanup(prune_all=True)
203 except Exception:
204 logging.info('Checkout cleanup failed, wiping buildroot:', exc_info=True)
Don Garrettacbb2392017-05-11 18:27:41 -0700205 metrics.Counter(METRIC_CLOBBER).increment(
206 field(metrics_fields, reason='repo_cleanup_failure'))
Don Garrettbf90cdf2017-05-19 15:54:02 -0700207 repository.ClearBuildRoot(repo.directory)
Don Garrett39963602017-02-27 14:41:58 -0800208
Don Garrettbf90cdf2017-05-19 15:54:02 -0700209 # Ensure buildroot exists. Save the state we are prepped for.
210 osutils.SafeMakedirs(repo.directory)
211 SetState(repo.branch, root)
Don Garrett7ade05a2017-02-17 13:31:47 -0800212
213
Don Garrett125d4dc2017-04-25 16:26:03 -0700214@StageDecorator
Don Garrettf324bc32017-05-23 14:00:53 -0700215def InitialCheckout(repo):
Don Garrett86881cb2017-02-15 15:41:55 -0800216 """Preliminary ChromeOS checkout.
217
218 Perform a complete checkout of ChromeOS on the specified branch. This does NOT
219 match what the build needs, but ensures the buildroot both has a 'hot'
220 checkout, and is close enough that the branched cbuildbot can successfully get
221 the right checkout.
222
223 This checks out full ChromeOS, even if a ChromiumOS build is going to be
224 performed. This is because we have no knowledge of the build config to be
225 used.
Don Garrettc4114cc2016-11-01 20:04:06 -0700226
227 Args:
Don Garrettf324bc32017-05-23 14:00:53 -0700228 repo: repository.RepoRepository instance.
Don Garrettc4114cc2016-11-01 20:04:06 -0700229 """
Don Garrettf324bc32017-05-23 14:00:53 -0700230 logging.PrintBuildbotStepText('Branch: %s' % repo.branch)
Don Garrett7ade05a2017-02-17 13:31:47 -0800231 logging.info('Bootstrap script starting initial sync on branch: %s',
Don Garrettf324bc32017-05-23 14:00:53 -0700232 repo.branch)
Don Garrett76496912017-05-11 16:59:11 -0700233 repo.Sync(detach=True)
Don Garrettc4114cc2016-11-01 20:04:06 -0700234
235
Don Garrett125d4dc2017-04-25 16:26:03 -0700236@StageDecorator
Don Garrett066e6f52017-09-28 19:14:01 -0700237def DepotToolsEnsureBootstrap(depot_tools_path):
238 """Start cbuildbot in specified directory with all arguments.
239
240 Args:
241 buildroot: Directory to be passed to cbuildbot with --buildroot.
242 depot_tools_path: Directory for depot_tools to be used by cbuildbot.
243 argv: Command line options passed to cbuildbot_launch.
244
245 Returns:
246 Return code of cbuildbot as an integer.
247 """
248 ensure_bootstrap_script = os.path.join(depot_tools_path, 'ensure_bootstrap')
249 if os.path.exists(ensure_bootstrap_script):
250 extra_env = {'PATH': PrependPath(depot_tools_path)}
251 cros_build_lib.RunCommand(
252 [ensure_bootstrap_script], extra_env=extra_env, cwd=depot_tools_path)
253 else:
254 # This is normal when checking out branches older than this script.
255 logging.warn('ensure_bootstrap not found, skipping: %s',
256 ensure_bootstrap_script)
257
258
259@StageDecorator
Don Garretta50bf492017-09-28 18:33:02 -0700260def RunCbuildbot(buildroot, depot_tools_path, argv):
Don Garrettc4114cc2016-11-01 20:04:06 -0700261 """Start cbuildbot in specified directory with all arguments.
262
263 Args:
Don Garrettbf90cdf2017-05-19 15:54:02 -0700264 buildroot: Directory to be passed to cbuildbot with --buildroot.
Don Garretta50bf492017-09-28 18:33:02 -0700265 depot_tools_path: Directory for depot_tools to be used by cbuildbot.
Don Garrettd1d90dd2017-06-13 17:35:52 -0700266 argv: Command line options passed to cbuildbot_launch.
Don Garrettc4114cc2016-11-01 20:04:06 -0700267
268 Returns:
269 Return code of cbuildbot as an integer.
270 """
Don Garrettbf90cdf2017-05-19 15:54:02 -0700271 logging.info('Bootstrap cbuildbot in: %s', buildroot)
Don Garrettbf90cdf2017-05-19 15:54:02 -0700272
Don Garrettd1d90dd2017-06-13 17:35:52 -0700273 # Fixup buildroot parameter.
274 argv = argv[:]
275 for i in xrange(len(argv)):
276 if argv[i] in ('-r', '--buildroot'):
277 argv[i+1] = buildroot
Don Garrett597ddff2017-02-17 18:29:37 -0800278
Don Garrettd1d90dd2017-06-13 17:35:52 -0700279 # This filters out command line arguments not supported by older versions
280 # of cbuildbot.
281 parser = cbuildbot.CreateParser()
Mike Frysinger80bba8a2017-08-18 15:28:36 -0400282 options = cbuildbot.ParseCommandLine(parser, argv)
Don Garrettd1d90dd2017-06-13 17:35:52 -0700283 cbuildbot_path = os.path.join(buildroot, 'chromite', 'bin', 'cbuildbot')
Don Garrett597ddff2017-02-17 18:29:37 -0800284 cmd = sync_stages.BootstrapStage.FilterArgsForTargetCbuildbot(
Don Garrettbf90cdf2017-05-19 15:54:02 -0700285 buildroot, cbuildbot_path, options)
Don Garrett597ddff2017-02-17 18:29:37 -0800286
Don Garretta50bf492017-09-28 18:33:02 -0700287 # We want cbuildbot to use branched depot_tools scripts from our manifest,
288 # so that depot_tools is branched to match cbuildbot.
289 logging.info('Adding depot_tools into PATH: %s', depot_tools_path)
290 extra_env = {'PATH': PrependPath(depot_tools_path)}
291
292 result = cros_build_lib.RunCommand(
293 cmd, extra_env=extra_env, error_code_ok=True, cwd=buildroot)
Don Garrettacbb2392017-05-11 18:27:41 -0700294 return result.returncode
Don Garrettc4114cc2016-11-01 20:04:06 -0700295
Don Garrett60967922017-04-12 18:51:44 -0700296
Don Garrett90c9da22017-09-12 16:45:40 -0700297def _InstallSystemCrcmodIfNeeded():
298 """Install Crcmod binary extension if needed.
299
300 If the build host has python-crcmod installed without the binary extension,
301 that breaks some versions of gsutil. In that case, this function installs
302 a new copy of the module with the extension.
303
304 Newer branches workaround this in gs.py, and hopefully future versions of
305 gsutil will work around this in gsutil, however, older branches will always
306 have this problem.
307
308 So... this method will always be required unless/until we chose to solve this
309 through configuration management of hosts.
310
311 http://crbug.com/763438 covers this in detail.
312 """
313 try:
314 import crcmod
315 # If crcmod exists on the system, but doesn't have the binary extension,
316 # gsutil behaves badly. Override the system module with one that contains
317 # the binary extension. This depends on /usr/local/lib overridding /usr/lib.
318 if not (getattr(crcmod, 'crcmod', None) and
319 getattr(crcmod.crcmod, '_usingExtension', None)):
320 logging.warn('FORCING CRCMOD INSTALL to workaround crbug.com/763438.')
321 cmd = ['pip', 'install', '--ignore-installed', 'crcmod']
322 result = cros_build_lib.SudoRunCommand(
323 cmd, error_code_ok=True, mute_output=True)
324 logging.warn('CRCMOD INSTALL RETURNED :%d', result.returncode)
325 except ImportError:
326 # If crcmod doesn't exist on the system, gs.py will properly use its
327 # version in the cache.
328 pass
329
330
Don Garrettf15d65b2017-04-12 12:39:55 -0700331def ConfigureGlobalEnvironment():
332 """Setup process wide environmental changes."""
Don Garrettf15d65b2017-04-12 12:39:55 -0700333 # Set umask to 022 so files created by buildbot are readable.
334 os.umask(0o22)
335
Don Garrett86fec482017-05-17 18:13:33 -0700336 # These variables can interfere with LANG / locale behavior.
337 unwanted_local_vars = [
338 'LC_ALL', 'LC_CTYPE', 'LC_COLLATE', 'LC_TIME', 'LC_NUMERIC',
339 'LC_MONETARY', 'LC_MESSAGES', 'LC_PAPER', 'LC_NAME', 'LC_ADDRESS',
340 'LC_TELEPHONE', 'LC_MEASUREMENT', 'LC_IDENTIFICATION',
341 ]
342 for v in unwanted_local_vars:
343 os.environ.pop(v, None)
344
345 # This variable is required for repo sync's to work in all cases.
346 os.environ['LANG'] = 'en_US.UTF-8'
347
Don Garrett90c9da22017-09-12 16:45:40 -0700348 _InstallSystemCrcmodIfNeeded()
Don Garrett90f5e7d2017-09-08 17:42:46 -0700349
Don Garrettc4114cc2016-11-01 20:04:06 -0700350
Don Garrettacbb2392017-05-11 18:27:41 -0700351def _main(argv):
Don Garrettc4114cc2016-11-01 20:04:06 -0700352 """main method of script.
353
354 Args:
355 argv: All command line arguments to pass as list of strings.
356
357 Returns:
358 Return code of cbuildbot as an integer.
359 """
Don Garrettd1d90dd2017-06-13 17:35:52 -0700360 options = PreParseArguments(argv)
361
362 branchname = options.branch or 'master'
363 root = options.buildroot
364 buildroot = os.path.join(root, 'repository')
Don Garretta50bf492017-09-28 18:33:02 -0700365 depot_tools_path = os.path.join(buildroot, constants.DEPOT_TOOLS_SUBPATH)
Don Garrettd1d90dd2017-06-13 17:35:52 -0700366 build_config = options.build_targets[0]
367
368 metrics_fields = {
369 'branch_name': branchname,
370 'build_config': build_config,
371 'tryjob': options.remote_trybot,
372 }
Don Garrettf15d65b2017-04-12 12:39:55 -0700373
Don Garrettacbb2392017-05-11 18:27:41 -0700374 # Does the entire build pass or fail.
Don Garrett45e77412017-06-14 16:57:55 -0700375 with metrics.Presence(METRIC_ACTIVE, metrics_fields), \
376 metrics.SuccessCounter(METRIC_COMPLETED, metrics_fields) as s_fields:
Don Garrettc4114cc2016-11-01 20:04:06 -0700377
Don Garrettacbb2392017-05-11 18:27:41 -0700378 # Preliminary set, mostly command line parsing.
Don Garrettd1d90dd2017-06-13 17:35:52 -0700379 with metrics.SuccessCounter(METRIC_INVOKED, metrics_fields):
Don Garrettfbbccec2017-09-20 14:04:48 -0700380 if options.enable_buildbot_tags:
381 logging.EnableBuildbotMarkers()
Don Garrettacbb2392017-05-11 18:27:41 -0700382 ConfigureGlobalEnvironment()
Don Garrett86881cb2017-02-15 15:41:55 -0800383
Don Garrettacbb2392017-05-11 18:27:41 -0700384 # Prepare the buildroot with source for the build.
385 with metrics.SuccessCounter(METRIC_PREP, metrics_fields):
386 site_config = config_lib.GetConfig()
387 manifest_url = site_config.params['MANIFEST_INT_URL']
388 repo = repository.RepoRepository(manifest_url, buildroot,
389 branch=branchname,
Don Garrettd1d90dd2017-06-13 17:35:52 -0700390 git_cache_dir=options.git_cache_dir)
Don Garrett86881cb2017-02-15 15:41:55 -0800391
Don Garrettacbb2392017-05-11 18:27:41 -0700392 # Clean up the buildroot to a safe state.
393 with metrics.SecondsTimer(METRIC_CLEAN, fields=metrics_fields):
Don Garrettbf90cdf2017-05-19 15:54:02 -0700394 CleanBuildRoot(root, repo, metrics_fields)
Don Garrettacbb2392017-05-11 18:27:41 -0700395
Don Garretta50bf492017-09-28 18:33:02 -0700396 # Get a checkout close enough to the branch that cbuildbot can handle it.
Don Garrettacbb2392017-05-11 18:27:41 -0700397 with metrics.SecondsTimer(METRIC_INITIAL, fields=metrics_fields):
398 InitialCheckout(repo)
399
Don Garrett066e6f52017-09-28 19:14:01 -0700400 # Get a checkout close enough to the branch that cbuildbot can handle it.
401 with metrics.SecondsTimer(METRIC_DEPOT_TOOLS, fields=metrics_fields):
402 DepotToolsEnsureBootstrap(depot_tools_path)
403
Don Garrettacbb2392017-05-11 18:27:41 -0700404 # Run cbuildbot inside the full ChromeOS checkout, on the specified branch.
405 with metrics.SecondsTimer(METRIC_CBUILDBOT, fields=metrics_fields):
Don Garretta50bf492017-09-28 18:33:02 -0700406 result = RunCbuildbot(buildroot, depot_tools_path, argv)
Don Garrettd1d90dd2017-06-13 17:35:52 -0700407 s_fields['success'] = (result == 0)
Don Garrettacbb2392017-05-11 18:27:41 -0700408 return result
409
410
411def main(argv):
412 # Enable Monarch metrics gathering.
413 with ts_mon_config.SetupTsMonGlobalState('cbuildbot_launch', indirect=True):
414 return _main(argv)