Example #1
0
    def _ExplainIfSudoNeeded(self, tf, dirs_to_remove):
        """Explains what to do if sudo needed to update gsutil software.

    Happens if gsutil was previously installed by a different user (typically if
    someone originally installed in a shared file system location, using sudo).

    Args:
      tf: Opened TarFile.
      dirs_to_remove: List of directories to remove.

    Raises:
      CommandException: if errors encountered.
    """
        # If running under Windows or Cygwin we don't need (or have) sudo.
        if IS_CYGWIN or IS_WINDOWS:
            return

        user_id = os.getuid()
        if os.stat(gslib.GSUTIL_DIR).st_uid == user_id:
            return

        # Won't fail - this command runs after main startup code that insists on
        # having a config file.
        config_file_list = GetBotoConfigFileList()
        config_files = ' '.join(config_file_list)
        self._CleanUpUpdateCommand(tf, dirs_to_remove)

        # Pick current protection of each boto config file for command that restores
        # protection (rather than fixing at 600) to support use cases like how GCE
        # installs a service account with an /etc/boto.cfg file protected to 644.
        chmod_cmds = []
        for config_file in config_file_list:
            mode = oct(stat.S_IMODE((os.stat(config_file)[stat.ST_MODE])))
            chmod_cmds.append('\n\tsudo chmod %s %s' % (mode, config_file))

        raise CommandException('\n'.join(
            textwrap.wrap(
                'Since it was installed by a different user previously, you will need '
                'to update using the following commands. You will be prompted for your '
                'password, and the install will run as "root". If you\'re unsure what '
                'this means please ask your system administrator for help:')
        ) + ('\n\tsudo chmod 0644 %s\n\tsudo env BOTO_CONFIG="%s" %s update'
             '%s') % (config_files, config_files, self.gsutil_path,
                      ' '.join(chmod_cmds)),
                               informational=True)
Example #2
0
def CheckAndGetCredentials(logger):
  """Returns credentials from the configuration file, if any are present.

  Args:
    logger: logging.Logger instance for outputting messages.

  Returns:
    OAuth2Credentials object if any valid ones are found, otherwise None.
  """
  configured_cred_types = []
  try:
    if _HasOauth2UserAccountCreds():
      configured_cred_types.append(CredTypes.OAUTH2_USER_ACCOUNT)
    if _HasOauth2ServiceAccountCreds():
      configured_cred_types.append(CredTypes.OAUTH2_SERVICE_ACCOUNT)
    if len(configured_cred_types) > 1:
      # We only allow one set of configured credentials. Otherwise, we're
      # choosing one arbitrarily, which can be very confusing to the user
      # (e.g., if only one is authorized to perform some action) and can
      # also mask errors.
      # Because boto merges config files, GCE credentials show up by default
      # for GCE VMs. We don't want to fail when a user creates a boto file
      # with their own credentials, so in this case we'll use the OAuth2
      # user credentials.
      failed_cred_type = None
      raise CommandException(
          ('You have multiple types of configured credentials (%s), which is '
           'not supported. One common way this happens is if you run gsutil '
           'config to create credentials and later run gcloud auth, and '
           'create a second set of credentials. Your boto config path is: '
           '%s. For more help, see "gsutil help creds".')
          % (configured_cred_types, GetBotoConfigFileList()))

    failed_cred_type = CredTypes.OAUTH2_USER_ACCOUNT
    user_creds = _GetOauth2UserAccountCredentials()
    failed_cred_type = CredTypes.OAUTH2_SERVICE_ACCOUNT
    service_account_creds = _GetOauth2ServiceAccountCredentials()
    failed_cred_type = CredTypes.GCE
    gce_creds = _GetGceCreds()
    failed_cred_type = CredTypes.DEVSHELL
    devshell_creds = _GetDevshellCreds()
    return user_creds or service_account_creds or gce_creds or devshell_creds
  except:  # pylint: disable=bare-except
    # If we didn't actually try to authenticate because there were multiple
    # types of configured credentials, don't emit this warning.
    if failed_cred_type:
      if logger.isEnabledFor(logging.DEBUG):
        logger.debug(traceback.format_exc())
      if os.environ.get('CLOUDSDK_WRAPPER') == '1':
        logger.warn(
            'Your "%s" credentials are invalid. Please run\n'
            '  $ gcloud auth login', failed_cred_type)
      else:
        logger.warn(
            'Your "%s" credentials are invalid. For more help, see '
            '"gsutil help creds", or re-run the gsutil config command (see '
            '"gsutil help config").', failed_cred_type)

    # If there's any set of configured credentials, we'll fail if they're
    # invalid, rather than silently falling back to anonymous config (as
    # boto does). That approach leads to much confusion if users don't
    # realize their credentials are invalid.
    raise
Example #3
0
def main():
  InitializeSignalHandling()
  # Any modules used in initializing multiprocessing variables must be
  # imported after importing gslib.__main__.
  # pylint: disable=redefined-outer-name,g-import-not-at-top
  import gslib.boto_translation
  import gslib.command
  import gslib.util
  from gslib.util import BOTO_IS_SECURE
  from gslib.util import CERTIFICATE_VALIDATION_ENABLED
  # pylint: disable=unused-variable
  from gcs_oauth2_boto_plugin import oauth2_client
  from apitools.base.py import credentials_lib
  # pylint: enable=unused-variable
  from gslib.util import CheckMultiprocessingAvailableAndInit
  if CheckMultiprocessingAvailableAndInit().is_available:
    # These setup methods must be called, and, on Windows, they can only be
    # called from within an "if __name__ == '__main__':" block.
    gslib.command.InitializeMultiprocessingVariables()
    gslib.boto_translation.InitializeMultiprocessingVariables()
  else:
    gslib.command.InitializeThreadingVariables()

  # This needs to be done after gslib.util.InitializeMultiprocessingVariables(),
  # since otherwise we can't call gslib.util.CreateLock.
  try:
    # pylint: disable=unused-import,g-import-not-at-top
    import gcs_oauth2_boto_plugin
    gsutil_client_id, gsutil_client_secret = GetGsutilClientIdAndSecret()
    gcs_oauth2_boto_plugin.oauth2_helper.SetFallbackClientIdAndSecret(
        gsutil_client_id, gsutil_client_secret)
    gcs_oauth2_boto_plugin.oauth2_helper.SetLock(CreateLock())
    credentials_lib.SetCredentialsCacheFileLock(CreateLock())
  except ImportError:
    pass

  global debug
  global test_exception_traces

  if not (2, 7) <= sys.version_info[:3] < (3,):
    raise CommandException('gsutil requires python 2.7.')

  # In gsutil 4.0 and beyond, we don't use the boto library for the JSON
  # API. However, we still store gsutil configuration data in the .boto
  # config file for compatibility with previous versions and user convenience.
  # Many users have a .boto configuration file from previous versions, and it
  # is useful to have all of the configuration for gsutil stored in one place.
  command_runner = CommandRunner()
  if not BOTO_IS_SECURE:
    raise CommandException('\n'.join(textwrap.wrap(
        'Your boto configuration has is_secure = False. Gsutil cannot be '
        'run this way, for security reasons.')))

  headers = {}
  parallel_operations = False
  quiet = False
  version = False
  debug = 0
  trace_token = None
  perf_trace_token = None
  test_exception_traces = False

  # If user enters no commands just print the usage info.
  if len(sys.argv) == 1:
    sys.argv.append('help')

  # Change the default of the 'https_validate_certificates' boto option to
  # True (it is currently False in boto).
  if not boto.config.has_option('Boto', 'https_validate_certificates'):
    if not boto.config.has_section('Boto'):
      boto.config.add_section('Boto')
    boto.config.setbool('Boto', 'https_validate_certificates', True)

  gslib.util.configured_certs_file = gslib.util.ConfigureCertsFile()
  for signal_num in GetCaughtSignals():
    RegisterSignalHandler(signal_num, _CleanupSignalHandler)
  GetCertsFile()

  try:
    try:
      opts, args = getopt.getopt(sys.argv[1:], 'dDvo:h:mq',
                                 ['debug', 'detailedDebug', 'version', 'option',
                                  'help', 'header', 'multithreaded', 'quiet',
                                  'testexceptiontraces', 'trace-token=',
                                  'perf-trace-token='])
    except getopt.GetoptError as e:
      _HandleCommandException(CommandException(e.msg))
    for o, a in opts:
      if o in ('-d', '--debug'):
        # Also causes boto to include httplib header output.
        debug = DEBUGLEVEL_DUMP_REQUESTS
      elif o in ('-D', '--detailedDebug'):
        # We use debug level 3 to ask gsutil code to output more detailed
        # debug output. This is a bit of a hack since it overloads the same
        # flag that was originally implemented for boto use. And we use -DD
        # to ask for really detailed debugging (i.e., including HTTP payload).
        if debug == DEBUGLEVEL_DUMP_REQUESTS:
          debug = DEBUGLEVEL_DUMP_REQUESTS_AND_PAYLOADS
        else:
          debug = DEBUGLEVEL_DUMP_REQUESTS
      elif o in ('-?', '--help'):
        _OutputUsageAndExit(command_runner)
      elif o in ('-h', '--header'):
        (hdr_name, _, hdr_val) = a.partition(':')
        if not hdr_name:
          _OutputUsageAndExit(command_runner)
        headers[hdr_name.lower()] = hdr_val
      elif o in ('-m', '--multithreaded'):
        parallel_operations = True
      elif o in ('-q', '--quiet'):
        quiet = True
      elif o in ('-v', '--version'):
        version = True
      elif o == '--perf-trace-token':
        perf_trace_token = a
      elif o == '--trace-token':
        trace_token = a
      elif o == '--testexceptiontraces':  # Hidden flag for integration tests.
        test_exception_traces = True
        # Avoid printing extra warnings to stderr regarding long retries by
        # setting the threshold very high.
        gslib.util.LONG_RETRY_WARN_SEC = 3600
      elif o in ('-o', '--option'):
        (opt_section_name, _, opt_value) = a.partition('=')
        if not opt_section_name:
          _OutputUsageAndExit(command_runner)
        (opt_section, _, opt_name) = opt_section_name.partition(':')
        if not opt_section or not opt_name:
          _OutputUsageAndExit(command_runner)
        if not boto.config.has_section(opt_section):
          boto.config.add_section(opt_section)
        boto.config.set(opt_section, opt_name, opt_value)
    metrics.LogCommandParams(global_opts=opts)
    httplib2.debuglevel = debug
    if trace_token:
      sys.stderr.write(TRACE_WARNING)
    if debug >= DEBUGLEVEL_DUMP_REQUESTS:
      sys.stderr.write(DEBUG_WARNING)
      _ConfigureLogging(level=logging.DEBUG)
      command_runner.RunNamedCommand('ver', ['-l'])
      config_items = []
      try:
        config_items.extend(boto.config.items('Boto'))
        config_items.extend(boto.config.items('GSUtil'))
      except ConfigParser.NoSectionError:
        pass
      for i in xrange(len(config_items)):
        config_item_key = config_items[i][0]
        if config_item_key in CONFIG_KEYS_TO_REDACT:
          config_items[i] = (config_item_key, 'REDACTED')
      sys.stderr.write('Command being run: %s\n' % ' '.join(sys.argv))
      sys.stderr.write('config_file_list: %s\n' % GetBotoConfigFileList())
      sys.stderr.write('config: %s\n' % str(config_items))
    elif quiet:
      _ConfigureLogging(level=logging.WARNING)
    else:
      _ConfigureLogging(level=logging.INFO)
      # oauth2client uses info logging in places that would better
      # correspond to gsutil's debug logging (e.g., when refreshing
      # access tokens).
      oauth2client.client.logger.setLevel(logging.WARNING)

    if not CERTIFICATE_VALIDATION_ENABLED:
      sys.stderr.write(HTTP_WARNING)

    if version:
      command_name = 'version'
    elif not args:
      command_name = 'help'
    else:
      command_name = args[0]

    _CheckAndWarnForProxyDifferences()

    if os.environ.get('_ARGCOMPLETE', '0') == '1':
      return _PerformTabCompletion(command_runner)

    return _RunNamedCommandAndHandleExceptions(
        command_runner, command_name, args=args[1:], headers=headers,
        debug_level=debug, trace_token=trace_token,
        parallel_operations=parallel_operations,
        perf_trace_token=perf_trace_token)
  finally:
    _Cleanup()
