示例#1
0
    def GetParser():
        """Returns parser for ChromeCommitter.

    Returns:
      Parser for ChromeCommitter.
    """
        # We need to use the account used by the builder to upload git CLs when
        # generating CLs.
        default_git_account = None
        if cros_build_lib.HostIsCIBuilder(golo_only=True):
            default_git_account = '*****@*****.**'
        elif cros_build_lib.HostIsCIBuilder(gce_only=True):
            default_git_account = '*****@*****.**'

        parser = commandline.ArgumentParser(usage=__doc__, add_help=False)
        parser.add_argument('--dryrun',
                            action='store_true',
                            default=False,
                            help="Don't commit changes or send out emails.")
        parser.add_argument(
            '--user_email',
            required=False,
            default=default_git_account,
            help='Email address to use when comitting changes.')
        parser.add_argument('--workdir',
                            default=os.path.join(os.getcwd(), 'chrome_src'),
                            help=('Path to a checkout of the chrome src. '
                                  'Defaults to PWD/chrome_src'))
        return parser
示例#2
0
 def _AssertGclientConfigSpec(self, expected_spec, use_cache=True):
     if cros_build_lib.HostIsCIBuilder() and use_cache:
         if cros_build_lib.IsInsideChroot():
             expected_spec += "cache_dir = '/tmp/b/git-cache'\n"
         else:
             expected_spec += "cache_dir = '/b/git-cache'\n"
     self.rc.assertCommandContains(
         ('gclient', 'config', '--spec', expected_spec), cwd=self._TEST_CWD)
    def testBuildBotOnNonCIBuilder(self):
        """Test BuildBot On Non-CIBuilder

    Buildbot should quite if run in a non-CIBuilder without
    both debug and remote.
    """
        if not cros_build_lib.HostIsCIBuilder():
            self.assertRaises(cros_build_lib.DieSystemExit, self.assertMain,
                              ['--buildbot', 'x86-generic-paladin'])
示例#4
0
def _GetGclientSpec(internal, rev, template, use_cache):
    """Return a formatted gclient spec.

  See WriteConfigFile below.
  """
    solutions = _GetGclientSolutions(internal=internal,
                                     rev=rev,
                                     template=template)
    result = 'solutions = %s\n' % pprint.pformat(solutions)

    # Horrible hack, I will go to hell for this.  The bots need to have a git
    # cache set up; but how can we tell whether this code is running on a bot
    # or a developer's machine?
    if cros_build_lib.HostIsCIBuilder() and use_cache:
        result += "cache_dir = '/b/git-cache'\n"

    return result
 def testHostIsCIBuilder(self):
     """Test HostIsCIBuilder."""
     fq_hostname_golo = 'test.golo.chromium.org'
     fq_hostname_gce_1 = 'test.chromeos-bot.internal'
     fq_hostname_gce_2 = 'test.chrome.corp.google.com'
     fq_hostname_invalid = 'test'
     self.assertTrue(cros_build_lib.HostIsCIBuilder(fq_hostname_golo))
     self.assertTrue(cros_build_lib.HostIsCIBuilder(fq_hostname_gce_1))
     self.assertTrue(cros_build_lib.HostIsCIBuilder(fq_hostname_gce_2))
     self.assertFalse(cros_build_lib.HostIsCIBuilder(fq_hostname_invalid))
     self.assertFalse(
         cros_build_lib.HostIsCIBuilder(fq_hostname=fq_hostname_golo,
                                        gce_only=True))
     self.assertFalse(
         cros_build_lib.HostIsCIBuilder(fq_hostname=fq_hostname_gce_1,
                                        golo_only=True))
