Merge pull request #10488 from chrisroberts/f-powershell-elevated
Only modify elevated username under specific conditions
This commit is contained in:
commit
19025bb8c3
|
@ -17,6 +17,10 @@ module VagrantPlugins
|
|||
class WinRMShell
|
||||
include Vagrant::Util::Retryable
|
||||
|
||||
# Exit code generated when user is invalid. Can occur
|
||||
# after a hostname update
|
||||
INVALID_USERID_EXITCODE = -196608
|
||||
|
||||
# These are the exceptions that we retry because they represent
|
||||
# errors that are generally fixed from a retry and don't
|
||||
# necessarily represent immediate failure cases.
|
||||
|
@ -71,15 +75,24 @@ module VagrantPlugins
|
|||
def elevated(command, opts = {}, &block)
|
||||
connection.shell(:elevated) do |shell|
|
||||
shell.interactive_logon = opts[:interactive] || false
|
||||
result = execute_with_rescue(shell, command, &block)
|
||||
if result.exitcode == INVALID_USERID_EXITCODE && result.stderr.include?(":UserId:")
|
||||
uname = shell.username
|
||||
ename = elevated_username
|
||||
if uname != ename
|
||||
@logger.warn("elevated command failed due to username error")
|
||||
@logger.warn("retrying command using machine prefixed username - #{ename}")
|
||||
begin
|
||||
shell.username = elevated_username
|
||||
execute_with_rescue(shell, command, &block)
|
||||
shell.username = ename
|
||||
result = execute_with_rescue(shell, command, &block)
|
||||
ensure
|
||||
shell.username = uname
|
||||
end
|
||||
end
|
||||
end
|
||||
result
|
||||
end
|
||||
end
|
||||
|
||||
def wql(query, opts = {}, &block)
|
||||
retryable(tries: @config.max_tries, on: @@exceptions_to_retry_on, sleep: @config.retry_delay) do
|
||||
|
@ -224,11 +237,8 @@ module VagrantPlugins
|
|||
end
|
||||
|
||||
def elevated_username
|
||||
if @elevated_username
|
||||
return @elevated_username
|
||||
end
|
||||
if username.include?("\\")
|
||||
return @elevated_username = username
|
||||
return username
|
||||
end
|
||||
computername = ""
|
||||
powershell("Write-Output $env:computername") do |type, data|
|
||||
|
@ -236,9 +246,9 @@ module VagrantPlugins
|
|||
end
|
||||
computername.strip!
|
||||
if computername.empty?
|
||||
return @elevated_username = username
|
||||
return username
|
||||
end
|
||||
@elevated_username = "#{computername}\\#{username}"
|
||||
"#{computername}\\#{username}"
|
||||
end
|
||||
end #WinShell class
|
||||
end
|
||||
|
|
|
@ -75,10 +75,16 @@ describe VagrantPlugins::CommunicatorWinRM::WinRMShell do
|
|||
end
|
||||
|
||||
describe ".elevated" do
|
||||
let(:eusername) { double("elevatedusername") }
|
||||
let(:username) { double("username") }
|
||||
let(:failed_output) { WinRM::Output.new.tap { |out|
|
||||
out.exitcode = -196608
|
||||
out << {stderr: "(10,8):UserId:"}
|
||||
out << {stderr: "At line:72 char:1"}
|
||||
} }
|
||||
|
||||
before do
|
||||
allow(subject).to receive(:elevated_username).and_return(username)
|
||||
allow(subject).to receive(:elevated_username).and_return(eusername)
|
||||
allow(shell).to receive(:username).and_return(username)
|
||||
allow(shell).to receive(:username=)
|
||||
end
|
||||
|
@ -102,12 +108,20 @@ describe VagrantPlugins::CommunicatorWinRM::WinRMShell do
|
|||
VagrantPlugins::CommunicatorWinRM::Errors::ExecutionError)
|
||||
end
|
||||
|
||||
it "should use elevated username" do
|
||||
expect(subject).to receive(:elevated_username).and_return(username)
|
||||
it "should use elevated username and retry on username failure" do
|
||||
expect(subject).to receive(:elevated_username).and_return(eusername)
|
||||
expect(shell).to receive(:run).with("dir").and_return(failed_output)
|
||||
expect(shell).to receive(:run).with("dir").and_return(output)
|
||||
expect(shell).to receive(:interactive_logon=).with(false)
|
||||
expect(subject.elevated("dir").exitcode).to eq(0)
|
||||
end
|
||||
|
||||
it "should not retry on username failure if elevated username is the same" do
|
||||
expect(subject).to receive(:elevated_username).and_return(username)
|
||||
expect(shell).to receive(:run).with("dir").and_return(failed_output)
|
||||
expect(shell).to receive(:interactive_logon=).with(false)
|
||||
expect(subject.elevated("dir").exitcode).to eq(failed_output.exitcode)
|
||||
end
|
||||
end
|
||||
|
||||
describe ".cmd" do
|
||||
|
@ -215,8 +229,8 @@ describe VagrantPlugins::CommunicatorWinRM::WinRMShell do
|
|||
expect(subject.send(:elevated_username)).to eq("COMPUTERNAME\\#{username}")
|
||||
end
|
||||
|
||||
it "should only compute elevated username once" do
|
||||
expect(subject).to receive(:powershell).once.with(/computername/).and_yield(:stdout, "COMPUTERNAME")
|
||||
it "should compute elevated username every time" do
|
||||
expect(subject).to receive(:powershell).twice.with(/computername/).and_yield(:stdout, "COMPUTERNAME")
|
||||
expect(subject.send(:elevated_username)).to eq("COMPUTERNAME\\#{username}")
|
||||
expect(subject.send(:elevated_username)).to eq("COMPUTERNAME\\#{username}")
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue