From 64fd2f71d64efe1c4b3dc55d1364a99a20c10604 Mon Sep 17 00:00:00 2001 From: Chris Roberts Date: Thu, 16 Feb 2017 15:18:18 -0800 Subject: [PATCH] communicator/ssh: discard stderr data before command run --- plugins/communicators/ssh/communicator.rb | 21 +++++++++++++--- .../communicators/ssh/communicator_test.rb | 24 +++++++++++++++++-- 2 files changed, 40 insertions(+), 5 deletions(-) diff --git a/plugins/communicators/ssh/communicator.rb b/plugins/communicators/ssh/communicator.rb index 4c3eb40ac..8e71ad02f 100644 --- a/plugins/communicators/ssh/communicator.rb +++ b/plugins/communicators/ssh/communicator.rb @@ -496,6 +496,8 @@ module VagrantPlugins marker_found = false data_buffer = '' + stderr_marker_found = false + stderr_data_buffer = '' ch.exec(shell_cmd(opts)) do |ch2, _| # Setup the channel callbacks so we can get data and exit status @@ -512,7 +514,7 @@ module VagrantPlugins if marker_index marker_found = true data_buffer.slice!(0, marker_index + CMD_GARBAGE_MARKER.size) - data.replace data_buffer + data.replace(data_buffer) data_buffer = nil end end @@ -527,7 +529,20 @@ module VagrantPlugins # Filter out the clear screen command data = remove_ansi_escape_codes(data) @logger.debug("stderr: #{data}") - yield :stderr, data if block_given? + if !stderr_marker_found + stderr_data_buffer << data + marker_index = stderr_data_buffer.index(CMD_GARBAGE_MARKER) + if marker_index + marker_found = true + stderr_data_buffer.slice!(0, marker_index + CMD_GARBAGE_MARKER.size) + data.replace(stderr_data_buffer) + data_buffer = nil + end + end + + if block_given? && marker_found + yield :stderr, data + end end ch2.on_request("exit-status") do |ch3, data| @@ -583,7 +598,7 @@ module VagrantPlugins data = data.force_encoding('ASCII-8BIT') ch2.send_data data else - ch2.send_data "printf '#{CMD_GARBAGE_MARKER}'\n#{command}\n".force_encoding('ASCII-8BIT') + ch2.send_data "printf '#{CMD_GARBAGE_MARKER}'\n(>&2 printf '#{CMD_GARBAGE_MARKER}')\n#{command}\n".force_encoding('ASCII-8BIT') # Remember to exit or this channel will hang open ch2.send_data "exit\n" end diff --git a/test/unit/plugins/communicators/ssh/communicator_test.rb b/test/unit/plugins/communicators/ssh/communicator_test.rb index 7de5b90d6..6a9c94fe0 100644 --- a/test/unit/plugins/communicators/ssh/communicator_test.rb +++ b/test/unit/plugins/communicators/ssh/communicator_test.rb @@ -132,7 +132,7 @@ describe VagrantPlugins::CommunicatorSSH::Communicator do it "prepends UUID output to command for garbage removal" do expect(command_channel).to receive(:send_data). - with("printf '#{command_garbage_marker}'\nls /\n") + with("printf '#{command_garbage_marker}'\n(>&2 printf '#{command_garbage_marker}')\nls /\n") expect(communicator.execute("ls /")).to eq(0) end @@ -159,13 +159,33 @@ describe VagrantPlugins::CommunicatorSSH::Communicator do stdout = '' expect( communicator.execute("ls /") do |type, data| - stdout << data + if type == :stdout + stdout << data + end end ).to eq(0) expect(stdout).to eq("bin\ntmp\n") end end + context "with garbage content prepended to command stderr output" do + let(:command_stderr_data) do + "Line of garbage\nMore garbage\n#{command_garbage_marker}bin\ntmp\n" + end + + it "removes any garbage output prepended to command stderr output" do + stderr = '' + expect( + communicator.execute("ls /") do |type, data| + if type == :stderr + stderr << data + end + end + ).to eq(0) + expect(stderr).to eq("bin\ntmp\n") + end + end + context "with pty enabled" do before do expect(ssh).to receive(:pty).and_return true