示例#6
0
  def __init__(self, goma_dir, goma_client_json, goma_tmp_dir=None,
               stage_name=None):
    """Initializes Goma instance.

    This ensures that |self.goma_log_dir| directory exists (if missing,
    creates it).

    Args:
      goma_dir: Path to the goma directory (outside of chroot).
      goma_client_json: Path to the service account json file to use goma.
        On bots, this must be specified, otherwise raise a ValueError.
        On local, this is optional, and can be set to None.
      goma_tmp_dir: Path to the GOMA_TMP_DIR to be passed to goma programs.
        If given, it is used. If not given, creates a directory under
        /tmp in the chroot, expecting that the directory is removed in the
        next run's clean up phase on bots.
      stage_name: optional name of the currently running stage. E.g.
        "build_packages" or "test_simple_chrome_workflow". If this is set
        deps cache is enabled.

    Raises:
       ValueError if 1) |goma_dir| does not point to a directory, 2)
       on bots, but |goma_client_json| is not given, 3) |goma_client_json|
       is given, but it does not point to a file, or 4) if |goma_tmp_dir| is
       given but it does not point to a directory.
    """
    # Sanity checks of given paths.
    if not os.path.isdir(goma_dir):
      raise ValueError('goma_dir does not point a directory: %s' % (goma_dir,))

    # If this script runs on bot, service account json file needs to be
    # provided, otherwise it cannot access to goma service.
    if cros_build_lib.HostIsCIBuilder() and goma_client_json is None:
      raise ValueError(
          'goma is enabled on bot, but goma_client_json is not provided')

    # If goma_client_json file is provided, it must be an existing file.
    if goma_client_json and not os.path.isfile(goma_client_json):
      raise ValueError(
          'Goma client json file is missing: %s' % (goma_client_json,))

    # If goma_tmp_dir is provided, it must be an existing directory.
    if goma_tmp_dir and not os.path.isdir(goma_tmp_dir):
      raise ValueError(
          'GOMA_TMP_DIR does not point a directory: %s' % (goma_tmp_dir,))

    self.goma_dir = goma_dir
    self.goma_client_json = goma_client_json
    if stage_name:
      self.goma_cache = os.path.join(goma_dir, 'goma_cache', stage_name)
      osutils.SafeMakedirs(self.goma_cache)
    else:
      self.goma_cache = None

    if goma_tmp_dir is None:
      # If |goma_tmp_dir| is not given, create GOMA_TMP_DIR (goma
      # compiler_proxy's working directory), and its log directory.
      # Create unique directory by mkdtemp under chroot's /tmp.
      # Expect this directory is removed in next run's clean up phase.
      goma_tmp_dir = tempfile.mkdtemp(
          prefix='goma_tmp_dir.', dir=path_util.FromChrootPath('/tmp'))
    self.goma_tmp_dir = goma_tmp_dir

    # Create log directory if not exist.
    if not os.path.isdir(self.goma_log_dir):
      os.mkdir(self.goma_log_dir)
