Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2053)

Unified Diff: gslib/__main__.py

Issue 698893003: Update checked in version of gsutil to version 4.6 (Closed) Base URL: http://dart.googlecode.com/svn/third_party/gsutil/
Patch Set: Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « gslib/__init__.py ('k') | gslib/aclhelpers.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: gslib/__main__.py
===================================================================
--- gslib/__main__.py (revision 33376)
+++ gslib/__main__.py (working copy)
@@ -1,5 +1,5 @@
#!/usr/bin/env python
-# coding=utf8
+# -*- coding: utf-8 -*-
# Copyright 2013 Google Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -13,20 +13,20 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
-
"""Main module for Google Cloud Storage command line tool."""
+from __future__ import absolute_import
+
import ConfigParser
+import datetime
import errno
import getopt
import logging
import os
-import pkgutil
import re
import signal
import socket
import sys
-import tempfile
import textwrap
import traceback
@@ -38,29 +38,45 @@
# so boto requests would not include gsutil/version# in the UserAgent string.
import boto
import gslib
+# TODO: gsutil-beta: Cloud SDK scans for this string and performs
+# substitution; ensure this works with both apitools and boto.
boto.UserAgent += ' gsutil/%s (%s)' % (gslib.VERSION, sys.platform)
-import apiclient.discovery
-import boto.exception
-from gslib import util
-from gslib import GSUTIL_DIR
+# pylint: disable=g-bad-import-order
+# pylint: disable=g-import-not-at-top
+import httplib2
+import oauth2client
from gslib import wildcard_iterator
+from gslib.cloud_api import AccessDeniedException
+from gslib.cloud_api import ArgumentException
+from gslib.cloud_api import BadRequestException
+from gslib.cloud_api import ProjectIdException
+from gslib.cloud_api import ServiceException
from gslib.command_runner import CommandRunner
+import gslib.exception
from gslib.exception import CommandException
-from gslib.util import BOTO_IS_SECURE
+import gslib.third_party.storage_apitools.exceptions as apitools_exceptions
+from gslib.util import CreateLock
from gslib.util import GetBotoConfigFileList
-from gslib.util import GetConfigFilePath
-from gslib.util import HasConfiguredCredentials
-from gslib.util import IsRunningInteractively
-import gslib.exception
-import httplib2
-import oauth2client
+from gslib.util import GetCertsFile
+from gslib.util import GetCleanupFiles
+GSUTIL_CLIENT_ID = '909320924072.apps.googleusercontent.com'
+# Google OAuth2 clients always have a secret, even if the client is an installed
+# application/utility such as gsutil. Of course, in such cases the "secret" is
+# actually publicly known; security depends entirely on the secrecy of refresh
+# tokens, which effectively become bearer tokens.
+GSUTIL_CLIENT_NOTSOSECRET = 'p3RlpR10xMFh9ZXBS/ZNLYUu'
+
+CONFIG_KEYS_TO_REDACT = ['proxy', 'proxy_port', 'proxy_user', 'proxy_pass']
+
+
# We don't use the oauth2 authentication plugin directly; importing it here
# ensures that it's loaded and available by default when an operation requiring
# authentication is performed.
try:
- from gslib.third_party.oauth2_plugin import oauth2_plugin
+ # pylint: disable=unused-import,g-import-not-at-top
+ import gcs_oauth2_boto_plugin
except ImportError:
pass
@@ -76,22 +92,19 @@
HTTP_WARNING = """
***************************** WARNING *****************************
-*** You are running gsutil with either the boto config variable "is_secure" set
-*** to False or the "https_validate_certificates" config variable set to False.
-*** These options should always be set to True in production environments, to
-*** protect against intercepted bearer tokens, man-in-the-middle attacks, and
-*** leaking of user data.
+*** You are running gsutil with the "https_validate_certificates" config
+*** variable set to False. This option should always be set to True in
+*** production environments to protect against man-in-the-middle attacks,
+*** and leaking of user data.
***************************** WARNING *****************************
""".lstrip()
debug = 0
+test_exception_traces = False
-# Temp files to delete, if possible, when program exits.
-cleanup_files = []
-
def _Cleanup():
- for fname in cleanup_files:
+ for fname in GetCleanupFiles():
try:
os.remove(fname)
except OSError:
@@ -99,13 +112,19 @@
def _OutputAndExit(message):
- if debug == 4:
+ """Outputs message and exists with code 1."""
+ from gslib.util import UTF8 # pylint: disable=g-import-not-at-top
+ if debug >= 2 or test_exception_traces:
stack_trace = traceback.format_exc()
err = ('DEBUG: Exception stack trace:\n %s\n' %
re.sub('\\n', '\n ', stack_trace))
else:
err = '%s\n' % message
- sys.stderr.write(err.encode('utf-8'))
+ try:
+ sys.stderr.write(err.encode(UTF8))
+ except UnicodeDecodeError:
+ # Can happen when outputting invalid Unicode filenames.
+ sys.stderr.write(err)
sys.exit(1)
@@ -114,40 +133,82 @@
sys.exit(1)
+class GsutilFormatter(logging.Formatter):
+ """A logging.Formatter that supports logging microseconds (%f)."""
+
+ def formatTime(self, record, datefmt=None):
+ if datefmt:
+ return datetime.datetime.fromtimestamp(record.created).strftime(datefmt)
+
+ # Use default implementation if datefmt is not specified.
+ return super(GsutilFormatter, self).formatTime(record, datefmt=datefmt)
+
+
def _ConfigureLogging(level=logging.INFO):
"""Similar to logging.basicConfig() except it always adds a handler."""
+ log_format = '%(levelname)s %(asctime)s %(filename)s] %(message)s'
+ date_format = '%m%d %H:%M:%S.%f'
+ formatter = GsutilFormatter(fmt=log_format, datefmt=date_format)
handler = logging.StreamHandler()
+ handler.setFormatter(formatter)
root_logger = logging.getLogger()
root_logger.addHandler(handler)
root_logger.setLevel(level)
def main():
- # These modules must be imported after importing gslib.__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.third_party.oauth2_plugin import oauth2_client
+ 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()
- oauth2_client.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.')
- config_file_list = GetBotoConfigFileList()
- command_runner = CommandRunner(config_file_list)
+ # 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:
@@ -160,40 +221,20 @@
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)
+ GetCertsFile()
try:
try:
opts, args = getopt.getopt(sys.argv[1:], 'dDvo:h:mq',
['debug', 'detailedDebug', 'version', 'option',
- 'help', 'header', 'multithreaded', 'quiet'])
+ '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 = 2
+ 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
@@ -216,6 +257,8 @@
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:
@@ -229,10 +272,8 @@
httplib2.debuglevel = debug
if debug > 1:
sys.stderr.write(DEBUG_WARNING)
- if debug == 2:
+ if debug >= 2:
_ConfigureLogging(level=logging.DEBUG)
- elif debug > 2:
- _ConfigureLogging(level=logging.DEBUG)
command_runner.RunNamedCommand('ver', ['-l'])
config_items = []
try:
@@ -240,7 +281,12 @@
config_items.extend(boto.config.items('GSUtil'))
except ConfigParser.NoSectionError:
pass
- sys.stderr.write('config_file_list: %s\n' % config_file_list)
+ 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)
@@ -250,10 +296,8 @@
# correspond to gsutil's debug logging (e.g., when refreshing access
# tokens).
oauth2client.client.logger.setLevel(logging.WARNING)
- apiclient.discovery.logger.setLevel(logging.WARNING)
- is_secure = BOTO_IS_SECURE
- if not is_secure[0]:
+ if not CERTIFICATE_VALIDATION_ENABLED:
sys.stderr.write(HTTP_WARNING)
if version:
@@ -272,8 +316,8 @@
del os.environ['http_proxy']
return _RunNamedCommandAndHandleExceptions(
- command_runner, command_name, args[1:], headers, debug,
- parallel_operations)
+ command_runner, command_name, args=args[1:], headers=headers,
+ debug_level=debug, parallel_operations=parallel_operations)
finally:
_Cleanup()
@@ -281,7 +325,7 @@
def _HandleUnknownFailure(e):
# Called if we fall through all known/handled exceptions. Allows us to
# print a stacktrace if -D option used.
- if debug > 2:
+ if debug >= 2:
stack_trace = traceback.format_exc()
sys.stderr.write('DEBUG: Exception stack trace:\n %s\n' %
re.sub('\\n', '\n ', stack_trace))
@@ -296,10 +340,18 @@
_OutputAndExit('CommandException: %s' % e.reason)
+# pylint: disable=unused-argument
def _HandleControlC(signal_num, cur_stack_frame):
- """Called when user hits ^C so we can print a brief message instead of
- the normal Python stack trace (unless -D option is used)."""
- if debug > 2:
+ """Called when user hits ^C.
+
+ This function prints a brief message instead of the normal Python stack trace
+ (unless -D option is used).
+
+ Args:
+ signal_num: Signal that was caught.
+ cur_stack_frame: Unused.
+ """
+ if debug >= 2:
stack_trace = ''.join(traceback.format_list(traceback.extract_stack()))
_OutputAndExit(
'DEBUG: Caught signal %d - Exception stack trace:\n'
@@ -310,86 +362,112 @@
def _HandleSigQuit(signal_num, cur_stack_frame):
"""Called when user hits ^\\, so we can force breakpoint a running gsutil."""
- import pdb
+ import pdb # pylint: disable=g-import-not-at-top
pdb.set_trace()
-def _ConstructAclHelp(default_project_id):
- acct_help_part_1 = (
-"""Your request resulted in an AccountProblem (403) error. Usually this happens
-if you attempt to create a bucket or upload an object without having first
-enabled billing for the project you are using. To remedy this problem, please do
-the following:
-1. Navigate to the https://cloud.google.com/console#/project, click on the
- project you will use, and then copy the Project Number listed under that
- project.
+def _ConstructAccountProblemHelp(reason):
+ """Constructs a help string for an access control error.
-""")
- acct_help_part_2 = '\n'
+ Args:
+ reason: e.reason string from caught exception.
+
+ Returns:
+ Contructed help text.
+ """
+ default_project_id = boto.config.get_value('GSUtil', 'default_project_id')
+ # pylint: disable=line-too-long, g-inconsistent-quotes
+ acct_help = (
+ "Your request resulted in an AccountProblem (403) error. Usually this "
+ "happens if you attempt to create a bucket without first having "
+ "enabled billing for the project you are using. Please ensure billing is "
+ "enabled for your project by following the instructions at "
+ "`Google Developers Console<https://developers.google.com/console/help/billing>`. ")
if default_project_id:
- acct_help_part_2 = (
-"""2. Click "Google Cloud Storage" on the left hand pane, and then check that
-the value listed for "x-goog-project-id" on this page matches the project ID
-(%s) from your boto config file.
+ acct_help += (
+ "In the project overview, ensure that the Project Number listed for "
+ "your project matches the project ID (%s) from your boto config file. "
+ % default_project_id)
+ acct_help += (
+ "If the above doesn't resolve your AccountProblem, please send mail to "
+ "gs-team@google.com requesting assistance, noting the exact command you "
+ "ran, the fact that you received a 403 AccountProblem error, and your "
+ "project ID. Please do not post your project ID on StackOverflow. "
+ "Note: It's possible to use Google Cloud Storage without enabling "
+ "billing if you're only listing or reading objects for which you're "
+ "authorized, or if you're uploading objects to a bucket billed to a "
+ "project that has billing enabled. But if you're attempting to create "
+ "buckets or upload objects to a bucket owned by your own project, you "
+ "must first enable billing for that project.")
+ return acct_help
-""" % default_project_id)
- acct_help_part_3 = (
-"""Check whether there's an "!" next to Billing. If so, click Billing and then
-enable billing for this project. Note that it can take up to one hour after
-enabling billing for the project to become activated for creating buckets and
-uploading objects.
-If the above doesn't resolve your AccountProblem, please send mail to
-gs-team@google.com requesting assistance, noting the exact command you ran, the
-fact that you received a 403 AccountProblem error, and your project ID. Please
-do not post your project ID on StackOverflow.
+def _CheckAndHandleCredentialException(e, args):
+ # Provide detail to users who have no boto config file (who might previously
+ # have been using gsutil only for accessing publicly readable buckets and
+ # objects).
+ # pylint: disable=g-import-not-at-top
+ from gslib.util import HasConfiguredCredentials
+ if (not HasConfiguredCredentials() and
+ not boto.config.get_value('Tests', 'bypass_anonymous_access_warning',
+ False)):
+ # The check above allows tests to assert that we get a particular,
+ # expected failure, rather than always encountering this error message
+ # when there are no configured credentials. This allows tests to
+ # simulate a second user without permissions, without actually requiring
+ # two separate configured users.
+ _OutputAndExit('\n'.join(textwrap.wrap(
+ 'You are attempting to access protected data with no configured '
+ 'credentials. Please visit '
+ 'https://cloud.google.com/console#/project and sign up for an '
+ 'account, and then run the "gsutil config" command to configure '
+ 'gsutil to use these credentials.')))
+ elif (e.reason and
+ (e.reason == 'AccountProblem' or e.reason == 'Account disabled.' or
+ 'account for the specified project has been disabled' in e.reason)
+ and ','.join(args).find('gs://') != -1):
+ _OutputAndExit('\n'.join(textwrap.wrap(
+ _ConstructAccountProblemHelp(e.reason))))
-Note: It's possible to use Google Cloud Storage without enabling billing if
-you're only listing or reading objects for which you're authorized, or if
-you're uploading objects to a bucket billed to a project that has billing
-enabled. But if you're attempting to create buckets or upload objects to a
-bucket owned by your own project, you must first enable billing for that
-project.""")
- return (acct_help_part_1, acct_help_part_2, acct_help_part_3)
def _RunNamedCommandAndHandleExceptions(command_runner, command_name, args=None,
- headers=None, debug=0,
+ headers=None, debug_level=0,
parallel_operations=False):
+ """Runs the command with the given command runner and arguments."""
+ # pylint: disable=g-import-not-at-top
+ from gslib.util import GetConfigFilePath
+ from gslib.util import IS_WINDOWS
+ from gslib.util import IsRunningInteractively
try:
# Catch ^C so we can print a brief message instead of the normal Python
# stack trace.
signal.signal(signal.SIGINT, _HandleControlC)
# Catch ^\ so we can force a breakpoint in a running gsutil.
- if not util.IS_WINDOWS:
+ if not IS_WINDOWS:
signal.signal(signal.SIGQUIT, _HandleSigQuit)
- return command_runner.RunNamedCommand(command_name, args, headers, debug,
- parallel_operations)
+ return command_runner.RunNamedCommand(command_name, args, headers,
+ debug_level, parallel_operations)
except AttributeError as e:
if str(e).find('secret_access_key') != -1:
_OutputAndExit('Missing credentials for the given URI(s). Does your '
'boto config file contain all needed credentials?')
else:
_OutputAndExit(str(e))
- except boto.exception.StorageDataError as e:
- _OutputAndExit('StorageDataError: %s.' % e.reason)
- except boto.exception.BotoClientError as e:
- _OutputAndExit('BotoClientError: %s.' % e.reason)
except gslib.exception.CommandException as e:
_HandleCommandException(e)
except getopt.GetoptError as e:
_HandleCommandException(gslib.exception.CommandException(e.msg))
- except boto.exception.InvalidAclError as e:
- _OutputAndExit('InvalidAclError: %s.' % str(e))
except boto.exception.InvalidUriError as e:
_OutputAndExit('InvalidUriError: %s.' % e.message)
- except gslib.exception.ProjectIdException as e:
- _OutputAndExit('ProjectIdException: %s.' % e.reason)
+ except gslib.exception.InvalidUrlError as e:
+ _OutputAndExit('InvalidUrlError: %s.' % e.message)
except boto.auth_handler.NotReadyToAuthenticate:
_OutputAndExit('NotReadyToAuthenticate')
except OSError as e:
_OutputAndExit('OSError: %s.' % e.strerror)
except IOError as e:
- if e.errno == errno.EPIPE and not IsRunningInteractively():
+ if (e.errno == errno.EPIPE or (IS_WINDOWS and e.errno == errno.EINVAL)
+ and not IsRunningInteractively()):
# If we get a pipe error, this just means that the pipe to stdout or
# stderr is broken. This can happen if the user pipes gsutil to a command
# that doesn't use the entire output stream. Instead of raising an error,
@@ -399,65 +477,42 @@
raise
except wildcard_iterator.WildcardException as e:
_OutputAndExit(e.reason)
- except boto.exception.StorageResponseError as e:
- # Check for access denied, and provide detail to users who have no boto
- # config file (who might previously have been using gsutil only for
- # accessing publicly readable buckets and objects).
- if (e.status == 403
- or (e.status == 400 and e.code == 'MissingSecurityHeader')):
- _, _, detail = util.ParseErrorDetail(e)
- if detail and detail.find('x-goog-project-id header is required') != -1:
- _OutputAndExit('\n'.join(textwrap.wrap(
- 'You are attempting to perform an operation that requires an '
- 'x-goog-project-id header, with none configured. Please re-run '
- 'gsutil config and make sure to follow the instructions for '
- 'finding and entering your default project id.')))
- if (not HasConfiguredCredentials() and
- not boto.config.get_value('Tests', 'bypass_anonymous_access_warning',
- False)):
- # The check above allows tests to assert that we get a particular,
- # expected failure, rather than always encountering this error message
- # when there are no configured credentials. This allows tests to
- # simulate a second user without permissions, without actually requiring
- # two separate configured users.
- _OutputAndExit('\n'.join(textwrap.wrap(
- 'You are attempting to access protected data with no configured '
- 'credentials. Please visit '
- 'https://cloud.google.com/console#/project and sign up for an '
- 'account, and then run the "gsutil config" command to configure '
- 'gsutil to use these credentials.')))
- elif (e.error_code == 'AccountProblem'
- and ','.join(args).find('gs://') != -1):
- default_project_id = boto.config.get_value('GSUtil',
- 'default_project_id')
- (acct_help_part_1, acct_help_part_2, acct_help_part_3) = (
- _ConstructAclHelp(default_project_id))
- if default_project_id:
- _OutputAndExit(acct_help_part_1 + acct_help_part_2 + '3. ' +
- acct_help_part_3)
- else:
- _OutputAndExit(acct_help_part_1 + '2. ' + acct_help_part_3)
-
- exc_name, message, detail = util.ParseErrorDetail(e)
- _OutputAndExit(util.FormatErrorMessage(
- exc_name, e.status, e.code, e.reason, message, detail))
- except boto.exception.ResumableUploadException as e:
- _OutputAndExit('ResumableUploadException: %s.' % e.message)
+ except ProjectIdException as e:
+ _OutputAndExit(
+ 'You are attempting to perform an operation that requires a '
+ 'project id, with none configured. Please re-run '
+ 'gsutil config and make sure to follow the instructions for '
+ 'finding and entering your default project id.')
+ except BadRequestException as e:
+ if e.reason == 'MissingSecurityHeader':
+ _CheckAndHandleCredentialException(e, args)
+ _OutputAndExit(e)
+ except AccessDeniedException as e:
+ _CheckAndHandleCredentialException(e, args)
+ _OutputAndExit(e)
+ except ArgumentException as e:
+ _OutputAndExit(e)
+ except ServiceException as e:
+ _OutputAndExit(e)
+ except apitools_exceptions.HttpError as e:
+ # These should usually be retried by the underlying implementation or
+ # wrapped by CloudApi ServiceExceptions, but if we do get them,
+ # print something useful.
+ _OutputAndExit('HttpError: %s, %s' % (getattr(e.response, 'status', ''),
+ e.content or ''))
except socket.error as e:
if e.args[0] == errno.EPIPE:
# Retrying with a smaller file (per suggestion below) works because
# the library code send loop (in boto/s3/key.py) can get through the
# entire file and then request the HTTP response before the socket
# gets closed and the response lost.
- message = (
-"""
-Got a "Broken pipe" error. This can happen to clients using Python 2.x,
-when the server sends an error response and then closes the socket (see
-http://bugs.python.org/issue5542). If you are trying to upload a large
-object you might retry with a small (say 200k) object, and see if you get
-a more specific error code.
-""")
- _OutputAndExit(message)
+ _OutputAndExit(
+ 'Got a "Broken pipe" error. This can happen to clients using Python '
+ '2.x, when the server sends an error response and then closes the '
+ 'socket (see http://bugs.python.org/issue5542). If you are trying to '
+ 'upload a large object you might retry with a small (say 200k) '
+ 'object, and see if you get a more specific error code.'
+ )
else:
_HandleUnknownFailure(e)
except Exception as e:
@@ -466,14 +521,16 @@
# different problems and both have unhelpful error messages. Moreover,
# the error type belongs to PyOpenSSL, which is not necessarily installed.
if 'mac verify failure' in str(e):
- _OutputAndExit("Encountered an error while refreshing access token." +
- " If you are using a service account,\nplease verify that the " +
- "gs_service_key_file_password field in your config file," +
- "\n%s, is correct." % GetConfigFilePath())
+ _OutputAndExit(
+ 'Encountered an error while refreshing access token. '
+ 'If you are using a service account,\nplease verify that the '
+ 'gs_service_key_file_password field in your config file,'
+ '\n%s, is correct.' % GetConfigFilePath())
elif 'asn1 encoding routines' in str(e):
- _OutputAndExit("Encountered an error while refreshing access token." +
- " If you are using a service account,\nplease verify that the " +
- "gs_service_key_file field in your config file,\n%s, is correct."
+ _OutputAndExit(
+ 'Encountered an error while refreshing access token. '
+ 'If you are using a service account,\nplease verify that the '
+ 'gs_service_key_file field in your config file,\n%s, is correct.'
% GetConfigFilePath())
_HandleUnknownFailure(e)
« no previous file with comments | « gslib/__init__.py ('k') | gslib/aclhelpers.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698