From 9bae0a7094cfba429ce11ed8d4385883a062c7a2 Mon Sep 17 00:00:00 2001 From: Chris Roberts Date: Fri, 14 Jun 2019 11:50:06 -0700 Subject: [PATCH] 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. --- lib/vagrant/environment.rb | 2 +- lib/vagrant/vagrantfile.rb | 30 ++++++++++++++----------- test/unit/vagrant/vagrantfile_test.rb | 32 +++++++++++++++++++++++++++ 3 files changed, 50 insertions(+), 14 deletions(-) diff --git a/lib/vagrant/environment.rb b/lib/vagrant/environment.rb index f0b8114ff..65786e3eb 100644 --- a/lib/vagrant/environment.rb +++ b/lib/vagrant/environment.rb @@ -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) diff --git a/lib/vagrant/vagrantfile.rb b/lib/vagrant/vagrantfile.rb index 27d9dcb52..3dc7ada99 100644 --- a/lib/vagrant/vagrantfile.rb +++ b/lib/vagrant/vagrantfile.rb @@ -112,7 +112,7 @@ module Vagrant # @param [Pathname] data_path Machine data path # @return [Hash] 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 diff --git a/test/unit/vagrant/vagrantfile_test.rb b/test/unit/vagrant/vagrantfile_test.rb index 129bb5874..d4b99445f 100644 --- a/test/unit/vagrant/vagrantfile_test.rb +++ b/test/unit/vagrant/vagrantfile_test.rb @@ -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) }