def RunCommand(self): """Command entry point for the version command.""" long_form = False if self.sub_opts: for o, _ in self.sub_opts: if o == '-l': long_form = True if GetConfigFilePaths(): config_paths = ', '.join(GetConfigFilePaths()) else: config_paths = 'no config found' shipped_checksum = gslib.CHECKSUM try: cur_checksum = self._ComputeCodeChecksum() except IOError: cur_checksum = 'MISSING FILES' if shipped_checksum == cur_checksum: checksum_ok_str = 'OK' else: checksum_ok_str = '!= %s' % shipped_checksum sys.stdout.write('gsutil version: %s\n' % gslib.VERSION) if long_form: long_form_output = ( 'checksum: {checksum} ({checksum_ok})\n' 'boto version: {boto_version}\n' 'python version: {python_version}\n' 'OS: {os_version}\n' 'multiprocessing available: {multiprocessing_available}\n' 'using cloud sdk: {cloud_sdk}\n' 'config path(s): {config_paths}\n' 'gsutil path: {gsutil_path}\n' 'compiled crcmod: {compiled_crcmod}\n' 'installed via package manager: {is_package_install}\n' 'editable install: {is_editable_install}\n') sys.stdout.write( long_form_output.format( checksum=cur_checksum, checksum_ok=checksum_ok_str, boto_version=boto.__version__, python_version=sys.version.replace('\n', ''), os_version='%s %s' % (platform.system(), platform.release()), multiprocessing_available=( CheckMultiprocessingAvailableAndInit().is_available), cloud_sdk=(os.environ.get('CLOUDSDK_WRAPPER') == '1'), config_paths=config_paths, gsutil_path=gslib.GSUTIL_PATH, compiled_crcmod=UsingCrcmodExtension(crcmod), is_package_install=gslib.IS_PACKAGE_INSTALL, is_editable_install=gslib.IS_EDITABLE_INSTALL, )) return 0
def _RunNamedCommandAndHandleExceptions( command_runner, command_name, args=None, headers=None, debug_level=0, trace_token=None, parallel_operations=False, perf_trace_token=None): """Runs the command and handles common exceptions.""" # pylint: disable=g-import-not-at-top from gslib.util import GetConfigFilePaths 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. Register as a final signal handler because this handler kills # the main gsutil process (so it must run last). RegisterSignalHandler(signal.SIGINT, _HandleControlC, is_final_handler=True) # Catch ^\ so we can force a breakpoint in a running gsutil. if not IS_WINDOWS: RegisterSignalHandler(signal.SIGQUIT, _HandleSigQuit) return command_runner.RunNamedCommand(command_name, args, headers, debug_level, trace_token, parallel_operations, perf_trace_token=perf_trace_token, collect_analytics=True) 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?', exception=e) else: _OutputAndExit(message=str(e), exception=e) except CommandException as e: _HandleCommandException(e) except getopt.GetoptError as e: _HandleCommandException(CommandException(e.msg)) except boto.exception.InvalidUriError as e: _OutputAndExit(message='InvalidUriError: %s.' % e.message, exception=e) except gslib.exception.InvalidUrlError as e: _OutputAndExit(message='InvalidUrlError: %s.' % e.message, exception=e) except boto.auth_handler.NotReadyToAuthenticate: _OutputAndExit(message='NotReadyToAuthenticate', exception=e) except OSError as e: _OutputAndExit(message='OSError: %s.' % e.strerror, exception=e) except IOError as e: 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, # just swallow it up and exit cleanly. sys.exit(0) else: raise except wildcard_iterator.WildcardException as e: _OutputAndExit(message=e.reason, exception=e) 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.', exception=e) except BadRequestException as e: if e.reason == 'MissingSecurityHeader': _CheckAndHandleCredentialException(e, args) _OutputAndExit(message=e, exception=e) except AccessDeniedException as e: _CheckAndHandleCredentialException(e, args) _OutputAndExit(message=e, exception=e) except ArgumentException as e: _OutputAndExit(message=e, exception=e) except ServiceException as e: _OutputAndExit(message=e, exception=e) except oauth2client.client.HttpAccessTokenRefreshError as e: if os.environ.get('CLOUDSDK_WRAPPER') == '1': _OutputAndExit('Your credentials are invalid. ' 'Please run\n$ gcloud auth login', exception=e) else: _OutputAndExit( 'Your credentials are invalid. For more help, see ' '"gsutil help creds", or re-run the gsutil config command (see ' '"gsutil help config").', exception=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 ''), exception=e) 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. _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.', exception=e) elif e.args[0] == errno.ECONNRESET and ' '.join(args).contains('s3://'): _OutputAndExit('\n'.join(textwrap.wrap( 'Got a "Connection reset by peer" error. One way this can happen is ' 'when copying data to/from an S3 regional bucket. If you are using a ' 'regional S3 bucket you could try re-running this command using the ' 'regional S3 endpoint, for example ' 's3://s3-<region>.amazonaws.com/your-bucket. For details about this ' 'problem see https://github.com/boto/boto/issues/2207')), exception=e) else: _HandleUnknownFailure(e) except oauth2client.client.FlowExchangeError as e: _OutputAndExit('\n%s\n\n' % '\n'.join(textwrap.wrap( 'Failed to retrieve valid credentials (%s). Make sure you selected and ' 'pasted the ENTIRE authorization code (including any numeric prefix ' "e.g. '4/')." % e)), exception=e) except Exception as e: # pylint: disable=broad-except if GetConfigFilePaths(): config_paths = ', '.join(GetConfigFilePaths()) else: config_paths = 'no config found' # Check for two types of errors related to service accounts. These errors # appear to be the same except for their messages, but they are caused by # 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(s),' '\n%s, is correct.' % config_paths, exception=e) 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(s),\n%s, is correct.' % config_paths, exception=e) _HandleUnknownFailure(e)