def Display(self):
        """The default display method."""

        if not log.IsUserOutputEnabled():
            log.info('Display disabled.')
            # NOTICE: Do not consume resources here. Some commands use this case to
            # access the results of Run() via the return value of Execute(). However,
            # to satisfy callers who are only interetsted in silent side effects,
            # generators/iterators must be converted to a list here.
            if resource_property.IsListLike(self._resources):
                return list(self._resources)
            return self._resources

        # Initialize the printer.
        self._InitPrinter()

        # Add a URI cache update tap if needed.
        self._AddUriCacheTap()

        # Add a resource page tap if needed.
        self._AddPageTap()

        # Add a resource flatten tap if needed.
        self._AddFlattenTap()

        # Add a sort tap if needed.
        self._AddSortByTap()

        # Add a resource filter tap if needed.
        self._AddFilterTap()

        # Add a resource limit tap if needed.
        self._AddLimitTap()

        # Add the URI replace tap if needed.
        self._AddUriReplaceTap()

        resources_were_displayed = True
        if self._printer:
            # Most command output will end up here.
            log.info('Display format "%s".', self._format)
            self._printer.Print(self._resources)
            resources_were_displayed = self._printer.ResourcesWerePrinted()
        elif hasattr(self._command, 'Display'):
            # This will eventually be rare.
            log.info('Explicit Display.')
            self._command.Display(self._args, self._resources)

        # Resource display is done.
        log.out.flush()

        # If the default format was used then display the epilog.
        if not self._args.IsSpecified('format'):
            self._command.Epilog(resources_were_displayed)

        return self._resources
Пример #2
0
  def Run(self, cli, args):
    """Run this command with the given arguments.

    Args:
      cli: The cli.CLI object for this command line tool.
      args: The arguments for this command as a namespace.

    Returns:
      The object returned by the module's Run() function.

    Raises:
      exceptions.Error: if thrown by the Run() function.
      exceptions.ExitCodeNoError: if the command is returning with a non-zero
        exit code.
    """
    def Http(**kwargs):
      # Possibly override timeout, making sure to leave kwargs[timeout]
      # undefined (as opposed to None) if args.http_timout is not set.
      if args.http_timeout:
        kwargs['timeout'] = args.http_timeout

      return core_cli.Http(cmd_path=self.dotted_name,
                           trace_token=args.trace_token,
                           log_http=properties.VALUES.core.log_http.GetBool(),
                           **kwargs)

    tool_context = self._config_hooks.load_context()
    last_group = None
    for context_filter in self._config_hooks.context_filters:
      last_group = context_filter(tool_context, Http, args)

    command_instance = self._common_type(
        cli=cli,
        context=tool_context,
        group=last_group,
        http_func=Http,
        format_string=args.format or 'yaml')

    if args.format:
      output_formatter = command_instance.format
    else:
      output_formatter = lambda obj: command_instance.Display(args, obj)

    log.debug('Running %s with %s.', self.dotted_name, args)
    metrics.Loaded()
    result = command_instance.Run(args)
    if log.IsUserOutputEnabled():
      output_formatter(result)
    metrics.Ran()

    if command_instance.exit_code != 0:
      raise exceptions.ExitCodeNoError(exit_code=command_instance.exit_code)

    return result
Пример #3
0
def RunExecutable(cmd_args,
                  strict_error_checking=True,
                  ignore_ssh_errors=False):
    """Run the given command, handling errors appropriately.

  Args:
    cmd_args: list of str, the arguments (including executable path) to run
    strict_error_checking: bool, whether a non-zero, non-255 exit code should be
      considered a failure.
    ignore_ssh_errors: bool, when true ignore all errors, including the 255
      exit code.

  Returns:
    int, the return code of the command

  Raises:
    CommandError: if the command failed (based on the command exit code and
      the strict_error_checking flag)
  """
    outfile = SSH_OUTPUT_FILE or os.devnull
    with open(outfile, 'w') as output_file:
        if log.IsUserOutputEnabled() and not SSH_OUTPUT_FILE:
            stdout, stderr = None, None
        else:
            stdout, stderr = output_file, output_file
        if (platforms.OperatingSystem.IsWindows()
                and not cmd_args[0].endswith('winkeygen.exe')):
            # TODO(b/25126583): Drop StrictHostKeyChecking=no and 'y'.
            # PuTTY and friends always prompt on fingerprint mismatch. A 'y' response
            # adds/updates the fingerprint registry entry and proceeds. The prompt
            # will appear once for each new/changed host. Redirecting stdin is not a
            # problem. Even interactive ssh is not a problem because a separate PuTTY
            # term is used and it ignores the calling process stdin.
            stdin = subprocess.PIPE
        else:
            stdin = None
        try:
            proc = subprocess.Popen(cmd_args,
                                    stdin=stdin,
                                    stdout=stdout,
                                    stderr=stderr)
            if stdin == subprocess.PIPE:
                # Max one prompt per host and there can't be more hosts than args.
                proc.communicate('y\n' * len(cmd_args))
            returncode = proc.wait()
        except OSError as e:
            raise CommandError(cmd_args[0], message=e.strerror)
        if not ignore_ssh_errors:
            if ((returncode and strict_error_checking)
                    or returncode == _SSH_ERROR_EXIT_CODE):
                raise CommandError(cmd_args[0], return_code=returncode)
        return returncode
