Provider-specific configuration overrides via 2nd block param

Example:

Vagrant.configure("2") do |config|
  # ...

  config.vm.provider :virtualbox do |p, vb_config|
    vb_config.vm.box = "virtualbox_box"
  end
end
This commit is contained in:
Mitchell Hashimoto 2013-04-03 14:57:14 -07:00
parent acd494d148
commit 52a2f48b20
4 changed files with 71 additions and 4 deletions

View File

@ -9,6 +9,12 @@ FEATURES:
- Box downloads are now done via `curl` rather than Ruby's built-in
HTTP library. This results in massive speedups, support for SSL
verification, FTP downloads, and more.
- `config.vm.provider` now takes an optional second parameter to the block,
allowing you to override any configuration value. These overrides are
applied last, and therefore override any other configuration value.
Note that while this feature is available, the "Vagrant way" is instead
to use box manifests to ensure that the "box" for every provider matches,
so these sorts of overrides are unnecessary.
IMPROVEMENTS:

View File

@ -355,6 +355,17 @@ module Vagrant
end
end
# If there are provider overrides for the machine, then we run
# those as well.
provider_overrides = config.vm.get_provider_overrides(provider)
if provider_overrides.length > 0
@logger.info("Applying #{provider_overrides.length} provider overrides. Reloading config.")
provider_override_key = "vm_#{name}_#{config.vm.box}_#{provider}".to_sym
@config_loader.set(provider_override_key, provider_overrides)
config, config_warnings, config_errors = \
@config_loader.load([:default, box_config_key, :home, :root, vm_config_key, provider_override_key])
end
# Get the provider configuration from the final loaded configuration
provider_config = config.vm.get_provider_config(provider)

View File

@ -33,6 +33,7 @@ module VagrantPlugins
# Internal state
@__compiled_provider_configs = {}
@__compiled_provider_overrides = {}
@__defined_vm_keys = []
@__defined_vms = {}
@__finalized = false
@ -196,17 +197,32 @@ module VagrantPlugins
# Compile all the provider configurations
@__providers.each do |name, blocks|
# If we don't have any configuration blocks, then ignore it
next if blocks.empty?
# Find the configuration class for this provider
config_class = Vagrant.plugin("2").manager.provider_configs[name]
next if !config_class
config_class ||= Vagrant::Config::V2::DummyConfig
# Load it up
config = config_class.new
blocks.each { |b| b.call(config) }
config = config_class.new
overrides = []
blocks.each do |b|
b.call(config, Vagrant::Config::V2::DummyConfig.new)
# If the block takes two arguments, then we store the second
# one away for overrides later.
if b.arity == 2
overrides << b.curry[Vagrant::Config::V2::DummyConfig.new]
end
end
config.finalize!
# Store it for retrieval later
@__compiled_provider_configs[name] = config
@__compiled_provider_configs[name] = config
@__compiled_provider_overrides[name] = overrides
end
# Flag that we finalized
@ -235,6 +251,17 @@ module VagrantPlugins
return result
end
# This returns a list of VM configurations that are overrides
# for this provider.
#
# @param [Symbol] name Name of the provider
# @return [Array<Proc>]
def get_provider_overrides(name)
(@__compiled_provider_overrides[name] || []).map do |p|
["2", p]
end
end
# This returns the list of networks configured.
def networks
@__networks.values

View File

@ -550,6 +550,29 @@ VF
machine.config.ssh.port.should == 100
end
it "should load the provider override if set" do
register_provider("bar")
register_provider("foo")
isolated_env = isolated_environment do |e|
e.vagrantfile(<<-VF)
Vagrant.configure("2") do |config|
config.vm.box = "foo"
config.vm.provider :foo do |_, c|
c.vm.box = "bar"
end
end
VF
end
env = isolated_env.create_vagrant_env
foo_vm = env.machine(:default, :foo)
bar_vm = env.machine(:default, :bar)
foo_vm.config.vm.box.should == "bar"
bar_vm.config.vm.box.should == "foo"
end
it "should reload the cache if refresh is set" do
# Create a provider
foo_provider = register_provider("foo")