示例#1
0
def main(gcloud_cli=None):
  metrics.Started(START_TIME)
  # TODO(b/36049857): Put a real version number here
  metrics.Executions(
      'gcloud',
      local_state.InstallationState.VersionForInstalledComponent('core'))
  if gcloud_cli is None:
    gcloud_cli = CreateCLI([])
  try:
    try:
      gcloud_cli.Execute()
    except IOError as err:
      # We want to ignore EPIPE IOErrors.
      # By default, Python ignores SIGPIPE (see
      # http://utcc.utoronto.ca/~cks/space/blog/python/SignalExceptionSurprise).
      # This means that attempting to write any output to a closed pipe (e.g. in
      # the case of output piped to `head` or `grep -q`) will result in an
      # IOError, which gets reported as a gcloud crash. We don't want this
      # behavior, so we ignore EPIPE (it's not a real error; it's a normal thing
      # to occur).
      # Before, we restore the SIGPIPE signal handler, but that caused issues
      # with scripts/programs that wrapped gcloud.
      if err.errno != errno.EPIPE:
        raise
  except Exception as err:  # pylint:disable=broad-except
    crash_handling.HandleGcloudCrash(err)
    if properties.VALUES.core.print_unhandled_tracebacks.GetBool():
      # We want to see the traceback as normally handled by Python
      raise
    else:
      # This is the case for most non-Cloud SDK developers. They shouldn't see
      # the full stack trace, but just the nice "gcloud crashed" message.
      sys.exit(1)
  def testCraReportCrashWithCorrectException(self):
    properties.VALUES.core.disable_usage_reporting.Set(False)
    properties.VALUES.metrics.command_name.Set(COMMAND)
    self.StartObjectPatch(metrics, 'GetCIDIfMetricsEnabled', return_value=CID)

    crash_handling.HandleGcloudCrash(Exception())

    self.assertTrue(self.report_event_mock.called)
    args, _ = self.report_event_mock.call_args_list[0]
    self.assertTrue(args[0].startswith(
        'https://clouderrorreporting.googleapis.com/v1beta1/projects/cloud-sdk'
        '-crashes/events:report?'))
    self.assertEqual(args[1], 'POST')
    self.assertEqual(
        args[2],
        '{"context": {"httpRequest": {"url": "command"}, "user": '******'"randomly-generated-id-adsfad"}, "message": "%s", "serviceContext": {'
        '"service": "gcloud", "version": "%s"}}'
        % (EXAMPLE_TRACEBACK_SERIALIZED, config.CLOUD_SDK_VERSION))
    content_length = str(447 + len(config.CLOUD_SDK_VERSION))
    self.assertEqual(
        args[3],
        {'content-length': content_length, 'content-type': 'application/json',
         'accept-encoding': 'gzip, deflate', 'accept': 'application/json',
         'user-agent': 'google-cloud-sdk'})

    self.AssertErrContains('gcloud crashed')
    self.AssertErrContains('If you would like to report this issue, please run '
                           'the following command:')
    self.AssertErrContains('gcloud feedback')
    self.AssertErrContains('To check gcloud for common problems, please run '
                           'the following command:')
    self.AssertErrContains('gcloud info --run-diagnostics')
 def testExceptionImportErrorRunCommand(self):
   # We want to suggest reinstall here and skip error reporting
   msg = 'Example exception message text'
   exception = command_loading.CommandLoadFailure('gcloud version',
                                                  ImportError(msg))
   crash_handling.HandleGcloudCrash(exception)
   self.report_error_mock.assert_not_called()
   self.AssertErrContains('gcloud failed to load')
   self.AssertErrContains('gcloud components reinstall')
   self.AssertErrContains('https://cloud.google.com/sdk/')
   self.AssertErrNotContains(r'gcloud feedback')
  def testDisableMetricsDontSendErrorReport(self):
    crash_handling.HandleGcloudCrash(Exception())

    self.report_event_mock.assert_not_called()

    self.AssertErrContains('gcloud crashed')
    self.AssertErrContains('If you would like to report this issue, please run '
                           'the following command:')
    self.AssertErrContains('gcloud feedback')
    self.AssertErrContains('To check gcloud for common problems, please run '
                           'the following command:')
    self.AssertErrContains('gcloud info --run-diagnostics')
 def testHandleGcloudCrashUsageTrueProperty(self):
   # disable_usage_reporting is set to True
   msg = 'Example exception message text'
   exception = Exception(msg)
   crash_handling.HandleGcloudCrash(exception)
   self.report_event_mock.assert_not_called()
   self.AssertErrContains('gcloud crashed')
   self.AssertErrContains('If you would like to report this issue, please run '
                          'the following command:')
   self.AssertErrContains('gcloud feedback')
   self.AssertErrContains('To check gcloud for common problems, please run '
                          'the following command:')
   self.AssertErrContains('gcloud info --run-diagnostics')
