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

Side by Side Diff: third_party/gsutil/gslib/gcs_json_api.py

Issue 1380943003: Roll version of gsutil to 4.15. (Closed) Base URL: https://github.com/catapult-project/catapult.git@master
Patch Set: rebase Created 5 years 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 unified diff | Download patch
« no previous file with comments | « third_party/gsutil/gslib/copy_helper.py ('k') | third_party/gsutil/gslib/gcs_json_media.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # -*- coding: utf-8 -*- 1 # -*- coding: utf-8 -*-
2 # Copyright 2014 Google Inc. All Rights Reserved. 2 # Copyright 2014 Google Inc. All Rights Reserved.
3 # 3 #
4 # Licensed under the Apache License, Version 2.0 (the "License"); 4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License. 5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at 6 # You may obtain a copy of the License at
7 # 7 #
8 # http://www.apache.org/licenses/LICENSE-2.0 8 # http://www.apache.org/licenses/LICENSE-2.0
9 # 9 #
10 # Unless required by applicable law or agreed to in writing, software 10 # Unless required by applicable law or agreed to in writing, software
(...skipping 18 matching lines...) Expand all
29 from apitools.base.py import encoding 29 from apitools.base.py import encoding
30 from apitools.base.py import exceptions as apitools_exceptions 30 from apitools.base.py import exceptions as apitools_exceptions
31 from apitools.base.py import http_wrapper as apitools_http_wrapper 31 from apitools.base.py import http_wrapper as apitools_http_wrapper
32 from apitools.base.py import transfer as apitools_transfer 32 from apitools.base.py import transfer as apitools_transfer
33 from apitools.base.py.util import CalculateWaitForRetry 33 from apitools.base.py.util import CalculateWaitForRetry
34 34
35 import boto 35 import boto
36 from boto import config 36 from boto import config
37 from gcs_oauth2_boto_plugin import oauth2_helper 37 from gcs_oauth2_boto_plugin import oauth2_helper
38 import httplib2 38 import httplib2
39 import oauth2client
39 from oauth2client import devshell 40 from oauth2client import devshell
40 from oauth2client import multistore_file 41 from oauth2client import multistore_file
41 42
42 from gslib.cloud_api import AccessDeniedException 43 from gslib.cloud_api import AccessDeniedException
43 from gslib.cloud_api import ArgumentException 44 from gslib.cloud_api import ArgumentException
44 from gslib.cloud_api import BadRequestException 45 from gslib.cloud_api import BadRequestException
45 from gslib.cloud_api import CloudApi 46 from gslib.cloud_api import CloudApi
46 from gslib.cloud_api import NotEmptyException 47 from gslib.cloud_api import NotEmptyException
47 from gslib.cloud_api import NotFoundException 48 from gslib.cloud_api import NotFoundException
48 from gslib.cloud_api import PreconditionException 49 from gslib.cloud_api import PreconditionException
(...skipping 17 matching lines...) Expand all
66 from gslib.progress_callback import ProgressCallbackWithBackoff 67 from gslib.progress_callback import ProgressCallbackWithBackoff
67 from gslib.project_id import PopulateProjectId 68 from gslib.project_id import PopulateProjectId
68 from gslib.third_party.storage_apitools import storage_v1_client as apitools_cli ent 69 from gslib.third_party.storage_apitools import storage_v1_client as apitools_cli ent
69 from gslib.third_party.storage_apitools import storage_v1_messages as apitools_m essages 70 from gslib.third_party.storage_apitools import storage_v1_messages as apitools_m essages
70 from gslib.tracker_file import DeleteTrackerFile 71 from gslib.tracker_file import DeleteTrackerFile
71 from gslib.tracker_file import GetRewriteTrackerFilePath 72 from gslib.tracker_file import GetRewriteTrackerFilePath
72 from gslib.tracker_file import HashRewriteParameters 73 from gslib.tracker_file import HashRewriteParameters
73 from gslib.tracker_file import ReadRewriteTrackerFile 74 from gslib.tracker_file import ReadRewriteTrackerFile
74 from gslib.tracker_file import WriteRewriteTrackerFile 75 from gslib.tracker_file import WriteRewriteTrackerFile
75 from gslib.translation_helper import CreateBucketNotFoundException 76 from gslib.translation_helper import CreateBucketNotFoundException
77 from gslib.translation_helper import CreateNotFoundExceptionForObjectWrite
76 from gslib.translation_helper import CreateObjectNotFoundException 78 from gslib.translation_helper import CreateObjectNotFoundException
77 from gslib.translation_helper import DEFAULT_CONTENT_TYPE 79 from gslib.translation_helper import DEFAULT_CONTENT_TYPE
80 from gslib.translation_helper import PRIVATE_DEFAULT_OBJ_ACL
78 from gslib.translation_helper import REMOVE_CORS_CONFIG 81 from gslib.translation_helper import REMOVE_CORS_CONFIG
79 from gslib.util import GetBotoConfigFileList 82 from gslib.util import GetBotoConfigFileList
80 from gslib.util import GetCertsFile 83 from gslib.util import GetCertsFile
81 from gslib.util import GetCredentialStoreFilename 84 from gslib.util import GetCredentialStoreFilename
82 from gslib.util import GetGceCredentialCacheFilename 85 from gslib.util import GetGceCredentialCacheFilename
83 from gslib.util import GetJsonResumableChunkSize 86 from gslib.util import GetJsonResumableChunkSize
84 from gslib.util import GetMaxRetryDelay 87 from gslib.util import GetMaxRetryDelay
85 from gslib.util import GetNewHttp 88 from gslib.util import GetNewHttp
86 from gslib.util import GetNumRetries 89 from gslib.util import GetNumRetries
87 from gslib.util import UTF8 90 from gslib.util import UTF8
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
125 """Service Unavailable. If you have recently changed 128 """Service Unavailable. If you have recently changed
126 https_validate_certificates from True to False in your boto configuration 129 https_validate_certificates from True to False in your boto configuration
127 file, please delete any cached access tokens in your filesystem (at %s) 130 file, please delete any cached access tokens in your filesystem (at %s)
128 and try again.""" % GetCredentialStoreFilename()) 131 and try again.""" % GetCredentialStoreFilename())
129 132
130 133
131 class GcsJsonApi(CloudApi): 134 class GcsJsonApi(CloudApi):
132 """Google Cloud Storage JSON implementation of gsutil Cloud API.""" 135 """Google Cloud Storage JSON implementation of gsutil Cloud API."""
133 136
134 def __init__(self, bucket_storage_uri_class, logger, provider=None, 137 def __init__(self, bucket_storage_uri_class, logger, provider=None,
135 credentials=None, debug=0): 138 credentials=None, debug=0, trace_token=None):
136 """Performs necessary setup for interacting with Google Cloud Storage. 139 """Performs necessary setup for interacting with Google Cloud Storage.
137 140
138 Args: 141 Args:
139 bucket_storage_uri_class: Unused. 142 bucket_storage_uri_class: Unused.
140 logger: logging.logger for outputting log messages. 143 logger: logging.logger for outputting log messages.
141 provider: Unused. This implementation supports only Google Cloud Storage. 144 provider: Unused. This implementation supports only Google Cloud Storage.
142 credentials: Credentials to be used for interacting with Google Cloud 145 credentials: Credentials to be used for interacting with Google Cloud
143 Storage. 146 Storage.
144 debug: Debug level for the API implementation (0..3). 147 debug: Debug level for the API implementation (0..3).
148 trace_token: Trace token to pass to the API implementation.
145 """ 149 """
146 # TODO: Plumb host_header for perfdiag / test_perfdiag. 150 # TODO: Plumb host_header for perfdiag / test_perfdiag.
147 # TODO: Add jitter to apitools' http_wrapper retry mechanism. 151 # TODO: Add jitter to apitools' http_wrapper retry mechanism.
148 super(GcsJsonApi, self).__init__(bucket_storage_uri_class, logger, 152 super(GcsJsonApi, self).__init__(bucket_storage_uri_class, logger,
149 provider='gs', debug=debug) 153 provider='gs', debug=debug)
150 no_op_credentials = False 154 no_op_credentials = False
151 if not credentials: 155 if not credentials:
152 loaded_credentials = self._CheckAndGetCredentials(logger) 156 loaded_credentials = self._CheckAndGetCredentials(logger)
153 157
154 if not loaded_credentials: 158 if not loaded_credentials:
155 loaded_credentials = NoOpCredentials() 159 loaded_credentials = NoOpCredentials()
156 no_op_credentials = True 160 no_op_credentials = True
157 else: 161 else:
158 if isinstance(credentials, NoOpCredentials): 162 if isinstance(credentials, NoOpCredentials):
159 no_op_credentials = True 163 no_op_credentials = True
160 164
161 self.credentials = credentials or loaded_credentials 165 self.credentials = credentials or loaded_credentials
162 166
163 self.certs_file = GetCertsFile() 167 self.certs_file = GetCertsFile()
164 168
165 self.http = GetNewHttp() 169 self.http = GetNewHttp()
170
171 # Re-use download and upload connections. This class is only called
172 # sequentially, but we can share TCP warmed-up connections across calls.
173 self.download_http = self._GetNewDownloadHttp()
174 self.upload_http = self._GetNewUploadHttp()
175 if self.credentials:
176 self.authorized_download_http = self.credentials.authorize(
177 self.download_http)
178 self.authorized_upload_http = self.credentials.authorize(self.upload_http)
179 else:
180 self.authorized_download_http = self.download_http
181 self.authorized_upload_http = self.upload_http
182
183 WrapDownloadHttpRequest(self.authorized_download_http)
184 WrapUploadHttpRequest(self.authorized_upload_http)
185
166 self.http_base = 'https://' 186 self.http_base = 'https://'
167 gs_json_host = config.get('Credentials', 'gs_json_host', None) 187 gs_json_host = config.get('Credentials', 'gs_json_host', None)
168 self.host_base = gs_json_host or 'www.googleapis.com' 188 self.host_base = gs_json_host or 'www.googleapis.com'
169 189
170 if not gs_json_host: 190 if not gs_json_host:
171 gs_host = config.get('Credentials', 'gs_host', None) 191 gs_host = config.get('Credentials', 'gs_host', None)
172 if gs_host: 192 if gs_host:
173 raise ArgumentException( 193 raise ArgumentException(
174 'JSON API is selected but gs_json_host is not configured, ' 194 'JSON API is selected but gs_json_host is not configured, '
175 'while gs_host is configured to %s. Please also configure ' 195 'while gs_host is configured to %s. Please also configure '
(...skipping 12 matching lines...) Expand all
188 % gs_port) 208 % gs_port)
189 self.host_port = '' 209 self.host_port = ''
190 else: 210 else:
191 self.host_port = ':' + config.get('Credentials', 'gs_json_port') 211 self.host_port = ':' + config.get('Credentials', 'gs_json_port')
192 212
193 self.api_version = config.get('GSUtil', 'json_api_version', 213 self.api_version = config.get('GSUtil', 'json_api_version',
194 DEFAULT_GCS_JSON_VERSION) 214 DEFAULT_GCS_JSON_VERSION)
195 self.url_base = (self.http_base + self.host_base + self.host_port + '/' + 215 self.url_base = (self.http_base + self.host_base + self.host_port + '/' +
196 'storage/' + self.api_version + '/') 216 'storage/' + self.api_version + '/')
197 217
218 credential_store_key_dict = self._GetCredentialStoreKeyDict(
219 self.credentials)
220
198 self.credentials.set_store( 221 self.credentials.set_store(
199 multistore_file.get_credential_storage_custom_string_key( 222 multistore_file.get_credential_storage_custom_key(
200 GetCredentialStoreFilename(), self.api_version)) 223 GetCredentialStoreFilename(), credential_store_key_dict))
201 224
202 self.num_retries = GetNumRetries() 225 self.num_retries = GetNumRetries()
226 self.max_retry_wait = GetMaxRetryDelay()
203 227
204 log_request = (debug >= 3) 228 log_request = (debug >= 3)
205 log_response = (debug >= 3) 229 log_response = (debug >= 3)
206 230
231 self.global_params = apitools_messages.StandardQueryParameters(
232 trace='token:%s' % trace_token) if trace_token else None
233
207 self.api_client = apitools_client.StorageV1( 234 self.api_client = apitools_client.StorageV1(
208 url=self.url_base, http=self.http, log_request=log_request, 235 url=self.url_base, http=self.http, log_request=log_request,
209 log_response=log_response, credentials=self.credentials, 236 log_response=log_response, credentials=self.credentials,
210 version=self.api_version) 237 version=self.api_version, default_global_params=self.global_params)
238 self.api_client.max_retry_wait = self.max_retry_wait
211 self.api_client.num_retries = self.num_retries 239 self.api_client.num_retries = self.num_retries
212 240
213 if no_op_credentials: 241 if no_op_credentials:
214 # This API key is not secret and is used to identify gsutil during 242 # This API key is not secret and is used to identify gsutil during
215 # anonymous requests. 243 # anonymous requests.
216 self.api_client.AddGlobalParam('key', 244 self.api_client.AddGlobalParam('key',
217 u'AIzaSyDnacJHrKma0048b13sh8cgxNUwulubmJM') 245 u'AIzaSyDnacJHrKma0048b13sh8cgxNUwulubmJM')
218 246
219 def _CheckAndGetCredentials(self, logger): 247 def _CheckAndGetCredentials(self, logger):
220 configured_cred_types = [] 248 configured_cred_types = []
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
302 raise 330 raise
303 331
304 def _GetDevshellCreds(self): 332 def _GetDevshellCreds(self):
305 try: 333 try:
306 return devshell.DevshellCredentials() 334 return devshell.DevshellCredentials()
307 except devshell.NoDevshellServer: 335 except devshell.NoDevshellServer:
308 return None 336 return None
309 except: 337 except:
310 raise 338 raise
311 339
312 def _GetNewDownloadHttp(self, download_stream): 340 def _GetCredentialStoreKeyDict(self, credentials):
313 return GetNewHttp(http_class=HttpWithDownloadStream, stream=download_stream) 341 """Disambiguates a credential for caching in a credential store.
342
343 Different credential types have different fields that identify them.
344 This function assembles relevant information in a dict and returns it.
345
346 Args:
347 credentials: An OAuth2Credentials object.
348
349 Returns:
350 Dict of relevant identifiers for credentials.
351 """
352 # TODO: If scopes ever become available in the credentials themselves,
353 # include them in the key dict.
354 key_dict = {'api_version': self.api_version}
355 # pylint: disable=protected-access
356 if isinstance(credentials, devshell.DevshellCredentials):
357 key_dict['user_email'] = credentials.user_email
358 elif isinstance(credentials,
359 oauth2client.service_account._ServiceAccountCredentials):
360 key_dict['_service_account_email'] = credentials._service_account_email
361 elif isinstance(credentials,
362 oauth2client.client.SignedJwtAssertionCredentials):
363 key_dict['service_account_name'] = credentials.service_account_name
364 elif isinstance(credentials, oauth2client.client.OAuth2Credentials):
365 if credentials.client_id and credentials.client_id != 'null':
366 key_dict['client_id'] = credentials.client_id
367 key_dict['refresh_token'] = credentials.refresh_token
368 # pylint: enable=protected-access
369
370 return key_dict
371
372 def _GetNewDownloadHttp(self):
373 return GetNewHttp(http_class=HttpWithDownloadStream)
314 374
315 def _GetNewUploadHttp(self): 375 def _GetNewUploadHttp(self):
316 """Returns an upload-safe Http object (by disabling httplib2 retries).""" 376 """Returns an upload-safe Http object (by disabling httplib2 retries)."""
317 return GetNewHttp(http_class=HttpWithNoRetries) 377 return GetNewHttp(http_class=HttpWithNoRetries)
318 378
319 def GetBucket(self, bucket_name, provider=None, fields=None): 379 def GetBucket(self, bucket_name, provider=None, fields=None):
320 """See CloudApi class for function doc strings.""" 380 """See CloudApi class for function doc strings."""
321 projection = (apitools_messages.StorageBucketsGetRequest 381 projection = (apitools_messages.StorageBucketsGetRequest
322 .ProjectionValueValuesEnum.full) 382 .ProjectionValueValuesEnum.full)
323 apitools_request = apitools_messages.StorageBucketsGetRequest( 383 apitools_request = apitools_messages.StorageBucketsGetRequest(
(...skipping 29 matching lines...) Expand all
353 'website'): 413 'website'):
354 attr = getattr(bucket_metadata, metadata_field, None) 414 attr = getattr(bucket_metadata, metadata_field, None)
355 if attr and not encoding.MessageToDict(attr): 415 if attr and not encoding.MessageToDict(attr):
356 setattr(bucket_metadata, metadata_field, None) 416 setattr(bucket_metadata, metadata_field, None)
357 apitools_include_fields.append(metadata_field) 417 apitools_include_fields.append(metadata_field)
358 418
359 if bucket_metadata.cors and bucket_metadata.cors == REMOVE_CORS_CONFIG: 419 if bucket_metadata.cors and bucket_metadata.cors == REMOVE_CORS_CONFIG:
360 bucket_metadata.cors = [] 420 bucket_metadata.cors = []
361 apitools_include_fields.append('cors') 421 apitools_include_fields.append('cors')
362 422
423 if (bucket_metadata.defaultObjectAcl and
424 bucket_metadata.defaultObjectAcl[0] == PRIVATE_DEFAULT_OBJ_ACL):
425 bucket_metadata.defaultObjectAcl = []
426 apitools_include_fields.append('defaultObjectAcl')
427
363 predefined_acl = None 428 predefined_acl = None
364 if canned_acl: 429 if canned_acl:
365 # Must null out existing ACLs to apply a canned ACL. 430 # Must null out existing ACLs to apply a canned ACL.
366 apitools_include_fields.append('acl') 431 apitools_include_fields.append('acl')
367 predefined_acl = ( 432 predefined_acl = (
368 apitools_messages.StorageBucketsPatchRequest. 433 apitools_messages.StorageBucketsPatchRequest.
369 PredefinedAclValueValuesEnum( 434 PredefinedAclValueValuesEnum(
370 self._BucketCannedAclToPredefinedAcl(canned_acl))) 435 self._BucketCannedAclToPredefinedAcl(canned_acl)))
371 436
372 predefined_def_acl = None 437 predefined_def_acl = None
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
521 try: 586 try:
522 object_list = self.api_client.objects.List(apitools_request, 587 object_list = self.api_client.objects.List(apitools_request,
523 global_params=global_params) 588 global_params=global_params)
524 except TRANSLATABLE_APITOOLS_EXCEPTIONS, e: 589 except TRANSLATABLE_APITOOLS_EXCEPTIONS, e:
525 self._TranslateExceptionAndRaise(e, bucket_name=bucket_name) 590 self._TranslateExceptionAndRaise(e, bucket_name=bucket_name)
526 591
527 for object_or_prefix in self._YieldObjectsAndPrefixes(object_list): 592 for object_or_prefix in self._YieldObjectsAndPrefixes(object_list):
528 yield object_or_prefix 593 yield object_or_prefix
529 594
530 def _YieldObjectsAndPrefixes(self, object_list): 595 def _YieldObjectsAndPrefixes(self, object_list):
596 # Yield prefixes first so that checking for the presence of a subdirectory
597 # is fast.
598 if object_list.prefixes:
599 for prefix in object_list.prefixes:
600 yield CloudApi.CsObjectOrPrefix(prefix,
601 CloudApi.CsObjectOrPrefixType.PREFIX)
531 if object_list.items: 602 if object_list.items:
532 for cloud_obj in object_list.items: 603 for cloud_obj in object_list.items:
533 yield CloudApi.CsObjectOrPrefix(cloud_obj, 604 yield CloudApi.CsObjectOrPrefix(cloud_obj,
534 CloudApi.CsObjectOrPrefixType.OBJECT) 605 CloudApi.CsObjectOrPrefixType.OBJECT)
535 if object_list.prefixes:
536 for prefix in object_list.prefixes:
537 yield CloudApi.CsObjectOrPrefix(prefix,
538 CloudApi.CsObjectOrPrefixType.PREFIX)
539 606
540 def GetObjectMetadata(self, bucket_name, object_name, generation=None, 607 def GetObjectMetadata(self, bucket_name, object_name, generation=None,
541 provider=None, fields=None): 608 provider=None, fields=None):
542 """See CloudApi class for function doc strings.""" 609 """See CloudApi class for function doc strings."""
543 projection = (apitools_messages.StorageObjectsGetRequest 610 projection = (apitools_messages.StorageObjectsGetRequest
544 .ProjectionValueValuesEnum.full) 611 .ProjectionValueValuesEnum.full)
545 612
546 if generation: 613 if generation:
547 generation = long(generation) 614 generation = long(generation)
548 615
(...skipping 17 matching lines...) Expand all
566 provider=None, generation=None, object_size=None, 633 provider=None, generation=None, object_size=None,
567 download_strategy=CloudApi.DownloadStrategy.ONE_SHOT, start_byte=0, 634 download_strategy=CloudApi.DownloadStrategy.ONE_SHOT, start_byte=0,
568 end_byte=None, progress_callback=None, serialization_data=None, 635 end_byte=None, progress_callback=None, serialization_data=None,
569 digesters=None): 636 digesters=None):
570 """See CloudApi class for function doc strings.""" 637 """See CloudApi class for function doc strings."""
571 # This implementation will get the object metadata first if we don't pass it 638 # This implementation will get the object metadata first if we don't pass it
572 # in via serialization_data. 639 # in via serialization_data.
573 if generation: 640 if generation:
574 generation = long(generation) 641 generation = long(generation)
575 642
643 # 'outer_total_size' is only used for formatting user output, and is
644 # expected to be one higher than the last byte that should be downloaded.
645 # TODO: Change DownloadCallbackConnectionClassFactory and progress callbacks
646 # to more elegantly handle total size for components of files.
576 outer_total_size = object_size 647 outer_total_size = object_size
577 if serialization_data: 648 if end_byte:
649 outer_total_size = end_byte + 1
650 elif serialization_data:
578 outer_total_size = json.loads(serialization_data)['total_size'] 651 outer_total_size = json.loads(serialization_data)['total_size']
579 652
580 if progress_callback: 653 if progress_callback:
581 if outer_total_size is None: 654 if outer_total_size is None:
582 raise ArgumentException('Download size is required when callbacks are ' 655 raise ArgumentException('Download size is required when callbacks are '
583 'requested for a download, but no size was ' 656 'requested for a download, but no size was '
584 'provided.') 657 'provided.')
585 progress_callback(0, outer_total_size) 658 progress_callback(start_byte, outer_total_size)
586 659
587 bytes_downloaded_container = BytesTransferredContainer() 660 bytes_downloaded_container = BytesTransferredContainer()
588 bytes_downloaded_container.bytes_transferred = start_byte 661 bytes_downloaded_container.bytes_transferred = start_byte
589 662
590 callback_class_factory = DownloadCallbackConnectionClassFactory( 663 callback_class_factory = DownloadCallbackConnectionClassFactory(
591 bytes_downloaded_container, total_size=outer_total_size, 664 bytes_downloaded_container, total_size=outer_total_size,
592 progress_callback=progress_callback, digesters=digesters) 665 progress_callback=progress_callback, digesters=digesters)
593 download_http_class = callback_class_factory.GetConnectionClass() 666 download_http_class = callback_class_factory.GetConnectionClass()
594 667
595 download_http = self._GetNewDownloadHttp(download_stream) 668 # Point our download HTTP at our download stream.
596 download_http.connections = {'https': download_http_class} 669 self.download_http.stream = download_stream
597 authorized_download_http = self.credentials.authorize(download_http) 670 self.download_http.connections = {'https': download_http_class}
598 WrapDownloadHttpRequest(authorized_download_http)
599 671
600 if serialization_data: 672 if serialization_data:
601 apitools_download = apitools_transfer.Download.FromData( 673 apitools_download = apitools_transfer.Download.FromData(
602 download_stream, serialization_data, self.api_client.http, 674 download_stream, serialization_data, self.api_client.http,
603 num_retries=self.num_retries) 675 num_retries=self.num_retries)
604 else: 676 else:
605 apitools_download = apitools_transfer.Download.FromStream( 677 apitools_download = apitools_transfer.Download.FromStream(
606 download_stream, auto_transfer=False, total_size=object_size, 678 download_stream, auto_transfer=False, total_size=object_size,
607 num_retries=self.num_retries) 679 num_retries=self.num_retries)
608 680
609 apitools_download.bytes_http = authorized_download_http 681 apitools_download.bytes_http = self.authorized_download_http
610 apitools_request = apitools_messages.StorageObjectsGetRequest( 682 apitools_request = apitools_messages.StorageObjectsGetRequest(
611 bucket=bucket_name, object=object_name, generation=generation) 683 bucket=bucket_name, object=object_name, generation=generation)
612 684
613 try: 685 try:
614 if download_strategy == CloudApi.DownloadStrategy.RESUMABLE: 686 if download_strategy == CloudApi.DownloadStrategy.RESUMABLE:
615 # Disable retries in apitools. We will handle them explicitly here. 687 # Disable retries in apitools. We will handle them explicitly here.
616 apitools_download.retry_func = ( 688 apitools_download.retry_func = (
617 apitools_http_wrapper.RethrowExceptionHandler) 689 apitools_http_wrapper.RethrowExceptionHandler)
618 return self._PerformResumableDownload( 690 return self._PerformResumableDownload(
619 bucket_name, object_name, download_stream, apitools_request, 691 bucket_name, object_name, download_stream, apitools_request,
(...skipping 27 matching lines...) Expand all
647 bytes_downloaded_container.bytes_transferred = start_byte 719 bytes_downloaded_container.bytes_transferred = start_byte
648 if start_byte > last_progress_byte: 720 if start_byte > last_progress_byte:
649 # We've made progress, so allow a fresh set of retries. 721 # We've made progress, so allow a fresh set of retries.
650 last_progress_byte = start_byte 722 last_progress_byte = start_byte
651 retries = 0 723 retries = 0
652 retries += 1 724 retries += 1
653 if retries > self.num_retries: 725 if retries > self.num_retries:
654 raise ResumableDownloadException( 726 raise ResumableDownloadException(
655 'Transfer failed after %d retries. Final exception: %s' % 727 'Transfer failed after %d retries. Final exception: %s' %
656 (self.num_retries, unicode(e).encode(UTF8))) 728 (self.num_retries, unicode(e).encode(UTF8)))
657 time.sleep(CalculateWaitForRetry(retries, max_wait=GetMaxRetryDelay())) 729 time.sleep(CalculateWaitForRetry(retries, max_wait=self.max_retry_wait))
658 if self.logger.isEnabledFor(logging.DEBUG): 730 if self.logger.isEnabledFor(logging.DEBUG):
659 self.logger.debug( 731 self.logger.debug(
660 'Retrying download from byte %s after exception: %s. Trace: %s', 732 'Retrying download from byte %s after exception: %s. Trace: %s',
661 start_byte, unicode(e).encode(UTF8), traceback.format_exc()) 733 start_byte, unicode(e).encode(UTF8), traceback.format_exc())
662 apitools_http_wrapper.RebuildHttpConnections( 734 apitools_http_wrapper.RebuildHttpConnections(
663 apitools_download.bytes_http) 735 apitools_download.bytes_http)
664 736
665 def _PerformDownload( 737 def _PerformDownload(
666 self, bucket_name, object_name, download_stream, apitools_request, 738 self, bucket_name, object_name, download_stream, apitools_request,
667 apitools_download, generation=None, start_byte=0, end_byte=None, 739 apitools_download, generation=None, start_byte=0, end_byte=None,
(...skipping 19 matching lines...) Expand all
687 # the bytes that we have locally and send a range request without 759 # the bytes that we have locally and send a range request without
688 # accept-encoding:gzip so that we can download only the (uncompressed) bytes 760 # accept-encoding:gzip so that we can download only the (uncompressed) bytes
689 # that we don't yet have. 761 # that we don't yet have.
690 762
691 # Since bytes_http is created in this function, we don't get the 763 # Since bytes_http is created in this function, we don't get the
692 # user-agent header from api_client's http automatically. 764 # user-agent header from api_client's http automatically.
693 additional_headers = { 765 additional_headers = {
694 'accept-encoding': 'gzip', 766 'accept-encoding': 'gzip',
695 'user-agent': self.api_client.user_agent 767 'user-agent': self.api_client.user_agent
696 } 768 }
697 if start_byte or end_byte: 769 if start_byte or end_byte is not None:
698 apitools_download.GetRange(additional_headers=additional_headers, 770 apitools_download.GetRange(additional_headers=additional_headers,
699 start=start_byte, end=end_byte, 771 start=start_byte, end=end_byte,
700 use_chunks=False) 772 use_chunks=False)
701 else: 773 else:
702 apitools_download.StreamMedia( 774 apitools_download.StreamMedia(
703 callback=_NoOpCallback, finish_callback=_NoOpCallback, 775 callback=_NoOpCallback, finish_callback=_NoOpCallback,
704 additional_headers=additional_headers, use_chunks=False) 776 additional_headers=additional_headers, use_chunks=False)
705 return apitools_download.encoding 777 return apitools_download.encoding
706 778
707 def PatchObjectMetadata(self, bucket_name, object_name, metadata, 779 def PatchObjectMetadata(self, bucket_name, object_name, metadata,
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
774 bytes_uploaded_container = BytesTransferredContainer() 846 bytes_uploaded_container = BytesTransferredContainer()
775 847
776 if progress_callback and size: 848 if progress_callback and size:
777 total_size = size 849 total_size = size
778 progress_callback(0, size) 850 progress_callback(0, size)
779 851
780 callback_class_factory = UploadCallbackConnectionClassFactory( 852 callback_class_factory = UploadCallbackConnectionClassFactory(
781 bytes_uploaded_container, total_size=total_size, 853 bytes_uploaded_container, total_size=total_size,
782 progress_callback=progress_callback) 854 progress_callback=progress_callback)
783 855
784 upload_http = self._GetNewUploadHttp()
785 upload_http_class = callback_class_factory.GetConnectionClass() 856 upload_http_class = callback_class_factory.GetConnectionClass()
786 upload_http.connections = {'http': upload_http_class, 857 self.upload_http.connections = {'http': upload_http_class,
787 'https': upload_http_class} 858 'https': upload_http_class}
788 859
789 authorized_upload_http = self.credentials.authorize(upload_http)
790 WrapUploadHttpRequest(authorized_upload_http)
791 # Since bytes_http is created in this function, we don't get the 860 # Since bytes_http is created in this function, we don't get the
792 # user-agent header from api_client's http automatically. 861 # user-agent header from api_client's http automatically.
793 additional_headers = { 862 additional_headers = {
794 'user-agent': self.api_client.user_agent 863 'user-agent': self.api_client.user_agent
795 } 864 }
796 865
797 try: 866 try:
798 content_type = None 867 content_type = None
799 apitools_request = None 868 apitools_request = None
800 global_params = None 869 global_params = None
(...skipping 14 matching lines...) Expand all
815 global_params = apitools_messages.StandardQueryParameters() 884 global_params = apitools_messages.StandardQueryParameters()
816 if fields: 885 if fields:
817 global_params.fields = ','.join(set(fields)) 886 global_params.fields = ','.join(set(fields))
818 887
819 if apitools_strategy == apitools_transfer.SIMPLE_UPLOAD: 888 if apitools_strategy == apitools_transfer.SIMPLE_UPLOAD:
820 # One-shot upload. 889 # One-shot upload.
821 apitools_upload = apitools_transfer.Upload( 890 apitools_upload = apitools_transfer.Upload(
822 upload_stream, content_type, total_size=size, auto_transfer=True, 891 upload_stream, content_type, total_size=size, auto_transfer=True,
823 num_retries=self.num_retries) 892 num_retries=self.num_retries)
824 apitools_upload.strategy = apitools_strategy 893 apitools_upload.strategy = apitools_strategy
825 apitools_upload.bytes_http = authorized_upload_http 894 apitools_upload.bytes_http = self.authorized_upload_http
826 895
827 return self.api_client.objects.Insert( 896 return self.api_client.objects.Insert(
828 apitools_request, 897 apitools_request,
829 upload=apitools_upload, 898 upload=apitools_upload,
830 global_params=global_params) 899 global_params=global_params)
831 else: # Resumable upload. 900 else: # Resumable upload.
832 return self._PerformResumableUpload( 901 return self._PerformResumableUpload(
833 upload_stream, authorized_upload_http, content_type, size, 902 upload_stream, self.authorized_upload_http, content_type, size,
834 serialization_data, apitools_strategy, apitools_request, 903 serialization_data, apitools_strategy, apitools_request,
835 global_params, bytes_uploaded_container, tracker_callback, 904 global_params, bytes_uploaded_container, tracker_callback,
836 additional_headers, progress_callback) 905 additional_headers, progress_callback)
837 except TRANSLATABLE_APITOOLS_EXCEPTIONS, e: 906 except TRANSLATABLE_APITOOLS_EXCEPTIONS, e:
907 not_found_exception = CreateNotFoundExceptionForObjectWrite(
908 self.provider, object_metadata.bucket)
838 self._TranslateExceptionAndRaise(e, bucket_name=object_metadata.bucket, 909 self._TranslateExceptionAndRaise(e, bucket_name=object_metadata.bucket,
839 object_name=object_metadata.name) 910 object_name=object_metadata.name,
911 not_found_exception=not_found_exception)
840 912
841 def _PerformResumableUpload( 913 def _PerformResumableUpload(
842 self, upload_stream, authorized_upload_http, content_type, size, 914 self, upload_stream, authorized_upload_http, content_type, size,
843 serialization_data, apitools_strategy, apitools_request, global_params, 915 serialization_data, apitools_strategy, apitools_request, global_params,
844 bytes_uploaded_container, tracker_callback, addl_headers, 916 bytes_uploaded_container, tracker_callback, addl_headers,
845 progress_callback): 917 progress_callback):
846 try: 918 try:
847 if serialization_data: 919 if serialization_data:
848 # Resuming an existing upload. 920 # Resuming an existing upload.
849 apitools_upload = apitools_transfer.Upload.FromData( 921 apitools_upload = apitools_transfer.Upload.FromData(
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
922 break 994 break
923 except HTTP_TRANSFER_EXCEPTIONS, e2: 995 except HTTP_TRANSFER_EXCEPTIONS, e2:
924 apitools_http_wrapper.RebuildHttpConnections( 996 apitools_http_wrapper.RebuildHttpConnections(
925 apitools_upload.bytes_http) 997 apitools_upload.bytes_http)
926 retries += 1 998 retries += 1
927 if retries > self.num_retries: 999 if retries > self.num_retries:
928 raise ResumableUploadException( 1000 raise ResumableUploadException(
929 'Transfer failed after %d retries. Final exception: %s' % 1001 'Transfer failed after %d retries. Final exception: %s' %
930 (self.num_retries, e2)) 1002 (self.num_retries, e2))
931 time.sleep( 1003 time.sleep(
932 CalculateWaitForRetry(retries, max_wait=GetMaxRetryDelay())) 1004 CalculateWaitForRetry(retries, max_wait=self.max_retry_wait))
933 if start_byte > last_progress_byte: 1005 if start_byte > last_progress_byte:
934 # We've made progress, so allow a fresh set of retries. 1006 # We've made progress, so allow a fresh set of retries.
935 last_progress_byte = start_byte 1007 last_progress_byte = start_byte
936 retries = 0 1008 retries = 0
937 else: 1009 else:
938 retries += 1 1010 retries += 1
939 if retries > self.num_retries: 1011 if retries > self.num_retries:
940 raise ResumableUploadException( 1012 raise ResumableUploadException(
941 'Transfer failed after %d retries. Final exception: %s' % 1013 'Transfer failed after %d retries. Final exception: %s' %
942 (self.num_retries, unicode(e).encode(UTF8))) 1014 (self.num_retries, unicode(e).encode(UTF8)))
943 time.sleep( 1015 time.sleep(
944 CalculateWaitForRetry(retries, max_wait=GetMaxRetryDelay())) 1016 CalculateWaitForRetry(retries, max_wait=self.max_retry_wait))
945 if self.logger.isEnabledFor(logging.DEBUG): 1017 if self.logger.isEnabledFor(logging.DEBUG):
946 self.logger.debug( 1018 self.logger.debug(
947 'Retrying upload from byte %s after exception: %s. Trace: %s', 1019 'Retrying upload from byte %s after exception: %s. Trace: %s',
948 start_byte, unicode(e).encode(UTF8), traceback.format_exc()) 1020 start_byte, unicode(e).encode(UTF8), traceback.format_exc())
949 except TRANSLATABLE_APITOOLS_EXCEPTIONS, e: 1021 except TRANSLATABLE_APITOOLS_EXCEPTIONS, e:
950 resumable_ex = self._TranslateApitoolsResumableUploadException(e) 1022 resumable_ex = self._TranslateApitoolsResumableUploadException(e)
951 if resumable_ex: 1023 if resumable_ex:
952 raise resumable_ex 1024 raise resumable_ex
953 else: 1025 else:
954 raise 1026 raise
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
1062 elif not resume_rewrite_token: 1134 elif not resume_rewrite_token:
1063 # Save the token and make a tracker file if they don't already exist. 1135 # Save the token and make a tracker file if they don't already exist.
1064 resume_rewrite_token = rewrite_response.rewriteToken 1136 resume_rewrite_token = rewrite_response.rewriteToken
1065 WriteRewriteTrackerFile(tracker_file_name, rewrite_params_hash, 1137 WriteRewriteTrackerFile(tracker_file_name, rewrite_params_hash,
1066 rewrite_response.rewriteToken) 1138 rewrite_response.rewriteToken)
1067 last_bytes_written = bytes_written 1139 last_bytes_written = bytes_written
1068 1140
1069 DeleteTrackerFile(tracker_file_name) 1141 DeleteTrackerFile(tracker_file_name)
1070 return rewrite_response.resource 1142 return rewrite_response.resource
1071 except TRANSLATABLE_APITOOLS_EXCEPTIONS, e: 1143 except TRANSLATABLE_APITOOLS_EXCEPTIONS, e:
1144 not_found_exception = CreateNotFoundExceptionForObjectWrite(
1145 self.provider, dst_obj_metadata.bucket, src_provider=self.provider,
1146 src_bucket_name=src_obj_metadata.bucket,
1147 src_object_name=src_obj_metadata.name, src_generation=src_generation)
1072 self._TranslateExceptionAndRaise(e, bucket_name=dst_obj_metadata.bucket, 1148 self._TranslateExceptionAndRaise(e, bucket_name=dst_obj_metadata.bucket,
1073 object_name=dst_obj_metadata.name) 1149 object_name=dst_obj_metadata.name,
1150 not_found_exception=not_found_exception)
1074 1151
1075 def DeleteObject(self, bucket_name, object_name, preconditions=None, 1152 def DeleteObject(self, bucket_name, object_name, preconditions=None,
1076 generation=None, provider=None): 1153 generation=None, provider=None):
1077 """See CloudApi class for function doc strings.""" 1154 """See CloudApi class for function doc strings."""
1078 if not preconditions: 1155 if not preconditions:
1079 preconditions = Preconditions() 1156 preconditions = Preconditions()
1080 1157
1081 if generation: 1158 if generation:
1082 generation = long(generation) 1159 generation = long(generation)
1083 1160
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
1203 'bucket-owner-full-control': 'bucketOwnerFullControl', 1280 'bucket-owner-full-control': 'bucketOwnerFullControl',
1204 'private': 'private', 1281 'private': 'private',
1205 'project-private': 'projectPrivate', 1282 'project-private': 'projectPrivate',
1206 'public-read': 'publicRead' 1283 'public-read': 'publicRead'
1207 } 1284 }
1208 if canned_acl_string in translation_dict: 1285 if canned_acl_string in translation_dict:
1209 return translation_dict[canned_acl_string] 1286 return translation_dict[canned_acl_string]
1210 raise ArgumentException('Invalid canned ACL %s' % canned_acl_string) 1287 raise ArgumentException('Invalid canned ACL %s' % canned_acl_string)
1211 1288
1212 def _TranslateExceptionAndRaise(self, e, bucket_name=None, object_name=None, 1289 def _TranslateExceptionAndRaise(self, e, bucket_name=None, object_name=None,
1213 generation=None): 1290 generation=None, not_found_exception=None):
1214 """Translates an HTTP exception and raises the translated or original value. 1291 """Translates an HTTP exception and raises the translated or original value.
1215 1292
1216 Args: 1293 Args:
1217 e: Any Exception. 1294 e: Any Exception.
1218 bucket_name: Optional bucket name in request that caused the exception. 1295 bucket_name: Optional bucket name in request that caused the exception.
1219 object_name: Optional object name in request that caused the exception. 1296 object_name: Optional object name in request that caused the exception.
1220 generation: Optional generation in request that caused the exception. 1297 generation: Optional generation in request that caused the exception.
1298 not_found_exception: Optional exception to raise in the not-found case.
1221 1299
1222 Raises: 1300 Raises:
1223 Translated CloudApi exception, or the original exception if it was not 1301 Translated CloudApi exception, or the original exception if it was not
1224 translatable. 1302 translatable.
1225 """ 1303 """
1226 translated_exception = self._TranslateApitoolsException( 1304 translated_exception = self._TranslateApitoolsException(
1227 e, bucket_name=bucket_name, object_name=object_name, 1305 e, bucket_name=bucket_name, object_name=object_name,
1228 generation=generation) 1306 generation=generation, not_found_exception=not_found_exception)
1229 if translated_exception: 1307 if translated_exception:
1230 raise translated_exception 1308 raise translated_exception
1231 else: 1309 else:
1232 raise 1310 raise
1233 1311
1234 def _GetMessageFromHttpError(self, http_error): 1312 def _GetMessageFromHttpError(self, http_error):
1235 if isinstance(http_error, apitools_exceptions.HttpError): 1313 if isinstance(http_error, apitools_exceptions.HttpError):
1236 if getattr(http_error, 'content', None): 1314 if getattr(http_error, 'content', None):
1237 try: 1315 try:
1238 json_obj = json.loads(http_error.content) 1316 json_obj = json.loads(http_error.content)
1239 if 'error' in json_obj and 'message' in json_obj['error']: 1317 if 'error' in json_obj and 'message' in json_obj['error']:
1240 return json_obj['error']['message'] 1318 return json_obj['error']['message']
1241 except Exception: # pylint: disable=broad-except 1319 except Exception: # pylint: disable=broad-except
1242 # If we couldn't decode anything, just leave the message as None. 1320 # If we couldn't decode anything, just leave the message as None.
1243 pass 1321 pass
1244 1322
1245 def _TranslateApitoolsResumableUploadException( 1323 def _TranslateApitoolsResumableUploadException(self, e):
1246 self, e, bucket_name=None, object_name=None, generation=None):
1247 if isinstance(e, apitools_exceptions.HttpError): 1324 if isinstance(e, apitools_exceptions.HttpError):
1248 message = self._GetMessageFromHttpError(e) 1325 message = self._GetMessageFromHttpError(e)
1249 if (e.status_code == 503 and 1326 if (e.status_code == 503 and
1250 self.http.disable_ssl_certificate_validation): 1327 self.http.disable_ssl_certificate_validation):
1251 return ServiceException(_VALIDATE_CERTIFICATES_503_MESSAGE, 1328 return ServiceException(_VALIDATE_CERTIFICATES_503_MESSAGE,
1252 status=e.status_code) 1329 status=e.status_code)
1253 elif e.status_code >= 500: 1330 elif e.status_code >= 500:
1254 return ResumableUploadException( 1331 return ResumableUploadException(
1255 message or 'Server Error', status=e.status_code) 1332 message or 'Server Error', status=e.status_code)
1256 elif e.status_code == 429: 1333 elif e.status_code == 429:
(...skipping 10 matching lines...) Expand all
1267 message or 'Bad Request', status=e.status_code) 1344 message or 'Bad Request', status=e.status_code)
1268 if isinstance(e, apitools_exceptions.StreamExhausted): 1345 if isinstance(e, apitools_exceptions.StreamExhausted):
1269 return ResumableUploadAbortException(e.message) 1346 return ResumableUploadAbortException(e.message)
1270 if (isinstance(e, apitools_exceptions.TransferError) and 1347 if (isinstance(e, apitools_exceptions.TransferError) and
1271 ('Aborting transfer' in e.message or 1348 ('Aborting transfer' in e.message or
1272 'Not enough bytes in stream' in e.message or 1349 'Not enough bytes in stream' in e.message or
1273 'additional bytes left in stream' in e.message)): 1350 'additional bytes left in stream' in e.message)):
1274 return ResumableUploadAbortException(e.message) 1351 return ResumableUploadAbortException(e.message)
1275 1352
1276 def _TranslateApitoolsException(self, e, bucket_name=None, object_name=None, 1353 def _TranslateApitoolsException(self, e, bucket_name=None, object_name=None,
1277 generation=None): 1354 generation=None, not_found_exception=None):
1278 """Translates apitools exceptions into their gsutil Cloud Api equivalents. 1355 """Translates apitools exceptions into their gsutil Cloud Api equivalents.
1279 1356
1280 Args: 1357 Args:
1281 e: Any exception in TRANSLATABLE_APITOOLS_EXCEPTIONS. 1358 e: Any exception in TRANSLATABLE_APITOOLS_EXCEPTIONS.
1282 bucket_name: Optional bucket name in request that caused the exception. 1359 bucket_name: Optional bucket name in request that caused the exception.
1283 object_name: Optional object name in request that caused the exception. 1360 object_name: Optional object name in request that caused the exception.
1284 generation: Optional generation in request that caused the exception. 1361 generation: Optional generation in request that caused the exception.
1362 not_found_exception: Optional exception to raise in the not-found case.
1285 1363
1286 Returns: 1364 Returns:
1287 CloudStorageApiServiceException for translatable exceptions, None 1365 CloudStorageApiServiceException for translatable exceptions, None
1288 otherwise. 1366 otherwise.
1289 """ 1367 """
1290 if isinstance(e, apitools_exceptions.HttpError): 1368 if isinstance(e, apitools_exceptions.HttpError):
1291 message = self._GetMessageFromHttpError(e) 1369 message = self._GetMessageFromHttpError(e)
1292 if e.status_code == 400: 1370 if e.status_code == 400:
1293 # It is possible that the Project ID is incorrect. Unfortunately the 1371 # It is possible that the Project ID is incorrect. Unfortunately the
1294 # JSON API does not give us much information about what part of the 1372 # JSON API does not give us much information about what part of the
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1326 return AccessDeniedException( 1404 return AccessDeniedException(
1327 'Access Not Configured. Please go to the Google Developers ' 1405 'Access Not Configured. Please go to the Google Developers '
1328 'Console (https://cloud.google.com/console#/project) for your ' 1406 'Console (https://cloud.google.com/console#/project) for your '
1329 'project, select APIs and Auth and enable the ' 1407 'project, select APIs and Auth and enable the '
1330 'Google Cloud Storage JSON API.', 1408 'Google Cloud Storage JSON API.',
1331 status=e.status_code) 1409 status=e.status_code)
1332 else: 1410 else:
1333 return AccessDeniedException(message or e.message, 1411 return AccessDeniedException(message or e.message,
1334 status=e.status_code) 1412 status=e.status_code)
1335 elif e.status_code == 404: 1413 elif e.status_code == 404:
1336 if bucket_name: 1414 if not_found_exception:
1415 # The exception is pre-constructed prior to translation; the HTTP
1416 # status code isn't available at that time.
1417 setattr(not_found_exception, 'status', e.status_code)
1418 return not_found_exception
1419 elif bucket_name:
1337 if object_name: 1420 if object_name:
1338 return CreateObjectNotFoundException(e.status_code, self.provider, 1421 return CreateObjectNotFoundException(e.status_code, self.provider,
1339 bucket_name, object_name, 1422 bucket_name, object_name,
1340 generation=generation) 1423 generation=generation)
1341 return CreateBucketNotFoundException(e.status_code, self.provider, 1424 return CreateBucketNotFoundException(e.status_code, self.provider,
1342 bucket_name) 1425 bucket_name)
1343 return NotFoundException(e.message, status=e.status_code) 1426 return NotFoundException(e.message, status=e.status_code)
1427
1344 elif e.status_code == 409 and bucket_name: 1428 elif e.status_code == 409 and bucket_name:
1345 if 'The bucket you tried to delete was not empty.' in str(e): 1429 if 'The bucket you tried to delete was not empty.' in str(e):
1346 return NotEmptyException('BucketNotEmpty (%s)' % bucket_name, 1430 return NotEmptyException('BucketNotEmpty (%s)' % bucket_name,
1347 status=e.status_code) 1431 status=e.status_code)
1348 return ServiceException( 1432 return ServiceException(
1349 'Bucket %s already exists.' % bucket_name, status=e.status_code) 1433 'Bucket %s already exists.' % bucket_name, status=e.status_code)
1350 elif e.status_code == 412: 1434 elif e.status_code == 412:
1351 return PreconditionException(message, status=e.status_code) 1435 return PreconditionException(message, status=e.status_code)
1352 elif (e.status_code == 503 and 1436 elif (e.status_code == 503 and
1353 not self.http.disable_ssl_certificate_validation): 1437 not self.http.disable_ssl_certificate_validation):
1354 return ServiceException(_VALIDATE_CERTIFICATES_503_MESSAGE, 1438 return ServiceException(_VALIDATE_CERTIFICATES_503_MESSAGE,
1355 status=e.status_code) 1439 status=e.status_code)
1356 return ServiceException(message, status=e.status_code) 1440 return ServiceException(message, status=e.status_code)
1357 elif isinstance(e, apitools_exceptions.TransferInvalidError): 1441 elif isinstance(e, apitools_exceptions.TransferInvalidError):
1358 return ServiceException('Transfer invalid (possible encoding error: %s)' 1442 return ServiceException('Transfer invalid (possible encoding error: %s)'
1359 % str(e)) 1443 % str(e))
OLDNEW
« no previous file with comments | « third_party/gsutil/gslib/copy_helper.py ('k') | third_party/gsutil/gslib/gcs_json_media.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698