Disable loading identical Vagrantfile twice from same dir

Prior to this commit, if a user set the env var VAGRANT_HOME to be the
same directory where the project home is, Vagrant would load that file
twice and merge its config. This caused various provisioner and other
provider blocks to unexpectedly run twice. This commit updates the
config loader to look and see if the `:root` and `:home` procs are
equal, and if so, removes the `:home` object so that it isn't loaded and
duplicated. This commit however does not prevent duplicate loading if an
identical Vagrantfile exists in the home and project dir if those
locations are different.
This commit is contained in:
Brian Cain 2017-06-20 16:05:07 -07:00
parent c5b3751a83
commit 774e19b152
2 changed files with 32 additions and 1 deletions

View File

@ -101,6 +101,18 @@ module Vagrant
warnings = []
errors = []
if !@sources[:root].nil? && @sources[:root].eql?(@sources[:home])
# Vagrants home dir is set to the same dir as its project directory
# so we don't want to load and merge the same Vagrantfile config
# and execute its settings/procs twice
#
# Note: This protection won't work if there are two separate but
# identical Vagrantfiles in the home and project dir
@logger.info("Duplicate Vagrantfile config objects detected in :root and :home.")
@sources.delete(:home)
@logger.info("Removed :home config from being loaded")
end
order.each do |key|
next if !@sources.key?(key)

View File

@ -23,7 +23,7 @@ describe Vagrant::Config::Loader do
end
def self.merge(old, new)
old.merge(new)
old.merge(new) {|key, oldval, newval| oldval.concat(newval)}
end
end
end
@ -177,6 +177,25 @@ describe Vagrant::Config::Loader do
end
end
it "should discard duplicate configs if :home and :root are the same" do
proc = Proc.new do |config|
config[:foo] = ["yep"]
end
order = [:root, :home]
instance.set(:root, [[current_version, proc]])
instance.set(:home, [[current_version, proc]])
result, warnings, errors = instance.load(order)
# Verify the config result
expect(result[:foo]).to eq(["yep"])
expect(result[:foo].size).to eq(1)
expect(warnings).to eq([])
expect(errors).to eq([])
end
it "should only load configuration files once" do
$_config_data = 0