Example #4
0
def main():
    # These modules must be imported after importing gslib.__main__.
    import gslib.command
    import gslib.util
    from gslib.third_party.oauth2_plugin import oauth2_client
    from gslib.util import MultiprocessingIsAvailable
    if MultiprocessingIsAvailable()[0]:
        # These setup methods must be called, and, on Windows, they can only be
        # called from within an "if __name__ == '__main__':" block.
        gslib.util.InitializeMultiprocessingVariables()
        gslib.command.InitializeMultiprocessingVariables()
    oauth2_client.InitializeMultiprocessingVariables()

    global debug

    if not (2, 6) <= sys.version_info[:3] < (3, ):
        raise gslib.exception.CommandException(
            'gsutil requires python 2.6 or 2.7.')

    config_file_list = GetBotoConfigFileList()
    command_runner = CommandRunner(config_file_list)
    headers = {}
    parallel_operations = False
    quiet = False
    version = False
    debug = 0

    # If user enters no commands just print the usage info.
    if len(sys.argv) == 1:
        sys.argv.append('help')

    # Change the default of the 'https_validate_certificates' boto option to
    # True (it is currently False in boto).
    if not boto.config.has_option('Boto', 'https_validate_certificates'):
        if not boto.config.has_section('Boto'):
            boto.config.add_section('Boto')
        boto.config.setbool('Boto', 'https_validate_certificates', True)

    # If ca_certificates_file is configured use it; otherwise configure boto to
    # use the cert roots distributed with gsutil.
    if not boto.config.get_value('Boto', 'ca_certificates_file', None):
        disk_certs_file = os.path.abspath(
            os.path.join(gslib.GSLIB_DIR, 'data', 'cacerts.txt'))
        if not os.path.exists(disk_certs_file):
            # If the file is not present on disk, this means the gslib module doesn't
            # actually exist on disk anywhere. This can happen if it's being imported
            # from a zip file. Unfortunately, we have to copy the certs file to a
            # local temp file on disk because the underlying SSL socket requires it
            # to be a filesystem path.
            certs_data = pkgutil.get_data('gslib', 'data/cacerts.txt')
            if not certs_data:
                raise gslib.exception.CommandException(
                    'Certificates file not found. Please reinstall gsutil from scratch'
                )
            fd, fname = tempfile.mkstemp(suffix='.txt',
                                         prefix='gsutil-cacerts')
            f = os.fdopen(fd, 'w')
            f.write(certs_data)
            f.close()
            disk_certs_file = fname
            cleanup_files.append(disk_certs_file)
        boto.config.set('Boto', 'ca_certificates_file', disk_certs_file)

    try:
        try:
            opts, args = getopt.getopt(sys.argv[1:], 'dDvo:h:mq', [
                'debug', 'detailedDebug', 'version', 'option', 'help',
                'header', 'multithreaded', 'quiet'
            ])
        except getopt.GetoptError as e:
            _HandleCommandException(gslib.exception.CommandException(e.msg))
        for o, a in opts:
            if o in ('-d', '--debug'):
                # Passing debug=2 causes boto to include httplib header output.
                debug = 2
            elif o in ('-D', '--detailedDebug'):
                # We use debug level 3 to ask gsutil code to output more detailed
                # debug output. This is a bit of a hack since it overloads the same
                # flag that was originally implemented for boto use. And we use -DD
                # to ask for really detailed debugging (i.e., including HTTP payload).
                if debug == 3:
                    debug = 4
                else:
                    debug = 3
            elif o in ('-?', '--help'):
                _OutputUsageAndExit(command_runner)
            elif o in ('-h', '--header'):
                (hdr_name, _, hdr_val) = a.partition(':')
                if not hdr_name:
                    _OutputUsageAndExit(command_runner)
                headers[hdr_name.lower()] = hdr_val
            elif o in ('-m', '--multithreaded'):
                parallel_operations = True
            elif o in ('-q', '--quiet'):
                quiet = True
            elif o in ('-v', '--version'):
                version = True
            elif o in ('-o', '--option'):
                (opt_section_name, _, opt_value) = a.partition('=')
                if not opt_section_name:
                    _OutputUsageAndExit(command_runner)
                (opt_section, _, opt_name) = opt_section_name.partition(':')
                if not opt_section or not opt_name:
                    _OutputUsageAndExit(command_runner)
                if not boto.config.has_section(opt_section):
                    boto.config.add_section(opt_section)
                boto.config.set(opt_section, opt_name, opt_value)
        httplib2.debuglevel = debug
        if debug > 1:
            sys.stderr.write(DEBUG_WARNING)
        if debug == 2:
            _ConfigureLogging(level=logging.DEBUG)
        elif debug > 2:
            _ConfigureLogging(level=logging.DEBUG)
            command_runner.RunNamedCommand('ver', ['-l'])
            config_items = []
            try:
                config_items.extend(boto.config.items('Boto'))
                config_items.extend(boto.config.items('GSUtil'))
            except ConfigParser.NoSectionError:
                pass
            sys.stderr.write('config_file_list: %s\n' % config_file_list)
            sys.stderr.write('config: %s\n' % str(config_items))
        elif quiet:
            _ConfigureLogging(level=logging.WARNING)
        else:
            _ConfigureLogging(level=logging.INFO)
            # apiclient and oauth2client use info logging in places that would better
            # correspond to gsutil's debug logging (e.g., when refreshing access
            # tokens).
            oauth2client.client.logger.setLevel(logging.WARNING)
            apiclient.discovery.logger.setLevel(logging.WARNING)

        if version:
            command_name = 'version'
        elif not args:
            command_name = 'help'
        else:
            command_name = args[0]

        # Unset http_proxy environment variable if it's set, because it confuses
        # boto. (Proxies should instead be configured via the boto config file.)
        if 'http_proxy' in os.environ:
            if debug > 1:
                sys.stderr.write(
                    'Unsetting http_proxy environment variable within gsutil run.\n'
                )
            del os.environ['http_proxy']

        return _RunNamedCommandAndHandleExceptions(command_runner,
                                                   command_name, args[1:],
                                                   headers, debug,
                                                   parallel_operations)
    finally:
        _Cleanup()
Example #5
0
def main():
  # Any modules used in initializing multiprocessing variables must be
  # imported after importing gslib.__main__.
  # pylint: disable=redefined-outer-name,g-import-not-at-top
  import gslib.boto_translation
  import gslib.command
  import gslib.util
  from gslib.util import BOTO_IS_SECURE
  from gslib.util import CERTIFICATE_VALIDATION_ENABLED
  from gcs_oauth2_boto_plugin import oauth2_client
  from gslib.util import MultiprocessingIsAvailable
  if MultiprocessingIsAvailable()[0]:
    # These setup methods must be called, and, on Windows, they can only be
    # called from within an "if __name__ == '__main__':" block.
    gslib.util.InitializeMultiprocessingVariables()
    gslib.command.InitializeMultiprocessingVariables()
    gslib.boto_translation.InitializeMultiprocessingVariables()

  # This needs to be done after gslib.util.InitializeMultiprocessingVariables(),
  # since otherwise we can't call gslib.util.CreateLock.
  try:
    # pylint: disable=unused-import,g-import-not-at-top
    import gcs_oauth2_boto_plugin
    gcs_oauth2_boto_plugin.oauth2_helper.SetFallbackClientIdAndSecret(
        GSUTIL_CLIENT_ID, GSUTIL_CLIENT_NOTSOSECRET)
    gcs_oauth2_boto_plugin.oauth2_helper.SetLock(CreateLock())
  except ImportError:
    pass

  global debug
  global test_exception_traces

  if not (2, 6) <= sys.version_info[:3] < (3,):
    raise gslib.exception.CommandException(
        'gsutil requires python 2.6 or 2.7.')

  # In gsutil 4.0 and beyond, we don't use the boto library for the JSON
  # API. However, we still store gsutil configuration data in the .boto
  # config file for compatibility with previous versions and user convenience.
  # Many users have a .boto configuration file from previous versions, and it
  # is useful to have all of the configuration for gsutil stored in one place.
  command_runner = CommandRunner()
  if not BOTO_IS_SECURE:
    raise CommandException('\n'.join(textwrap.wrap(
        'Your boto configuration has is_secure = False. Gsutil cannot be '
        'run this way, for security reasons.')))

  headers = {}
  parallel_operations = False
  quiet = False
  version = False
  debug = 0
  test_exception_traces = False

  # If user enters no commands just print the usage info.
  if len(sys.argv) == 1:
    sys.argv.append('help')

  # Change the default of the 'https_validate_certificates' boto option to
  # True (it is currently False in boto).
  if not boto.config.has_option('Boto', 'https_validate_certificates'):
    if not boto.config.has_section('Boto'):
      boto.config.add_section('Boto')
    boto.config.setbool('Boto', 'https_validate_certificates', True)

  GetCertsFile()

  try:
    try:
      opts, args = getopt.getopt(sys.argv[1:], 'dDvo:h:mq',
                                 ['debug', 'detailedDebug', 'version', 'option',
                                  'help', 'header', 'multithreaded', 'quiet',
                                  'testexceptiontraces'])
    except getopt.GetoptError as e:
      _HandleCommandException(gslib.exception.CommandException(e.msg))
    for o, a in opts:
      if o in ('-d', '--debug'):
        # Passing debug=2 causes boto to include httplib header output.
        debug = 3
      elif o in ('-D', '--detailedDebug'):
        # We use debug level 3 to ask gsutil code to output more detailed
        # debug output. This is a bit of a hack since it overloads the same
        # flag that was originally implemented for boto use. And we use -DD
        # to ask for really detailed debugging (i.e., including HTTP payload).
        if debug == 3:
          debug = 4
        else:
          debug = 3
      elif o in ('-?', '--help'):
        _OutputUsageAndExit(command_runner)
      elif o in ('-h', '--header'):
        (hdr_name, _, hdr_val) = a.partition(':')
        if not hdr_name:
          _OutputUsageAndExit(command_runner)
        headers[hdr_name.lower()] = hdr_val
      elif o in ('-m', '--multithreaded'):
        parallel_operations = True
      elif o in ('-q', '--quiet'):
        quiet = True
      elif o in ('-v', '--version'):
        version = True
      elif o == '--testexceptiontraces':  # Hidden flag for integration tests.
        test_exception_traces = True
      elif o in ('-o', '--option'):
        (opt_section_name, _, opt_value) = a.partition('=')
        if not opt_section_name:
          _OutputUsageAndExit(command_runner)
        (opt_section, _, opt_name) = opt_section_name.partition(':')
        if not opt_section or not opt_name:
          _OutputUsageAndExit(command_runner)
        if not boto.config.has_section(opt_section):
          boto.config.add_section(opt_section)
        boto.config.set(opt_section, opt_name, opt_value)
    httplib2.debuglevel = debug
    if debug > 1:
      sys.stderr.write(DEBUG_WARNING)
    if debug >= 2:
      _ConfigureLogging(level=logging.DEBUG)
      command_runner.RunNamedCommand('ver', ['-l'])
      config_items = []
      try:
        config_items.extend(boto.config.items('Boto'))
        config_items.extend(boto.config.items('GSUtil'))
      except ConfigParser.NoSectionError:
        pass
      for i in xrange(len(config_items)):
        config_item_key = config_items[i][0]
        if config_item_key in CONFIG_KEYS_TO_REDACT:
          config_items[i] = (config_item_key, 'REDACTED')
      sys.stderr.write('Command being run: %s\n' % ' '.join(sys.argv))
      sys.stderr.write('config_file_list: %s\n' % GetBotoConfigFileList())
      sys.stderr.write('config: %s\n' % str(config_items))
    elif quiet:
      _ConfigureLogging(level=logging.WARNING)
    else:
      _ConfigureLogging(level=logging.INFO)
      # oauth2client uses info logging in places that would better
      # correspond to gsutil's debug logging (e.g., when refreshing
      # access tokens).
      oauth2client.client.logger.setLevel(logging.WARNING)

    if not CERTIFICATE_VALIDATION_ENABLED:
      sys.stderr.write(HTTP_WARNING)

    if version:
      command_name = 'version'
    elif not args:
      command_name = 'help'
    else:
      command_name = args[0]

    # Unset http_proxy environment variable if it's set, because it confuses
    # boto. (Proxies should instead be configured via the boto config file.)
    if 'http_proxy' in os.environ:
      if debug > 1:
        sys.stderr.write(
            'Unsetting http_proxy environment variable within gsutil run.\n')
      del os.environ['http_proxy']

    if os.environ.get('_ARGCOMPLETE', '0') == '1':
      return _PerformTabCompletion(command_runner)

    return _RunNamedCommandAndHandleExceptions(
        command_runner, command_name, args=args[1:], headers=headers,
        debug_level=debug, parallel_operations=parallel_operations)
  finally:
    _Cleanup()
