#!/usr/bin/python

# Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Main builder code for Chromium OS.

Used by Chromium OS buildbot configuration for all Chromium OS builds including
full and pre-flight-queue builds.
"""

import collections
import distutils.version
import errno
import glob
import logging
import optparse
import os
import pprint
import sys
import time
import traceback

from chromite.buildbot import builderstage as bs
from chromite.buildbot import cbuildbot_config
from chromite.buildbot import cbuildbot_stages as stages
from chromite.buildbot import cbuildbot_results as results_lib
from chromite.buildbot import constants
from chromite.buildbot import remote_try
from chromite.buildbot import repository
from chromite.buildbot import tee
from chromite.buildbot import trybot_patch_pool

from chromite.lib import cgroups
from chromite.lib import cleanup
from chromite.lib import commandline
from chromite.lib import cros_build_lib
from chromite.lib import gclient
from chromite.lib import gerrit
from chromite.lib import git
from chromite.lib import osutils
from chromite.lib import patch as cros_patch
from chromite.lib import parallel
from chromite.lib import sudo


_DEFAULT_LOG_DIR = 'cbuildbot_logs'
_BUILDBOT_LOG_FILE = 'cbuildbot.log'
_DEFAULT_EXT_BUILDROOT = 'trybot'
_DEFAULT_INT_BUILDROOT = 'trybot-internal'
_DISTRIBUTED_TYPES = [constants.PFQ_TYPE, constants.CANARY_TYPE,
                      constants.CHROME_PFQ_TYPE, constants.PALADIN_TYPE]
_BUILDBOT_REQUIRED_BINARIES = ('pbzip2',)
_API_VERSION_ATTR = 'api_version'


def _PrintValidConfigs(display_all=False):
  """Print a list of valid buildbot configs.

  Args:
    display_all: Print all configs.  Otherwise, prints only configs with
                 trybot_list=True.
  """
  def _GetSortKey(config_name):
    config_dict = cbuildbot_config.config[config_name]
    return (not config_dict['trybot_list'], config_dict['description'],
            config_name)

  COLUMN_WIDTH = 45
  print 'config'.ljust(COLUMN_WIDTH), 'description'
  print '------'.ljust(COLUMN_WIDTH), '-----------'
  config_names = cbuildbot_config.config.keys()
  config_names.sort(key=_GetSortKey)
  for name in config_names:
    if display_all or cbuildbot_config.config[name]['trybot_list']:
      desc = cbuildbot_config.config[name].get('description')
      desc = desc if desc else ''
      print name.ljust(COLUMN_WIDTH), desc


def _GetConfig(config_name):
  """Gets the configuration for the build"""
  if not cbuildbot_config.config.has_key(config_name):
    print 'Non-existent configuration %s specified.' % config_name
    print 'Please specify one of:'
    _PrintValidConfigs()
    sys.exit(1)

  result = cbuildbot_config.config[config_name]

  return result


def AcquirePoolFromOptions(options):
  """Generate patch objects from passed in options.

  Args:
    options: The options object generated by optparse.

  Returns:
    trybot_patch_pool.TrybotPatchPool object.

  Raises:
    gerrit.GerritException, cros_patch.PatchException
  """
  gerrit_patches = []
  local_patches = []
  remote_patches = []

  if options.gerrit_patches:
    gerrit_patches = gerrit.GetGerritPatchInfo(
        options.gerrit_patches)
    for patch in gerrit_patches:
      if patch.IsAlreadyMerged():
        cros_build_lib.Warning('Patch %s has already been merged.' % str(patch))

  if options.local_patches:
    manifest = git.ManifestCheckout.Cached(options.sourceroot)
    local_patches = cros_patch.PrepareLocalPatches(manifest,
                                                   options.local_patches)

  if options.remote_patches:
    remote_patches = cros_patch.PrepareRemotePatches(
        options.remote_patches)

  return trybot_patch_pool.TrybotPatchPool(gerrit_patches, local_patches,
                                           remote_patches)


class Builder(object):
  """Parent class for all builder types.

  This class functions as an abstract parent class for various build types.
  Its intended use is builder_instance.Run().

  Vars:
    build_config: The configuration dictionary from cbuildbot_config.
    options: The options provided from optparse in main().
    release_tag: The associated "chrome os version" of this build.
  """

  def __init__(self, options, build_config):
    """Initializes instance variables. Must be called by all subclasses."""
    self.build_config = build_config
    self.options = options

    if self.build_config['chromeos_official']:
      os.environ['CHROMEOS_OFFICIAL'] = '1'

    self.archive_stages = {}
    self.release_tag = None
    self.patch_pool = trybot_patch_pool.TrybotPatchPool()

    bs.BuilderStage.SetManifestBranch(self.options.branch)

  def Initialize(self):
    """Runs through the initialization steps of an actual build."""
    if self.options.resume:
      results_lib.LoadCheckpoint(self.options.buildroot)

    self._RunStage(stages.CleanUpStage)

  def _GetStageInstance(self, stage, *args, **kwargs):
    """Helper function to get a stage instance given the args.

    Useful as almost all stages just take in options and build_config.
    """
    # Normally the current build config is used, but that config can be
    # overridden with a config kwarg.  For example, when getting a stage
    # for a "child" config.
    config = kwargs.pop('config', self.build_config)
    return stage(self.options, config, *args, **kwargs)

  def _SetReleaseTag(self):
    """Sets the release tag from the manifest_manager.

    Must be run after sync stage as syncing enables us to have a release tag.
    """
    # Extract version we have decided to build into self.release_tag.
    manifest_manager = stages.ManifestVersionedSyncStage.manifest_manager
    if manifest_manager:
      self.release_tag = manifest_manager.current_version

  def _RunStage(self, stage, *args, **kwargs):
    """Wrapper to run a stage.

    Args:
      stage: A BuilderStage class.
      args: args to pass to stage constructor.
      kwargs: kwargs to pass to stage constructor.
    Returns:
      Whatever the stage's Run method returns.
    """
    stage_instance = self._GetStageInstance(stage, *args, **kwargs)
    return stage_instance.Run()

  def GetSyncInstance(self):
    """Returns an instance of a SyncStage that should be run.

    Subclasses must override this method.
    """
    raise NotImplementedError()

  def GetCompletionInstance(self):
    """Returns the LKGMCandidateSyncCompletionStage for this build.

    Subclasses may override this method.

    Returns:
      None
    """
    return None

  def RunStages(self):
    """Subclasses must override this method.  Runs the appropriate code."""
    raise NotImplementedError()

  def _ShouldReExecuteInBuildRoot(self):
    """Returns True if this build should be re-executed in the buildroot."""
    # The commandline --noreexec flag can override the config.
    if not (self.options.postsync_reexec and
            self.build_config['postsync_reexec']):
      return False

    abs_buildroot = os.path.abspath(self.options.buildroot)
    return not os.path.abspath(__file__).startswith(abs_buildroot)

  def _ReExecuteInBuildroot(self, sync_instance):
    """Reexecutes self in buildroot and returns True if build succeeds.

    This allows the buildbot code to test itself when changes are patched for
    buildbot-related code.  This is a no-op if the buildroot == buildroot
    of the running chromite checkout.

    Args:
      sync_instance:  Instance of the sync stage that was run to sync.

    Returns:
      True if the Build succeeded.
    """
    if not self.options.resume:
      results_lib.WriteCheckpoint(self.options.buildroot)

    args = stages.BootstrapStage.FilterArgsForTargetCbuildbot(
        self.options.buildroot, constants.PATH_TO_CBUILDBOT, self.options)

    # Specify a buildroot explicitly (just in case, for local trybot).
    # Suppress any timeout options given from the commandline in the
    # invoked cbuildbot; our timeout will enforce it instead.
    args += ['--resume', '--timeout', '0', '--notee', '--nocgroups',
             '--buildroot', os.path.abspath(self.options.buildroot)]

    if stages.ManifestVersionedSyncStage.manifest_manager:
      ver = stages.ManifestVersionedSyncStage.manifest_manager.current_version
      args += ['--version', ver]

    pool = getattr(sync_instance, 'pool', None)
    if pool:
      filename = os.path.join(self.options.buildroot, 'validation_pool.dump')
      pool.Save(filename)
      args += ['--validation_pool', filename]

    # Reset the cache dir so that the child will calculate it automatically.
    if not self.options.cache_dir_specified:
      commandline.BaseParser.ConfigureCacheDir(None)

    # Re-run the command in the buildroot.
    # Finally, be generous and give the invoked cbuildbot 30s to shutdown
    # when something occurs.  It should exit quicker, but the sigterm may
    # hit while the system is particularly busy.
    return_obj = cros_build_lib.RunCommand(
        args, cwd=self.options.buildroot, error_code_ok=True, kill_timeout=30)
    return return_obj.returncode == 0

  def _InitializeTrybotPatchPool(self):
    """Generate patch pool from patches specified on the command line.

    Do this only if we need to patch changes later on.
    """
    changes_stage = stages.PatchChangesStage.StageNamePrefix()
    check_func = results_lib.Results.PreviouslyCompletedRecord
    if not check_func(changes_stage) or self.options.bootstrap:
      self.patch_pool = AcquirePoolFromOptions(self.options)

  def _GetBootstrapStage(self):
    """Constructs and returns the BootStrapStage object.

    We return None when there are no chromite patches to test, and
    --test-bootstrap wasn't passed in.
    """
    stage = None
    chromite_pool = self.patch_pool.Filter(project=constants.CHROMITE_PROJECT)
    manifest_pool = self.patch_pool.FilterManifest()
    chromite_branch = git.GetChromiteTrackingBranch()
    if (chromite_pool or manifest_pool or self.options.test_bootstrap
        or chromite_branch != self.options.branch):
      stage = stages.BootstrapStage(self.options, self.build_config,
                                    chromite_pool, manifest_pool)
    return stage

  def Run(self):
    """Main runner for this builder class.  Runs build and prints summary.

    Returns:
      Whether the build succeeded.
    """
    self._InitializeTrybotPatchPool()

    if self.options.bootstrap:
      bootstrap_stage = self._GetBootstrapStage()
      if bootstrap_stage:
        # BootstrapStage blocks on re-execution of cbuildbot.
        bootstrap_stage.Run()
        return bootstrap_stage.returncode == 0

    print_report = True
    exception_thrown = False
    success = True
    sync_instance = None
    try:
      self.Initialize()
      sync_instance = self.GetSyncInstance()
      sync_instance.Run()
      self._SetReleaseTag()

      if self.options.postsync_patch and self.build_config['postsync_patch']:
        # Filter out patches to manifest, since PatchChangesStage can't handle
        # them.  Manifest patches are patched in the BootstrapStage.
        non_manifest_patches = self.patch_pool.FilterManifest(negate=True)
        if non_manifest_patches:
          self._RunStage(stages.PatchChangesStage, non_manifest_patches)

      if self._ShouldReExecuteInBuildRoot():
        print_report = False
        success = self._ReExecuteInBuildroot(sync_instance)
      else:
        self.RunStages()

    except Exception as ex:
      # If the build is marked as successful, but threw exceptions, that's a
      # problem.
      exception_thrown = True
      if results_lib.Results.BuildSucceededSoFar():
        traceback.print_exc(file=sys.stdout)
        raise

      if not (print_report and isinstance(ex, results_lib.StepFailure)):
        raise

    finally:
      if print_report:
        results_lib.WriteCheckpoint(self.options.buildroot)
        completion_instance = self.GetCompletionInstance()
        self._RunStage(stages.ReportStage, self.archive_stages,
                       self.release_tag, sync_instance, completion_instance)
        success = results_lib.Results.BuildSucceededSoFar()
        if exception_thrown and success:
          success = False
          cros_build_lib.PrintBuildbotStepWarnings()
          print """\
Exception thrown, but all stages marked successful. This is an internal error,
because the stage that threw the exception should be marked as failing."""

    return success


BoardConfig = collections.namedtuple('BoardConfig', ['board', 'name'])


class SimpleBuilder(Builder):
  """Builder that performs basic vetting operations."""

  def GetSyncInstance(self):
    """Sync to lkgm or TOT as necessary.

    Returns:
      The instance of the sync stage to run.
    """
    if self.options.force_version:
      sync_stage = self._GetStageInstance(stages.ManifestVersionedSyncStage)
    elif self.build_config['use_lkgm']:
      sync_stage = self._GetStageInstance(stages.LKGMSyncStage)
    elif self.build_config['use_chrome_lkgm']:
      sync_stage = self._GetStageInstance(stages.ChromeLKGMSyncStage)
    else:
      sync_stage = self._GetStageInstance(stages.SyncStage)

    return sync_stage

  @staticmethod
  def _RunParallelStages(stage_objs):
    """Run the specified stages in parallel.

    Args:
      stage_objs: BuilderStage objects.
    """
    steps = [stage.Run for stage in stage_objs]
    try:
      parallel.RunParallelSteps(steps)
    except BaseException as ex:
      # If a stage threw an exception, it might not have correctly reported
      # results (e.g. because it was killed before it could report the
      # results.) In this case, attribute the exception to any stages that
      # didn't report back correctly (if any).
      for stage in stage_objs:
        for name in stage.GetStageNames():
          if not results_lib.Results.StageHasResults(name):
            results_lib.Results.Record(name, ex, str(ex))

      raise

  def _RunBackgroundStagesForBoard(self, config, board, compilecheck):
    """Run background board-specific stages for the specified board.

    Args:
      config: Build config dict.
      board: Board name.
      compilecheck: Boolean.  If True, run only the compile steps.
    """
    archive_stage = self.archive_stages[BoardConfig(board, config['name'])]
    if config['pgo_generate']:
      self._RunParallelStages([archive_stage])
      return

    if compilecheck:
      self._RunStage(stages.BuildPackagesStage, board, archive_stage,
                     config=config)
      self._RunStage(stages.UnitTestStage, board, config=config)
      return

    stage_list = []
    if self.options.chrome_sdk and self.build_config['chrome_sdk']:
      stage_list.append([stages.ChromeSDKStage, board, archive_stage])
    stage_list += [
        [stages.RetryStage, 1, stages.VMTestStage, board, archive_stage],
        [stages.SignerTestStage, board, archive_stage],
        [stages.UnitTestStage, board],
        [stages.UploadPrebuiltsStage, board, archive_stage],
        [stages.DevInstallerPrebuiltsStage, board, archive_stage]
    ]

    # We can not run hw tests without archiving the payloads.
    if self.options.archive:
      for suite_config in config['hw_tests']:
        if suite_config.async:
          stage_list.append([stages.ASyncHWTestStage, board, archive_stage,
                             suite_config])
        elif suite_config.suite == constants.HWTEST_AU_SUITE:
          stage_list.append([stages.AUTestStage, board, archive_stage,
                             suite_config])
        elif suite_config.suite == constants.HWTEST_QAV_SUITE:
          stage_list.append([stages.QATestStage, board,
                             archive_stage, suite_config])
        else:
          stage_list.append([stages.HWTestStage, board, archive_stage,
                             suite_config])

    stage_objs = [self._GetStageInstance(*x, config=config) for x in stage_list]
    self._RunParallelStages(stage_objs + [archive_stage])

  def _RunChrootBuilderTypeBuild(self):
    """Runs through stages of a CHROOT_BUILDER_TYPE build."""
    self._RunStage(stages.UprevStage, boards=[], enter_chroot=False)
    self._RunStage(stages.InitSDKStage)
    self._RunStage(stages.SetupBoardStage, [constants.CHROOT_BUILDER_BOARD])
    self._RunStage(stages.SyncChromeStage)
    self._RunStage(stages.PatchChromeStage)
    self._RunStage(stages.SDKPackageStage)
    self._RunStage(stages.SDKTestStage)
    self._RunStage(stages.UploadPrebuiltsStage,
                   constants.CHROOT_BUILDER_BOARD, None)

  def _RunRefreshPackagesTypeBuild(self):
    """Runs through the stages of a REFRESH_PACKAGES_TYPE build."""
    self._RunStage(stages.InitSDKStage)
    self._RunStage(stages.SetupBoardStage)
    self._RunStage(stages.RefreshPackageStatusStage)

  def _RunDefaultTypeBuild(self):
    """Runs through the stages of a non-special-type build."""
    self._RunStage(stages.InitSDKStage)
    self._RunStage(stages.UprevStage)
    self._RunStage(stages.SetupBoardStage)

    # We need a handle to this stage to extract info from it.
    # TODO(mtennant): Just have _RunStage return the stage object, since
    # nothing uses the return value of _RunStage now, and the Run method
    # of stage objects does not appear to return anything, either.
    sync_chrome_stage = self._GetStageInstance(stages.SyncChromeStage)
    sync_chrome_stage.Run()
    self._RunStage(stages.PatchChromeStage)

    # Prepare stages to run in background.
    configs = self.build_config['child_configs'] or [self.build_config]
    tasks = []
    for config in configs:
      for board in config['boards']:
        archive_stage = self._GetStageInstance(
            stages.ArchiveStage, board, self.release_tag, config=config,
            chrome_version=sync_chrome_stage.chrome_version)
        board_config = BoardConfig(board, config['name'])
        self.archive_stages[board_config] = archive_stage
        tasks.append((config, board, archive_stage))

    # Set up a process pool to run test/archive stages in the background.
    # This process runs task(board) for each board added to the queue.
    task_runner = self._RunBackgroundStagesForBoard
    with parallel.BackgroundTaskRunner(task_runner) as queue:
      for config, board, archive_stage in tasks:
        compilecheck = config['compilecheck'] or self.options.compilecheck
        if not compilecheck:
          # Run BuildPackages and BuildImage in the foreground, generating
          # or using PGO data if requested.
          kwargs = {'archive_stage': archive_stage, 'config': config}
          if config['pgo_generate']:
            kwargs['pgo_generate'] = True
          elif config['pgo_use']:
            kwargs['pgo_use'] = True

          self._RunStage(stages.BuildPackagesStage, board, **kwargs)
          self._RunStage(stages.BuildImageStage, board, **kwargs)

          if config['pgo_generate']:
            suite = cbuildbot_config.PGORecordTest()
            self._RunStage(stages.HWTestStage, board, archive_stage, suite,
                           config=config)

        # Kick off our background stages.
        queue.put([config, board, compilecheck])

  def RunStages(self):
    """Runs through build process."""
    # TODO(sosa): Split these out into classes.
    if self.build_config['build_type'] == constants.PRE_CQ_LAUNCHER_TYPE:
      self._RunStage(stages.PreCQLauncherStage)
    elif self.build_config['build_type'] == constants.CREATE_BRANCH_TYPE:
      self._RunStage(stages.BranchUtilStage)
    elif self.build_config['build_type'] == constants.CHROOT_BUILDER_TYPE:
      self._RunChrootBuilderTypeBuild()
    elif self.build_config['build_type'] == constants.REFRESH_PACKAGES_TYPE:
      self._RunRefreshPackagesTypeBuild()
    else:
      self._RunDefaultTypeBuild()


class DistributedBuilder(SimpleBuilder):
  """Build class that has special logic to handle distributed builds.

  These builds sync using git/manifest logic in manifest_versions.  In general
  they use a non-distributed builder code for the bulk of the work.
  """
  def __init__(self, *args, **kwargs):
    """Initializes a buildbot builder.

    Extra variables:
      completion_stage_class:  Stage used to complete a build.  Set in the Sync
        stage.
    """
    super(DistributedBuilder, self).__init__(*args, **kwargs)
    self.completion_stage_class = None
    self.sync_stage = None
    self._completion_stage = None

  def GetSyncInstance(self):
    """Syncs the tree using one of the distributed sync logic paths.

    Returns:
      The instance of the sync stage to run.
    """
    # Determine sync class to use.  CQ overrides PFQ bits so should check it
    # first.
    if self.build_config['pre_cq'] or self.options.pre_cq:
      sync_stage = self._GetStageInstance(stages.PreCQSyncStage,
                                          self.patch_pool.gerrit_patches)
      self.completion_stage_class = stages.PreCQCompletionStage
      self.patch_pool.gerrit_patches = []
    elif cbuildbot_config.IsCQType(self.build_config['build_type']):
      sync_stage = self._GetStageInstance(stages.CommitQueueSyncStage)
      self.completion_stage_class = stages.CommitQueueCompletionStage
    elif cbuildbot_config.IsPFQType(self.build_config['build_type']):
      sync_stage = self._GetStageInstance(stages.LKGMCandidateSyncStage)
      self.completion_stage_class = stages.LKGMCandidateSyncCompletionStage
    else:
      sync_stage = self._GetStageInstance(stages.ManifestVersionedSyncStage)
      self.completion_stage_class = stages.ManifestVersionedSyncCompletionStage

    self.sync_stage = sync_stage
    return self.sync_stage

  def GetCompletionInstance(self):
    """Returns the completion_stage_class instance that was used for this build.

    Returns None if the completion_stage instance was not yet created (this
    occurs during Publish).
    """
    return self._completion_stage

  def Publish(self, was_build_successful):
    """Completes build by publishing any required information."""
    completion_stage = self._GetStageInstance(self.completion_stage_class,
                                              self.sync_stage,
                                              was_build_successful)
    self._completion_stage = completion_stage
    completion_successful = False
    try:
      completion_stage.Run()
      completion_successful = True
    finally:
      if not completion_successful:
        was_build_successful = False
      if self.build_config['push_overlays']:
        self._RunStage(stages.PublishUprevChangesStage, was_build_successful)

  def RunStages(self):
    """Runs simple builder logic and publishes information to overlays."""
    was_build_successful = False
    try:
      super(DistributedBuilder, self).RunStages()
      was_build_successful = results_lib.Results.BuildSucceededSoFar()
    except SystemExit as ex:
      # If a stage calls sys.exit(0), it's exiting with success, so that means
      # we should mark ourselves as successful.
      if ex.code == 0:
        was_build_successful = True
      raise
    finally:
      self.Publish(was_build_successful)


def _ConfirmBuildRoot(buildroot):
  """Confirm with user the inferred buildroot, and mark it as confirmed."""
  cros_build_lib.Warning('Using default directory %s as buildroot', buildroot)
  if not cros_build_lib.BooleanPrompt(default=False):
    print('Please specify a different buildroot via the --buildroot option.')
    sys.exit(0)

  if not os.path.exists(buildroot):
    os.mkdir(buildroot)

  repository.CreateTrybotMarker(buildroot)


def _ConfirmRemoteBuildbotRun():
  """Confirm user wants to run with --buildbot --remote."""
  cros_build_lib.Warning(
       'You are about to launch a PRODUCTION job!  This is *NOT* a '
       'trybot run! Are you sure?')
  if not cros_build_lib.BooleanPrompt(default=False):
    print('Please specify --pass-through="--debug".')
    sys.exit(0)


def _DetermineDefaultBuildRoot(sourceroot, internal_build):
  """Default buildroot to be under the directory that contains current checkout.

  Args:
    internal_build: Whether the build is an internal build
    sourceroot: Use specified sourceroot.
  """
  if not repository.IsARepoRoot(sourceroot):
    cros_build_lib.Die(
        'Could not find root of local checkout at %s.  Please specify '
        'using the --sourceroot option.' % sourceroot)

  # Place trybot buildroot under the directory containing current checkout.
  top_level = os.path.dirname(os.path.realpath(sourceroot))
  if internal_build:
    buildroot = os.path.join(top_level, _DEFAULT_INT_BUILDROOT)
  else:
    buildroot = os.path.join(top_level, _DEFAULT_EXT_BUILDROOT)

  return buildroot


def _DisableYamaHardLinkChecks():
  """Disable Yama kernel hardlink security checks.

  The security module disables hardlinking to files you do not have
  write access to which causes some of our build scripts problems.
  Disable it so we don't have to worry about it.
  """
  PROC_PATH = '/proc/sys/kernel/yama/protected_nonaccess_hardlinks'
  SYSCTL_PATH = PROC_PATH[len('/proc/sys/'):].replace('/', '.')

  # Yama not available in this system -- nothing to do.
  if not os.path.exists(PROC_PATH):
    return

  # Already disabled -- nothing to do.
  if osutils.ReadFile(PROC_PATH).strip() == '0':
    return

  # Create a hardlink in a tempdir and see if we get back EPERM.
  with osutils.TempDir() as tempdir:
    try:
      os.link('/bin/sh', os.path.join(tempdir, 'sh'))
    except OSError as e:
      if e.errno == errno.EPERM:
        cros_build_lib.Warning('Disabling Yama hardlink security')
        cros_build_lib.SudoRunCommand(['sysctl', '%s=0' % SYSCTL_PATH])


def _BackupPreviousLog(log_file, backup_limit=25):
  """Rename previous log.

  Args:
    log_file: The absolute path to the previous log.
  """
  if os.path.exists(log_file):
    old_logs = sorted(glob.glob(log_file + '.*'),
                      key=distutils.version.LooseVersion)

    if len(old_logs) >= backup_limit:
      os.remove(old_logs[0])

    last = 0
    if old_logs:
      last = int(old_logs.pop().rpartition('.')[2])

    os.rename(log_file, log_file + '.' + str(last + 1))


def _RunBuildStagesWrapper(options, build_config):
  """Helper function that wraps RunBuildStages()."""
  def IsDistributedBuilder():
    """Determines whether the build_config should be a DistributedBuilder."""
    if build_config['pre_cq'] or options.pre_cq:
      return True
    elif not options.buildbot:
      return False
    elif build_config['build_type'] in _DISTRIBUTED_TYPES:
      # We don't do distributed logic to TOT Chrome PFQ's, nor local
      # chrome roots (e.g. chrome try bots)
      if chrome_rev not in [constants.CHROME_REV_TOT,
                            constants.CHROME_REV_LOCAL,
                            constants.CHROME_REV_SPEC]:
        return True

    return False

  cros_build_lib.Info("cbuildbot executed with args %s"
                      % ' '.join(map(repr, sys.argv)))

  chrome_rev = build_config['chrome_rev']
  if options.chrome_rev:
    chrome_rev = options.chrome_rev
  if chrome_rev == constants.CHROME_REV_TOT:
    # Build the TOT Chrome revision.
    svn_url = gclient.GetBaseURLs()[0]
    options.chrome_version = gclient.GetTipOfTrunkSvnRevision(svn_url)
    options.chrome_rev = constants.CHROME_REV_SPEC

  # If it's likely we'll need to build Chrome, fetch the source.
  if build_config['sync_chrome'] is None:
    options.managed_chrome = (chrome_rev != constants.CHROME_REV_LOCAL and
        (not build_config['usepkg_build_packages'] or chrome_rev or
         build_config['profile'] or options.rietveld_patches))
  else:
    options.managed_chrome = build_config['sync_chrome']

  if options.managed_chrome:
    # Tell Chrome to fetch the source locally.
    internal = constants.USE_CHROME_INTERNAL in (build_config['useflags'] or [])
    chrome_src = 'chrome-src-internal' if internal else 'chrome-src'
    options.chrome_root = os.path.join(options.cache_dir, 'distfiles', 'target',
                                       chrome_src)
  elif options.rietveld_patches:
    cros_build_lib.Die('This builder does not support Rietveld patches.')

  target = DistributedBuilder if IsDistributedBuilder() else SimpleBuilder
  buildbot = target(options, build_config)
  if not buildbot.Run():
    sys.exit(1)


# Parser related functions
def _CheckLocalPatches(sourceroot, local_patches):
  """Do an early quick check of the passed-in patches.

  If the branch of a project is not specified we append the current branch the
  project is on.

  TODO(davidjames): The project:branch format isn't unique, so this means that
  we can't differentiate what directory the user intended to apply patches to.
  We should references by directory instead.

  Args:
    sourceroot: The checkout where patches are coming from.

  Returns:
    A list of patches that have been verified, in project:branch format.
  """
  verified_patches = []
  manifest = git.ManifestCheckout.Cached(sourceroot)
  for patch in local_patches:
    project, _, branch = patch.partition(':')

    checkouts = manifest.FindCheckouts(project)
    if not checkouts:
      cros_build_lib.Die('Project %s does not exist.' % (project,))
    if len(checkouts) > 1:
      cros_build_lib.Die(
          'We do not yet support local patching for projects that are checked '
          'out to multiple directories. Try uploading your patch to gerrit '
          'and referencing it via the -g option instead.'
      )

    ok = False
    for checkout in checkouts:
      project_dir = checkout.GetPath(absolute=True)

      # If no branch was specified, we use the project's current branch.
      if not branch:
        local_branch = git.GetCurrentBranch(project_dir)
      else:
        local_branch = branch

      if local_branch and git.DoesLocalBranchExist(project_dir, local_branch):
        verified_patches.append('%s:%s' % (project, local_branch))
        ok = True

    if not ok:
      if branch:
        cros_build_lib.Die('Project %s does not have branch %s'
                            % (project, branch))
      else:
        cros_build_lib.Die('Project %s is not on a branch!' % (project,))

  return verified_patches


def _CheckChromeVersionOption(_option, _opt_str, value, parser):
  """Upgrade other options based on chrome_version being passed."""
  value = value.strip()

  if parser.values.chrome_rev is None and value:
    parser.values.chrome_rev = constants.CHROME_REV_SPEC

  parser.values.chrome_version = value


def _CheckChromeRootOption(_option, _opt_str, value, parser):
  """Validate and convert chrome_root to full-path form."""
  if parser.values.chrome_rev is None:
    parser.values.chrome_rev = constants.CHROME_REV_LOCAL

  parser.values.chrome_root = value


def _CheckChromeRevOption(_option, _opt_str, value, parser):
  """Validate the chrome_rev option."""
  value = value.strip()
  if value not in constants.VALID_CHROME_REVISIONS:
    raise optparse.OptionValueError('Invalid chrome rev specified')

  parser.values.chrome_rev = value


def FindCacheDir(_parser, _options):
  return None


class CustomGroup(optparse.OptionGroup):
  def add_remote_option(self, *args, **kwargs):
    """For arguments that are passed-through to remote trybot."""
    return optparse.OptionGroup.add_option(self, *args,
                                           remote_pass_through=True,
                                           **kwargs)


class CustomOption(commandline.FilteringOption):
  """Subclass FilteringOption class to implement pass-through and api."""

  ACTIONS = commandline.FilteringOption.ACTIONS + ('extend',)
  STORE_ACTIONS = commandline.FilteringOption.STORE_ACTIONS + ('extend',)
  TYPED_ACTIONS = commandline.FilteringOption.TYPED_ACTIONS + ('extend',)
  ALWAYS_TYPED_ACTIONS = (commandline.FilteringOption.ALWAYS_TYPED_ACTIONS +
                          ('extend',))

  def __init__(self, *args, **kwargs):
    # The remote_pass_through argument specifies whether we should directly
    # pass the argument (with its value) onto the remote trybot.
    self.pass_through = kwargs.pop('remote_pass_through', False)
    self.api_version = int(kwargs.pop('api', '0'))
    commandline.FilteringOption.__init__(self, *args, **kwargs)

  def take_action(self, action, dest, opt, value, values, parser):
    if action == 'extend':
      # If there is extra spaces between each argument, we get '' which later
      # code barfs on, so skip those.  e.g. We see this with the forms:
      #  cbuildbot -p 'proj:branch ' ...
      #  cbuildbot -p ' proj:branch' ...
      #  cbuildbot -p 'proj:branch  proj2:branch' ...
      lvalue = value.split()
      values.ensure_value(dest, []).extend(lvalue)

    commandline.FilteringOption.take_action(
        self, action, dest, opt, value, values, parser)


class CustomParser(commandline.FilteringParser):

  DEFAULT_OPTION_CLASS = CustomOption

  def add_remote_option(self, *args, **kwargs):
    """For arguments that are passed-through to remote trybot."""
    return self.add_option(*args, remote_pass_through=True, **kwargs)


def _CreateParser():
  """Generate and return the parser with all the options."""
  # Parse options
  usage = "usage: %prog [options] buildbot_config"
  parser = CustomParser(usage=usage, caching=FindCacheDir)

  # Main options
  parser.add_option('-l', '--list', action='store_true', dest='list',
                    default=False,
                    help='List the suggested trybot configs to use (see --all)')
  parser.add_option('-a', '--all', action='store_true', dest='print_all',
                    default=False,
                    help='List all of the buildbot configs available w/--list')

  parser.add_option('--local', default=False, action='store_true',
                    help='Specifies that this tryjob should be run locally. '
                         'Implies --debug.')
  parser.add_option('--remote', default=False, action='store_true',
                    help='Specifies that this tryjob should be run remotely.')

  parser.add_remote_option('-b', '--branch',
                           help='The manifest branch to test.  The branch to '
                                'check the buildroot out to.')
  parser.add_option('-r', '--buildroot', dest='buildroot', type='path',
                    help='Root directory where source is checked out to, and '
                         'where the build occurs. For external build configs, '
                         "defaults to 'trybot' directory at top level of your "
                         'repo-managed checkout.')
  parser.add_remote_option('--chrome_rev', default=None, type='string',
                           action='callback', dest='chrome_rev',
                           callback=_CheckChromeRevOption,
                           help=('Revision of Chrome to use, of type [%s]'
                                 % '|'.join(constants.VALID_CHROME_REVISIONS)))
  parser.add_remote_option('--profile', default=None, type='string',
                           action='store', dest='profile',
                           help='Name of profile to sub-specify board variant.')

  #
  # Patch selection options.
  #

  group = CustomGroup(
      parser,
      'Patch Options')

  group.add_remote_option('-g', '--gerrit-patches', action='extend',
                          default=[], type='string',
                          metavar="'Id1 *int_Id2...IdN'",
                          help="Space-separated list of short-form Gerrit "
                               "Change-Id's or change numbers to patch. "
                               "Please prepend '*' to internal Change-Id's")
  group.add_remote_option('-G', '--rietveld-patches', action='extend',
                          default=[], type='string',
                          metavar="'id1[:subdir1]...idN[:subdirN]'",
                          help='Space-separated list of short-form Rietveld '
                               'issue numbers to patch. If no subdir is '
                               'specified, the src directory is used.')
  group.add_option('-p', '--local-patches', action='extend', default=[],
                   metavar="'<project1>[:<branch1>]...<projectN>[:<branchN>]'",
                   help='Space-separated list of project branches with '
                        'patches to apply.  Projects are specified by name. '
                        'If no branch is specified the current branch of the '
                        'project will be used.')

  parser.add_option_group(group)

  #
  # Remote trybot options.
  #

  group = CustomGroup(
      parser,
      'Remote Trybot Options (--remote)')

  group.add_remote_option('--hwtest', dest='hwtest', action='store_true',
                           default=False,
                           help='Run the HWTest stage (tests on real hardware)')
  group.add_option('--remote-description', default=None,
                   help='Attach an optional description to a --remote run '
                        'to make it easier to identify the results when it '
                        'finishes')
  group.add_option('--slaves', action='extend', default=[],
                   help='Specify specific remote tryslaves to run on (e.g. '
                        'build149-m2); if the bot is busy, it will be queued')
  group.add_option('--test-tryjob', action='store_true',
                   default=False,
                   help='Submit a tryjob to the test repository.  Will not '
                        'show up on the production trybot waterfall.')

  parser.add_option_group(group)

  #
  # Branch creation options.
  #

  group = CustomGroup(
      parser,
      'Branch Creation Options (used with branch-util)')

  group.add_remote_option('--branch-name',
                          help='The branch to create or delete.')
  group.add_remote_option('--delete-branch', default=False, action='store_true',
                          help='Delete the branch specified in --branch-name.')
  group.add_remote_option('--rename-to', type='string',
                          help='Rename a branch to the specified name.')
  group.add_remote_option('--force-create', default=False, action='store_true',
                          help='Overwrites an existing branch.')

  parser.add_option_group(group)

  #
  # Advanced options.
  #

  group = CustomGroup(
      parser,
      'Advanced Options',
      'Caution: use these options at your own risk.')

  group.add_remote_option('--bootstrap-args', action='append', default=[],
                          help='Args passed directly to the bootstrap re-exec '
                               'to skip verification by the bootstrap code')
  group.add_remote_option('--buildbot', dest='buildbot', action='store_true',
                          default=False, help='This is running on a buildbot')
  group.add_remote_option('--buildnumber', help='build number', type='int',
                          default=0)
  group.add_option('--chrome_root', default=None, type='path',
                   action='callback', callback=_CheckChromeRootOption,
                   dest='chrome_root', help='Local checkout of Chrome to use.')
  group.add_remote_option('--chrome_version', default=None, type='string',
                          action='callback', dest='chrome_version',
                          callback=_CheckChromeVersionOption,
                          help='Used with SPEC logic to force a particular SVN '
                               'revision of chrome rather than the latest.')
  group.add_remote_option('--clobber', action='store_true', dest='clobber',
                          default=False,
                          help='Clears an old checkout before syncing')
  group.add_remote_option('--latest-toolchain', action='store_true',
                          default=False,
                          help='Use the latest toolchain.')
  parser.add_option('--log_dir', dest='log_dir', type='path',
                    help=('Directory where logs are stored.'))
  group.add_remote_option('--maxarchives', dest='max_archive_builds',
                          default=3, type='int',
                          help="Change the local saved build count limit.")
  parser.add_remote_option('--manifest-repo-url',
                           help=('Overrides the default manifest repo url.'))
  group.add_remote_option('--compilecheck', action='store_true', default=False,
                          help='Only verify compilation and unit tests.')
  group.add_remote_option('--noarchive', action='store_false', dest='archive',
                          default=True, help="Don't run archive stage.")
  group.add_remote_option('--nobootstrap', action='store_false',
                          dest='bootstrap', default=True,
                          help="Don't checkout and run from a standalone "
                               "chromite repo.")
  group.add_remote_option('--nobuild', action='store_false', dest='build',
                          default=True,
                          help="Don't actually build (for cbuildbot dev)")
  group.add_remote_option('--noclean', action='store_false', dest='clean',
                          default=True, help="Don't clean the buildroot")
  group.add_remote_option('--nocgroups', action='store_false', dest='cgroups',
                          default=True,
                          help='Disable cbuildbots usage of cgroups.')
  group.add_remote_option('--nochromesdk', action='store_false',
                          dest='chrome_sdk', default=True,
                          help="Don't run the ChromeSDK stage which builds "
                               "Chrome outside of the chroot.")
  group.add_remote_option('--noprebuilts', action='store_false',
                          dest='prebuilts', default=True,
                          help="Don't upload prebuilts.")
  group.add_remote_option('--nopatch', action='store_false',
                          dest='postsync_patch', default=True,
                          help=("Don't run PatchChanges stage.  This does not "
                                "disable patching in of chromite patches "
                                "during BootstrapStage."))
  group.add_remote_option('--noreexec', action='store_false',
                          dest='postsync_reexec', default=True,
                          help="Don't reexec into the buildroot after syncing.")
  group.add_remote_option('--nosdk', action='store_true',
                          default=False,
                          help='Re-create the SDK from scratch.')
  group.add_remote_option('--nosync', action='store_false', dest='sync',
                          default=True, help="Don't sync before building.")
  group.add_remote_option('--notests', action='store_false', dest='tests',
                          default=True,
                          help='Override values from buildconfig and run no '
                               'tests.')
  group.add_remote_option('--nouprev', action='store_false', dest='uprev',
                          default=True,
                          help='Override values from buildconfig and never '
                               'uprev.')
  group.add_option('--resume', action='store_true', default=False,
                   help='Skip stages already successfully completed.')
  group.add_remote_option('--timeout', action='store', type='int', default=0,
                          help='Specify the maximum amount of time this job '
                               'can run for, at which point the build will be '
                               'aborted.  If set to zero, then there is no '
                               'timeout.')
  group.add_remote_option('--version', dest='force_version', default=None,
                          help='Used with manifest logic.  Forces use of this '
                               'version rather than create or get latest. '
                               'Examples: 4815.0.0-rc1, 4815.1.2')

  parser.add_option_group(group)

  #
  # Internal options.
  #

  group = CustomGroup(
      parser,
      'Internal ChromeOS Build Team Options',
      'Caution: these are for meant for the ChromeOS build team only')

  group.add_remote_option('--archive-base', type='gs_path',
                          help='Base GS URL (gs://<bucket_name>/<path>) to '
                               'upload archive artifacts to')
  group.add_remote_option('--cq-gerrit-query', dest='cq_gerrit_override',
                          default=None,
                          help=
      "If given, this gerrit query will be used to find what patches to test, "
      "rather than the normal 'CommitQueue=1 AND Verified=1 AND CodeReview=2' "
      "query it defaults to.  Use with care- note additionally this setting "
      "only has an effect if the buildbot target is a cq target, and we're "
      "in buildbot mode.")
  group.add_option('--pass-through', dest='pass_through_args', action='append',
                   type='string', default=[])
  group.add_remote_option('--pre-cq', action='store_true', default=False,
                          help='Mark CLs as tested by the PreCQ on success.')
  group.add_option('--reexec-api-version', dest='output_api_version',
                   action='store_true', default=False,
                   help='Used for handling forwards/backwards compatibility '
                        'with --resume and --bootstrap')
  group.add_option('--remote-trybot', dest='remote_trybot',
                   action='store_true', default=False,
                   help='Indicates this is running on a remote trybot machine')
  group.add_remote_option('--remote-patches', action='extend', default=[],
                          help='Patches uploaded by the trybot client when run '
                               'using the -p option')
  # Note the default here needs to be hardcoded to 3; that is the last version
  # that lacked this functionality.
  group.add_option('--remote-version', default=3, type=int, action='store',
                   help='Used for compatibility checks w/tryjobs running in '
                        'older chromite instances')
  group.add_option('--sourceroot', type='path', default=constants.SOURCE_ROOT)
  group.add_remote_option('--test-bootstrap', action='store_true',
                          default=False,
                          help='Causes cbuildbot to bootstrap itself twice, in '
                               'the sequence A->B->C: A(unpatched) patches and '
                               'bootstraps B; B patches and bootstraps C')
  group.add_remote_option('--validation_pool', default=None,
                          help='Path to a pickled validation pool. Intended '
                               'for use only with the commit queue.')

  parser.add_option_group(group)

  #
  # Debug options
  #
  # Temporary hack; in place till --dry-run replaces --debug.
  # pylint: disable=W0212
  group = parser.debug_group
  debug = [x for x in group.option_list if x._long_opts == ['--debug']][0]
  debug.help += "  Currently functions as --dry-run in addition."
  debug.pass_through = True
  group.add_option('--dump_config', action='store_true', dest='dump_config',
                    default=False,
                    help='Dump out build config options, and exit.')
  group.add_option('--notee', action='store_false', dest='tee', default=True,
                    help="Disable logging and internal tee process.  Primarily "
                         "used for debugging cbuildbot itself.")
  return parser


def _FinishParsing(options, args):
  """Perform some parsing tasks that need to take place after optparse.

  This function needs to be easily testable!  Keep it free of
  environment-dependent code.  Put more detailed usage validation in
  _PostParseCheck().

  Args:
    options: The options object returned by optparse
    args: The args object returned by optparse
  """
  # Populate options.pass_through_args.
  accepted, _ = commandline.FilteringParser.FilterArgs(
      options.parsed_args, lambda x: x.opt_inst.pass_through)
  options.pass_through_args.extend(accepted)

  if options.chrome_root:
    if options.chrome_rev != constants.CHROME_REV_LOCAL:
      cros_build_lib.Die('Chrome rev must be %s if chrome_root is set.' %
                         constants.CHROME_REV_LOCAL)
  elif options.chrome_rev == constants.CHROME_REV_LOCAL:
    cros_build_lib.Die('Chrome root must be set if chrome_rev is %s.' %
                       constants.CHROME_REV_LOCAL)

  if options.chrome_version:
    if options.chrome_rev != constants.CHROME_REV_SPEC:
      cros_build_lib.Die('Chrome rev must be %s if chrome_version is set.' %
                         constants.CHROME_REV_SPEC)
  elif options.chrome_rev == constants.CHROME_REV_SPEC:
    cros_build_lib.Die(
        'Chrome rev must not be %s if chrome_version is not set.'
        % constants.CHROME_REV_SPEC)

  patches = bool(options.gerrit_patches or options.local_patches or
                 options.rietveld_patches)
  if options.remote:
    if options.local:
      cros_build_lib.Die('Cannot specify both --remote and --local')

    if not options.buildbot and not patches:
      if not cros_build_lib.BooleanPrompt(
          prompt="No patches were provided; are you sure you want to just "
          "run a remote build of ToT?", default=False):
        cros_build_lib.Die('Must provide patches when running with --remote.')

    # --debug needs to be explicitly passed through for remote invocations.
    release_mode_with_patches = (options.buildbot and patches and
                                 '--debug' not in options.pass_through_args)
  else:
    if len(args) > 1:
      cros_build_lib.Die('Multiple configs not supported if not running with '
                         '--remote.  Got %r', args)

    if options.slaves:
      cros_build_lib.Die('Cannot use --slaves if not running with --remote.')

    release_mode_with_patches = (options.buildbot and patches and
                                 not options.debug)

  # When running in release mode, make sure we are running with checked-in code.
  # We want checked-in cbuildbot/scripts to prevent errors, and we want to build
  # a release image with checked-in code for CrOS packages.
  if release_mode_with_patches:
    cros_build_lib.Die(
        'Cannot provide patches when running with --buildbot!')

  if options.buildbot and options.remote_trybot:
    cros_build_lib.Die(
        '--buildbot and --remote-trybot cannot be used together.')

  # Record whether --debug was set explicitly vs. it was inferred.
  options.debug_forced = False
  if options.debug:
    options.debug_forced = True
  if not options.debug:
    # We don't set debug by default for
    # 1. --buildbot invocations.
    # 2. --remote invocations, because it needs to push changes to the tryjob
    #    repo.
    options.debug = not options.buildbot and not options.remote

  # Record the configs targeted.
  options.build_targets = args[:]

  if constants.BRANCH_UTIL_CONFIG in options.build_targets:
    if options.remote:
      cros_build_lib.Die(
          'Running branch-util as a remote tryjob is not yet supported.')
    if len(options.build_targets) > 1:
      cros_build_lib.Die(
          'Cannot run branch-util with any other configs.')
    if not options.branch_name:
      cros_build_lib.Die(
          'Must specify --branch-name with the branch-util config.')
    if not any([options.force_version, options.delete_branch,
                options.rename_to]):
      cros_build_lib.Die(
          'Must specify --version with the branch-util config, unless '
          'running with --delete-branch or --rename-to.')
  elif any([options.delete_branch, options.rename_to, options.branch_name]):
    cros_build_lib.Die(
        'Cannot specify --delete-branch, --rename-to or --branch-name when not '
        'running the %s config', constants.BRANCH_UTIL_CONFIG)


# pylint: disable=W0613
def _PostParseCheck(parser, options, args):
  """Perform some usage validation after we've parsed the arguments

  Args:
    options/args: The options/args object returned by optparse
  """
  if not options.branch:
    options.branch = git.GetChromiteTrackingBranch()

  if not repository.IsARepoRoot(options.sourceroot):
    if options.local_patches:
      raise Exception('Could not find repo checkout at %s!'
                      % options.sourceroot)

  # Because the default cache dir depends on other options, FindCacheDir
  # always returns None, and we setup the default here.
  if options.cache_dir is None:
    # Note, options.sourceroot is set regardless of the path
    # actually existing.
    if options.buildroot is not None:
      options.cache_dir = os.path.join(options.buildroot, '.cache')
    elif os.path.exists(options.sourceroot):
      options.cache_dir = os.path.join(options.sourceroot, '.cache')
    else:
      options.cache_dir = parser.FindCacheDir(parser, options)
    options.cache_dir = os.path.abspath(options.cache_dir)
    parser.ConfigureCacheDir(options.cache_dir)

  osutils.SafeMakedirsNonRoot(options.cache_dir)

  if options.local_patches:
    options.local_patches = _CheckLocalPatches(
        options.sourceroot, options.local_patches)

  default = os.environ.get('CBUILDBOT_DEFAULT_MODE')
  if (default and not any([options.local, options.buildbot,
                           options.remote, options.remote_trybot])):
    cros_build_lib.Info("CBUILDBOT_DEFAULT_MODE=%s env var detected, using it."
                        % default)
    default = default.lower()
    if default == 'local':
      options.local = True
    elif default == 'remote':
      options.remote = True
    elif default == 'buildbot':
      options.buildbot = True
    else:
      cros_build_lib.Die("CBUILDBOT_DEFAULT_MODE value %s isn't supported. "
                         % default)


def _ParseCommandLine(parser, argv):
  """Completely parse the commandline arguments"""
  (options, args) = parser.parse_args(argv)

  if options.output_api_version:
    print constants.REEXEC_API_VERSION
    sys.exit(0)

  if options.list:
    _PrintValidConfigs(options.print_all)
    sys.exit(0)

  # Strip out null arguments.
  # TODO(rcui): Remove when buildbot is fixed
  args = [arg for arg in args if arg]
  if not args:
    parser.error('Invalid usage.  Use -h to see usage.  Use -l to list '
                 'supported configs.')

  _FinishParsing(options, args)
  return options, args


# TODO(build): This function is too damn long.
def main(argv):
  # Turn on strict sudo checks.
  cros_build_lib.STRICT_SUDO = True

  # Set umask to 022 so files created by buildbot are readable.
  os.umask(0o22)

  parser = _CreateParser()
  (options, args) = _ParseCommandLine(parser, argv)

  _PostParseCheck(parser, options, args)

  cros_build_lib.AssertOutsideChroot()

  if options.remote:
    cros_build_lib.logger.setLevel(logging.WARNING)

    # Verify configs are valid.
    # If hwtest flag is enabled, post a warning that HWTest step may fail if the
    # specified board is not a released platform or it is a generic overlay.
    for bot in args:
      build_config = _GetConfig(bot)
      if options.hwtest:
        cros_build_lib.Warning(
            'If %s is not a released platform or it is a generic overlay, '
            'the HWTest step will most likely not run; please ask the lab '
            'team for help if this is unexpected.' % build_config['boards'])

    # Verify gerrit patches are valid.
    print 'Verifying patches...'
    patch_pool = AcquirePoolFromOptions(options)

    # --debug need to be explicitly passed through for remote invocations.
    if options.buildbot and '--debug' not in options.pass_through_args:
      _ConfirmRemoteBuildbotRun()

    print 'Submitting tryjob...'
    tryjob = remote_try.RemoteTryJob(options, args, patch_pool.local_patches)
    tryjob.Submit(testjob=options.test_tryjob, dryrun=False)
    print 'Tryjob submitted!'
    print ('Go to %s to view the status of your job.'
           % tryjob.GetTrybotWaterfallLink())
    sys.exit(0)

  elif (not options.buildbot and not options.remote_trybot
        and not options.resume and not options.local):
    options.local = True
    cros_build_lib.Warning(
        'Running in LOCAL TRYBOT mode!  Use --remote to submit REMOTE '
        'tryjobs.  Use --local to suppress this message.')
    cros_build_lib.Warning(
        'In the future, --local will be required to run the local '
        'trybot.')
    time.sleep(5)

  # Only one config arg is allowed in this mode, which was confirmed earlier.
  bot_id = args[-1]
  build_config = _GetConfig(bot_id)

  if (options.buildbot or options.remote_trybot) and not options.resume:
    if not options.cgroups:
      parser.error('Options --buildbot/--remote-trybot and --nocgroups cannot '
                   'be used together.  Cgroup support is required for '
                   'buildbot/remote-trybot mode.')
    if not cgroups.Cgroup.IsSupported():
      parser.error('Option --buildbot/--remote-trybot was given, but this '
                   'system does not support cgroups.  Failing.')

    missing = osutils.FindMissingBinaries(_BUILDBOT_REQUIRED_BINARIES)
    if missing:
      parser.error("Option --buildbot/--remote-trybot requires the following "
                   "binaries which couldn't be found in $PATH: %s"
                   % (', '.join(missing)))

  if options.dump_config:
    # This works, but option ordering is bad...
    print 'Configuration %s:' % bot_id
    pretty_printer = pprint.PrettyPrinter(indent=2)
    pretty_printer.pprint(build_config)
    sys.exit(0)

  if not options.buildroot:
    if options.buildbot:
      parser.error('Please specify a buildroot with the --buildbot option.')

    options.buildroot = _DetermineDefaultBuildRoot(options.sourceroot,
                                                   build_config['internal'])
    # We use a marker file in the buildroot to indicate the user has
    # consented to using this directory.
    if not os.path.exists(repository.GetTrybotMarkerPath(options.buildroot)):
      _ConfirmBuildRoot(options.buildroot)

  # Sanity check of buildroot- specifically that it's not pointing into the
  # midst of an existing repo since git-repo doesn't support nesting.
  if (not repository.IsARepoRoot(options.buildroot) and
      git.FindRepoDir(options.buildroot)):
    parser.error('Configured buildroot %s points into a repository checkout, '
                 'rather than the root of it.  This is not supported.'
                 % options.buildroot)

  if not options.log_dir:
    options.log_dir = os.path.join(options.buildroot, _DEFAULT_LOG_DIR)

  log_file = None
  if options.tee:
    log_file = os.path.join(options.log_dir, _BUILDBOT_LOG_FILE)
    osutils.SafeMakedirs(options.log_dir)
    _BackupPreviousLog(log_file)

  with cros_build_lib.ContextManagerStack() as stack:
    # TODO(ferringb): update this once
    # https://chromium-review.googlesource.com/25359
    # is landed- it's sensitive to the manifest-versions cache path.
    options.preserve_paths = set(['manifest-versions', '.cache',
                                  'manifest-versions-internal'])
    if log_file is not None:
      # We don't want the critical section to try to clean up the tee process,
      # so we run Tee (forked off) outside of it. This prevents a deadlock
      # because the Tee process only exits when its pipe is closed, and the
      # critical section accidentally holds on to that file handle.
      stack.Add(tee.Tee, log_file)
      options.preserve_paths.add(_DEFAULT_LOG_DIR)

    critical_section = stack.Add(cleanup.EnforcedCleanupSection)
    stack.Add(sudo.SudoKeepAlive)

    if not options.resume:
      # If we're in resume mode, use our parents tempdir rather than
      # nesting another layer.
      stack.Add(osutils.TempDir, prefix='cbuildbot-tmp', set_global=True)
      logging.debug("Cbuildbot tempdir is %r.", os.environ.get('TMP'))

    if options.cgroups:
      stack.Add(cgroups.SimpleContainChildren, 'cbuildbot')

    # Mark everything between EnforcedCleanupSection and here as having to
    # be rolled back via the contextmanager cleanup handlers.  This
    # ensures that sudo bits cannot outlive cbuildbot, that anything
    # cgroups would kill gets killed, etc.
    stack.Add(critical_section.ForkWatchdog)

    if options.timeout > 0:
      stack.Add(cros_build_lib.Timeout, options.timeout)

    if not options.buildbot:
      build_config = cbuildbot_config.OverrideConfigForTrybot(
          build_config,
          options)

    if options.buildbot or options.remote_trybot:
      _DisableYamaHardLinkChecks()

    _RunBuildStagesWrapper(options, build_config)
