class HrrRbSsh::Client

Public Class Methods

new(target, tmp_options={}) click to toggle source
# File lib/hrr_rb_ssh/client.rb, line 30
def initialize target, tmp_options={}
  @closed = true
  options = initialize_options tmp_options
  io = case target
       when IO
         target
       when Array
         io = TCPSocket.new *target
       when String
         port = 22
         io = TCPSocket.new target, port
       end
  transport      = HrrRbSsh::Transport.new      io, HrrRbSsh::Mode::CLIENT, options, logger: logger
  authentication = HrrRbSsh::Authentication.new transport, HrrRbSsh::Mode::CLIENT, options, logger: logger
  @connection    = HrrRbSsh::Connection.new     authentication, HrrRbSsh::Mode::CLIENT, options, logger: logger
end
start(target, options={}) { |client| ... } click to toggle source
# File lib/hrr_rb_ssh/client.rb, line 16
def self.start target, options={}
  client = self.new target, options
  client.start
  if block_given?
    begin
      yield client
    ensure
      client.close unless client.closed?
    end
  else
    client
  end
end

Public Instance Methods

close() click to toggle source
# File lib/hrr_rb_ssh/client.rb, line 77
def close
  log_info { "closing client" }
  @closed = true
  @connection.close
  log_info { "client closed" }
end
closed?() click to toggle source
# File lib/hrr_rb_ssh/client.rb, line 73
def closed?
  @closed
end
exec(command, pty: false, env: {}) { |io| ... } click to toggle source
# File lib/hrr_rb_ssh/client.rb, line 143
def exec command, pty: false, env: {}
  log_info { "start exec: #{command}" }
  begin
    log_info { "Opning channel" }
    channel = @connection.request_channel_open "session"
    log_info { "Channel opened" }
    if pty
      channel.send_channel_request_pty_req 'xterm', 80, 24, 580, 336, ''
    end
    env.each{ |variable_name, variable_value|
      channel.send_channel_request_env variable_name, variable_value
    }
    channel.send_channel_request_exec command
    yield channel.io
  rescue => e
    log_error { "Failed opening channel" }
    log_error { [e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join }
    raise "Error in shell"
  ensure
    if channel
      log_info { "closing channel IOs" }
      channel.io.each{ |io| io.close rescue nil }
      log_info { "channel IOs closed" }
      log_info { "closing channel" }
      log_info { "wait until threads closed in channel" }
      channel.wait_until_closed
      channel.close
      log_info { "channel closed" }
    end
  end
  channel_exit_status = channel.exit_status rescue nil
end
exec!(command, pty: false, env: {}) click to toggle source
# File lib/hrr_rb_ssh/client.rb, line 84
def exec! command, pty: false, env: {}
  log_info { "start exec!: #{command}" }
  out_buf = StringIO.new
  err_buf = StringIO.new
  begin
    log_info { "Opning channel" }
    channel = @connection.request_channel_open "session"
    log_info { "Channel opened" }
    if pty
      channel.send_channel_request_pty_req 'xterm', 80, 24, 580, 336, ''
    end
    env.each{ |variable_name, variable_value|
      channel.send_channel_request_env variable_name, variable_value
    }
    channel.send_channel_request_exec command
    out_t = Thread.new {
      while true
        begin
          out_buf.write channel.io[1].readpartial(10240)
        rescue
          break
        end
      end
    }
    err_t = Thread.new {
      while true
        begin
          err_buf.write channel.io[2].readpartial(10240)
        rescue
          break
        end
      end
    }
    [out_t, err_t].each{ |t|
      begin
        t.join
      rescue => e
        log_warn { [e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join }
      end
    }
  rescue => e
    log_error { "Failed opening channel" }
    log_error { [e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join }
    raise "Error in exec!"
  ensure
    if channel
      log_info { "closing channel IOs" }
      channel.io.each{ |io| io.close rescue nil }
      log_info { "channel IOs closed" }
      log_info { "closing channel" }
      log_info { "wait until threads closed in channel" }
      channel.wait_until_closed
      channel.close
      log_info { "channel closed" }
    end
  end
  [out_buf.string, err_buf.string]
end
initialize_options(tmp_options) click to toggle source
# File lib/hrr_rb_ssh/client.rb, line 47
def initialize_options tmp_options
  tmp_options = Hash[tmp_options.map{|k, v| [k.to_s, v]}]
  self.logger = tmp_options['logger']
  options = {}
  options['username'] = tmp_options['username']
  options['authentication_preferred_authentication_methods'] = tmp_options['authentication_preferred_authentication_methods']
  options['client_authentication_password']                  = tmp_options['password']
  options['client_authentication_publickey']                 = tmp_options['publickey']
  options['client_authentication_keyboard_interactive']      = tmp_options['keyboard_interactive']
  options['transport_preferred_encryption_algorithms']       = tmp_options['transport_preferred_encryption_algorithms']
  options['transport_preferred_server_host_key_algorithms']  = tmp_options['transport_preferred_server_host_key_algorithms']
  options['transport_preferred_kex_algorithms']              = tmp_options['transport_preferred_kex_algorithms']
  options['transport_preferred_mac_algorithms']              = tmp_options['transport_preferred_mac_algorithms']
  options['transport_preferred_compression_algorithms']      = tmp_options['transport_preferred_compression_algorithms']
  options
end
loop() click to toggle source
# File lib/hrr_rb_ssh/client.rb, line 69
def loop
  @connection.loop
end
shell(env: {}) { |io| ... } click to toggle source
# File lib/hrr_rb_ssh/client.rb, line 176
def shell env: {}
  log_info { "start shell" }
  begin
    log_info { "Opning channel" }
    channel = @connection.request_channel_open "session"
    log_info { "Channel opened" }
    channel.send_channel_request_pty_req 'xterm', 80, 24, 580, 336, ''
    env.each{ |variable_name, variable_value|
      channel.send_channel_request_env variable_name, variable_value
    }
    channel.send_channel_request_shell
    yield channel.io
  rescue => e
    log_error { "Failed opening channel" }
    log_error { [e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join }
    raise "Error in shell"
  ensure
    if channel
      log_info { "closing channel IOs" }
      channel.io.each{ |io| io.close rescue nil }
      log_info { "channel IOs closed" }
      log_info { "closing channel" }
      log_info { "wait until threads closed in channel" }
      channel.wait_until_closed
      channel.close
      log_info { "channel closed" }
    end
  end
  channel_exit_status = channel.exit_status rescue nil
end
start() click to toggle source
# File lib/hrr_rb_ssh/client.rb, line 64
def start
  @connection.start foreground: false
  @closed = false
end
subsystem(name) { |io| ... } click to toggle source
# File lib/hrr_rb_ssh/client.rb, line 207
def subsystem name
  log_info { "start subsystem" }
  begin
    log_info { "Opning channel" }
    channel = @connection.request_channel_open "session"
    log_info { "Channel opened" }
    channel.send_channel_request_subsystem name
    yield channel.io
  rescue => e
    log_error { "Failed opening channel" }
    log_error { [e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join }
    raise "Error in subsystem"
  ensure
    if channel
      log_info { "closing channel IOs" }
      channel.io.each{ |io| io.close rescue nil }
      log_info { "channel IOs closed" }
      log_info { "closing channel" }
      log_info { "wait until threads closed in channel" }
      channel.wait_until_closed
      channel.close
      log_info { "channel closed" }
    end
  end
  channel_exit_status = channel.exit_status rescue nil
end