Example #6
0
def main():
  global debug

  if not (2, 6) <= sys.version_info[:3] < (3,):
    raise gslib.exception.CommandException(
        'gsutil requires python 2.6 or 2.7.')

  # Load the gsutil version number and append it to boto.UserAgent so the value
  # is set before anything instantiates boto. (If parts of boto were
  # instantiated first those parts would have the old value of boto.UserAgent,
  # so we wouldn't be guaranteed that all code paths send the correct user
  # agent.)
  boto.UserAgent += ' gsutil/%s (%s)' % (gslib.VERSION, sys.platform)

  config_file_list = GetBotoConfigFileList()
  command_runner = CommandRunner(config_file_list)
  headers = {}
  parallel_operations = False
  quiet = False
  version = False
  debug = 0

  # If user enters no commands just print the usage info.
  if len(sys.argv) == 1:
    sys.argv.append('help')

  # Change the default of the 'https_validate_certificates' boto option to
  # True (it is currently False in boto).
  if not boto.config.has_option('Boto', 'https_validate_certificates'):
    if not boto.config.has_section('Boto'):
      boto.config.add_section('Boto')
    boto.config.setbool('Boto', 'https_validate_certificates', True)

  # If ca_certificates_file is configured use it; otherwise configure boto to
  # use the cert roots distributed with gsutil.
  if not boto.config.get_value('Boto', 'ca_certificates_file', None):
    boto.config.set('Boto', 'ca_certificates_file', DEFAULT_CA_CERTS_FILE)

  try:
    opts, args = getopt.getopt(sys.argv[1:], 'dDvh:mq',
                               ['debug', 'detailedDebug', 'version', 'help',
                                'header', 'multithreaded', 'quiet'])
  except getopt.GetoptError as e:
    _HandleCommandException(gslib.exception.CommandException(e.msg))
  for o, a in opts:
    if o in ('-d', '--debug'):
      # Passing debug=2 causes boto to include httplib header output.
      debug = 2
    elif o in ('-D', '--detailedDebug'):
      # We use debug level 3 to ask gsutil code to output more detailed
      # debug output. This is a bit of a hack since it overloads the same
      # flag that was originally implemented for boto use. And we use -DD
      # to ask for really detailed debugging (i.e., including HTTP payload).
      if debug == 3:
        debug = 4
      else:
        debug = 3
    elif o in ('-?', '--help'):
      _OutputUsageAndExit(command_runner)
    elif o in ('-h', '--header'):
      (hdr_name, unused_ptn, hdr_val) = a.partition(':')
      if not hdr_name:
        _OutputUsageAndExit(command_runner)
      headers[hdr_name.lower()] = hdr_val
    elif o in ('-m', '--multithreaded'):
      parallel_operations = True
    elif o in ('-q', '--quiet'):
      quiet = True
    elif o in ('-v', '--version'):
      version = True
  httplib2.debuglevel = debug
  if debug > 1:
    sys.stderr.write(
        '***************************** WARNING *****************************\n'
        '*** You are running gsutil with debug output enabled.\n'
        '*** Be aware that debug output includes authentication '
        'credentials.\n'
        '*** Do not share (e.g., post to support forums) debug output\n'
        '*** unless you have sanitized authentication tokens in the\n'
        '*** output, or have revoked your credentials.\n'
        '***************************** WARNING *****************************\n')
  if debug == 2:
    logging.basicConfig(level=logging.DEBUG)
  elif debug > 2:
    logging.basicConfig(level=logging.DEBUG)
    command_runner.RunNamedCommand('ver', ['-l'])
    config_items = []
    try:
      config_items.extend(boto.config.items('Boto'))
      config_items.extend(boto.config.items('GSUtil'))
    except ConfigParser.NoSectionError:
      pass
    sys.stderr.write('config_file_list: %s\n' % config_file_list)
    sys.stderr.write('config: %s\n' % str(config_items))
  elif quiet:
    logging.basicConfig(level=logging.WARNING)
  else:
    logging.basicConfig(level=logging.INFO)
    # apiclient and oauth2client use info logging in places that would better
    # correspond to gsutil's debug logging (e.g., when refreshing access
    # tokens).
    oauth2client.client.logger.setLevel(logging.WARNING)
    apiclient.discovery.logger.setLevel(logging.WARNING)

  if version:
    command_name = 'version'
  elif not args:
    command_name = 'help'
  else:
    command_name = args[0]

  # Unset http_proxy environment variable if it's set, because it confuses
  # boto. (Proxies should instead be configured via the boto config file.)
  if 'http_proxy' in os.environ:
    if debug > 1:
      sys.stderr.write(
          'Unsetting http_proxy environment variable within gsutil run.\n')
    del os.environ['http_proxy']

  return _RunNamedCommandAndHandleExceptions(command_runner, command_name,
                                             args[1:], headers, debug,
                                             parallel_operations)