Skip to content

Commit 795bf03

Browse files
committed
Refactor SSHAdapter
1 parent 0548ee2 commit 795bf03

2 files changed

Lines changed: 68 additions & 48 deletions

File tree

.rubocop.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ Metrics/AbcSize:
99
Max: 22
1010

1111
Metrics/ClassLength:
12-
Max: 75
12+
Max: 100
1313

1414
Metrics/MethodLength:
1515
Max: 24

lib/remote_ruby/ssh_adapter.rb

Lines changed: 67 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -25,81 +25,101 @@ def open(code, stdin, stdout, stderr)
2525
Net::SSH.start(host, nil, config) do |ssh|
2626
with_temp_file(code, ssh) do |fname|
2727
res = run_code(ssh, fname, stdin, stdout, stderr)
28-
ret = get_result(ssh, fname, res)
28+
ret = get_result(ssh, fname) if res.zero?
2929
end
3030
end
3131
ret
3232
end
3333

34-
def run_code(ssh, fname, stdin_r, stdout_w, stderr_w)
35-
res = nil
36-
stdin_r = RemoteRuby::CompatIOReader.new(stdin_r)
37-
ssh.open_channel do |channel|
38-
channel.exec("cd '#{working_dir}' && ruby \"#{fname}\"") do |ch, success|
39-
raise UnableToExecuteError unless success
34+
def connection_name
35+
"#{user}@#{host}:#{working_dir || '~'}> "
36+
end
4037

41-
ssh.listen_to(stdin_r.readable) do |io|
42-
data = io.read_nonblock(4096)
43-
ch.send_data(data)
44-
rescue EOFError
45-
ssh.stop_listening_to(stdin_r.readable)
46-
ch.eof!
47-
end
38+
private
4839

49-
ch.on_data do |_, data|
50-
stdout_w.write(data)
51-
end
40+
def handle_stdin(chan, stdin)
41+
return if stdin.nil?
5242

53-
ch.on_extended_data do |_, _, data|
54-
stderr_w.write(data)
55-
end
43+
if stdin.is_a?(StringIO)
44+
chan.send_data(stdin.string)
45+
chan.eof!
46+
return
47+
end
5648

57-
ch.on_request('exit-status') do |_, data|
58-
res = data.read_long
59-
end
49+
stdin = RemoteRuby::CompatIOReader.new(stdin)
6050

61-
ch.on_close do
62-
ssh.stop_listening_to(stdin_r.readable)
63-
end
64-
end
65-
end.wait
51+
chan.connection.listen_to(stdin.readable) do |io|
52+
data = io.read_nonblock(4096)
53+
chan.send_data(data)
54+
rescue EOFError
55+
chan.connection.stop_listening_to(stdin.readable)
56+
chan.eof!
57+
end
6658

67-
stdin_r.join
68-
res
59+
chan.on_close do
60+
chan.connection.stop_listening_to(stdin.readable)
61+
stdin.join
62+
end
6963
end
7064

71-
def get_result(ssh, fname, process_status)
72-
raise "Process exited with code #{process_status}" unless process_status.zero?
65+
def handle_stdout(chan, stdout)
66+
return if stdout.nil?
7367

74-
ssh.exec!("cat \"#{fname}\"")
68+
chan.on_data do |_, data|
69+
stdout.write(data)
70+
end
7571
end
7672

77-
def connection_name
78-
"#{user}@#{host}:#{working_dir || '~'}> "
73+
def handle_stderr(chan, stderr)
74+
return if stderr.nil?
75+
76+
chan.on_extended_data do |_, _, data|
77+
stderr.write(data)
78+
end
7979
end
8080

81-
def with_temp_file(code, ssh)
82-
fname = String.new
81+
def handle_exit_code(chan)
82+
chan.on_request('exit-status') do |_, data|
83+
yield data.read_long
84+
end
85+
end
86+
87+
def run_remote_process(ssh, cmd, stdin, stdout, stderr)
88+
res = nil
89+
8390
ssh.open_channel do |channel|
84-
channel.exec('f=$(mktemp --tmpdir remote_ruby.XXXXXX) && cat > $f && echo $f') do |ch, success|
91+
channel.exec(cmd) do |ch, success|
8592
raise UnableToExecuteError unless success
8693

87-
ch.on_data do |_, data|
88-
fname << data
94+
handle_stdin(ch, stdin)
95+
handle_stdout(ch, stdout)
96+
handle_stderr(ch, stderr)
97+
handle_exit_code(ch) do |code|
98+
res = code
8999
end
90-
91-
ch.send_data(code)
92-
ch.eof!
93100
end
94101
end.wait
95102

96-
fname.strip!
103+
res
104+
end
105+
106+
def run_code(ssh, fname, stdin, stdout, stderr)
107+
run_remote_process(ssh, "cd '#{working_dir}' && ruby \"#{fname}\"", stdin, stdout, stderr)
108+
end
109+
110+
def get_result(ssh, fname)
111+
ssh.exec!("cat \"#{fname}\"")
112+
end
113+
114+
def with_temp_file(code, ssh)
115+
out = StringIO.new
116+
cmd = 'f=$(mktemp --tmpdir remote_ruby.XXXXXX) && cat > $f && echo $f'
117+
run_remote_process(ssh, cmd, StringIO.new(code), out, nil)
118+
fname = out.string.strip
97119

98120
yield fname
99121
ensure
100-
Net::SSH.start(host, nil, config) do |del_ssh|
101-
del_ssh.exec!("rm \"#{fname}\"")
102-
end
122+
ssh.exec!("rm \"#{fname}\"")
103123
end
104124
end
105125
end

0 commit comments

Comments
 (0)