summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Smith <tsmith@chef.io>2020-08-21 16:34:06 -0700
committerGitHub <noreply@github.com>2020-08-21 16:34:06 -0700
commite8c3017825e526c207c5c7a49c13a0353b3b6838 (patch)
treed6d2cf25f10be884b5f8eaa3f33f282b01ef217d
parent2293419b0d5ba15685eff1550a93050f26bfd168 (diff)
parentc88ea34bd538afba22358f8548ad1d7c01a44b5c (diff)
downloadchef-e8c3017825e526c207c5c7a49c13a0353b3b6838.tar.gz
Merge pull request #9482 from MsysTechnologiesllc/dh/Fix-knife-ssh-hang-win2k16
Avoid knife ssh freeze on windows
-rw-r--r--lib/chef/knife/ssh.rb17
-rw-r--r--spec/unit/knife/ssh_spec.rb4
2 files changed, 18 insertions, 3 deletions
diff --git a/lib/chef/knife/ssh.rb b/lib/chef/knife/ssh.rb
index 5e856ec011..a6428d9726 100644
--- a/lib/chef/knife/ssh.rb
+++ b/lib/chef/knife/ssh.rb
@@ -358,11 +358,21 @@ class Chef
subsession ||= session
command = fixup_sudo(command)
command.force_encoding("binary") if command.respond_to?(:force_encoding)
+ begin
+ open_session(subsession, command)
+ rescue => e
+ open_session(subsession, command, true)
+ end
+ end
+
+ def open_session(subsession, command, pty = false)
+ stderr = ""
+ exit_status = 0
subsession.open_channel do |chan|
if config[:on_error] && exit_status != 0
chan.close
else
- chan.request_pty
+ chan.request_pty if pty
chan.exec command do |ch, success|
raise ArgumentError, "Cannot execute #{command}" unless success
@@ -373,6 +383,11 @@ class Chef
ichannel.send_data("#{get_password}\n")
end
end
+
+ ch.on_extended_data do |_, _type, data|
+ stderr += data
+ end
+
ch.on_request "exit-status" do |ichannel, data|
exit_status = [exit_status, data.read_long].max
end
diff --git a/spec/unit/knife/ssh_spec.rb b/spec/unit/knife/ssh_spec.rb
index 72111eed3d..8606045e8c 100644
--- a/spec/unit/knife/ssh_spec.rb
+++ b/spec/unit/knife/ssh_spec.rb
@@ -283,10 +283,10 @@ describe Chef::Knife::Ssh do
end
describe "#ssh_command" do
- let(:execution_channel) { double(:execution_channel, on_data: nil) }
+ let(:execution_channel) { double(:execution_channel, on_data: nil, on_extended_data: nil) }
let(:session_channel) { double(:session_channel, request_pty: nil) }
- let(:execution_channel2) { double(:execution_channel, on_data: nil) }
+ let(:execution_channel2) { double(:execution_channel, on_data: nil, on_extended_data: nil) }
let(:session_channel2) { double(:session_channel, request_pty: nil) }
let(:session) { double(:session, loop: nil) }