Пример #4
0
  def __exit__(self, exc_type, exc_val, exc_tb):
    if not exc_val:
      status = 'SUCCESS'
    elif isinstance(exc_val, console_io.OperationCancelledError):
      status = 'INTERRUPTED'
    else:
      status = 'FAILURE'

    if log.IsUserOutputEnabled():
      self._stream.write(console_io.JsonUXStub(
          console_io.UXElementType.PROGRESS_TRACKER,
          message=self._message, status=status) + '\n')
    return super(_StubProgressTracker, self).__exit__(exc_type, exc_val, exc_tb)
Пример #5
0
    def Run(self, cli, args):
        """Run this command with the given arguments.

    Args:
      cli: The cli.CLI object for this command line tool.
      args: The arguments for this command as a namespace.

    Returns:
      The object returned by the module's Run() function.

    Raises:
      exceptions.Error: if thrown by the Run() function.
    """
        def Http(**kwargs):
            return core_cli.Http(cmd_path=self.dotted_name,
                                 trace_token=args.trace_token,
                                 log_http=args.log_http,
                                 timeout=args.http_timeout,
                                 **kwargs)

        tool_context = self._config_hooks.load_context()
        last_group = None
        for context_filter in self._config_hooks.context_filters:
            last_group = context_filter(tool_context, Http, args)

        command_instance = self._common_type(cli=cli,
                                             context=tool_context,
                                             group=last_group,
                                             http_func=Http,
                                             format_string=args.format
                                             or 'yaml')

        if args.format:
            output_formatter = command_instance.format
        else:
            output_formatter = lambda obj: command_instance.Display(args, obj)

        log.debug('Running %s with %s.', self.dotted_name, args)
        metrics.Loaded()
        result = command_instance.Run(args)
        if log.IsUserOutputEnabled():
            output_formatter(result)
        metrics.Ran()

        if command_instance.exit_code != 0:
            raise exceptions.ExitCodeNoError(
                exit_code=command_instance.exit_code)

        return result
Пример #6
0
  def Display(self):
    """The default display method."""

    if not log.IsUserOutputEnabled():
      log.info('Display disabled.')
      # NOTICE: Do not consume resources here. Some commands use this case to
      # access the results of Run() via the return value of Execute().
      return self._resources

    # Initialize the printer.
    self._InitPrinter()

    # Add a URI cache update tap if needed.
    self._AddUriCacheTap()

    # Add a resource page tap if needed.
    self._AddPageTap()

    # Add a resource flatten tap if needed.
    self._AddFlattenTap()

    # Add a resource filter tap if needed.
    self._AddFilterTap()

    # Add a resource limit tap if needed.
    self._AddLimitTap()

    # Add the URI replace tap if needed.
    self._AddUriReplaceTap()

    resources_were_displayed = True
    if self._printer:
      # Most command output will end up here.
      log.info('Display format "%s".', self._format)
      self._printer.Print(self._resources)
      resources_were_displayed = self._printer.ResourcesWerePrinted()
    elif hasattr(self._command, 'Display'):
      # This will eventually be rare.
      log.info('Explict Display.')
      self._command.Display(self._args, self._resources)

    # Resource display is done.
    log.out.flush()

    # If the default format was used then display the epilog.
    if self._default_format_used:
      self._command.Epilog(resources_were_displayed)

    return self._resources
