Merge pull request #2922 from tmatilai/file_provisioner_expand_path

provisioners/file: expand destination path if capable
This commit is contained in:
Mitchell Hashimoto 2014-02-03 02:52:57 -08:00
commit 592c577b2e
13 changed files with 267 additions and 14 deletions

View File

@ -304,10 +304,6 @@ module Vagrant
error_key(:linux_nfs_mount_failed) error_key(:linux_nfs_mount_failed)
end end
class LinuxShellExpandFailed < VagrantError
error_key(:linux_shell_expand_failed)
end
class LocalDataDirectoryNotAccessible < VagrantError class LocalDataDirectoryNotAccessible < VagrantError
error_key(:local_data_dir_not_accessible) error_key(:local_data_dir_not_accessible)
end end
@ -444,6 +440,10 @@ module Vagrant
error_key(:shared_folder_create_failed) error_key(:shared_folder_create_failed)
end end
class ShellExpandFailed < VagrantError
error_key(:shell_expand_failed)
end
class SSHAuthenticationFailed < VagrantError class SSHAuthenticationFailed < VagrantError
error_key(:ssh_authentication_failed) error_key(:ssh_authentication_failed)
end end

View File

@ -14,7 +14,7 @@ module VagrantPlugins
if !real_path if !real_path
# If no real guest path was detected, this is really strange # If no real guest path was detected, this is really strange
# and we raise an exception because this is a bug. # and we raise an exception because this is a bug.
raise DarwinShellExpandFailed raise ShellExpandFailed
end end
# Chomp the string so that any trailing newlines are killed # Chomp the string so that any trailing newlines are killed

View File

@ -0,0 +1,27 @@
module VagrantPlugins
module GuestFreeBSD
module Cap
class ShellExpandGuestPath
def self.shell_expand_guest_path(machine, path)
real_path = nil
machine.communicate.execute("printf #{path}",
shell: "sh") do |type, data|
if type == :stdout
real_path ||= ""
real_path += data
end
end
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
end
# Chomp the string so that any trailing newlines are killed
return real_path.chomp
end
end
end
end
end

View File

@ -30,6 +30,11 @@ module VagrantPlugins
require_relative "cap/mount_nfs_folder" require_relative "cap/mount_nfs_folder"
Cap::MountNFSFolder Cap::MountNFSFolder
end end
guest_capability("freebsd", "shell_expand_guest_path") do
require_relative "cap/shell_expand_guest_path"
Cap::ShellExpandGuestPath
end
end end
end end
end end

View File

@ -17,7 +17,7 @@ module VagrantPlugins
if !real_path if !real_path
# If no real guest path was detected, this is really strange # If no real guest path was detected, this is really strange
# and we raise an exception because this is a bug. # and we raise an exception because this is a bug.
raise LinuxShellExpandFailed raise ShellExpandFailed
end end
# Chomp the string so that any trailing newlines are killed # Chomp the string so that any trailing newlines are killed

View File

@ -0,0 +1,26 @@
module VagrantPlugins
module GuestNetBSD
module Cap
class ShellExpandGuestPath
def self.shell_expand_guest_path(machine, path)
real_path = nil
machine.communicate.execute("printf #{path}") do |type, data|
if type == :stdout
real_path ||= ""
real_path += data
end
end
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
end
# Chomp the string so that any trailing newlines are killed
return real_path.chomp
end
end
end
end
end

View File

@ -30,6 +30,11 @@ module VagrantPlugins
require_relative "cap/mount_nfs_folder" require_relative "cap/mount_nfs_folder"
Cap::MountNFSFolder Cap::MountNFSFolder
end end
guest_capability("netbsd", "shell_expand_guest_path") do
require_relative "cap/shell_expand_guest_path"
Cap::ShellExpandGuestPath
end
end end
end end
end end

View File

@ -0,0 +1,26 @@
module VagrantPlugins
module GuestOpenBSD
module Cap
class ShellExpandGuestPath
def self.shell_expand_guest_path(machine, path)
real_path = nil
machine.communicate.execute("printf #{path}") do |type, data|
if type == :stdout
real_path ||= ""
real_path += data
end
end
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
end
# Chomp the string so that any trailing newlines are killed
return real_path.chomp
end
end
end
end
end

View File

@ -30,6 +30,11 @@ module VagrantPlugins
require_relative "cap/mount_nfs_folder" require_relative "cap/mount_nfs_folder"
Cap::MountNFSFolder Cap::MountNFSFolder
end end
guest_capability("openbsd", "shell_expand_guest_path") do
require_relative "cap/shell_expand_guest_path"
Cap::ShellExpandGuestPath
end
end end
end end
end end

View File

@ -3,12 +3,25 @@ module VagrantPlugins
class Provisioner < Vagrant.plugin("2", :provisioner) class Provisioner < Vagrant.plugin("2", :provisioner)
def provision def provision
@machine.communicate.tap do |comm| @machine.communicate.tap do |comm|
destination = expand_guest_path(config.destination)
# Make sure the remote path exists # Make sure the remote path exists
command = "mkdir -p %s" % File.dirname(config.destination) command = "mkdir -p %s" % File.dirname(destination)
comm.execute(command) comm.execute(command)
# now upload the file # now upload the file
comm.upload(File.expand_path(config.source), config.destination) comm.upload(File.expand_path(config.source), destination)
end
end
private
# Expand the guest path if the guest has the capability
def expand_guest_path(destination)
if machine.guest.capability?(:shell_expand_guest_path)
machine.guest.capability(:shell_expand_guest_path, destination)
else
destination
end end
end end
end end