示例#7
0
def main(argv):
    # We get false positives with the options object.
    # pylint: disable=attribute-defined-outside-init

    # 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 = ParseCommandLine(parser, argv)

    # Fetch our site_config now, because we need it to do anything else.
    site_config = config_lib.GetConfig()

    _PostParseCheck(parser, options, site_config)

    cros_build_lib.AssertOutsideChroot()

    if options.enable_buildbot_tags:
        logging.EnableBuildbotMarkers()

    if (options.buildbot and not options.debug
            and not options.build_config_name == constants.BRANCH_UTIL_CONFIG
            and not cros_build_lib.HostIsCIBuilder()):
        # --buildbot can only be used on a real builder, unless it's debug, or
        # 'branch-util'.
        cros_build_lib.Die('This host is not a supported build machine.')

    # Only one config arg is allowed in this mode, which was confirmed earlier.
    build_config = site_config[options.build_config_name]

    # TODO: Re-enable this block when reference_repo support handles this
    #       properly. (see chromium:330775)
    # if options.reference_repo is None:
    #   repo_path = os.path.join(options.sourceroot, '.repo')
    #   # If we're being run from a repo checkout, reuse the repo's git pool to
    #   # cut down on sync time.
    #   if os.path.exists(repo_path):
    #     options.reference_repo = options.sourceroot

    if options.reference_repo:
        if not os.path.exists(options.reference_repo):
            parser.error('Reference path %s does not exist' %
                         (options.reference_repo, ))
        elif not os.path.exists(os.path.join(options.reference_repo, '.repo')):
            parser.error('Reference path %s does not look to be the base of a '
                         'repo checkout; no .repo exists in the root.' %
                         (options.reference_repo, ))

    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.reference_repo:
        options.reference_repo = os.path.abspath(options.reference_repo)

    # 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)):
        cros_build_lib.Die(
            'Configured buildroot %s is a subdir of an existing repo checkout.'
            % 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:
        options.preserve_paths = set()
        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.mock_tree_status is not None:
            stack.Add(_ObjectMethodPatcher,
                      tree_status,
                      '_GetStatus',
                      return_value=options.mock_tree_status)

        if options.mock_slave_status is not None:
            with open(options.mock_slave_status, 'r') as f:
                mock_statuses = pickle.load(f)
                for key, value in mock_statuses.iteritems():
                    mock_statuses[key] = builder_status_lib.BuilderStatus(
                        **value)
            stack.Add(_ObjectMethodPatcher,
                      completion_stages.MasterSlaveSyncCompletionStage,
                      '_FetchSlaveStatuses',
                      return_value=mock_statuses)

        stack.Add(_SetupConnections, options, build_config)
        retry_stats.SetupStats()

        timeout_display_message = None
        # For master-slave builds: Update slave's timeout using master's published
        # deadline.
        if options.buildbot and options.master_build_id is not None:
            slave_timeout = None
            if cidb.CIDBConnectionFactory.IsCIDBSetup():
                cidb_handle = cidb.CIDBConnectionFactory.GetCIDBConnectionForBuilder(
                )
                if cidb_handle:
                    slave_timeout = cidb_handle.GetTimeToDeadline(
                        options.master_build_id)

            if slave_timeout is not None:
                # We artificially set a minimum slave_timeout because '0' is handled
                # specially, and because we don't want to timeout while trying to set
                # things up.
                slave_timeout = max(slave_timeout, 20)
                if options.timeout == 0 or slave_timeout < options.timeout:
                    logging.info(
                        'Updating slave build timeout to %d seconds enforced '
                        'by the master', slave_timeout)
                    options.timeout = slave_timeout
                    timeout_display_message = (
                        'This build has reached the timeout deadline set by the master. '
                        'Either this stage or a previous one took too long (see stage '
                        'timing historical summary in ReportStage) or the build failed '
                        'to start on time.')
            else:
                logging.warning(
                    'Could not get master deadline for master-slave build. '
                    'Can not set slave timeout.')

        if options.timeout > 0:
            stack.Add(timeout_util.FatalTimeout, options.timeout,
                      timeout_display_message)
        try:
            _RunBuildStagesWrapper(options, site_config, build_config)
        except failures_lib.ExitEarlyException as ex:
            # This build finished successfully. Do not re-raise ExitEarlyException.
            logging.info('One stage exited early: %s', ex)
示例#8
0
    def __init__(self,
                 goma_dir,
                 goma_client_json,
                 goma_tmp_dir=None,
                 stage_name=None,
                 chromeos_goma_dir=None,
                 chroot_dir=None,
                 goma_approach=None):
        """Initializes Goma instance.

    This ensures that |self.goma_log_dir| directory exists (if missing,
    creates it).

    Args:
      goma_dir: Path to the Goma client used for simplechrome
                (outside of chroot).
      goma_client_json: Path to the service account json file to use goma.
        On bots, this must be specified, otherwise raise a ValueError.
        On local, this is optional, and can be set to None.
      goma_tmp_dir: Path to the GOMA_TMP_DIR to be passed to goma programs.
        If given, it is used. If not given, creates a directory under
        /tmp in the chroot, expecting that the directory is removed in the
        next run's clean up phase on bots.
      stage_name: optional name of the currently running stage. E.g.
        "build_packages" or "test_simple_chrome_workflow". If this is set
        deps cache is enabled.
      chromeos_goma_dir: Path to the Goma client used for build package.
                         path should be represented as outside of chroot.
                         If None, goma_dir will be used instead.
      chroot_dir: The base chroot path to use when the chroot path is not at
        the default location.
      goma_approach: Indicates some extra environment variables to set when
        testing alternative goma approaches.

    Raises:
      ValueError if 1) |goma_dir| does not point to a directory, 2)
      on bots, but |goma_client_json| is not given, 3) |goma_client_json|
      is given, but it does not point to a file, or 4) if |goma_tmp_dir| is
      given but it does not point to a directory.
    """
        # Sanity checks of given paths.
        if not os.path.isdir(goma_dir):
            raise ValueError('goma_dir does not point a directory: %s' %
                             (goma_dir, ))

        # If this script runs on bot, service account json file needs to be
        # provided, otherwise it cannot access to goma service.
        if cros_build_lib.HostIsCIBuilder() and goma_client_json is None:
            raise ValueError(
                'goma is enabled on bot, but goma_client_json is not provided')

        # If goma_client_json file is provided, it must be an existing file.
        if goma_client_json and not os.path.isfile(goma_client_json):
            raise ValueError('Goma client json file is missing: %s' %
                             (goma_client_json, ))

        # If goma_tmp_dir is provided, it must be an existing directory.
        if goma_tmp_dir and not os.path.isdir(goma_tmp_dir):
            raise ValueError('GOMA_TMP_DIR does not point a directory: %s' %
                             (goma_tmp_dir, ))

        self.linux_goma_dir = goma_dir
        self.chromeos_goma_dir = chromeos_goma_dir
        self.goma_approach = goma_approach
        # If Goma dir for ChromeOS SDK does not set, fallback to use goma_dir.
        if self.chromeos_goma_dir is None:
            self.chromeos_goma_dir = goma_dir
        # Sanity checks of given paths.
        if not os.path.isdir(self.chromeos_goma_dir):
            raise ValueError(
                'chromeos_goma_dir does not point a directory: %s' %
                (self.chromeos_goma_dir, ))

        self.goma_client_json = goma_client_json
        if stage_name:
            self.goma_cache = os.path.join(goma_dir, 'goma_cache', stage_name)
            osutils.SafeMakedirs(self.goma_cache)
        else:
            self.goma_cache = None

        if goma_tmp_dir is None:
            # path_util depends on the chroot directory existing at
            # SOURCE_ROOT/chroot. This assumption is not valid for Luci builders,
            # but generally shouldn't be an assumption anyway since we allow setting
            # the chroot location. This block, and the two a few lines down, bypass
            # path_util to compensate for those assumptions.
            # TODO(crbug.com/1014138) Cleanup when path_util can handle custom chroot.
            if chroot_dir:
                chroot_tmp = os.path.join(chroot_dir, 'tmp')
            else:
                chroot_tmp = path_util.FromChrootPath('/tmp')

            # If |goma_tmp_dir| is not given, create GOMA_TMP_DIR (goma
            # compiler_proxy's working directory), and its log directory.
            # Create unique directory by mkdtemp under chroot's /tmp.
            # Expect this directory is removed in next run's clean up phase.
            goma_tmp_dir = tempfile.mkdtemp(prefix='goma_tmp_dir.',
                                            dir=chroot_tmp)
        self.goma_tmp_dir = goma_tmp_dir

        if chroot_dir:
            self.chroot_goma_tmp_dir = os.path.join(
                '/', os.path.relpath(self.goma_tmp_dir, chroot_dir))
        else:
            self.chroot_goma_tmp_dir = path_util.ToChrootPath(
                self.goma_tmp_dir)

        # Create log directory if not exist.
        if not os.path.isdir(self.goma_log_dir):
            os.mkdir(self.goma_log_dir)

        if chroot_dir:
            self.chroot_goma_log_dir = os.path.join(
                '/', os.path.relpath(self.goma_log_dir, chroot_dir))
        else:
            self.chroot_goma_log_dir = path_util.ToChrootPath(
                self.goma_log_dir)