diff options
author | Luke Duncalfe <lduncalfe@eml.cc> | 2019-03-11 13:24:01 +1300 |
---|---|---|
committer | Luke Duncalfe <lduncalfe@eml.cc> | 2019-03-11 15:30:17 +1300 |
commit | fd8cb7461be4f5364fcf9e9150daede365397fc9 (patch) | |
tree | 1af5918c41402652fe8bdb13a7549572a9d56ddb | |
parent | 1de36fd2eef900a93606e1c0558f736ad88717cd (diff) | |
download | gitlab-ce-use-popen-module-for-open3.tar.gz |
Use Popen module for non-deadlocking reading of IOuse-popen-module-for-open3
The Gitlab::Popen module reads from standard out and standard error in
a way that avoids deadlocks, and can be used as a substitute for open3.
-rw-r--r-- | app/models/ssh_host_key.rb | 20 | ||||
-rw-r--r-- | spec/models/ssh_host_key_spec.rb | 6 |
2 files changed, 13 insertions, 13 deletions
diff --git a/app/models/ssh_host_key.rb b/app/models/ssh_host_key.rb index b6fb39ee81f..4abc7b01a30 100644 --- a/app/models/ssh_host_key.rb +++ b/app/models/ssh_host_key.rb @@ -89,21 +89,17 @@ class SshHostKey end def calculate_reactive_cache - known_hosts, errors, status = - Open3.popen3({}, *%W[ssh-keyscan -T 5 -p #{url.port} -f-]) do |stdin, stdout, stderr, wait_thr| - stdin.puts(url.host) - stdin.close - - [ - cleanup(stdout.read), - cleanup(stderr.read), - wait_thr.value - ] - end + result = Gitlab::Popen.popen_with_detail(%W[ssh-keyscan -T 5 -p #{url.port} -f-]) do |stdin| + stdin.puts(url.host) + end + + known_hosts = cleanup(result.stdout) + errors = cleanup(result.stderr) + status = result.status # ssh-keyscan returns an exit code 0 in several error conditions, such as an # unknown hostname, so check both STDERR and the exit code - if status.success? && !errors.present? + if status&.success? && !errors.present? { known_hosts: known_hosts } else Rails.logger.debug("Failed to detect SSH host keys for #{id}: #{errors}") diff --git a/spec/models/ssh_host_key_spec.rb b/spec/models/ssh_host_key_spec.rb index 4c677569561..5bb84f4a81f 100644 --- a/spec/models/ssh_host_key_spec.rb +++ b/spec/models/ssh_host_key_spec.rb @@ -40,8 +40,12 @@ describe SshHostKey do stdout = double(:stdout, read: stdout) stderr = double(:stderr, read: stderr) wait_thr = double(:wait_thr, value: double(success?: status)) + path = Dir.pwd + vars = { 'PWD' => path } + cmd = ['ssh-keyscan'].concat(args) + options = { chdir: path } - expect(Open3).to receive(:popen3).with({}, 'ssh-keyscan', *args).and_yield(stdin, stdout, stderr, wait_thr) + expect(Open3).to receive(:popen3).with(vars, *cmd, options).and_yield(stdin, stdout, stderr, wait_thr) stdin end |