示例#6
0
def main(gcloud_cli=None, credential_providers=None):
    if not platforms.PythonVersion().IsCompatible(
            allow_py3=properties.VALUES.core.allow_py3.GetBool()):
        sys.exit(1)
    metrics.Started(START_TIME)
    # TODO(b/36049857): Put a real version number here
    metrics.Executions(
        'gcloud',
        local_state.InstallationState.VersionForInstalledComponent('core'))
    if gcloud_cli is None:
        gcloud_cli = CreateCLI([])

    # Register some other sources for credentials and project.
    credential_providers = credential_providers or [
        creds_store.DevShellCredentialProvider(),
        creds_store.GceCredentialProvider(),
    ]
    for provider in credential_providers:
        provider.Register()
    # Register support for service account impersonation.
    creds_store.IMPERSONATION_TOKEN_PROVIDER = (
        iamcred_util.ImpersonationAccessTokenProvider())

    try:
        try:
            gcloud_cli.Execute()
        except IOError as err:
            # We want to ignore EPIPE IOErrors.
            # By default, Python ignores SIGPIPE (see
            # http://utcc.utoronto.ca/~cks/space/blog/python/SignalExceptionSurprise).
            # This means that attempting to write any output to a closed pipe (e.g. in
            # the case of output piped to `head` or `grep -q`) will result in an
            # IOError, which gets reported as a gcloud crash. We don't want this
            # behavior, so we ignore EPIPE (it's not a real error; it's a normal thing
            # to occur).
            # Before, we restore the SIGPIPE signal handler, but that caused issues
            # with scripts/programs that wrapped gcloud.
            if err.errno != errno.EPIPE:
                raise
    except Exception as err:  # pylint:disable=broad-except
        crash_handling.HandleGcloudCrash(err)
        if properties.VALUES.core.print_unhandled_tracebacks.GetBool():
            # We want to see the traceback as normally handled by Python
            raise
        else:
            # This is the case for most non-Cloud SDK developers. They shouldn't see
            # the full stack trace, but just the nice "gcloud crashed" message.
            sys.exit(1)
    finally:
        for provider in credential_providers:
            provider.UnRegister()
 def testHandleGcloudCrashUsageFalseProperty(self):
   # disable_usage_reporting is set to False
   msg = 'Example exception message text'
   exception = Exception(msg)
   properties.VALUES.core.disable_usage_reporting.Set(False)
   crash_handling.HandleGcloudCrash(exception)
   self.report_error_mock.assert_called_with(is_crash=True)
   self.AssertErrContains('gcloud crashed')
   self.AssertErrContains('If you would like to report this issue, please run '
                          'the following command:')
   self.AssertErrContains('gcloud feedback')
   self.AssertErrContains('To check gcloud for common problems, please run '
                          'the following command:')
   self.AssertErrContains('gcloud info --run-diagnostics')
  def testMetricsError(self):
    self.report_event_mock.side_effect = apitools_exceptions.Error
    properties.VALUES.core.disable_usage_reporting.Set(False)
    properties.VALUES.metrics.command_name.Set(COMMAND)
    self.StartObjectPatch(metrics, 'GetCIDIfMetricsEnabled', return_value=CID)

    crash_handling.HandleGcloudCrash(Exception())

    self.report_event_mock.assert_called_once()

    self.AssertErrContains('gcloud crashed')
    self.AssertErrContains('If you would like to report this issue, please run '
                           'the following command:')
    self.AssertErrContains('gcloud feedback')
    self.AssertErrContains('To check gcloud for common problems, please run '
                           'the following command:')
    self.AssertErrContains('gcloud info --run-diagnostics')
 def testInvalidCaCerts(self):
   msg = 'certificate verify failed'
   crash_handling.HandleGcloudCrash(Exception(msg))
   self.report_error_mock.assert_called_once()
   self.AssertErrContains('gcloud crashed')
   self.AssertErrContains('gcloud\'s default CA certificates failed to verify '
                          'your connection, which can happen if you are behind'
                          ' a proxy or firewall.')
   self.AssertErrContains('To use a custom CA certificates file, please run '
                          'the following command:')
   self.AssertErrContains('  gcloud config set core/custom_ca_certs_file '
                          '/path/to/ca_certs')
   self.AssertErrContains('If you would like to report this issue, please run '
                          'the following command:')
   self.AssertErrContains('gcloud feedback')
   self.AssertErrContains('To check gcloud for common problems, please run '
                          'the following command:')
   self.AssertErrContains('gcloud info --run-diagnostics')
