Support loading machine configuration without provider validation

Allow Vagrantfile#machine_config to load properly when the requested
provider may not be currently available. Update the Environment to
utilize this when searching for plugin information to properly allow
box provided Vagrantfiles to define required plugins.
This commit is contained in:
Chris Roberts 2019-06-14 11:50:06 -07:00
parent 206ff9d4ca
commit 9bae0a7094
3 changed files with 50 additions and 14 deletions

View File

@ -955,7 +955,7 @@ module Vagrant
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]
plugins << vagrantfile.machine_config(mname, guess_provider, boxes, ldp, false)[:config]
end
result = plugins.reverse.inject(Vagrant::Util::HashWithIndifferentAccess.new) do |memo, val|
Vagrant::Util::DeepMerge.deep_merge(memo, val.vagrant.plugins)

View File

@ -112,7 +112,7 @@ module Vagrant
# @param [Pathname] data_path Machine data path
# @return [Hash<Symbol, Object>] Various configuration parameters for a
# machine. See the main documentation body for more info.
def machine_config(name, provider, boxes, data_path=nil)
def machine_config(name, provider, boxes, data_path=nil, validate_provider=true)
keys = @keys.dup
sub_machine = @config.vm.defined_vms[name]
@ -127,7 +127,7 @@ module Vagrant
box_formats = nil
if provider != nil
provider_plugin = Vagrant.plugin("2").manager.providers[provider]
if !provider_plugin
if !provider_plugin && validate_provider
providers = Vagrant.plugin("2").manager.providers.to_hash.keys
if providers
providers_str = providers.join(', ')
@ -145,18 +145,22 @@ module Vagrant
machine: name, provider: provider, providers: providers_str
end
provider_cls = provider_plugin[0]
provider_options = provider_plugin[1]
box_formats = provider_options[:box_format] || provider
if validate_provider
provider_cls = provider_plugin[0]
provider_options = provider_plugin[1]
box_formats = provider_options[:box_format] || provider
# Test if the provider is usable or not
begin
provider_cls.usable?(true)
rescue Errors::VagrantError => e
raise Errors::ProviderNotUsable,
machine: name.to_s,
provider: provider.to_s,
message: e.to_s
# Test if the provider is usable or not
begin
provider_cls.usable?(true)
rescue Errors::VagrantError => e
raise Errors::ProviderNotUsable,
machine: name.to_s,
provider: provider.to_s,
message: e.to_s
end
else
box_formats = provider
end
end

View File

@ -368,6 +368,38 @@ describe Vagrant::Vagrantfile do
to raise_error(Vagrant::Errors::ProviderNotUsable)
end
context "when provider validation is ignored" do
before do
configure do |config|
config.vm.box = "base"
config.vm.box_version = "1.0"
config.vm.define :guest1
config.vm.define :guest2
config.vm.provider "custom" do |_, c|
c.ssh.port = 123
end
end
iso_env.box3("base", "1.0", :custom, vagrantfile: <<-VF)
Vagrant.configure("2") do |config|
config.vagrant.plugins = "vagrant-custom"
end
VF
end
it "should not raise an error if provider is not found" do
expect { subject.machine_config(:guest1, :custom, boxes, nil, false) }.
not_to raise_error
end
it "should return configuration from box Vagrantfile" do
config = subject.machine_config(:guest1, :custom, boxes, nil, false)[:config]
expect(config.vagrant.plugins).to be_a(Hash)
expect(config.vagrant.plugins.keys).to include("vagrant-custom")
end
end
context "local box metadata file" do
let(:data_path) { double(:data_path) }
let(:meta_file) { double(:meta_file) }