class Datacenter::Shell::Remote

Attributes

args[R]
session[R]

Public Class Methods

new(*args) click to toggle source
# File lib/datacenter/shell/remote.rb, line 5
def initialize(*args)
  @args = args
end
open(*args) { |shell| ... } click to toggle source
# File lib/datacenter/shell/remote.rb, line 28
def self.open(*args)
  shell = new(*args)
  shell.open
  yield shell
ensure
  shell.close
end

Public Instance Methods

close() click to toggle source
# File lib/datacenter/shell/remote.rb, line 13
def close
  if session && !session.closed?
    session.close
    @session = nil
  end
end
open() click to toggle source
# File lib/datacenter/shell/remote.rb, line 9
def open
  @session ||= Net::SSH.start(*args)
end
run(command, options={}) click to toggle source
# File lib/datacenter/shell/remote.rb, line 20
def run(command, options={})
  if session
    run! command, options
  else
    self.class.open(*args) { |shell| shell.run command, options }
  end
end

Private Instance Methods

run!(command, options={}) click to toggle source
# File lib/datacenter/shell/remote.rb, line 40
def run!(command, options={})
  Datacenter.logger.debug(self.class) { command }

  result = ''
  error = ''
  
  out = options[:out] || StringIO.new
  err = options[:err] || StringIO.new

  exit_code = nil

  session.open_channel do |channel|
    channel.exec(command) do |ch, success|
      abort "FAILED: couldn't execute command (ssh.channel.exec)" unless success
      
      channel.on_data do |ch, data|
        out << data
        result << data
      end

      channel.on_extended_data do |ch, type, data|
        err << data
        error << data
      end

      channel.on_request('exit-status') do |ch, data|
        exit_code = data.read_long
      end
    end
  end

  session.loop

  raise CommandError.new(command, error) unless exit_code == 0

  result
end