Esempio n. 1
0
def main():
  # Use adhoc argument parsing because of twisted's twisted argument parsing.
  # Change the current directory to the directory of the script.
  os.chdir(SCRIPT_DIR)
  depot_tools = os.path.join(ROOT_DIR, 'depot_tools')
  if not os.path.isdir(depot_tools):
    error('You must put a copy of depot_tools in %s' % depot_tools)
  bot_password_file = os.path.normpath(
      os.path.join(BUILD_DIR, 'site_config', '.bot_password'))
  if not os.path.isfile(bot_password_file):
    error('You forgot to put the password at %s' % bot_password_file)

  if SpawnSubdirBuildbotsIfNeeded():
    # If subdir buildbots were used, don't spawn the root process.
    return

  # Make sure the current python path is absolute.
  old_pythonpath = os.environ.get('PYTHONPATH', '')
  os.environ['PYTHONPATH'] = ''
  for path in old_pythonpath.split(os.pathsep):
    if path:
      os.environ['PYTHONPATH'] += os.path.abspath(path) + os.pathsep

  # Update the python path.
  python_path = [
    os.path.join(BUILD_DIR, 'site_config'),
    os.path.join(BUILD_DIR, 'scripts'),
    os.path.join(BUILD_DIR, 'scripts', 'release'),
    os.path.join(BUILD_DIR, 'third_party'),
    os.path.join(BUILD_DIR, 'third_party', 'requests_1_2_3'),
    os.path.join(ROOT_DIR, 'build_internal', 'site_config'),
    os.path.join(ROOT_DIR, 'build_internal', 'symsrc'),
    SCRIPT_DIR,  # Include the current working directory by default.
  ]

  # Need to update sys.path prior to the following imports.
  sys.path = python_path + sys.path
  import slave.bootstrap
  import config_bootstrap
  active_slavename = chromium_utils.GetActiveSlavename()
  config_bootstrap.Master.active_slavename = active_slavename
  active_master = GetActiveMaster(
      slave.bootstrap, config_bootstrap, active_slavename)

  bb_ver, tw_ver = GetThirdPartyVersions(active_master)
  python_path.append(os.path.join(BUILD_DIR, 'third_party', bb_ver))
  python_path.append(os.path.join(BUILD_DIR, 'third_party', tw_ver))
  sys.path = python_path[-2:] + sys.path

  os.environ['PYTHONPATH'] = (
      os.pathsep.join(python_path) + os.pathsep + os.environ['PYTHONPATH'])

  os.environ['CHROME_HEADLESS'] = '1'
  os.environ['PAGER'] = 'cat'

  # Platform-specific initialization.

  if sys.platform.startswith('win'):
    # list of all variables that we want to keep
    env_var = [
        'APPDATA',
        'BUILDBOT_ARCHIVE_FORCE_SSH',
        'CHROME_HEADLESS',
        'CHROMIUM_BUILD',
        'COMMONPROGRAMFILES',
        'COMMONPROGRAMFILES(X86)',
        'COMMONPROGRAMW6432',
        'COMSPEC',
        'COMPUTERNAME',
        'DBUS_SESSION_BUS_ADDRESS',
        'DEPOT_TOOLS_GIT_BLEEDING',
        # TODO(maruel): Remove once everyone is on 2.7.5.
        'DEPOT_TOOLS_PYTHON_275',
        'DXSDK_DIR',
        'GIT_USER_AGENT',
        'HOME',
        'HOMEDRIVE',
        'HOMEPATH',
        'LOCALAPPDATA',
        'NUMBER_OF_PROCESSORS',
        'OS',
        'PATH',
        'PATHEXT',
        'PROCESSOR_ARCHITECTURE',
        'PROCESSOR_ARCHITEW6432',
        'PROCESSOR_IDENTIFIER',
        'PROGRAMFILES',
        'PROGRAMW6432',
        'PYTHONPATH',
        'SYSTEMDRIVE',
        'SYSTEMROOT',
        'TEMP',
        'TESTING_MASTER',
        'TESTING_MASTER_HOST',
        'TESTING_SLAVENAME',
        'TMP',
        'USERNAME',
        'USERDOMAIN',
        'USERPROFILE',
        'VS100COMNTOOLS',
        'VS110COMNTOOLS',
        'WINDIR',
    ]

    remove_all_vars_except(os.environ, env_var)

    # Extend the env variables with the chrome-specific settings.
    slave_path = [
        depot_tools,
        # Reuse the python executable used to start this script.
        os.path.dirname(sys.executable),
        os.path.join(os.environ['SYSTEMROOT'], 'system32'),
        os.path.join(os.environ['SYSTEMROOT'], 'system32', 'WBEM'),
        # Use os.sep to make this absolute, not relative.
        os.path.join(os.environ['SYSTEMDRIVE'], os.sep, 'Program Files',
                     '7-Zip'),
        # TODO(hinoka): Remove this when its no longer needed crbug.com/481695
        os.path.join(os.environ['SYSTEMDRIVE'], os.sep, 'cmake', 'bin'),
    ]
    # build_internal/tools contains tools we can't redistribute.
    tools = os.path.join(ROOT_DIR, 'build_internal', 'tools')
    if os.path.isdir(tools):
      slave_path.append(os.path.abspath(tools))
    os.environ['PATH'] = os.pathsep.join(slave_path)
    os.environ['LOGNAME'] = os.environ['USERNAME']

  elif sys.platform in ('darwin', 'posix', 'linux2'):
    # list of all variables that we want to keep
    env_var = [
        'CCACHE_DIR',
        'CHROME_ALLOCATOR',
        'CHROME_HEADLESS',
        'CHROME_VALGRIND_NUMCPUS',
        'DISPLAY',
        'DISTCC_DIR',
        'GIT_USER_AGENT',
        'HOME',
        'HOSTNAME',
        'HTTP_PROXY',
        'http_proxy',
        'HTTPS_PROXY',
        'LANG',
        'LOGNAME',
        'PAGER',
        'PATH',
        'PWD',
        'PYTHONPATH',
        'SHELL',
        'SSH_AGENT_PID',
        'SSH_AUTH_SOCK',
        'SSH_CLIENT',
        'SSH_CONNECTION',
        'SSH_TTY',
        'TESTING_MASTER',
        'TESTING_MASTER_HOST',
        'TESTING_SLAVENAME',
        'USER',
        'USERNAME',
    ]

    remove_all_vars_except(os.environ, env_var)
    slave_path = [
        os.path.join(os.path.expanduser('~'), 'slavebin'),
        depot_tools,
    ]
    # Git on mac is installed from git-scm.com/download/mac
    if sys.platform == 'darwin' and os.path.isdir('/usr/local/git/bin'):
      slave_path.append('/usr/local/git/bin')
    slave_path += [
        # Reuse the python executable used to start this script.
        os.path.dirname(sys.executable),
        '/usr/bin', '/bin', '/usr/sbin', '/sbin', '/usr/local/bin'
    ]
    os.environ['PATH'] = os.pathsep.join(slave_path)

  else:
    error('Platform %s is not implemented yet' % sys.platform)

  git_exe = 'git' + ('.bat' if sys.platform.startswith('win') else '')
  try:
    git_version = subprocess.check_output([git_exe, '--version'])
  except (OSError, subprocess.CalledProcessError) as e:
    Log('WARNING: Could not get git version information: %r' % e)
    git_version = '?'
  os.environ.setdefault('GIT_USER_AGENT', '%s git/%s %s' % (
      sys.platform, git_version.rstrip().split()[-1], socket.getfqdn()))
  # This may be redundant, unless this is imported and main is called.
  UseBotoPath()

  # This envrionment is defined only when testing the slave on a dev machine.
  is_testing = 'TESTING_MASTER' in os.environ
  HotPatchSlaveBuilder(is_testing)

  import twisted.scripts.twistd as twistd
  twistd.run()
  shutdown_file = os.path.join(os.path.dirname(__file__), 'shutdown.stamp')
  if os.path.isfile(shutdown_file):
    # If this slave is being shut down gracefully, don't reboot it.
    try:
      os.remove(shutdown_file)
      # Only disable reboot if the file can be removed.  Otherwise, the slave
      # might get stuck offline after every build.
      global needs_reboot
      needs_reboot = False
    except OSError:
      Log('Could not delete graceful shutdown signal file %s' % shutdown_file)

  # Although prevent_reboot_file looks similar to shutdown_file above, it is not
  # the same as shutdown.stamp is actually used by Buildbot to shut down the
  # slave process, while ~/no_reboot prevents rebooting the slave machine.
  prevent_reboot_file = os.path.join(os.path.expanduser('~'), 'no_reboot')
  if needs_reboot:
    if not os.path.isfile(prevent_reboot_file):
      # Send the appropriate system shutdown command.
      Reboot()
      # This line should not be reached.
    else:
      Log('Reboot was prevented by %s. Please remove the file and reboot the '
          'slave manually to resume automatic reboots.' % prevent_reboot_file)
