Support loading plugin information from nested Vagrantfiles
Since plugin installation happens when the environment is first initialized, attempt to determine the provider in use and load any box provided Vagrantfiles to include any plugin configuration they may include.
This commit is contained in:
parent
b3877f4b2c
commit
50c4464d44
|
@ -175,9 +175,7 @@ module Vagrant
|
|||
# Load any global plugins
|
||||
Vagrant::Plugin::Manager.instance.load_plugins(plugins)
|
||||
|
||||
if !vagrantfile.config.vagrant.plugins.empty?
|
||||
plugins = process_configured_plugins
|
||||
end
|
||||
plugins = process_configured_plugins
|
||||
|
||||
# Call the hooks that does not require configurations to be loaded
|
||||
# by using a "clean" action runner
|
||||
|
@ -922,6 +920,49 @@ module Vagrant
|
|||
|
||||
protected
|
||||
|
||||
# Attempt to guess the configured provider in use. Will fallback
|
||||
# to the default provider if an explicit provider name is not
|
||||
# provided. This can be pretty error prone, but is used during
|
||||
# initial environment setup to allow loading plugins so it doesn't
|
||||
# need to be perfect
|
||||
#
|
||||
# @return [String]
|
||||
def guess_provider
|
||||
gp = nil
|
||||
ARGV.each_with_index do |val, idx|
|
||||
if val.start_with?("--provider=")
|
||||
gp = val.split("=", 2).last
|
||||
break
|
||||
elsif val == "--provider"
|
||||
gp = ARGV[idx+1]
|
||||
break
|
||||
end
|
||||
end
|
||||
return gp if gp
|
||||
begin
|
||||
default_provider
|
||||
rescue Errors::NoDefaultProvider
|
||||
# if a provider cannot be determined just return nil
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
# Load any configuration provided by guests defined within
|
||||
# the Vagrantfile to pull plugin information they may have
|
||||
# defined.
|
||||
def find_configured_plugins
|
||||
plugins = []
|
||||
provider = guess_provider
|
||||
vagrantfile.machine_names.each do |mname|
|
||||
ldp = @local_data_path.join("machines/#{mname}/#{provider}") if @local_data_path
|
||||
plugins << vagrantfile.machine_config(mname, guess_provider, boxes, ldp)[:config]
|
||||
end
|
||||
result = plugins.reverse.inject(Vagrant::Util::HashWithIndifferentAccess.new) do |memo, val|
|
||||
Vagrant::Util::DeepMerge.deep_merge(memo, val.vagrant.plugins)
|
||||
end
|
||||
Vagrant::Util::DeepMerge.deep_merge(result, vagrantfile.config.vagrant.plugins)
|
||||
end
|
||||
|
||||
# Check for any local plugins defined within the Vagrantfile. If
|
||||
# found, validate they are available. If they are not available,
|
||||
# request to install them, or raise an exception
|
||||
|
@ -939,7 +980,7 @@ module Vagrant
|
|||
# Check if defined plugins are installed
|
||||
installed = Plugin::Manager.instance.installed_plugins
|
||||
needs_install = []
|
||||
config_plugins = vagrantfile.config.vagrant.plugins
|
||||
config_plugins = find_configured_plugins
|
||||
config_plugins.each do |name, info|
|
||||
if !installed[name]
|
||||
needs_install << name
|
||||
|
|
|
@ -165,7 +165,7 @@ describe Vagrant::Environment do
|
|||
|
||||
collection = double("collection")
|
||||
expect(Vagrant::BoxCollection).to receive(:new).with(
|
||||
env.homedir.join("boxes"), anything).and_return(collection)
|
||||
env.homedir.join("boxes"), anything).twice.and_return(collection)
|
||||
expect(collection).to receive(:upgrade_v1_1_v1_5).once
|
||||
subject
|
||||
end
|
||||
|
@ -761,6 +761,7 @@ VF
|
|||
before do
|
||||
m = Vagrant.plugin("2").manager
|
||||
allow(m).to receive(:providers).and_return(plugin_providers)
|
||||
allow_any_instance_of(described_class).to receive(:process_configured_plugins)
|
||||
end
|
||||
|
||||
it "is the highest matching usable provider" do
|
||||
|
@ -1431,6 +1432,108 @@ VF
|
|||
end
|
||||
end
|
||||
|
||||
describe "guess_provider" do
|
||||
before { allow_any_instance_of(described_class).to receive(:process_configured_plugins) }
|
||||
|
||||
it "should return the default provider by default" do
|
||||
expect(subject).to receive(:default_provider).and_return("default_provider")
|
||||
expect(subject.send(:guess_provider)).to eq("default_provider")
|
||||
end
|
||||
|
||||
context "when provider is defined via command line argument" do
|
||||
before { stub_const("ARGV", argv) }
|
||||
|
||||
context "when provider is given as single argument" do
|
||||
let(:argv) { ["--provider=single_arg"] }
|
||||
|
||||
it "should return the provider name" do
|
||||
expect(subject.send(:guess_provider)).to eq("single_arg")
|
||||
end
|
||||
end
|
||||
|
||||
context "when provider is given as two arguments" do
|
||||
let(:argv) { ["--provider", "double_arg"] }
|
||||
|
||||
it "should return the provider name" do
|
||||
expect(subject.send(:guess_provider)).to eq("double_arg")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "when no default provider is available" do
|
||||
before {
|
||||
expect(subject).to receive(:default_provider).
|
||||
and_raise(Vagrant::Errors::NoDefaultProvider) }
|
||||
|
||||
it "should return a nil value" do
|
||||
expect(subject.send(:guess_provider)).to be_nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#find_configured_plugins" do
|
||||
before do
|
||||
allow_any_instance_of(described_class).to receive(:guess_provider).and_return(:dummy)
|
||||
allow_any_instance_of(described_class).to receive(:process_configured_plugins)
|
||||
end
|
||||
|
||||
it "should find no plugins when no plugins are configured" do
|
||||
expect(subject.send(:find_configured_plugins)).to be_empty
|
||||
end
|
||||
|
||||
context "when plugins are defined in the Vagrantfile" do
|
||||
before do
|
||||
env.vagrantfile <<-VF
|
||||
Vagrant.configure("2") do |config|
|
||||
config.vagrant.plugins = "vagrant-plugin"
|
||||
end
|
||||
VF
|
||||
end
|
||||
|
||||
it "should return the vagrant-plugin" do
|
||||
expect(subject.send(:find_configured_plugins).keys).to include("vagrant-plugin")
|
||||
end
|
||||
end
|
||||
|
||||
context "when plugins are defined in the Vagrantfile of a box" do
|
||||
before do
|
||||
env.box3("foo", "1.0", :dummy, vagrantfile: <<-VF)
|
||||
Vagrant.configure("2") do |config|
|
||||
config.vagrant.plugins = "vagrant-plugin"
|
||||
end
|
||||
VF
|
||||
env.vagrantfile <<-VF
|
||||
Vagrant.configure("2") do |config|
|
||||
config.vm.box = "foo"
|
||||
end
|
||||
VF
|
||||
end
|
||||
|
||||
it "should return the vagrant-plugin" do
|
||||
expect(subject.send(:find_configured_plugins).keys).to include("vagrant-plugin")
|
||||
end
|
||||
end
|
||||
|
||||
context "when the box does not match the provider" do
|
||||
before do
|
||||
env.box3("foo", "1.0", :other, vagrantfile: <<-VF)
|
||||
Vagrant.configure("2") do |config|
|
||||
config.vagrant.plugins = "vagrant-plugin"
|
||||
end
|
||||
VF
|
||||
env.vagrantfile <<-VF
|
||||
Vagrant.configure("2") do |config|
|
||||
config.vm.box = "foo"
|
||||
end
|
||||
VF
|
||||
end
|
||||
|
||||
it "should not return the vagrant-plugin" do
|
||||
expect(subject.send(:find_configured_plugins).keys).not_to include("vagrant-plugin")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#process_configured_plugins" do
|
||||
let(:env) do
|
||||
isolated_environment.tap do |e|
|
||||
|
|
|
@ -39,7 +39,7 @@ describe Vagrant::Util::SSH do
|
|||
dsa_authentication: true
|
||||
}}
|
||||
|
||||
let(:ssh_path) { "/usr/bin/ssh" }
|
||||
let(:ssh_path) { /.*ssh/ }
|
||||
|
||||
it "searches original PATH for executable" do
|
||||
expect(Vagrant::Util::Which).to receive(:which).with("ssh", original_path: true).and_return("valid-return")
|
||||
|
@ -97,8 +97,6 @@ describe Vagrant::Util::SSH do
|
|||
dsa_authentication: true
|
||||
}}
|
||||
|
||||
let(:ssh_path) { "/usr/bin/ssh" }
|
||||
|
||||
it "uses the IdentityFile argument and escapes the '%' character" do
|
||||
allow(Vagrant::Util::SafeExec).to receive(:exec).and_return(nil)
|
||||
described_class.exec(ssh_info)
|
||||
|
@ -247,7 +245,7 @@ describe Vagrant::Util::SSH do
|
|||
it "enables ssh config loading" do
|
||||
allow(Vagrant::Util::SafeExec).to receive(:exec).and_return(nil)
|
||||
expect(Vagrant::Util::SafeExec).to receive(:exec) do |exe_path, *args|
|
||||
expect(exe_path).to eq(ssh_path)
|
||||
expect(exe_path).to match(ssh_path)
|
||||
config_options = ["-F", "/path/to/config"]
|
||||
expect(args & config_options).to eq(config_options)
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue