Merge pull request #8880 from briancain/8603/master/fix-scp-usage-in-file-prov

Ensure remote folder exists prior to scp in file provisioner
This commit is contained in:
Brian Cain 2017-08-15 10:04:14 -07:00 committed by GitHub
commit 0d8f58e5da
12 changed files with 263 additions and 13 deletions

View File

@ -4,7 +4,7 @@ module VagrantPlugins
class ShellExpandGuestPath
def self.shell_expand_guest_path(machine, path)
real_path = nil
machine.communicate.execute("printf #{path}") do |type, data|
machine.communicate.execute("printf \"#{path}\"") do |type, data|
if type == :stdout
real_path ||= ""
real_path += data
@ -14,7 +14,7 @@ module VagrantPlugins
if !real_path
# If no real guest path was detected, this is really strange
# and we raise an exception because this is a bug.
raise ShellExpandFailed
raise Vagrant::Errors::ShellExpandFailed
end
# Chomp the string so that any trailing newlines are killed

View File

@ -4,7 +4,7 @@ module VagrantPlugins
class ShellExpandGuestPath
def self.shell_expand_guest_path(machine, path)
real_path = nil
machine.communicate.execute("printf #{path}",
machine.communicate.execute("printf \"#{path}\"",
shell: "sh") do |type, data|
if type == :stdout
real_path ||= ""
@ -15,7 +15,7 @@ module VagrantPlugins
if !real_path
# If no real guest path was detected, this is really strange
# and we raise an exception because this is a bug.
raise ShellExpandFailed
raise Vagrant::Errors::ShellExpandFailed
end
# Chomp the string so that any trailing newlines are killed

View File

@ -4,7 +4,7 @@ module VagrantPlugins
class ShellExpandGuestPath
def self.shell_expand_guest_path(machine, path)
real_path = nil
machine.communicate.execute("echo; printf #{path}") do |type, data|
machine.communicate.execute("echo; printf \"#{path}\"") do |type, data|
if type == :stdout
real_path ||= ""
real_path += data
@ -19,7 +19,7 @@ module VagrantPlugins
if !real_path
# If no real guest path was detected, this is really strange
# and we raise an exception because this is a bug.
raise ShellExpandFailed
raise Vagrant::Errors::ShellExpandFailed
end
# Chomp the string so that any trailing newlines are killed

View File

@ -4,7 +4,7 @@ module VagrantPlugins
class ShellExpandGuestPath
def self.shell_expand_guest_path(machine, path)
real_path = nil
machine.communicate.execute("printf #{path}") do |type, data|
machine.communicate.execute("printf \"#{path}\"") do |type, data|
if type == :stdout
real_path ||= ""
real_path += data
@ -14,7 +14,7 @@ module VagrantPlugins
if !real_path
# If no real guest path was detected, this is really strange
# and we raise an exception because this is a bug.
raise ShellExpandFailed
raise Vagrant::Errors::ShellExpandFailed
end
# Chomp the string so that any trailing newlines are killed

View File

@ -4,7 +4,7 @@ module VagrantPlugins
class ShellExpandGuestPath
def self.shell_expand_guest_path(machine, path)
real_path = nil
machine.communicate.execute("printf #{path}") do |type, data|
machine.communicate.execute("printf \"#{path}\"") do |type, data|
if type == :stdout
real_path ||= ""
real_path += data
@ -14,7 +14,7 @@ module VagrantPlugins
if !real_path
# If no real guest path was detected, this is really strange
# and we raise an exception because this is a bug.
raise ShellExpandFailed
raise Vagrant::Errors::ShellExpandFailed
end
# Chomp the string so that any trailing newlines are killed

View File

@ -3,14 +3,30 @@ module VagrantPlugins
class Provisioner < Vagrant.plugin("2", :provisioner)
def provision
@machine.communicate.tap do |comm|
source = File.expand_path(config.source)
destination = expand_guest_path(config.destination)
# if source is a directory, make it then trim destination with dirname
# Make sure the remote path exists
command = "mkdir -p %s" % File.dirname(destination)
if File.directory?(source)
# We need to make sure the actual destination folder
# also exists before uploading, otherwise
# you will get nested folders. We also need to append
# a './' to the source folder so we copy the contents
# rather than the folder itself, in case a users destination
# folder differs from its source.
#
# https://serverfault.com/questions/538368/make-scp-always-overwrite-or-create-directory
# https://unix.stackexchange.com/questions/292641/get-scp-path-behave-like-rsync-path/292732
command = "mkdir -p \"%s\"" % destination
source << "/."
else
command = "mkdir -p \"%s\"" % File.dirname(destination)
end
comm.execute(command)
# now upload the file
comm.upload(File.expand_path(config.source), destination)
comm.upload(source, destination)
end
end

View File

@ -0,0 +1,43 @@
require_relative "../../../../base"
describe "VagrantPlugins::GuestDarwin::Cap::ShellExpandGuestPath" do
let(:caps) do
VagrantPlugins::GuestDarwin::Plugin
.components
.guest_capabilities[:darwin]
end
let(:machine) { double("machine") }
let(:comm) { VagrantTests::DummyCommunicator::Communicator.new(machine) }
before do
allow(machine).to receive(:communicate).and_return(comm)
end
describe "#shell_expand_guest_path" do
let(:cap) { caps.get(:shell_expand_guest_path) }
it "expands the path" do
path = "/home/vagrant/folder"
allow(machine.communicate).to receive(:execute).
with(any_args).and_yield(:stdout, "/home/vagrant/folder")
cap.shell_expand_guest_path(machine, path)
end
it "raises an exception if no path was detected" do
path = "/home/vagrant/folder"
expect { cap.shell_expand_guest_path(machine, path) }.
to raise_error(Vagrant::Errors::ShellExpandFailed)
end
it "returns a path with a space in it" do
path = "/home/vagrant folder/folder"
allow(machine.communicate).to receive(:execute).
with(any_args).and_yield(:stdout, "/home/vagrant folder/folder")
expect(machine.communicate).to receive(:execute).with("printf \"#{path}\"")
cap.shell_expand_guest_path(machine, path)
end
end
end

View File

@ -0,0 +1,44 @@
require_relative "../../../../base"
describe "VagrantPlugins::GuestFreeBSD::Cap::ShellExpandGuestPath" do
let(:caps) do
VagrantPlugins::GuestFreeBSD::Plugin
.components
.guest_capabilities[:freebsd]
end
let(:machine) { double("machine") }
let(:comm) { VagrantTests::DummyCommunicator::Communicator.new(machine) }
before do
allow(machine).to receive(:communicate).and_return(comm)
end
describe "#shell_expand_guest_path" do
let(:cap) { caps.get(:shell_expand_guest_path) }
it "expands the path" do
path = "/home/vagrant/folder"
allow(machine.communicate).to receive(:execute).
with(any_args).and_yield(:stdout, "/home/vagrant/folder")
cap.shell_expand_guest_path(machine, path)
end
it "raises an exception if no path was detected" do
path = "/home/vagrant/folder"
expect { cap.shell_expand_guest_path(machine, path) }.
to raise_error(Vagrant::Errors::ShellExpandFailed)
end
it "returns a path with a space in it" do
path = "/home/vagrant folder/folder"
allow(machine.communicate).to receive(:execute).
with(any_args).and_yield(:stdout, "/home/vagrant folder/folder")
expect(machine.communicate).to receive(:execute)
.with("printf \"#{path}\"", {:shell=>"sh"})
cap.shell_expand_guest_path(machine, path)
end
end
end

View File

@ -0,0 +1,43 @@
require_relative "../../../../base"
describe "VagrantPlugins::GuestLinux::Cap::ShellExpandGuestPath" do
let(:caps) do
VagrantPlugins::GuestLinux::Plugin
.components
.guest_capabilities[:linux]
end
let(:machine) { double("machine") }
let(:comm) { VagrantTests::DummyCommunicator::Communicator.new(machine) }
before do
allow(machine).to receive(:communicate).and_return(comm)
end
describe "#shell_expand_guest_path" do
let(:cap) { caps.get(:shell_expand_guest_path) }
it "expands the path" do
path = "/home/vagrant/folder"
allow(machine.communicate).to receive(:execute).
with(any_args).and_yield(:stdout, "/home/vagrant/folder")
cap.shell_expand_guest_path(machine, path)
end
it "raises an exception if no path was detected" do
path = "/home/vagrant/folder"
expect { cap.shell_expand_guest_path(machine, path) }.
to raise_error(Vagrant::Errors::ShellExpandFailed)
end
it "returns a path with a space in it" do
path = "/home/vagrant folder/folder"
allow(machine.communicate).to receive(:execute).
with(any_args).and_yield(:stdout, "/home/vagrant folder/folder")
expect(machine.communicate).to receive(:execute).with("echo; printf \"#{path}\"")
cap.shell_expand_guest_path(machine, path)
end
end
end

View File

@ -0,0 +1,43 @@
require_relative "../../../../base"
describe "VagrantPlugins::GuestNetBSD::Cap::ShellExpandGuestPath" do
let(:caps) do
VagrantPlugins::GuestNetBSD::Plugin
.components
.guest_capabilities[:netbsd]
end
let(:machine) { double("machine") }
let(:comm) { VagrantTests::DummyCommunicator::Communicator.new(machine) }
before do
allow(machine).to receive(:communicate).and_return(comm)
end
describe "#shell_expand_guest_path" do
let(:cap) { caps.get(:shell_expand_guest_path) }
it "expands the path" do
path = "/home/vagrant/folder"
allow(machine.communicate).to receive(:execute).
with(any_args).and_yield(:stdout, "/home/vagrant/folder")
cap.shell_expand_guest_path(machine, path)
end
it "raises an exception if no path was detected" do
path = "/home/vagrant/folder"
expect { cap.shell_expand_guest_path(machine, path) }.
to raise_error(Vagrant::Errors::ShellExpandFailed)
end
it "returns a path with a space in it" do
path = "/home/vagrant folder/folder"
allow(machine.communicate).to receive(:execute).
with(any_args).and_yield(:stdout, "/home/vagrant folder/folder")
expect(machine.communicate).to receive(:execute).with("printf \"#{path}\"")
cap.shell_expand_guest_path(machine, path)
end
end
end

View File

@ -0,0 +1,43 @@
require_relative "../../../../base"
describe "VagrantPlugins::GuestOpenBSD::Cap::ShellExpandGuestPath" do
let(:caps) do
VagrantPlugins::GuestOpenBSD::Plugin
.components
.guest_capabilities[:openbsd]
end
let(:machine) { double("machine") }
let(:comm) { VagrantTests::DummyCommunicator::Communicator.new(machine) }
before do
allow(machine).to receive(:communicate).and_return(comm)
end
describe "#shell_expand_guest_path" do
let(:cap) { caps.get(:shell_expand_guest_path) }
it "expands the path" do
path = "/home/vagrant/folder"
allow(machine.communicate).to receive(:execute).
with(any_args).and_yield(:stdout, "/home/vagrant/folder")
cap.shell_expand_guest_path(machine, path)
end
it "raises an exception if no path was detected" do
path = "/home/vagrant/folder"
expect { cap.shell_expand_guest_path(machine, path) }.
to raise_error(Vagrant::Errors::ShellExpandFailed)
end
it "returns a path with a space in it" do
path = "/home/vagrant folder/folder"
allow(machine.communicate).to receive(:execute).
with(any_args).and_yield(:stdout, "/home/vagrant folder/folder")
expect(machine.communicate).to receive(:execute).with("printf \"#{path}\"")
cap.shell_expand_guest_path(machine, path)
end
end
end

View File

@ -34,7 +34,25 @@ describe VagrantPlugins::FileUpload::Provisioner do
allow(config).to receive(:source).and_return("/source")
allow(config).to receive(:destination).and_return("/foo/bar")
expect(communicator).to receive(:execute).with("mkdir -p /foo")
expect(communicator).to receive(:execute).with("mkdir -p \"/foo\"")
subject.provision
end
it "creates the destination directory with a space" do
allow(config).to receive(:source).and_return("/source")
allow(config).to receive(:destination).and_return("/foo bar/bar")
expect(communicator).to receive(:execute).with("mkdir -p \"/foo bar\"")
subject.provision
end
it "creates the destination directory above file" do
allow(config).to receive(:source).and_return("/source/file.sh")
allow(config).to receive(:destination).and_return("/foo/bar/file.sh")
expect(communicator).to receive(:execute).with("mkdir -p \"/foo/bar\"")
subject.provision
end