This repository has been archived by the owner on Sep 1, 2020. It is now read-only.
/
ssh_methods.rb
99 lines (85 loc) · 2.42 KB
/
ssh_methods.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
class GitDeploy
module SSHMethods
private
def sudo_cmd
"sudo -p 'sudo password: '"
end
def system(*args)
puts "[local] $ " + args.join(' ').gsub(' && ', " && \\\n ")
super unless options.noop?
end
def run(cmd = nil)
cmd = yield(cmd) if block_given?
cmd = cmd.join(' && ') if Array === cmd
puts "[#{options[:remote]}] $ " + cmd.gsub(' && ', " && \\\n ")
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
def run_test(cmd)
status, output = ssh_exec(cmd) { }
status == 0
end
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
# TODO: use Highline for cross-platform support
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
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
def ssh_connection
@ssh ||= begin
ssh = Net::SSH.start(host, remote_user, :port => remote_port)
at_exit { ssh.close }
ssh
end
end
end
end