Beispiel #1
0
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.
    if os.environ.get('CLOUDSDK_WRAPPER') == '1':
      _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 "gcloud auth login" command to '
          'configure gsutil to use these credentials.')))
    else:
      _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))))
Beispiel #2
0
def _RunNamedCommandAndHandleExceptions(command_runner,
                                        command_name,
                                        args=None,
                                        headers=None,
                                        debug=0,
                                        parallel_operations=False):
    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:
            signal.signal(signal.SIGQUIT, _HandleSigQuit)
        return command_runner.RunNamedCommand(command_name, args, headers,
                                              debug, 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 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 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(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 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)
        else:
            _HandleUnknownFailure(e)
    except Exception as e:
        # 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," +
                "\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."
                % GetConfigFilePath())
        _HandleUnknownFailure(e)
Beispiel #3
0
    def _MaybeCheckForAndOfferSoftwareUpdate(self, command_name, debug):
        """Checks the last time we checked for an update, and if it's been longer
       than the configured threshold offers the user to update gsutil.

      Args:
        command_name: The name of the command being run.
        debug: Debug level to pass in to boto connection (range 0..3).

      Returns:
        True if the user decides to update.
    """
        # Don't try to interact with user if:
        # - gsutil is not connected to a tty (e.g., if being run from cron);
        # - user is running gsutil -q
        # - user is running the update command (which could otherwise cause an
        #   additional note that an update is available when user is already trying
        #   to perform an update);
        # - user doesn't have credentials configured; or,
        # - user specified gs_host (which could be a non-production different
        #   service instance, in which case credentials won't work for checking
        #   gsutil tarball).
        gs_host = boto.config.get('Credentials', 'gs_host', None)
        if (not sys.stdout.isatty() or not sys.stderr.isatty()
                or not sys.stdin.isatty() or command_name == 'update'
                or not logging.getLogger().isEnabledFor(logging.INFO)
                or not HasConfiguredCredentials() or gs_host):
            return False

        software_update_check_period = boto.config.get(
            'GSUtil', 'software_update_check_period', 30)
        # Setting software_update_check_period to 0 means periodic software
        # update checking is disabled.
        if software_update_check_period == 0:
            return False

        cur_ts = int(time.time())
        if not os.path.isfile(LAST_CHECKED_FOR_GSUTIL_UPDATE_TIMESTAMP_FILE):
            # Set last_checked_ts from date of VERSION file, so if the user installed
            # an old copy of gsutil it will get noticed (and an update offered) the
            # first time they try to run it.
            last_checked_ts = int(os.path.getmtime(gslib.VERSION_FILE))
            with open(LAST_CHECKED_FOR_GSUTIL_UPDATE_TIMESTAMP_FILE, 'w') as f:
                f.write(str(last_checked_ts))
        else:
            with open(LAST_CHECKED_FOR_GSUTIL_UPDATE_TIMESTAMP_FILE, 'r') as f:
                last_checked_ts = int(f.readline())

        if (cur_ts - last_checked_ts >
                software_update_check_period * SECONDS_PER_DAY):
            suri_builder = StorageUriBuilder(debug,
                                             self.bucket_storage_uri_class)
            cur_ver = LookUpGsutilVersion(
                suri_builder.StorageUri(GSUTIL_PUB_TARBALL))
            with open(LAST_CHECKED_FOR_GSUTIL_UPDATE_TIMESTAMP_FILE, 'w') as f:
                f.write(str(cur_ts))
            if gslib.VERSION != cur_ver:
                print '\n'.join(
                    textwrap.wrap(
                        'A newer version of gsutil (%s) is available than the version you '
                        'are running (%s). A detailed log of gsutil release changes is '
                        'available at gs://pub/gsutil_ReleaseNotes.txt if you would like '
                        'to read them before updating.' %
                        (cur_ver, gslib.VERSION),
                        width=78))
                if gslib.IS_PACKAGE_INSTALL:
                    return False
                print
                answer = raw_input('Would you like to update [Y/n]? ')
                return not answer or answer.lower()[0] != 'n'
        return False