Esempio n. 2
0
def main():
    # Use adhoc argument parsing because of twisted's twisted argument parsing.
    # Change the current directory to the directory of the script.
    os.chdir(SCRIPT_DIR)
    depot_tools = os.path.join(ROOT_DIR, 'depot_tools')
    if not os.path.isdir(depot_tools):
        error('You must put a copy of depot_tools in %s' % depot_tools)
    bot_password_file = os.path.normpath(
        os.path.join(BUILD_DIR, 'site_config', '.bot_password'))
    if not os.path.isfile(bot_password_file):
        error('You forgot to put the password at %s' % bot_password_file)

    if (os.path.exists(os.path.join(GetRoot(), 'b'))
            and os.path.exists(os.path.join(GetRoot(), 'c'))):
        SpawnSubdirBuildbotsIfNeeded()

    # Make sure the current python path is absolute.
    old_pythonpath = os.environ.get('PYTHONPATH', '')
    os.environ['PYTHONPATH'] = ''
    for path in old_pythonpath.split(os.pathsep):
        if path:
            os.environ['PYTHONPATH'] += os.path.abspath(path) + os.pathsep

    # Update the python path.
    python_path = [
        os.path.join(BUILD_DIR, 'site_config'),
        os.path.join(BUILD_DIR, 'scripts'),
        os.path.join(BUILD_DIR, 'scripts', 'release'),
        os.path.join(BUILD_DIR, 'third_party'),
        os.path.join(ROOT_DIR, 'build_internal', 'site_config'),
        os.path.join(ROOT_DIR, 'build_internal', 'symsrc'),
        SCRIPT_DIR,  # Include the current working directory by default.
    ]

    # Need to update sys.path prior to the following imports.
    sys.path = python_path + sys.path
    import slave.bootstrap
    import config_bootstrap
    active_slavename = chromium_utils.GetActiveSlavename()
    config_bootstrap.Master.active_slavename = active_slavename
    active_master = GetActiveMaster(slave.bootstrap, config_bootstrap,
                                    active_slavename)

    bb_ver, tw_ver = GetThirdPartyVersions(active_master)
    python_path.append(os.path.join(BUILD_DIR, 'third_party', bb_ver))
    python_path.append(os.path.join(BUILD_DIR, 'third_party', tw_ver))
    sys.path.extend(python_path[-2:])

    os.environ['PYTHONPATH'] = (os.pathsep.join(python_path) + os.pathsep +
                                os.environ['PYTHONPATH'])

    os.environ['CHROME_HEADLESS'] = '1'
    os.environ['PAGER'] = 'cat'

    # Platform-specific initialization.

    if sys.platform.startswith('win'):
        # list of all variables that we want to keep
        env_var = [
            'APPDATA',
            'BUILDBOT_ARCHIVE_FORCE_SSH',
            'CHROME_HEADLESS',
            'CHROMIUM_BUILD',
            'COMMONPROGRAMFILES',
            'COMMONPROGRAMFILES(X86)',
            'COMMONPROGRAMW6432',
            'COMSPEC',
            'COMPUTERNAME',
            'DBUS_SESSION_BUS_ADDRESS',
            # TODO(maruel): Remove once everyone is on 2.7.5.
            'DEPOT_TOOLS_PYTHON_275',
            'DXSDK_DIR',
            'HOMEDRIVE',
            'HOMEPATH',
            'LOCALAPPDATA',
            'NUMBER_OF_PROCESSORS',
            'OS',
            'PATH',
            'PATHEXT',
            'PROCESSOR_ARCHITECTURE',
            'PROCESSOR_ARCHITEW6432',
            'PROCESSOR_IDENTIFIER',
            'PROGRAMFILES',
            'PROGRAMW6432',
            'PYTHONPATH',
            'SYSTEMDRIVE',
            'SYSTEMROOT',
            'TEMP',
            'TESTING_MASTER',
            'TESTING_MASTER_HOST',
            'TESTING_SLAVENAME',
            'TMP',
            'USERNAME',
            'USERDOMAIN',
            'USERPROFILE',
            'VS100COMNTOOLS',
            'VS110COMNTOOLS',
            'WINDIR',
        ]

        remove_all_vars_except(os.environ, env_var)

        # Extend the env variables with the chrome-specific settings.
        slave_path = [
            depot_tools,
            # Reuse the python executable used to start this script.
            os.path.dirname(sys.executable),
            os.path.join(os.environ['SYSTEMROOT'], 'system32'),
            os.path.join(os.environ['SYSTEMROOT'], 'system32', 'WBEM'),
            os.path.join(os.environ['SYSTEMDRIVE'], 'Program Files', '7-Zip'),
        ]
        # build_internal/tools contains tools we can't redistribute.
        tools = os.path.join(ROOT_DIR, 'build_internal', 'tools')
        if os.path.isdir(tools):
            slave_path.append(os.path.abspath(tools))
        os.environ['PATH'] = os.pathsep.join(slave_path)
        os.environ['LOGNAME'] = os.environ['USERNAME']

    elif sys.platform in ('darwin', 'posix', 'linux2'):
        # list of all variables that we want to keep
        env_var = [
            'CCACHE_DIR',
            'CHROME_ALLOCATOR',
            'CHROME_HEADLESS',
            'CHROME_VALGRIND_NUMCPUS',
            'DISPLAY',
            'DISTCC_DIR',
            'HOME',
            'HOSTNAME',
            'HTTP_PROXY',
            'http_proxy',
            'HTTPS_PROXY',
            'LANG',
            'LOGNAME',
            'PAGER',
            'PATH',
            'PWD',
            'PYTHONPATH',
            'SHELL',
            'SSH_AGENT_PID',
            'SSH_AUTH_SOCK',
            'SSH_CLIENT',
            'SSH_CONNECTION',
            'SSH_TTY',
            'TESTING_MASTER',
            'TESTING_MASTER_HOST',
            'TESTING_SLAVENAME',
            'USER',
            'USERNAME',
        ]

        remove_all_vars_except(os.environ, env_var)
        slave_path = [
            os.path.join(os.path.expanduser('~'), 'slavebin'),
            depot_tools,
        ]
        # Git on mac is installed from git-scm.com/download/mac
        if sys.platform == 'darwin' and os.path.isdir('/usr/local/git/bin'):
            slave_path.append('/usr/local/git/bin')
        slave_path += [
            # Reuse the python executable used to start this script.
            os.path.dirname(sys.executable),
            '/usr/bin',
            '/bin',
            '/usr/sbin',
            '/sbin',
            '/usr/local/bin'
        ]
        os.environ['PATH'] = os.pathsep.join(slave_path)

    else:
        error('Platform %s is not implemented yet' % sys.platform)

    # This may be redundant, unless this is imported and main is called.
    UseBotoPath()

    # This envrionment is defined only when testing the slave on a dev machine.
    is_testing = 'TESTING_MASTER' in os.environ
    if not is_testing:
        # Don't overwrite the ~/.subversion/config file when TESTING_MASTER is set.
        FixSubversionConfig()
    HotPatchSlaveBuilder(is_testing)

    import twisted.scripts.twistd as twistd
    twistd.run()
    if needs_reboot:
        # Send the appropriate system shutdown command.
        Reboot()