Пример #7
0
def _RunExecutable(cmd_args, interactive_ssh=False):
    with open(os.devnull, 'w') as devnull:
        if log.IsUserOutputEnabled():
            stdout, stderr = None, None
        else:
            stdout, stderr = devnull, devnull
        try:
            subprocess.check_call(cmd_args, stdout=stdout, stderr=stderr)
        except OSError as e:
            raise SshLikeCmdFailed(cmd_args[0], message=e.strerror)
        except subprocess.CalledProcessError as e:
            # Interactive ssh exits with the exit status of the last command executed.
            # This is traditionally not interpreted as an error.
            if not interactive_ssh or e.returncode == 255:
                raise SshLikeCmdFailed(cmd_args[0], return_code=e.returncode)
def _RunExecutable(cmd_args, strict_error_checking=True):
    """Run the given command, handling errors appropriately.

  Args:
    cmd_args: list of str, the arguments (including executable path) to run
    strict_error_checking: bool, whether a non-zero, non-255 exit code should be
      considered a failure.

  Returns:
    int, the return code of the command

  Raises:
    SshLikeCmdFailed: if the command failed (based on the command exit code and
      the strict_error_checking flag)
  """
    with open(os.devnull, 'w') as devnull:
        if log.IsUserOutputEnabled():
            stdout, stderr = None, None
        else:
            stdout, stderr = devnull, devnull
        if _IsRunningOnWindows() and not cmd_args[0].endswith('winkeygen.exe'):
            # TODO(user): b/25126583 will drop StrictHostKeyChecking=no and 'y'.
            # PuTTY and friends always prompt on fingerprint mismatch. A 'y' response
            # adds/updates the fingerprint registry entry and proceeds. The prompt
            # will appear once for each new/changed host. Redirecting stdin is not a
            # problem. Even interactive ssh is not a problem because a separate PuTTY
            # term is used and it ignores the calling process stdin.
            stdin = subprocess.PIPE
        else:
            stdin = None
        try:
            proc = subprocess.Popen(cmd_args,
                                    stdin=stdin,
                                    stdout=stdout,
                                    stderr=stderr)
            if stdin == subprocess.PIPE:
                # Max one prompt per host and there can't be more hosts than args.
                proc.communicate('y\n' * len(cmd_args))
            returncode = proc.wait()
        except OSError as e:
            raise SshLikeCmdFailed(cmd_args[0], message=e.strerror)
        except subprocess.CalledProcessError as e:
            if strict_error_checking or e.returncode == _SSH_ERROR_EXIT_CODE:
                raise SshLikeCmdFailed(cmd_args[0], return_code=e.returncode)
            return e.returncode
        return returncode
Пример #9
0
def _RunExecutable(cmd_args, interactive_ssh=False):
    with open(os.devnull, 'w') as devnull:
        if log.IsUserOutputEnabled():
            stdout, stderr = None, None
        else:
            stdout, stderr = devnull, devnull
        try:
            subprocess.check_call(cmd_args, stdout=stdout, stderr=stderr)
        except OSError as e:
            raise exceptions.ToolException('[{0}] exited with [{1}].'.format(
                cmd_args[0], e.strerror))
        except subprocess.CalledProcessError as e:
            # Interactive ssh exits with the exit status of the last command executed.
            # This is traditionally not interpreted as an error.
            if not interactive_ssh or e.returncode == 255:
                raise exceptions.ToolException(
                    '[{0}] exited with return code [{1}].'.format(
                        cmd_args[0], e.returncode))
Пример #10
0
    def Display(self):
        """The default display method."""

        if not log.IsUserOutputEnabled():
            log.info('Display disabled.')
            # NOTICE: Do not consume resources here. Some commands use this case to
            # access the results of Run() via the return value of Execute().
            return self._resources

        # Determine the format.
        fmt = self._GetFormat()

        # Add a URI cache update tap if needed.
        self._AddUriCacheTap()

        # Add a resource page tap if needed.
        self._AddPageTap()

        # Add a resource flatten tap if needed.
        self._AddFlattenTap()

        # Add a resource filter tap if needed.
        self._AddFilterTap()

        # Add a resource limit tap if needed.
        self._AddLimitTap()

        if fmt:
            # Most command output will end up here.
            log.info('Display format "%s".', fmt)
            resource_printer.Print(self._resources,
                                   fmt,
                                   defaults=self._defaults,
                                   out=log.out)
        elif hasattr(self._command, 'Display'):
            # This will eventually be rare.
            log.info('Explict Display.')
            self._command.Display(self._args, self._resources)

        # If the default format was used then display the epilog.
        if self._default_format_used:
            self._command.Epilog(self._args)

        return self._resources
Пример #11
0
  def __exit__(self, exc_type, exc_val, exc_tb):
    if exc_val and isinstance(exc_val, console_io.OperationCancelledError):
      status_message = 'INTERRUPTED'
    elif exc_val:
      status_message = 'FAILURE'
    elif self.HasWarning():
      status_message = 'WARNING'
    else:
      status_message = 'SUCCESS'

    if log.IsUserOutputEnabled():
      self._stream.write(console_io.JsonUXStub(
          console_io.UXElementType.STAGED_PROGRESS_TRACKER,
          message=self._message,
          status=status_message,
          succeeded_stages=self._succeeded_stages,
          failed_stage=self._failed_stage) + '\n')
    return super(
        _StubStagedProgressTracker, self).__exit__(exc_type, exc_val, exc_tb)
Пример #12
0
  def __init__(self, message, stages, success_message, warning_message,
               failure_message, autotick, tick_delay, interruptable,
               aborted_message, tracker_id, done_message_callback,
               console=None):
    self._stages = collections.OrderedDict()
    for stage in stages:
      if stage.key in self._stages:
        raise ValueError('Duplicate stage key: {}'.format(stage.key))
      self._stages[stage.key] = stage
    self._stream = sys.stderr
    # TODO(b/111637901): Support detailed message callback when true multiline
    # support is available.
    self._message = message
    self._success_message = success_message
    self._warning_message = warning_message
    self._failure_message = failure_message
    self._aborted_message = aborted_message
    self._done_message_callback = done_message_callback
    self._tracker_id = tracker_id
    if console is None:
      console = console_attr.GetConsoleAttr()
    console_width = console.GetTermSize()[0]
    if not isinstance(console_width, int) or console_width < 0:
      # This can happen if we're on a pseudo-TTY. Set it to 0 and also
      # turn off output to prevent hanging.
      console_width = 0
    self._output_enabled = log.IsUserOutputEnabled() and console_width != 0
    # Don't bother autoticking if we aren't going to print anything.
    self.__autotick = autotick and self._output_enabled
    self._interruptable = interruptable
    self._tick_delay = tick_delay

    self._symbols = console.GetProgressTrackerSymbols()
    self._done = False
    self._exception_is_uncaught = True
    self._ticks = 0
    self._ticker = None
    self._running_stages = set()
    self._completed_stages = []
    self._completed_with_warnings_stages = []
    self._exit_output_warnings = []
    self._lock = threading.Lock()
Пример #13
0
    def Display(self):
        """The default display method."""

        if not log.IsUserOutputEnabled():
            log.debug('Display disabled.')
            # NOTICE: Do not consume resources here. Some commands use this case to
            # access the results of Run() via the return value of Execute().
            return

        # Determine the format.
        fmt = self._GetFormat()

        if fmt:
            # Most command output will end up here.
            log.debug('Display format "%s".', fmt)
            # TODO(gsfowler): b/24267426
            if self._resources is not None:
                resource_printer.Print(self._resources, fmt, out=log.out)
        else:
            # This will eventually be rare.
            log.debug('Explict Display.')
            self._command.Display(self._args, self._resources)
Пример #14
0
 def __init__(self, message, autotick, detail_message_callback, tick_delay,
              interruptable, aborted_message):
   self._stream = sys.stderr
   if message is None:
     self._spinner_only = True
     self._message = ''
     self._prefix = ''
   else:
     self._spinner_only = False
     self._message = message
     self._prefix = message + '...'
   self._detail_message_callback = detail_message_callback
   self._ticks = 0
   self._done = False
   self._lock = threading.Lock()
   self._tick_delay = tick_delay
   self._ticker = None
   self._output_enabled = log.IsUserOutputEnabled()
   # Don't bother autoticking if we aren't going to print anything.
   self.__autotick = autotick and self._output_enabled
   self._interruptable = interruptable
   self._aborted_message = aborted_message
   self._old_signal_handler = None
   self._symbols = console_attr.GetConsoleAttr().GetProgressTrackerSymbols()