View File

@ -463,11 +463,6 @@ en:
that the NFS client software is properly installed, and consult any resources that the NFS client software is properly installed, and consult any resources
specific to the linux distro you're using for more information on how to specific to the linux distro you're using for more information on how to
do this. do this.
linux_shell_expand_failed: |-
Vagrant failed to determine the shell expansion of the guest path
for one of your shared folders. This is an extremely rare error case
and most likely indicates an unusual configuration of the guest system.
Please report a bug with your Vagrantfile.
machine_guest_not_ready: |- machine_guest_not_ready: |-
Guest-specific operations were attempted on a machine that is not Guest-specific operations were attempted on a machine that is not
ready for guest communication. This should not happen and a bug ready for guest communication. This should not happen and a bug
@ -591,6 +586,11 @@ en:
%{path} %{path}
Please create the folder manually or specify another path to share. Please create the folder manually or specify another path to share.
shell_expand_failed: |-
Vagrant failed to determine the shell expansion of a guest path
(probably for one of your shared folders). This is an extremely rare
error case and most likely indicates an unusual configuration of the
guest system. Please report a bug with your Vagrantfile and debug log.
ssh_authentication_failed: |- ssh_authentication_failed: |-
SSH authentication failed! This is typically caused by the public/private SSH authentication failed! This is typically caused by the public/private
keypair for the SSH user not being properly set on the guest VM. Please keypair for the SSH user not being properly set on the guest VM. Please

View File

@ -0,0 +1,71 @@
require_relative "../../../base"
require Vagrant.source_root.join("plugins/provisioners/file/config")
describe VagrantPlugins::FileUpload::Config do
include_context "unit"
subject { described_class.new }
let(:machine) { double("machine") }
describe "#validate" do
it "returns an error if destination is not specified" do
existing_file = File.expand_path(__FILE__)
subject.source = existing_file
subject.finalize!
result = subject.validate(machine)
expect(result["File provisioner"]).to eql([
I18n.t("vagrant.provisioners.file.no_dest_file")
])
end
it "returns an error if source is not specified" do
subject.destination = "/tmp/foo"
subject.finalize!
result = subject.validate(machine)
expect(result["File provisioner"]).to eql([
I18n.t("vagrant.provisioners.file.no_source_file")
])
end
it "returns an error if source file does not exist" do
non_existing_file = "this/does/not/exist"
subject.source = non_existing_file
subject.destination = "/tmp/foo"
subject.finalize!
result = subject.validate(machine)
expect(result["File provisioner"]).to eql([
I18n.t("vagrant.provisioners.file.path_invalid",
path: File.expand_path(non_existing_file))
])
end
it "passes with absolute source path" do
existing_absolute_path = File.expand_path(__FILE__)
subject.source = existing_absolute_path
subject.destination = "/tmp/foo"
subject.finalize!
result = subject.validate(machine)
expect(result["File provisioner"]).to eql([])
end
it "passes with relative source path" do
existing_relative_path = __FILE__
subject.source = existing_relative_path
subject.destination = "/tmp/foo"
subject.finalize!
result = subject.validate(machine)
expect(result["File provisioner"]).to eql([])
end
end
end

View File

@ -0,0 +1,75 @@
require_relative "../../../base"
require Vagrant.source_root.join("plugins/provisioners/file/provisioner")
describe VagrantPlugins::FileUpload::Provisioner do
include_context "unit"
subject { described_class.new(machine, config) }
let(:iso_env) do
# We have to create a Vagrantfile so there is a root path
env = isolated_environment
env.vagrantfile("")
env.create_vagrant_env
end
let(:machine) { iso_env.machine(iso_env.machine_names[0], :dummy) }
let(:config) { double("config") }
let(:communicator) { double("comm") }
let(:guest) { double("guest") }
before do
machine.stub(communicate: communicator)
machine.stub(guest: guest)
communicator.stub(execute: true)
communicator.stub(upload: true)
guest.stub(capability?: false)
end
describe "#provision" do
it "creates the destination directory" do
config.stub(source: "/source")
config.stub(destination: "/foo/bar")
expect(communicator).to receive(:execute).with("mkdir -p /foo")
subject.provision
end
it "uploads the file" do
config.stub(source: "/source")
config.stub(destination: "/foo/bar")
expect(communicator).to receive(:upload).with("/source", "/foo/bar")
subject.provision
end
it "expands the source file path" do
config.stub(source: "source")
config.stub(destination: "/foo/bar")
expect(communicator).to receive(:upload).with(
File.expand_path("source"), "/foo/bar")
subject.provision
end
it "expands the destination file path if capable" do
config.stub(source: "/source")
config.stub(destination: "$HOME/foo")
expect(guest).to receive(:capability?).
with(:shell_expand_guest_path).and_return(true)
expect(guest).to receive(:capability).
with(:shell_expand_guest_path, "$HOME/foo").and_return("/home/foo")
expect(communicator).to receive(:upload).with("/source", "/home/foo")
subject.provision
end
end
end