summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Duncalfe <lduncalfe@eml.cc>2019-03-11 13:24:01 +1300
committerLuke Duncalfe <lduncalfe@eml.cc>2019-03-11 15:30:17 +1300
commitfd8cb7461be4f5364fcf9e9150daede365397fc9 (patch)
tree1af5918c41402652fe8bdb13a7549572a9d56ddb
parent1de36fd2eef900a93606e1c0558f736ad88717cd (diff)
downloadgitlab-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.rb20
-rw-r--r--spec/models/ssh_host_key_spec.rb6
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