示例#10
0
def main(gcloud_cli=None, credential_providers=None):
    if not platforms.PythonVersion().IsCompatible(
            allow_py3=properties.VALUES.core.allow_py3.GetBool()):
        sys.exit(1)
    metrics.Started(START_TIME)
    # TODO(b/36049857): Put a real version number here
    metrics.Executions(
        'gcloud',
        local_state.InstallationState.VersionForInstalledComponent('core'))
    if gcloud_cli is None:
        gcloud_cli = CreateCLI([])

    # Register some other sources for credentials and project.
    credential_providers = credential_providers or [
        creds_store.DevShellCredentialProvider(),
        creds_store.GceCredentialProvider(),
    ]
    for provider in credential_providers:
        provider.Register()
    # Register support for service account impersonation.
    creds_store.IMPERSONATION_TOKEN_PROVIDER = (
        iamcred_util.ImpersonationAccessTokenProvider())

    try:
        try:
            gcloud_cli.Execute()
            # Flush stdout so that if we've received a SIGPIPE we handle the broken
            # pipe within this try block, instead of potentially during interpreter
            # shutdown.
            sys.stdout.flush()
        except IOError as err:
            # We want to ignore EPIPE IOErrors (as of Python 3.3 these can be caught
            # specifically with BrokenPipeError, but we do it this way for Python 2
            # compatibility).
            #
            # By default, Python ignores SIGPIPE (see
            # http://utcc.utoronto.ca/~cks/space/blog/python/SignalExceptionSurprise).
            # This means that attempting to write any output to a closed pipe (e.g. in
            # the case of output piped to `head` or `grep -q`) will result in an
            # IOError, which gets reported as a gcloud crash. We don't want this
            # behavior, so we ignore EPIPE (it's not a real error; it's a normal thing
            # to occur).
            #
            # Before, we restored the SIGPIPE signal handler, but that caused issues
            # with scripts/programs that wrapped gcloud.
            if err.errno == errno.EPIPE:
                # At this point we've caught the broken pipe, but since Python flushes
                # standard streams on exit, it's still possible for a broken pipe error
                # to happen during interpreter shutdown. The interpreter will catch this
                # but in Python 3 it still prints a warning to stderr saying that the
                # exception was ignored (see https://bugs.python.org/issue11380):
                #
                # Exception ignored in: <_io.TextIOWrapper name='<stdout>' mode='w'
                # encoding='UTF-8'>
                # BrokenPipeError: [Errno 32] Broken pipe
                #
                # To prevent this from happening, we redirect any remaining output to
                # devnull as recommended here:
                # https://docs.python.org/3/library/signal.html#note-on-sigpipe.
                devnull = os.open(os.devnull, os.O_WRONLY)
                os.dup2(devnull, sys.stdout.fileno())
            else:
                raise
    except Exception as err:  # pylint:disable=broad-except
        crash_handling.HandleGcloudCrash(err)
        if properties.VALUES.core.print_unhandled_tracebacks.GetBool():
            # We want to see the traceback as normally handled by Python
            raise
        else:
            # This is the case for most non-Cloud SDK developers. They shouldn't see
            # the full stack trace, but just the nice "gcloud crashed" message.
            sys.exit(1)
    finally:
        for provider in credential_providers:
            provider.UnRegister()