Esempio n. 3
0
def main():
    # Use adhoc argument parsing because of twisted's twisted argument parsing.
    # Change the current directory to the directory of the script.
    os.chdir(SCRIPT_DIR)
    depot_tools = os.path.join(ROOT_DIR, 'depot_tools')
    if not os.path.isdir(depot_tools):
        error('You must put a copy of depot_tools in %s' % depot_tools)
    bot_password_file = os.path.normpath(
        os.path.join(BUILD_DIR, 'site_config', '.bot_password'))
    if not os.path.isfile(bot_password_file):
        error('You forgot to put the password at %s' % bot_password_file)

    if SpawnSubdirBuildbotsIfNeeded():
        # If subdir buildbots were used, don't spawn the root process.
        return

    # Make sure the current python path is absolute.
    old_pythonpath = os.environ.get('PYTHONPATH', '')
    os.environ['PYTHONPATH'] = ''
    for path in old_pythonpath.split(os.pathsep):
        if path:
            os.environ['PYTHONPATH'] += os.path.abspath(path) + os.pathsep

    # Update the python path.
    python_path = [
        os.path.join(BUILD_DIR, 'site_config'),
        os.path.join(BUILD_DIR, 'scripts'),
        os.path.join(BUILD_DIR, 'scripts', 'release'),
        os.path.join(BUILD_DIR, 'third_party'),
        os.path.join(BUILD_DIR, 'third_party', 'google_api_python_client'),
        os.path.join(BUILD_DIR, 'third_party', 'httplib2', 'python2'),
        os.path.join(BUILD_DIR, 'third_party', 'infra_libs'),
        os.path.join(BUILD_DIR, 'third_party', 'oauth2client'),
        os.path.join(BUILD_DIR, 'third_party', 'pyasn1'),
        os.path.join(BUILD_DIR, 'third_party', 'pyasn1-modules'),
        os.path.join(BUILD_DIR, 'third_party', 'python-rsa'),
        os.path.join(BUILD_DIR, 'third_party', 'requests_2_10_0'),
        os.path.join(BUILD_DIR, 'third_party', 'setuptools-0.6c11'),
        os.path.join(BUILD_DIR, 'third_party', 'site-packages'),
        os.path.join(BUILD_DIR, 'third_party', 'uritemplate'),
        os.path.join(ROOT_DIR, 'build_internal', 'site_config'),
        os.path.join(ROOT_DIR, 'build_internal', 'symsrc'),
        SCRIPT_DIR,  # Include the current working directory by default.
    ]

    # Need to update sys.path prior to the following imports.  Remove any
    # dist-packages and site-packages directories from the path - we want all our
    # dependencies to come from third_party, not from random packages that happen
    # to be installed on the machine.  We want to *remove* the paths (rather than
    # just being before them) because conflicts occur when a module is found in
    # multiple locations on the path.  In particular this causes problems when
    # google-protobuf is installed as a system package (often at an earlier
    # version than ours in third_party).  It uses setuptools to make "google" a
    # namespace package, and importing google.protobuf then gets us the wrong one.
    if sys.platform == 'win32':
        # Don't remove site-packages on Windows.  pywin32 is in there, which is
        # needed by twisted.
        filtered_sys_path = sys.path
    else:
        filtered_sys_path = [
            x for x in sys.path
            if 'dist-packages' not in x and 'site-packages' not in x
        ]
    sys.path = python_path + filtered_sys_path

    import slave.bootstrap
    import config_bootstrap
    active_slavename = chromium_utils.GetActiveSlavename()
    config_bootstrap.Master.active_slavename = active_slavename

    active_master_class_name = chromium_utils.GetActiveMaster(active_slavename)
    if not active_master_class_name:
        raise RuntimeError('*** Failed to detect the active master')

    active_master = GetActiveMasterClass(active_master_class_name,
                                         slave.bootstrap, config_bootstrap)
    active_subdir = chromium_utils.GetActiveSubdir()

    bb_ver, tw_ver = GetThirdPartyVersions(active_master)
    python_path.append(os.path.join(BUILD_DIR, 'third_party', bb_ver))
    python_path.append(os.path.join(BUILD_DIR, 'third_party', tw_ver))
    sys.path = python_path[-2:] + sys.path

    os.environ['PYTHONPATH'] = (os.pathsep.join(python_path) + os.pathsep +
                                os.environ['PYTHONPATH'])

    os.environ['CHROME_HEADLESS'] = '1'
    os.environ['PAGER'] = 'cat'

    # Platform-specific initialization.
    if sys.platform.startswith('win'):
        # list of all variables that we want to keep
        env_var = [
            'APPDATA',
            'BUILDBOT_ARCHIVE_FORCE_SSH',
            'CHROME_HEADLESS',
            'CHROMIUM_BUILD',
            'CLASSPATH',
            'COMMONPROGRAMFILES',
            'COMMONPROGRAMFILES(X86)',
            'COMMONPROGRAMW6432',
            'COMPUTERNAME',
            'COMSPEC',
            'DBUS_SESSION_BUS_ADDRESS',
            'DEPOT_TOOLS_GIT_BLEEDING',
            'DXSDK_DIR',
            'GIT_USER_AGENT',
            'HOME',
            'HOMEDRIVE',
            'HOMEPATH',
            'JAVA_HOME',
            'JDK_HOME',
            'JRE_HOME',
            'LOCALAPPDATA',
            'NUMBER_OF_PROCESSORS',
            'OS',
            'PATH',
            'PATHEXT',
            'PROCESSOR_ARCHITECTURE',
            'PROCESSOR_ARCHITEW6432',
            'PROCESSOR_IDENTIFIER',
            'PROGRAMFILES',
            'PROGRAMFILES(X86)',
            'PROGRAMW6432',
            'PYTHONPATH',
            'PYTHONUNBUFFERED',
            'SYSTEMDRIVE',
            'SYSTEMROOT',
            'TEMP',
            'TESTING_MASTER',
            'TESTING_MASTER_HOST',
            'TESTING_SLAVENAME',
            'TMP',
            'USERDOMAIN',
            'USERNAME',
            'USERPROFILE',
            'VS100COMNTOOLS',
            'VS110COMNTOOLS',
            'WINDIR',
        ]

        remove_all_vars_except(os.environ, env_var)

        # Extend the env variables with the chrome-specific settings. Tailor the
        # slave process' (and derivative tasks') PATH environment variable.
        slave_path = [
            depot_tools,
            # Reuse the python executable used to start this script.
            os.path.dirname(sys.executable),
            os.path.join(os.environ['SYSTEMROOT'], 'system32'),
            os.path.join(os.environ['SYSTEMROOT'], 'system32', 'WBEM'),
            # Use os.sep to make this absolute, not relative.
            os.path.join(os.environ['SYSTEMDRIVE'], os.sep, 'Program Files',
                         '7-Zip'),
            # TODO(hinoka): Remove this when its no longer needed crbug.com/481695
            os.path.join(os.environ['SYSTEMDRIVE'], os.sep, 'cmake', 'bin'),
        ]

        # Include Windows PowerShell in PATH, if defined.
        def which_path(cmd):
            path = chromium_utils.Which(cmd)
            return ([os.path.dirname(os.path.abspath(path))] if path else [])

        slave_path += which_path('powershell.exe')

        # build_internal/tools contains tools we can't redistribute.
        tools = os.path.join(ROOT_DIR, 'build_internal', 'tools')
        if os.path.isdir(tools):
            slave_path.append(os.path.abspath(tools))
        if 'JAVA_HOME' in os.environ:
            slave_path.append(os.path.join(os.environ['JAVA_HOME'], 'bin'))
        os.environ['PATH'] = os.pathsep.join(slave_path)
        os.environ['LOGNAME'] = os.environ['USERNAME']

    elif sys.platform in ('darwin', 'posix', 'linux2'):
        # list of all variables that we want to keep
        env_var = [
            'CCACHE_DIR',
            'CHROME_ALLOCATOR',
            'CHROME_HEADLESS',
            'CHROME_VALGRIND_NUMCPUS',
            'CLASSPATH',
            'DISPLAY',
            'DISTCC_DIR',
            'GIT_USER_AGENT',
            'HOME',
            'HOSTNAME',
            'HTTP_PROXY',
            'http_proxy',
            'HTTPS_PROXY',
            'JAVA_HOME',
            'JDK_HOME',
            'JRE_HOME',
            'LANG',
            'LOGNAME',
            'PAGER',
            'PATH',
            'PWD',
            'PYTHONPATH',
            'PYTHONUNBUFFERED',
            'SHELL',
            'SSH_AGENT_PID',
            'SSH_AUTH_SOCK',
            'SSH_CLIENT',
            'SSH_CONNECTION',
            'SSH_TTY',
            'TESTING_MASTER',
            'TESTING_MASTER_HOST',
            'TESTING_SLAVENAME',
            'TMPDIR',
            'USER',
            'USERNAME',
        ]

        remove_all_vars_except(os.environ, env_var)
        slave_path = [
            os.path.join(os.path.expanduser('~'), 'slavebin'),
            depot_tools,
        ]
        # Git on mac is installed from git-scm.com/download/mac
        if sys.platform == 'darwin' and os.path.isdir('/usr/local/git/bin'):
            slave_path.append('/usr/local/git/bin')
        slave_path += [
            # Reuse the python executable used to start this script.
            os.path.dirname(sys.executable),
            '/usr/bin',
            '/bin',
            '/usr/sbin',
            '/sbin',
            '/usr/local/bin'
        ]
        if 'JAVA_HOME' in os.environ:
            slave_path.append(os.path.join(os.environ['JAVA_HOME'], 'bin'))
        os.environ['PATH'] = os.pathsep.join(slave_path)

    else:
        error('Platform %s is not implemented yet' % sys.platform)

    # Export the active master name in the enviornment. We do this because some
    # scripts actually rely on this value, and it is not available otherwise.
    #
    # XXX: This is a BuildBot transition hack. Please do NOT use these variables.
    # They will go away and if you use them, we're not going to fix your code; it
    # will just break.
    os.environ['INFRA_BUILDBOT_MASTER_CLASS_NAME'] = active_master_class_name
    os.environ['INFRA_BUILDBOT_SLAVE_NAME'] = active_slavename
    os.environ['INFRA_BUILDBOT_SLAVE_ACTIVE_SUBDIR'] = active_subdir or ''

    git_exe = 'git' + ('.bat' if sys.platform.startswith('win') else '')
    try:
        git_version = subprocess.check_output([git_exe, '--version'])
    except (OSError, subprocess.CalledProcessError) as e:
        Log('WARNING: Could not get git version information: %r' % e)
        git_version = '?'

    # Add some extra information to the git User-Agent string to allow for
    # logging/debugging on the server side.
    # This string needs to begin with git/X.Y.Z otherwise for certain servers
    # (e.g. github) fail to recognize the request as coming from git.
    os.environ.setdefault(
        'GIT_USER_AGENT', 'git/%s %s %s' %
        (git_version.rstrip().split()[-1], sys.platform, socket.getfqdn()))

    # This may be redundant, unless this is imported and main is called.
    UseBotoPath()

    # This envrionment is defined only when testing the slave on a dev machine.
    is_testing = 'TESTING_MASTER' in os.environ
    HotPatchSlaveBuilder(is_testing)

    import twisted.scripts.twistd as twistd
    twistd.run()
    shutdown_file = os.path.join(os.path.dirname(__file__), 'shutdown.stamp')
    if os.path.isfile(shutdown_file):
        # If this slave is being shut down gracefully, don't reboot it.
        try:
            os.remove(shutdown_file)
            # Only disable reboot if the file can be removed.  Otherwise, the slave
            # might get stuck offline after every build.
            global needs_reboot
            needs_reboot = False
        except OSError:
            Log('Could not delete graceful shutdown signal file %s' %
                shutdown_file)

    # Although prevent_reboot_file looks similar to shutdown_file above, it is not
    # the same as shutdown.stamp is actually used by Buildbot to shut down the
    # slave process, while ~/no_reboot prevents rebooting the slave machine.
    prevent_reboot_file = os.path.join(os.path.expanduser('~'), 'no_reboot')
    if needs_reboot:
        if not os.path.isfile(prevent_reboot_file):
            # Send the appropriate system shutdown command.
            Reboot()
            # This line should not be reached.
        else:
            Log('Reboot was prevented by %s. Please remove the file and reboot the '
                'slave manually to resume automatic reboots.' %
                prevent_reboot_file)