Merge b42c885cf1
into b231abe114
This commit is contained in:
commit
058036927d
|
@ -213,13 +213,20 @@ module Vagrant
|
||||||
return path if !cygwin?
|
return path if !cygwin?
|
||||||
|
|
||||||
# Replace all "\" with "/", otherwise cygpath doesn't work.
|
# Replace all "\" with "/", otherwise cygpath doesn't work.
|
||||||
path = path.gsub("\\", "/")
|
path = unix_windows_path(path)
|
||||||
|
|
||||||
# Call out to cygpath and gather the result
|
# Call out to cygpath and gather the result
|
||||||
process = Subprocess.execute("cygpath", "-w", "-l", "-a", path.to_s)
|
process = Subprocess.execute("cygpath", "-w", "-l", "-a", path.to_s)
|
||||||
return process.stdout.chomp
|
return process.stdout.chomp
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# This takes any path and converts Windows-style path separators
|
||||||
|
# to Unix-like path separators.
|
||||||
|
# @return [String]
|
||||||
|
def unix_windows_path(path)
|
||||||
|
path.gsub("\\", "/")
|
||||||
|
end
|
||||||
|
|
||||||
# This checks if the filesystem is case sensitive. This is not a
|
# This checks if the filesystem is case sensitive. This is not a
|
||||||
# 100% correct check, since it is possible that the temporary
|
# 100% correct check, since it is possible that the temporary
|
||||||
# directory runs a different filesystem than the root directory.
|
# directory runs a different filesystem than the root directory.
|
||||||
|
|
|
@ -65,7 +65,7 @@ module VagrantPlugins
|
||||||
while true
|
while true
|
||||||
ssh_info = @machine.ssh_info
|
ssh_info = @machine.ssh_info
|
||||||
break if ssh_info
|
break if ssh_info
|
||||||
sleep 0.5
|
sleep(0.5)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Got it! Let the user know what we're connecting to.
|
# Got it! Let the user know what we're connecting to.
|
||||||
|
@ -227,6 +227,7 @@ module VagrantPlugins
|
||||||
command: command,
|
command: command,
|
||||||
shell: nil,
|
shell: nil,
|
||||||
sudo: false,
|
sudo: false,
|
||||||
|
force_raw: false
|
||||||
}.merge(opts || {})
|
}.merge(opts || {})
|
||||||
|
|
||||||
opts[:good_exit] = Array(opts[:good_exit])
|
opts[:good_exit] = Array(opts[:good_exit])
|
||||||
|
@ -238,6 +239,7 @@ module VagrantPlugins
|
||||||
shell_opts = {
|
shell_opts = {
|
||||||
sudo: opts[:sudo],
|
sudo: opts[:sudo],
|
||||||
shell: opts[:shell],
|
shell: opts[:shell],
|
||||||
|
force_raw: opts[:force_raw]
|
||||||
}
|
}
|
||||||
|
|
||||||
shell_execute(connection, command, **shell_opts) do |type, data|
|
shell_execute(connection, command, **shell_opts) do |type, data|
|
||||||
|
@ -354,6 +356,11 @@ module VagrantPlugins
|
||||||
wait_for_ready(5)
|
wait_for_ready(5)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def generate_environment_export(env_key, env_value)
|
||||||
|
template = machine_config_ssh.export_command_template
|
||||||
|
template.sub("%ENV_KEY%", env_key).sub("%ENV_VALUE%", env_value) + "\n"
|
||||||
|
end
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
||||||
# Opens an SSH connection and yields it to a block.
|
# Opens an SSH connection and yields it to a block.
|
||||||
|
@ -628,7 +635,7 @@ module VagrantPlugins
|
||||||
end
|
end
|
||||||
|
|
||||||
# Set the terminal
|
# Set the terminal
|
||||||
ch2.send_data generate_environment_export("TERM", "vt100")
|
ch2.send_data(generate_environment_export("TERM", "vt100"))
|
||||||
|
|
||||||
# Set SSH_AUTH_SOCK if we are in sudo and forwarding agent.
|
# Set SSH_AUTH_SOCK if we are in sudo and forwarding agent.
|
||||||
# This is to work around often misconfigured boxes where
|
# This is to work around often misconfigured boxes where
|
||||||
|
@ -651,7 +658,7 @@ module VagrantPlugins
|
||||||
@logger.warn("No SSH_AUTH_SOCK found despite forward_agent being set.")
|
@logger.warn("No SSH_AUTH_SOCK found despite forward_agent being set.")
|
||||||
else
|
else
|
||||||
@logger.info("Setting SSH_AUTH_SOCK remotely: #{auth_socket}")
|
@logger.info("Setting SSH_AUTH_SOCK remotely: #{auth_socket}")
|
||||||
ch2.send_data generate_environment_export("SSH_AUTH_SOCK", auth_socket)
|
ch2.send_data(generate_environment_export("SSH_AUTH_SOCK", auth_socket))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -669,11 +676,11 @@ module VagrantPlugins
|
||||||
data += "printf #{PTY_DELIM_END}\n"
|
data += "printf #{PTY_DELIM_END}\n"
|
||||||
data += "exit $exitcode\n"
|
data += "exit $exitcode\n"
|
||||||
data = data.force_encoding('ASCII-8BIT')
|
data = data.force_encoding('ASCII-8BIT')
|
||||||
ch2.send_data data
|
ch2.send_data(data)
|
||||||
else
|
else
|
||||||
ch2.send_data "printf '#{CMD_GARBAGE_MARKER}'\n(>&2 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
|
# Remember to exit or this channel will hang open
|
||||||
ch2.send_data "exit\n"
|
ch2.send_data("exit\n")
|
||||||
end
|
end
|
||||||
|
|
||||||
# Send eof to let server know we're done
|
# Send eof to let server know we're done
|
||||||
|
@ -759,11 +766,6 @@ module VagrantPlugins
|
||||||
return File.read(path).chomp == source_path.read.chomp
|
return File.read(path).chomp == source_path.read.chomp
|
||||||
end
|
end
|
||||||
|
|
||||||
def generate_environment_export(env_key, env_value)
|
|
||||||
template = machine_config_ssh.export_command_template
|
|
||||||
template.sub("%ENV_KEY%", env_key).sub("%ENV_VALUE%", env_value) + "\n"
|
|
||||||
end
|
|
||||||
|
|
||||||
def create_remote_directory(dir)
|
def create_remote_directory(dir)
|
||||||
execute("mkdir -p \"#{dir}\"")
|
execute("mkdir -p \"#{dir}\"")
|
||||||
end
|
end
|
||||||
|
|
|
@ -15,11 +15,13 @@ module VagrantPlugins
|
||||||
def shell_execute(connection, command, **opts)
|
def shell_execute(connection, command, **opts)
|
||||||
opts = {
|
opts = {
|
||||||
sudo: false,
|
sudo: false,
|
||||||
shell: nil
|
shell: nil,
|
||||||
|
force_raw: false
|
||||||
}.merge(opts)
|
}.merge(opts)
|
||||||
|
|
||||||
sudo = opts[:sudo]
|
sudo = opts[:sudo]
|
||||||
shell = (opts[:shell] || machine_config_ssh.shell).to_s
|
shell = (opts[:shell] || machine_config_ssh.shell).to_s
|
||||||
|
force_raw = opts[:force_raw]
|
||||||
|
|
||||||
@logger.info("Execute: #{command} (sudo=#{sudo.inspect})")
|
@logger.info("Execute: #{command} (sudo=#{sudo.inspect})")
|
||||||
exit_status = nil
|
exit_status = nil
|
||||||
|
@ -31,33 +33,42 @@ module VagrantPlugins
|
||||||
stderr_marker_found = false
|
stderr_marker_found = false
|
||||||
stderr_data_buffer = ''
|
stderr_data_buffer = ''
|
||||||
|
|
||||||
tfile = Tempfile.new('vagrant-ssh')
|
if force_raw
|
||||||
remote_ext = shell == "powershell" ? "ps1" : "bat"
|
if shell == "powershell"
|
||||||
remote_name = "#{machine_config_ssh.upload_directory}\\#{File.basename(tfile.path)}.#{remote_ext}"
|
base_cmd = "powershell \"Write-Host #{CMD_GARBAGE_MARKER}; [Console]::Error.WriteLine('#{CMD_GARBAGE_MARKER}'); #{command}\""
|
||||||
|
else
|
||||||
|
base_cmd = "cmd /q /c \"ECHO #{CMD_GARBAGE_MARKER} && ECHO #{CMD_GARBAGE_MARKER} 1>&2 && #{command}\""
|
||||||
|
end
|
||||||
|
else
|
||||||
|
tfile = Tempfile.new('vagrant-ssh')
|
||||||
|
remote_ext = shell == "powershell" ? "ps1" : "bat"
|
||||||
|
remote_name = "#{machine_config_ssh.upload_directory}\\#{File.basename(tfile.path)}.#{remote_ext}"
|
||||||
|
|
||||||
if shell == "powershell"
|
if shell == "powershell"
|
||||||
base_cmd = "powershell -File #{remote_name}"
|
base_cmd = "powershell -File #{remote_name}"
|
||||||
tfile.puts <<-SCRIPT.force_encoding('ASCII-8BIT')
|
tfile.puts <<-SCRIPT.force_encoding('ASCII-8BIT')
|
||||||
Remove-Item #{remote_name}
|
Remove-Item #{remote_name}
|
||||||
Write-Host #{CMD_GARBAGE_MARKER}
|
Write-Host #{CMD_GARBAGE_MARKER}
|
||||||
[Console]::Error.WriteLine("#{CMD_GARBAGE_MARKER}")
|
[Console]::Error.WriteLine("#{CMD_GARBAGE_MARKER}")
|
||||||
#{command}
|
#{command}
|
||||||
SCRIPT
|
SCRIPT
|
||||||
else
|
else
|
||||||
base_cmd = remote_name
|
base_cmd = remote_name
|
||||||
tfile.puts <<-SCRIPT.force_encoding('ASCII-8BIT')
|
tfile.puts <<-SCRIPT.force_encoding('ASCII-8BIT')
|
||||||
ECHO OFF
|
ECHO OFF
|
||||||
ECHO #{CMD_GARBAGE_MARKER}
|
ECHO #{CMD_GARBAGE_MARKER}
|
||||||
ECHO #{CMD_GARBAGE_MARKER} 1>&2
|
ECHO #{CMD_GARBAGE_MARKER} 1>&2
|
||||||
#{command}
|
#{command}
|
||||||
SCRIPT
|
SCRIPT
|
||||||
|
end
|
||||||
|
|
||||||
|
tfile.close
|
||||||
|
upload(tfile.path, remote_name)
|
||||||
|
tfile.delete
|
||||||
|
|
||||||
|
base_cmd = shell_cmd(opts.merge(shell: base_cmd))
|
||||||
end
|
end
|
||||||
|
|
||||||
tfile.close
|
|
||||||
upload(tfile.path, remote_name)
|
|
||||||
tfile.delete
|
|
||||||
|
|
||||||
base_cmd = shell_cmd(opts.merge(shell: base_cmd))
|
|
||||||
@logger.debug("Base SSH exec command: #{base_cmd}")
|
@logger.debug("Base SSH exec command: #{base_cmd}")
|
||||||
|
|
||||||
ch.exec(base_cmd) do |ch2, _|
|
ch.exec(base_cmd) do |ch2, _|
|
||||||
|
@ -156,6 +167,68 @@ SCRIPT
|
||||||
@machine.config.winssh
|
@machine.config.winssh
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def upload(from, to)
|
||||||
|
to = Vagrant::Util::Platform.unix_windows_path(to)
|
||||||
|
@logger.debug("Uploading: #{from} to #{to}")
|
||||||
|
|
||||||
|
if File.directory?(from)
|
||||||
|
if from.end_with?(".")
|
||||||
|
@logger.debug("Uploading directory contents of: #{from}")
|
||||||
|
from = from.sub(/\.$/, "")
|
||||||
|
else
|
||||||
|
@logger.debug("Uploading full directory container of: #{from}")
|
||||||
|
to = File.join(to, File.basename(File.expand_path(from)))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
scp_connect do |scp|
|
||||||
|
uploader = lambda do |path, remote_dest=nil|
|
||||||
|
if File.directory?(path)
|
||||||
|
Dir.new(path).each do |entry|
|
||||||
|
next if entry == "." || entry == ".."
|
||||||
|
full_path = File.join(path, entry)
|
||||||
|
dest = File.join(to, path.sub(/^#{Regexp.escape(from)}/, ""))
|
||||||
|
create_remote_directory(dest)
|
||||||
|
uploader.call(full_path, dest)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if remote_dest
|
||||||
|
dest = File.join(remote_dest, File.basename(path))
|
||||||
|
else
|
||||||
|
dest = to
|
||||||
|
if to.end_with?(File::SEPARATOR)
|
||||||
|
dest = File.join(to, File.basename(path))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
@logger.debug("Ensuring remote directory exists for destination upload")
|
||||||
|
create_remote_directory(File.dirname(dest), force_raw: true)
|
||||||
|
@logger.debug("Uploading file #{path} to remote #{dest}")
|
||||||
|
upload_file = File.open(path, "rb")
|
||||||
|
begin
|
||||||
|
scp.upload!(upload_file, dest)
|
||||||
|
ensure
|
||||||
|
upload_file.close
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
uploader.call(from)
|
||||||
|
end
|
||||||
|
rescue RuntimeError => e
|
||||||
|
# Net::SCP raises a runtime error for this so the only way we have
|
||||||
|
# to really catch this exception is to check the message to see if
|
||||||
|
# it is something we care about. If it isn't, we re-raise.
|
||||||
|
raise if e.message !~ /Permission denied/
|
||||||
|
|
||||||
|
# Otherwise, it is a permission denied, so let's raise a proper
|
||||||
|
# exception
|
||||||
|
raise Vagrant::Errors::SCPPermissionDenied,
|
||||||
|
from: from.to_s,
|
||||||
|
to: to.to_s
|
||||||
|
end
|
||||||
|
|
||||||
|
def create_remote_directory(dir, force_raw=false)
|
||||||
|
execute("if not exist \"#{dir}\" mkdir \"#{dir}\"", shell: "cmd", force_raw: force_raw)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -37,7 +37,7 @@ module VagrantPlugins
|
||||||
|
|
||||||
# Ensure the user's ssh directory exists
|
# Ensure the user's ssh directory exists
|
||||||
remote_ssh_dir = "#{home_dir}\\.ssh"
|
remote_ssh_dir = "#{home_dir}\\.ssh"
|
||||||
comm.execute("dir \"#{remote_ssh_dir}\"\n if errorlevel 1 (mkdir \"#{remote_ssh_dir}\")", shell: "cmd")
|
comm.create_remote_directory(remote_ssh_dir)
|
||||||
remote_upload_path = "#{temp_dir}\\vagrant-insert-pubkey-#{Time.now.to_i}"
|
remote_upload_path = "#{temp_dir}\\vagrant-insert-pubkey-#{Time.now.to_i}"
|
||||||
remote_authkeys_path = "#{remote_ssh_dir}\\authorized_keys"
|
remote_authkeys_path = "#{remote_ssh_dir}\\authorized_keys"
|
||||||
|
|
||||||
|
@ -55,7 +55,7 @@ module VagrantPlugins
|
||||||
File.write(keys_file.path, keys.join("\r\n") + "\r\n")
|
File.write(keys_file.path, keys.join("\r\n") + "\r\n")
|
||||||
comm.upload(keys_file.path, remote_upload_path)
|
comm.upload(keys_file.path, remote_upload_path)
|
||||||
keys_file.delete
|
keys_file.delete
|
||||||
comm.execute <<-EOC.gsub(/^\s*/, ""), shell: "powershell"
|
comm.execute(<<-EOC.gsub(/^\s*/, ""), shell: "powershell")
|
||||||
Set-Acl "#{remote_upload_path}" (Get-Acl "#{remote_authkeys_path}")
|
Set-Acl "#{remote_upload_path}" (Get-Acl "#{remote_authkeys_path}")
|
||||||
Move-Item -Force "#{remote_upload_path}" "#{remote_authkeys_path}"
|
Move-Item -Force "#{remote_upload_path}" "#{remote_authkeys_path}"
|
||||||
EOC
|
EOC
|
||||||
|
|
|
@ -55,7 +55,7 @@ module VagrantPlugins
|
||||||
@sha384 = nil if @sha384 == UNSET_VALUE
|
@sha384 = nil if @sha384 == UNSET_VALUE
|
||||||
@sha512 = nil if @sha512 == UNSET_VALUE
|
@sha512 = nil if @sha512 == UNSET_VALUE
|
||||||
@env = {} if @env == UNSET_VALUE
|
@env = {} if @env == UNSET_VALUE
|
||||||
@upload_path = "/tmp/vagrant-shell" if @upload_path == UNSET_VALUE
|
@upload_path = nil if @upload_path == UNSET_VALUE
|
||||||
@privileged = true if @privileged == UNSET_VALUE
|
@privileged = true if @privileged == UNSET_VALUE
|
||||||
@binary = false if @binary == UNSET_VALUE
|
@binary = false if @binary == UNSET_VALUE
|
||||||
@keep_color = false if @keep_color == UNSET_VALUE
|
@keep_color = false if @keep_color == UNSET_VALUE
|
||||||
|
@ -109,11 +109,6 @@ module VagrantPlugins
|
||||||
errors << I18n.t("vagrant.provisioners.shell.env_must_be_a_hash")
|
errors << I18n.t("vagrant.provisioners.shell.env_must_be_a_hash")
|
||||||
end
|
end
|
||||||
|
|
||||||
# There needs to be a path to upload the script to
|
|
||||||
if !upload_path
|
|
||||||
errors << I18n.t("vagrant.provisioners.shell.upload_path_not_set")
|
|
||||||
end
|
|
||||||
|
|
||||||
if !args_valid?
|
if !args_valid?
|
||||||
errors << I18n.t("vagrant.provisioners.shell.args_bad_type")
|
errors << I18n.t("vagrant.provisioners.shell.args_bad_type")
|
||||||
end
|
end
|
||||||
|
|
|
@ -38,6 +38,22 @@ module VagrantPlugins
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def upload_path
|
||||||
|
if !defined?(@_upload_path)
|
||||||
|
@_upload_path = config.upload_path.to_s
|
||||||
|
|
||||||
|
if @_upload_path.empty?
|
||||||
|
case @machine.config.vm.guest
|
||||||
|
when :windows
|
||||||
|
@_upload_path = "C:\\tmp\\vagrant-shell"
|
||||||
|
else
|
||||||
|
@_upload_path = "/tmp/vagrant-shell"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
@_upload_path
|
||||||
|
end
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
||||||
# This handles outputting the communication data back to the UI
|
# This handles outputting the communication data back to the UI
|
||||||
|
@ -63,10 +79,10 @@ module VagrantPlugins
|
||||||
env = config.env.map { |k,v| "#{k}=#{quote_and_escape(v.to_s)}" }
|
env = config.env.map { |k,v| "#{k}=#{quote_and_escape(v.to_s)}" }
|
||||||
env = env.join(" ")
|
env = env.join(" ")
|
||||||
|
|
||||||
command = "chmod +x '#{config.upload_path}'"
|
command = "chmod +x '#{upload_path}'"
|
||||||
command << " &&"
|
command << " &&"
|
||||||
command << " #{env}" if !env.empty?
|
command << " #{env}" if !env.empty?
|
||||||
command << " #{config.upload_path}#{args}"
|
command << " #{upload_path}#{args}"
|
||||||
|
|
||||||
with_script_file do |path|
|
with_script_file do |path|
|
||||||
# Upload the script to the machine
|
# Upload the script to the machine
|
||||||
|
@ -79,10 +95,10 @@ module VagrantPlugins
|
||||||
end
|
end
|
||||||
|
|
||||||
user = info[:username]
|
user = info[:username]
|
||||||
comm.sudo("chown -R #{user} #{config.upload_path}",
|
comm.sudo("chown -R #{user} #{upload_path}",
|
||||||
error_check: false)
|
error_check: false)
|
||||||
|
|
||||||
comm.upload(path.to_s, config.upload_path)
|
comm.upload(path.to_s, upload_path)
|
||||||
|
|
||||||
if config.name
|
if config.name
|
||||||
@machine.ui.detail(I18n.t("vagrant.provisioners.shell.running",
|
@machine.ui.detail(I18n.t("vagrant.provisioners.shell.running",
|
||||||
|
@ -114,7 +130,6 @@ module VagrantPlugins
|
||||||
# Upload the script to the machine
|
# Upload the script to the machine
|
||||||
@machine.communicate.tap do |comm|
|
@machine.communicate.tap do |comm|
|
||||||
env = config.env.map{|k,v| comm.generate_environment_export(k, v)}.join
|
env = config.env.map{|k,v| comm.generate_environment_export(k, v)}.join
|
||||||
upload_path = config.upload_path.to_s
|
|
||||||
if File.extname(upload_path).empty?
|
if File.extname(upload_path).empty?
|
||||||
remote_ext = @machine.config.winssh.shell == "powershell" ? "ps1" : "bat"
|
remote_ext = @machine.config.winssh.shell == "powershell" ? "ps1" : "bat"
|
||||||
upload_path << ".#{remote_ext}"
|
upload_path << ".#{remote_ext}"
|
||||||
|
@ -174,7 +189,6 @@ module VagrantPlugins
|
||||||
@machine.communicate.tap do |comm|
|
@machine.communicate.tap do |comm|
|
||||||
# Make sure that the upload path has an extension, since
|
# Make sure that the upload path has an extension, since
|
||||||
# having an extension is critical for Windows execution
|
# having an extension is critical for Windows execution
|
||||||
upload_path = config.upload_path.to_s
|
|
||||||
if File.extname(upload_path) == ""
|
if File.extname(upload_path) == ""
|
||||||
upload_path += File.extname(path.to_s)
|
upload_path += File.extname(path.to_s)
|
||||||
end
|
end
|
||||||
|
|
|
@ -69,10 +69,10 @@ describe VagrantPlugins::CommunicatorWinSSH::Communicator do
|
||||||
# by providing to `before`
|
# by providing to `before`
|
||||||
connection_setup = proc do
|
connection_setup = proc do
|
||||||
allow(connection).to receive(:logger)
|
allow(connection).to receive(:logger)
|
||||||
allow(connection).to receive(:closed?).and_return false
|
allow(connection).to receive(:closed?).and_return(false)
|
||||||
allow(connection).to receive(:open_channel).
|
allow(connection).to receive(:open_channel).
|
||||||
and_yield(channel).and_return(channel)
|
and_yield(channel).and_return(channel)
|
||||||
allow(channel).to receive(:wait).and_return true
|
allow(channel).to receive(:wait).and_return(true)
|
||||||
allow(channel).to receive(:close)
|
allow(channel).to receive(:close)
|
||||||
allow(command_channel).to receive(:send_data)
|
allow(command_channel).to receive(:send_data)
|
||||||
allow(command_channel).to receive(:eof!)
|
allow(command_channel).to receive(:eof!)
|
||||||
|
@ -88,7 +88,7 @@ describe VagrantPlugins::CommunicatorWinSSH::Communicator do
|
||||||
allow(channel).to receive(:on_request)
|
allow(channel).to receive(:on_request)
|
||||||
allow(channel).to receive(:on_process)
|
allow(channel).to receive(:on_process)
|
||||||
allow(channel).to receive(:exec).with(anything).
|
allow(channel).to receive(:exec).with(anything).
|
||||||
and_yield(command_channel, '').and_return channel
|
and_yield(command_channel, '').and_return(channel)
|
||||||
expect(command_channel).to receive(:on_request).with('exit-status').
|
expect(command_channel).to receive(:on_request).with('exit-status').
|
||||||
and_yield(nil, exit_data)
|
and_yield(nil, exit_data)
|
||||||
# Return mocked net-ssh connection during setup
|
# Return mocked net-ssh connection during setup
|
||||||
|
@ -132,11 +132,11 @@ describe VagrantPlugins::CommunicatorWinSSH::Communicator do
|
||||||
|
|
||||||
context "with an invalid shell test" do
|
context "with an invalid shell test" do
|
||||||
before do
|
before do
|
||||||
expect(exit_data).to receive(:read_long).and_return 1
|
expect(exit_data).to receive(:read_long).and_return(1)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "returns raises SSHInvalidShell error" do
|
it "returns raises SSHInvalidShell error" do
|
||||||
expect{ communicator.ready? }.to raise_error Vagrant::Errors::SSHInvalidShell
|
expect{ communicator.ready? }.to raise_error(Vagrant::Errors::SSHInvalidShell)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -203,6 +203,29 @@ describe VagrantPlugins::CommunicatorWinSSH::Communicator do
|
||||||
expect(stderr).to eq("Dir1\nDir2\n")
|
expect(stderr).to eq("Dir1\nDir2\n")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context "with force_raw set to true" do
|
||||||
|
it "does not write to a temp file" do
|
||||||
|
expect(ssh_cmd_file).to_not receive(:puts)
|
||||||
|
expect(communicator.execute("dir", force_raw: true)).to eq(0)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "does not upload a wrapper script" do
|
||||||
|
expect(communicator).to_not receive(:upload)
|
||||||
|
expect(communicator.execute("dir", force_raw: true)).to eq(0)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "executes the base command" do
|
||||||
|
expect(channel).to receive(:exec).with(/dir/)
|
||||||
|
expect(communicator.execute("dir", force_raw: true)).to eq(0)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "prepends UUID output to command for garbage removal" do
|
||||||
|
expect(channel).to receive(:exec).
|
||||||
|
with(/ECHO #{command_garbage_marker} && ECHO #{command_garbage_marker}.*/)
|
||||||
|
expect(communicator.execute("dir", force_raw: true)).to eq(0)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe ".test" do
|
describe ".test" do
|
||||||
|
@ -215,7 +238,7 @@ describe VagrantPlugins::CommunicatorWinSSH::Communicator do
|
||||||
|
|
||||||
context "with exit code as non-zero" do
|
context "with exit code as non-zero" do
|
||||||
before do
|
before do
|
||||||
expect(exit_data).to receive(:read_long).and_return 1
|
expect(exit_data).to receive(:read_long).and_return(1)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "returns false" do
|
it "returns false" do
|
||||||
|
@ -224,7 +247,7 @@ describe VagrantPlugins::CommunicatorWinSSH::Communicator do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe ".upload" do
|
describe "#upload" do
|
||||||
before do
|
before do
|
||||||
allow(communicator).to receive(:create_remote_directory)
|
allow(communicator).to receive(:create_remote_directory)
|
||||||
expect(communicator).to receive(:scp_connect).and_yield(scp)
|
expect(communicator).to receive(:scp_connect).and_yield(scp)
|
||||||
|
@ -241,7 +264,9 @@ describe VagrantPlugins::CommunicatorWinSSH::Communicator do
|
||||||
it "uploads a file if local path is a file" do
|
it "uploads a file if local path is a file" do
|
||||||
file = Tempfile.new('vagrant-test')
|
file = Tempfile.new('vagrant-test')
|
||||||
begin
|
begin
|
||||||
expect(scp).to receive(:upload!).with(instance_of(File), 'C:\destination\file')
|
expect(scp).to receive(:upload!).with(instance_of(File), 'C:/destination/file')
|
||||||
|
expect(Vagrant::Util::Platform).to receive(:unix_windows_path).with('C:\destination\file').
|
||||||
|
and_call_original
|
||||||
communicator.upload(file.path, 'C:\destination\file')
|
communicator.upload(file.path, 'C:\destination\file')
|
||||||
ensure
|
ensure
|
||||||
file.delete
|
file.delete
|
||||||
|
@ -251,7 +276,7 @@ describe VagrantPlugins::CommunicatorWinSSH::Communicator do
|
||||||
it "raises custom error on permission errors" do
|
it "raises custom error on permission errors" do
|
||||||
file = Tempfile.new('vagrant-test')
|
file = Tempfile.new('vagrant-test')
|
||||||
begin
|
begin
|
||||||
expect(scp).to receive(:upload!).with(instance_of(File), 'C:\destination\file').
|
expect(scp).to receive(:upload!).with(instance_of(File), 'C:/destination/file').
|
||||||
and_raise("Permission denied")
|
and_raise("Permission denied")
|
||||||
expect{ communicator.upload(file.path, 'C:\destination\file') }.to(
|
expect{ communicator.upload(file.path, 'C:\destination\file') }.to(
|
||||||
raise_error(Vagrant::Errors::SCPPermissionDenied)
|
raise_error(Vagrant::Errors::SCPPermissionDenied)
|
||||||
|
@ -264,7 +289,7 @@ describe VagrantPlugins::CommunicatorWinSSH::Communicator do
|
||||||
it "does not raise custom error on non-permission errors" do
|
it "does not raise custom error on non-permission errors" do
|
||||||
file = Tempfile.new('vagrant-test')
|
file = Tempfile.new('vagrant-test')
|
||||||
begin
|
begin
|
||||||
expect(scp).to receive(:upload!).with(instance_of(File), 'C:\destination\file').
|
expect(scp).to receive(:upload!).with(instance_of(File), 'C:/destination/file').
|
||||||
and_raise("Some other error")
|
and_raise("Some other error")
|
||||||
expect{ communicator.upload(file.path, 'C:\destination\file') }.to raise_error(RuntimeError)
|
expect{ communicator.upload(file.path, 'C:\destination\file') }.to raise_error(RuntimeError)
|
||||||
ensure
|
ensure
|
||||||
|
|
|
@ -22,6 +22,7 @@ describe "VagrantPlugins::GuestWindows::Cap::InsertPublicKey" do
|
||||||
allow(comm).to receive(:execute).with(/echo .+/, shell: "cmd").and_yield(:stdout, "TEMP\r\nHOME\r\n")
|
allow(comm).to receive(:execute).with(/echo .+/, shell: "cmd").and_yield(:stdout, "TEMP\r\nHOME\r\n")
|
||||||
allow(comm).to receive(:execute).with(/dir .+\.ssh/, shell: "cmd")
|
allow(comm).to receive(:execute).with(/dir .+\.ssh/, shell: "cmd")
|
||||||
allow(comm).to receive(:execute).with(/dir .+authorized_keys/, shell: "cmd", error_check: false).and_return(auth_keys_check_result)
|
allow(comm).to receive(:execute).with(/dir .+authorized_keys/, shell: "cmd", error_check: false).and_return(auth_keys_check_result)
|
||||||
|
allow(comm).to receive(:create_remote_directory)
|
||||||
end
|
end
|
||||||
|
|
||||||
after do
|
after do
|
||||||
|
|
|
@ -29,6 +29,7 @@ describe "VagrantPlugins::GuestWindows::Cap::RemovePublicKey" do
|
||||||
allow(comm).to receive(:execute).with(/echo .+/, shell: "cmd").and_yield(:stdout, "TEMP\r\nHOME\r\n")
|
allow(comm).to receive(:execute).with(/echo .+/, shell: "cmd").and_yield(:stdout, "TEMP\r\nHOME\r\n")
|
||||||
allow(comm).to receive(:execute).with(/dir .+\.ssh/, shell: "cmd")
|
allow(comm).to receive(:execute).with(/dir .+\.ssh/, shell: "cmd")
|
||||||
allow(comm).to receive(:execute).with(/dir .+authorized_keys/, shell: "cmd", error_check: false).and_return(auth_keys_check_result)
|
allow(comm).to receive(:execute).with(/dir .+authorized_keys/, shell: "cmd", error_check: false).and_return(auth_keys_check_result)
|
||||||
|
allow(comm).to receive(:create_remote_directory)
|
||||||
end
|
end
|
||||||
|
|
||||||
after do
|
after do
|
||||||
|
|
|
@ -7,6 +7,7 @@ describe "VagrantPlugins::Shell::Config" do
|
||||||
|
|
||||||
let(:machine) { double('machine', env: Vagrant::Environment.new) }
|
let(:machine) { double('machine', env: Vagrant::Environment.new) }
|
||||||
let(:file_that_exists) { File.expand_path(__FILE__) }
|
let(:file_that_exists) { File.expand_path(__FILE__) }
|
||||||
|
let(:unset_value) { Vagrant::Plugin::V2::Config::UNSET_VALUE }
|
||||||
|
|
||||||
subject { described_class.new }
|
subject { described_class.new }
|
||||||
|
|
||||||
|
@ -142,6 +143,15 @@ describe "VagrantPlugins::Shell::Config" do
|
||||||
result = subject.validate(machine)
|
result = subject.validate(machine)
|
||||||
expect(result["shell provisioner"]).to be_empty
|
expect(result["shell provisioner"]).to be_empty
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "returns no error if upload_path is unset" do
|
||||||
|
subject.inline = "script"
|
||||||
|
subject.upload_path = unset_value
|
||||||
|
subject.finalize!
|
||||||
|
|
||||||
|
result = subject.validate(machine)
|
||||||
|
expect(result["shell provisioner"]).to be_empty
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'finalize!' do
|
describe 'finalize!' do
|
||||||
|
@ -150,7 +160,7 @@ describe "VagrantPlugins::Shell::Config" do
|
||||||
subject.args = 1
|
subject.args = 1
|
||||||
subject.finalize!
|
subject.finalize!
|
||||||
|
|
||||||
expect(subject.args).to eq '1'
|
expect(subject.args).to eq('1')
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'changes integer args in arrays into strings' do
|
it 'changes integer args in arrays into strings' do
|
||||||
|
@ -158,7 +168,14 @@ describe "VagrantPlugins::Shell::Config" do
|
||||||
subject.args = ["string", 1, 2]
|
subject.args = ["string", 1, 2]
|
||||||
subject.finalize!
|
subject.finalize!
|
||||||
|
|
||||||
expect(subject.args).to eq ["string", '1', '2']
|
expect(subject.args).to eq(["string", '1', '2'])
|
||||||
|
end
|
||||||
|
|
||||||
|
it "no longer sets a default for upload_path" do
|
||||||
|
subject.upload_path = unset_value
|
||||||
|
subject.finalize!
|
||||||
|
|
||||||
|
expect(subject.upload_path).to eq(nil)
|
||||||
end
|
end
|
||||||
|
|
||||||
context "with sensitive option enabled" do
|
context "with sensitive option enabled" do
|
||||||
|
|
|
@ -8,6 +8,7 @@ describe "Vagrant::Shell::Provisioner" do
|
||||||
let(:machine) {
|
let(:machine) {
|
||||||
double(:machine, env: env, id: "ID").tap { |machine|
|
double(:machine, env: env, id: "ID").tap { |machine|
|
||||||
allow(machine).to receive_message_chain(:config, :vm, :communicator).and_return(:not_winrm)
|
allow(machine).to receive_message_chain(:config, :vm, :communicator).and_return(:not_winrm)
|
||||||
|
allow(machine).to receive_message_chain(:config, :vm, :guest).and_return(:linux)
|
||||||
allow(machine).to receive_message_chain(:communicate, :tap) {}
|
allow(machine).to receive_message_chain(:communicate, :tap) {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -323,4 +324,82 @@ describe "Vagrant::Shell::Provisioner" do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "#upload_path" do
|
||||||
|
context "when upload path is not set" do
|
||||||
|
let(:vsp) {
|
||||||
|
VagrantPlugins::Shell::Provisioner.new(machine, config)
|
||||||
|
}
|
||||||
|
|
||||||
|
let(:config) {
|
||||||
|
double(
|
||||||
|
:config,
|
||||||
|
:args => "doesn't matter",
|
||||||
|
:env => {},
|
||||||
|
:upload_path => nil,
|
||||||
|
:remote? => false,
|
||||||
|
:path => "doesn't matter",
|
||||||
|
:inline => "doesn't matter",
|
||||||
|
:binary => false,
|
||||||
|
:reset => true,
|
||||||
|
:reboot => false,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
it "should default to /tmp/vagrant-shell" do
|
||||||
|
expect(vsp.upload_path).to eq("/tmp/vagrant-shell")
|
||||||
|
end
|
||||||
|
|
||||||
|
context "windows" do
|
||||||
|
before do
|
||||||
|
allow(machine).to receive_message_chain(:config, :vm, :guest).and_return(:windows)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should default to C:\\tmp\\vagrant-shell" do
|
||||||
|
expect(vsp.upload_path).to eq("C:\\tmp\\vagrant-shell")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "when upload_path is set" do
|
||||||
|
let(:config) {
|
||||||
|
double(
|
||||||
|
:config,
|
||||||
|
:args => "doesn't matter",
|
||||||
|
:env => {},
|
||||||
|
:upload_path => "arbitrary",
|
||||||
|
:remote? => false,
|
||||||
|
:path => "doesn't matter",
|
||||||
|
:inline => "doesn't matter",
|
||||||
|
:binary => false,
|
||||||
|
:reset => true,
|
||||||
|
:reboot => false,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
let(:vsp) {
|
||||||
|
VagrantPlugins::Shell::Provisioner.new(machine, config)
|
||||||
|
}
|
||||||
|
|
||||||
|
it "should use the value from from config" do
|
||||||
|
expect(vsp.upload_path).to eq("arbitrary")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "with cached value" do
|
||||||
|
let(:config) { double(:config) }
|
||||||
|
|
||||||
|
let(:vsp) {
|
||||||
|
VagrantPlugins::Shell::Provisioner.new(machine, config)
|
||||||
|
}
|
||||||
|
|
||||||
|
before do
|
||||||
|
vsp.instance_variable_set(:@_upload_path, "anything")
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should use cached value" do
|
||||||
|
expect(vsp.upload_path).to eq("anything")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -280,7 +280,7 @@ describe Vagrant::Util::Platform do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should return false when path is within /mnt" do
|
it "should return false when path is within /mnt" do
|
||||||
expect(subject.wsl_path?("/mnt/c")).to be false
|
expect(subject.wsl_path?("/mnt/c")).to be(false)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -533,5 +533,11 @@ EOF
|
||||||
expect(subject.wsl_drvfs_path?("/home/vagrant/some/path")).to be_falsey
|
expect(subject.wsl_drvfs_path?("/home/vagrant/some/path")).to be_falsey
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe ".unix_windows_path" do
|
||||||
|
it "takes a windows path and returns a unixy path" do
|
||||||
|
expect(subject.unix_windows_path("C:\\Temp\\Windows")).to eq("C:/Temp/Windows")
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue