Ensure windows files get an extension

This commit is contained in:
sophia 2020-04-14 10:49:49 -04:00
parent c1b695c471
commit 2ddd12047c
2 changed files with 53 additions and 16 deletions

View File

@ -4,11 +4,14 @@ require "tempfile"
require "vagrant/util/downloader"
require "vagrant/util/retryable"
require "pry-byebug"
module VagrantPlugins
module Shell
class Provisioner < Vagrant.plugin("2", :provisioner)
include Vagrant::Util::Retryable
DEFAULT_WINDOWS_SHELL_EXT = ".ps1".freeze
def provision
args = ""
if config.args.is_a?(String)
@ -135,16 +138,14 @@ module VagrantPlugins
# Upload the script to the machine
@machine.communicate.tap do |comm|
env = config.env.map{|k,v| comm.generate_environment_export(k, v)}.join(';')
shell = comm.machine_config_ssh.shell
if File.extname(upload_path).empty?
remote_ext = File.extname(path)[1..-1]
if !remote_ext
remote_ext = @machine.config.winssh.shell == "cmd" ? "bat" : "ps1"
end
upload_path << ".#{remote_ext}"
remote_ext = File.extname(path)
if remote_ext.empty?
remote_ext = @machine.config.winssh.shell == "cmd" ? ".bat" : ".ps1"
end
remote_path = add_extension(upload_path(), remote_ext)
if remote_ext == "bat"
command = "#{env}\n cmd.exe /c \"#{upload_path}\" #{args}"
command = "#{env}\n cmd.exe /c \"#{remote_path}\" #{args}"
else
# Copy powershell_args from configuration
shell_args = config.powershell_args
@ -152,7 +153,7 @@ module VagrantPlugins
shell_args += " -ExecutionPolicy Bypass" if config.powershell_args !~ /[-\/]ExecutionPolicy/i
# CLIXML output is kinda useless, especially on non-windows hosts
shell_args += " -OutputFormat Text" if config.powershell_args !~ /[-\/]OutputFormat/i
command = "#{env}\npowershell #{shell_args} -file \"#{upload_path}\"#{args}"
command = "#{env}\npowershell #{shell_args} -file \"#{remote_path}\"#{args}"
end
# Reset upload path permissions for the current ssh user
@ -161,8 +162,8 @@ module VagrantPlugins
info = @machine.ssh_info
raise Vagrant::Errors::SSHNotReady if info.nil?
end
comm.upload(path.to_s, upload_path)
comm.upload(path.to_s, remote_path)
if config.name
@machine.ui.detail(I18n.t("vagrant.provisioners.shell.running",
@ -198,10 +199,7 @@ module VagrantPlugins
@machine.communicate.tap do |comm|
# Make sure that the upload path has an extension, since
# having an extension is critical for Windows execution
winrm_upload_path = upload_path
if File.extname(winrm_upload_path) == ""
winrm_upload_path += File.extname(path.to_s)
end
winrm_upload_path = add_extension(upload_path, DEFAULT_WINDOWS_SHELL_EXT)
# Upload it
comm.upload(path.to_s, winrm_upload_path)
@ -260,6 +258,11 @@ module VagrantPlugins
"#{quote}#{text.gsub(/#{quote}/) { |m| "#{m}\\#{m}#{m}" }}#{quote}"
end
def add_extension(path, ext)
return path if !File.extname(path.to_s).empty?
path + ext
end
# This method yields the path to a script to upload and execute
# on the remote server. This method will properly clean up the
# script file if needed.

View File

@ -456,12 +456,46 @@ describe "Vagrant::Shell::Provisioner" do
allow(machine).to receive(:communicate).and_return(communicator)
allow(machine).to receive(:guest).and_return(guest)
allow(machine).to receive(:ui).and_return(ui)
allow(vsp).to receive(:with_script_file).and_yield(config.path)
}
it "ensures that files are uploaded with an extension" do
allow(vsp).to receive(:with_script_file).and_yield(config.path)
expect(communicator).to receive(:upload).with(config.path, /arbitrary.ps1$/)
vsp.send(:provision_winrm, "")
end
context "inline option set" do
let(:config) {
double(
:config,
:args => "doesn't matter",
:env => {},
:remote? => false,
:inline => "some commands",
:upload_path => nil,
:path => nil,
:binary => false,
:md5 => nil,
:sha1 => 'EXPECTED_VALUE',
:sha256 => nil,
:sha384 => nil,
:sha512 => nil,
:reset => false,
:reboot => false,
:powershell_args => "",
:name => nil,
:privileged => false,
:powershell_elevated_interactive => false
)
}
it "creates an executable with an extension" do
default_path = "C:/tmp/vagrant-shell"
allow(vsp).to receive(:with_script_file).and_yield(default_path)
allow(communicator).to receive(:upload).with(default_path, /vagrant-shell/)
expect(communicator).to receive(:sudo).with(/vagrant-shell.ps1/, anything)
vsp.send(:provision_winrm, "")
end
end
end
end