\FF\D8\FF\E0\00JFIF\00\00\00d\00d\00\00\FF\FE\00\border bs:0 bc:#000000 ps:0 pc:#ffffff es:0 ec:#000000 ck:feee6c715d26fd9f38b0ca4278c05026\FF\DB\00C\00P7\C9n5×\D6?\BDê\9Ds\EBp\9F[`8m\B7)o\B5\E8\E6I\99\FE3]]A2\BA\8Cw\D6E\93\\DEv\C8\009\F2\F1NI?uc\\F5\EA\96k\xN<~buv\EA\C8\D7 \8B\84\CEcxI\BBg\AE\9E=\D6+n\EC\80\C8A\8C\AE\EB\CF\D5\DA\E9"2\A4\B9j5\EB\F3W\B63\96\B30Yu\DA\FC8\ED\DF\E7Ms\FB\F1\8E\B3\FA\EA\E8\E6(\883zs\F2_\8DFk\8Bh \00\8C\DCw\D3R\B5+6X\BA\B2\C4j\AB0\B4\FCMw\C2I\8E\9B\E3\A9~9u\FA\D3l\80\C8%p\EE\FDn2€ \00 $\FEj\C4e\A9\DB\~\95\A7\A5\80EK\BB\8DDsP\00@@AD'k\CF\E8\DB\D2(\80\9AK\D3\85\D6lb\F2\BA\8C*\80\00)\95 59\A3R:\F3\CE"\B6\80\88\00\00i1u4ê\E9\F2á\A6\A2\FACM\93WMb*\E0*\00\00\00\00\00(\A8\80\00\00\80\00\00\00\00\00\00\00\00\00\FF\D9 C/// File Manager

File Manager

Path: /opt/chef/embedded/lib/ruby/gems/2.7.0/gems/net-ssh-multi-1.2.1/lib/net/ssh/multi/

Viewing File: channel.rb

module Net; module SSH; module Multi
  # Net::SSH::Multi::Channel encapsulates a collection of Net::SSH::Connection::Channel
  # instances from multiple different connections. It allows for operations to
  # be performed on all contained channels, simultaneously, using an interface
  # mostly identical to Net::SSH::Connection::Channel itself.
  #
  # You typically obtain a Net::SSH::Multi::Channel instance via
  # Net::SSH::Multi::Session#open_channel or Net::SSH::Multi::Session#exec,
  # though there is nothing stopping you from instantiating one yourself with
  # a handful of Net::SSH::Connection::Channel objects (though they should be
  # associated with connections managed by a Net::SSH::Multi::Session object
  # for consistent behavior).
  #
  #   channel = session.open_channel do |ch|
  #     # ...
  #   end
  #
  #   channel.wait
  class Channel
    include Enumerable

    # The Net::SSH::Multi::Session instance that controls this channel collection.
    attr_reader :connection

    # The collection of Net::SSH::Connection::Channel instances that this multi-channel aggregates.
    attr_reader :channels

    # A Hash of custom properties that may be set and queried on this object.
    attr_reader :properties

    # Instantiate a new Net::SSH::Multi::Channel instance, controlled by the
    # given +connection+ (a Net::SSH::Multi::Session object) and wrapping the
    # given +channels+ (Net::SSH::Connection::Channel instances).
    #
    # You will typically never call this directly; rather, you'll get your
    # multi-channel references via Net::SSH::Multi::Session#open_channel and
    # friends.
    def initialize(connection, channels)
      @connection = connection
      @channels = channels
      @properties = {}
    end

    # Iterate over each component channel object, yielding each in order to the
    # associated block.
    def each
      @channels.each { |channel| yield channel }
    end

    # Retrieve the property (see #properties) with the given +key+.
    #
    #   host = channel[:host]
    def [](key)
      @properties[key]
    end

    # Set the property (see #properties) with the given +key+ to the given
    # +value+.
    #
    #   channel[:visited] = true
    def []=(key, value)
      @properties[key] = value
    end

    # Perform an +exec+ command on all component channels. The block, if given,
    # is passed to each component channel, so it will (potentially) be invoked
    # once for every channel in the collection. The block will receive two
    # parameters: the specific channel object being operated on, and a boolean
    # indicating whether the exec succeeded or not.
    #
    #   channel.exec "ls -l" do |ch, success|
    #     # ...
    #   end
    #
    # See the documentation in Net::SSH for Net::SSH::Connection::Channel#exec
    # for more information on how to work with the callback.
    def exec(command, &block)
      channels.each { |channel| channel.exec(command, &block) }
      self
    end

    # Perform a +request_pty+ command on all component channels. The block, if
    # given, is passed to each component channel, so it will (potentially) be
    # invoked once for every channel in the collection. The block will
    # receive two parameters: the specific channel object being operated on,
    # and a boolean indicating whether the pty request succeeded or not.
    #
    #   channel.request_pty do |ch, success|
    #     # ...
    #   end
    #
    # See the documentation in Net::SSH for
    # Net::SSH::Connection::Channel#request_pty for more information on how to
    # work with the callback.
    def request_pty(opts={}, &block)
      channels.each { |channel| channel.request_pty(opts, &block) }
      self
    end

    # Send the given +data+ to each component channel. It will be sent to the
    # remote process, typically being received on the process' +stdin+ stream.
    #
    #   channel.send_data "password\n"
    def send_data(data)
      channels.each { |channel| channel.send_data(data) }
      self
    end

    # Returns true as long as any of the component channels are active.
    #
    #   connection.loop { channel.active? }
    def active?
      channels.any? { |channel| channel.active? }
    end

    # Runs the connection's event loop until the channel is no longer active
    # (see #active?).
    #
    #   channel.exec "something"
    #   channel.wait
    def wait
      connection.loop { active? }
      self
    end

    # Closes all component channels.
    def close
      channels.each { |channel| channel.close }
      self
    end

    # Tells the remote process for each component channel not to expect any
    # further data from this end of the channel.
    def eof!
      channels.each { |channel| channel.eof! }
      self
    end

    # Registers a callback on all component channels, to be invoked when the
    # remote process emits data (usually on its +stdout+ stream). The block
    # will be invoked with two arguments: the specific channel object, and the
    # data that was received.
    #
    #   channel.on_data do |ch, data|
    #     puts "got data: #{data}"
    #   end
    def on_data(&block)
      channels.each { |channel| channel.on_data(&block) }
      self
    end

    # Registers a callback on all component channels, to be invoked when the
    # remote process emits "extended" data (typically on its +stderr+ stream).
    # The block will be invoked with three arguments: the specific channel
    # object, an integer describing the data type (usually a 1 for +stderr+)
    # and the data that was received.
    #
    #   channel.on_extended_data do |ch, type, data|
    #     puts "got extended data: #{data}"
    #   end
    def on_extended_data(&block)
      channels.each { |channel| channel.on_extended_data(&block) }
      self
    end

    # Registers a callback on all component channels, to be invoked during the
    # idle portion of the connection event loop. The callback will be invoked
    # with one argument: the specific channel object being processed.
    #
    #   channel.on_process do |ch|
    #     # ...
    #   end
    def on_process(&block)
      channels.each { |channel| channel.on_process(&block) }
      self
    end

    # Registers a callback on all component channels, to be invoked when the
    # remote server terminates the channel. The callback will be invoked
    # with one argument: the specific channel object being closed.
    #
    #   channel.on_close do |ch|
    #     # ...
    #   end
    def on_close(&block)
      channels.each { |channel| channel.on_close(&block) }
      self
    end

    # Registers a callback on all component channels, to be invoked when the
    # remote server has no further data to send. The callback will be invoked
    # with one argument: the specific channel object being marked EOF.
    #
    #   channel.on_eof do |ch|
    #     # ...
    #   end
    def on_eof(&block)
      channels.each { |channel| channel.on_eof(&block) }
      self
    end

    # Registers a callback on all component channels, to be invoked when the
    # remote server is unable to open the channel. The callback will be
    # invoked with three arguments: the channel object that couldn't be
    # opened, a description of the error (as a string), and an integer code
    # representing the error.
    #
    #   channel.on_open_failed do |ch, description, code|
    #     # ...
    #   end
    def on_open_failed(&block)
      channels.each { |channel| channel.on_open_failed(&block) }
      self
    end

    # Registers a callback on all component channels, to be invoked when the
    # remote server sends a channel request of the given +type+. The callback
    # will be invoked with two arguments: the specific channel object receiving
    # the request, and a Net::SSH::Buffer instance containing the request-specific
    # data.
    #
    #   channel.on_request("exit-status") do |ch, data|
    #     puts "exited with #{data.read_long}"
    #   end
    def on_request(type, &block)
      channels.each { |channel| channel.on_request(type, &block) }
      self
    end
  end
end; end; end