From 96ebd3e8f72d436986ce45f85f4aabe7ce3e1829 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Sat, 6 Apr 2013 18:20:14 -0700 Subject: [PATCH] Providers can support multiple box formats if they choose to. Currently, providers must match a box format exactly the same as that provider's name. i.e. the virtuabox provider needs a "virtualbox" box and the "vmware_fusion" provider needs a "vmware_fusion" box. Now, the provider can specify what the box format is they want and support multiple if wanted. Other box formats are specified in the provider definition within a plugin: class Plugin < Vagrant.plugin("2", "provider") # ... other stuff provider("foo", box_format: ["virtualbox", "other_format"]) do # .. same end end Now when using the example "foo" provider above, boxes for both "virtualbox" or "other_format" are searched for. If both are found, the order in which the formats exist determines precedence. --- CHANGELOG.md | 2 + lib/vagrant/environment.rb | 28 ++++++++++---- test/unit/vagrant/environment_test.rb | 54 ++++++++++++++++++++++++++- 3 files changed, 75 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index deaba670b..084b62797 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,6 +30,8 @@ FEATURES: certain guest operating systems can implement. This allows greater flexibility in doing guest-specific behavior. - Ansible provisioner support. [GH-1465] + - Providers can now support multiple box formats by specifying the + `box_format:` option. IMPROVEMENTS: diff --git a/lib/vagrant/environment.rb b/lib/vagrant/environment.rb index 40bf6673e..b031b7ee7 100644 --- a/lib/vagrant/environment.rb +++ b/lib/vagrant/environment.rb @@ -328,13 +328,27 @@ module Vagrant box = nil if config.vm.box - begin - box = boxes.find(config.vm.box, provider) - rescue Errors::BoxUpgradeRequired - # Upgrade the box if we must - @logger.info("Upgrading box during config load: #{config.vm.box}") - boxes.upgrade(config.vm.box) - retry + # Determine the box formats we support + formats = provider_options[:box_format] + formats ||= provider + formats = [formats] if !formats.is_a?(Array) + + @logger.info("Provider-supported box formats: #{formats.inspect}") + formats.each do |format| + begin + box = boxes.find(config.vm.box, format.to_s) + rescue Errors::BoxUpgradeRequired + # Upgrade the box if we must + @logger.info("Upgrading box during config load: #{config.vm.box}") + boxes.upgrade(config.vm.box) + retry + end + + # If a box was found, we exit + if box + @logger.info("Box found with format: #{format}") + break + end end end diff --git a/test/unit/vagrant/environment_test.rb b/test/unit/vagrant/environment_test.rb index e2cb2da08..9c7ec68a4 100644 --- a/test/unit/vagrant/environment_test.rb +++ b/test/unit/vagrant/environment_test.rb @@ -408,11 +408,11 @@ VF describe "getting a machine" do # A helper to register a provider for use in tests. - def register_provider(name, config_class=nil) + def register_provider(name, config_class=nil, options=nil) provider_cls = Class.new(Vagrant.plugin("2", :provider)) register_plugin("2") do |p| - p.provider(name) { provider_cls } + p.provider(name, options) { provider_cls } if config_class p.config(name, :provider) { config_class } @@ -572,6 +572,56 @@ VF machine.config.ssh.port.should == 100 end + it "should load the box configuration for other formats for a V2 box" do + register_provider("foo", nil, box_format: "bar") + + environment = isolated_environment do |env| + env.vagrantfile(<<-VF) +Vagrant.configure("2") do |config| + config.vm.box = "base" +end +VF + + env.box2("base", :bar, :vagrantfile => <<-VF) +Vagrant.configure("2") do |config| + config.ssh.port = 100 +end +VF + end + + env = environment.create_vagrant_env + machine = env.machine(:default, :foo) + machine.config.ssh.port.should == 100 + end + + it "prefer sooner formats when multiple box formats are available" do + register_provider("foo", nil, box_format: ["fA", "fB"]) + + environment = isolated_environment do |env| + env.vagrantfile(<<-VF) +Vagrant.configure("2") do |config| + config.vm.box = "base" +end +VF + + env.box2("base", :fA, :vagrantfile => <<-VF) +Vagrant.configure("2") do |config| + config.ssh.port = 100 +end +VF + + env.box2("base", :fB, :vagrantfile => <<-VF) +Vagrant.configure("2") do |config| + config.ssh.port = 200 +end +VF + end + + env = environment.create_vagrant_env + machine = env.machine(:default, :foo) + machine.config.ssh.port.should == 100 + end + it "should load the provider override if set" do register_provider("bar") register_provider("foo")