module GitDeploy::SSHMethods

Private Instance Methods

askpass() click to toggle source

TODO: use Highline for cross-platform support

# File lib/git_deploy/ssh_methods.rb, line 69
def askpass
  tty_state = `stty -g`
  system 'stty raw -echo -icanon isig' if $?.success?
  pass = ''
  while char = $stdin.getbyte and not (char == 13 or char == 10)
    if char == 127 or char == 8
      pass[-1,1] = '' unless pass.empty?
    else
      pass << char.chr
    end
  end
  pass
ensure
  system "stty #{tty_state}" unless tty_state.empty?
end
run(cmd = nil, opt = {}) { |cmd| ... } click to toggle source
# File lib/git_deploy/ssh_methods.rb, line 14
def run(cmd = nil, opt = {})
  cmd = yield(cmd) if block_given?
  cmd = cmd.join(' && ') if Array === cmd

  if opt.fetch(:echo, true)
    puts "[#{options[:remote]}] $ " + cmd.gsub(' && ', " && \\\n  ")
  end

  unless options.noop?
    status, output = ssh_exec cmd do |ch, stream, data|
      case stream
      when :stdout then $stdout.print data
      when :stderr then $stderr.print data
      end
      ch.send_data(askpass) if data =~ /^sudo password: /
    end
    output
  end
end
run_test(cmd) click to toggle source
# File lib/git_deploy/ssh_methods.rb, line 34
def run_test(cmd)
  status, output = ssh_exec(cmd) { }
  status == 0
end
scp_upload(files) click to toggle source
# File lib/git_deploy/ssh_methods.rb, line 85
def scp_upload(files)
  channels = []
  files.each do |local, remote|
    puts "FILE: [local] #{local.sub(LOCAL_DIR + '/', '')}  ->  [#{options[:remote]}] #{remote}"
    channels << ssh_connection.scp.upload(local, remote) unless options.noop?
  end
  channels.each { |c| c.wait }
end
ssh_connection() click to toggle source
# File lib/git_deploy/ssh_methods.rb, line 94
def ssh_connection
  @ssh ||= begin
    ssh = Net::SSH.start(host, remote_user, :port => remote_port)
    at_exit { ssh.close }
    ssh
  end
end
ssh_exec(cmd) { |c, :stdout, data| ... } click to toggle source
# File lib/git_deploy/ssh_methods.rb, line 39
def ssh_exec(cmd, &block)
  status = nil
  output = ''

  channel = ssh_connection.open_channel do |chan|
    chan.exec(cmd) do |ch, success|
      raise "command failed: #{cmd.inspect}" unless success
      # ch.request_pty

      ch.on_data do |c, data|
        output << data
        yield(c, :stdout, data)
      end

      ch.on_extended_data do |c, type, data|
        output << data
        yield(c, :stderr, data)
      end

      ch.on_request "exit-status" do |ch, data|
        status = data.read_long
      end
    end
  end

  channel.wait
  [status, output]
end
sudo_cmd() click to toggle source
# File lib/git_deploy/ssh_methods.rb, line 5
def sudo_cmd
  "sudo -p 'sudo password: '"
end
system(*args) click to toggle source
Calls superclass method
# File lib/git_deploy/ssh_methods.rb, line 9
def system(*args)
  puts "[local] $ " + args.join(' ').gsub(' && ', " && \\\n  ")
  super unless options.noop?
end