Module: Postgres::Clone::RemoteCommands

Includes:
CommandLine, Logger
Included in:
Commands
Defined in:
lib/postgres/clone/remote_commands.rb

Constant Summary

Constants included from Logger

Logger::DEFAULT_COLOR

Instance Method Summary collapse

Methods included from Logger

#log_message

Methods included from CommandLine

#build_command, #log_command

Instance Method Details

#close_ssh_connectionsObject



11
12
13
# File 'lib/postgres/clone/remote_commands.rb', line 11

def close_ssh_connections
  (@ssh_connections || {}).values.each(&:close)
end

#open_ssh_connection(host_name, user) ⇒ Object



15
16
17
18
19
20
21
# File 'lib/postgres/clone/remote_commands.rb', line 15

def open_ssh_connection(host_name, user)
  @ssh_connections ||= {}
  @ssh_connections[host_name] ||= begin
    log_message("Opening ssh connection to #{host_name} as #{user}")
    Net::SSH.start(host_name, user)
  end
end

#run_remote(host_name, command, user: current_user, sudo: false) ⇒ Object



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/postgres/clone/remote_commands.rb', line 23

def run_remote(host_name, command, user: current_user, sudo: false)
  result_attributes = { exit_code: nil, output: '' }

  ssh = open_ssh_connection(host_name, user)
  ssh.open_channel do |channel|
    channel.request_pty { |_, success| abort('could not obtain pty') unless success }

    actual_command = build_command(command, user: user, sudo: sudo)
    log_message(actual_command, host_name: host_name, color: :gray)

    channel.exec(actual_command) do |_, success|
      abort('could not execute command') unless success

      channel.on_data do |_, data|
        puts data
        case data
        when /^\[sudo\] password for (.+):/i
          password = user_password(host_name, $1)
          log_message("Sending sudo password for #{user}", host_name: host_name, color: :gray)
          channel.send_data("#{password}\n")
        when /(.+)@(.+)'s password:/i
          password = user_password($2, $1)
          log_message("Sending user password for #{$1}", host_name: host_name, color: :gray)
          channel.send_data("#{password}\n")
        when /are you sure you want to continue connecting \(yes\/no\)\?/i
          log_message('ignoring key warning', host_name: host_name, color: :yellow)
          channel.send_data("yes\n")
        else
          result_attributes[:output] += data
        end
      end

      channel.on_extended_data do |_, _, data|
        log_message("stderr: #{data}", host_name: host_name, color: :red)
      end

      channel.on_request('exit-status') do |_, data|
        result_attributes[:exit_code] = data.read_long
      end
    end
  end

  ssh.loop

  CommandResult.new(result_attributes)
end

#sudo_remote(host_name, command, user: nil) ⇒ Object



70
71
72
# File 'lib/postgres/clone/remote_commands.rb', line 70

def sudo_remote(host_name, command, user: nil)
  run_remote(host_name, command, user: user, sudo: true)
end