From 3533256cd71a61ee5ad2f325d4319bb16665fbb3 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Thu, 6 Feb 2014 21:31:11 -0800 Subject: [PATCH] core: Vagrantfile can create machines, Environment#machine uses that --- lib/vagrant/environment.rb | 33 +------- lib/vagrant/machine.rb | 2 +- lib/vagrant/vagrantfile.rb | 62 +++++++++++++++ test/unit/vagrant/vagrantfile_test.rb | 110 ++++++++++++++++---------- 4 files changed, 134 insertions(+), 73 deletions(-) diff --git a/lib/vagrant/environment.rb b/lib/vagrant/environment.rb index d8330b955..b8eae97fe 100644 --- a/lib/vagrant/environment.rb +++ b/lib/vagrant/environment.rb @@ -301,45 +301,16 @@ module Vagrant @logger.info("Uncached load of machine.") - # Load the actual configuration for the machine - results = vagrantfile.machine_config(name, provider, boxes) - box = results[:box] - config = results[:config] - config_errors = results[:config_errors] - config_warnings = results[:config_warnings] - provider_cls = results[:provider_cls] - provider_options = results[:provider_options] - # Determine the machine data directory and pass it to the machine. # XXX: Permissions error here. machine_data_path = @local_data_path.join( "machines/#{name}/#{provider}") FileUtils.mkdir_p(machine_data_path) - # If there were warnings or errors we want to output them - if !config_warnings.empty? || !config_errors.empty? - # The color of the output depends on whether we have warnings - # or errors... - level = config_errors.empty? ? :warn : :error - output = Util::TemplateRenderer.render( - "config/messages", - :warnings => config_warnings, - :errors => config_errors).chomp - @ui.send(level, I18n.t("vagrant.general.config_upgrade_messages", - name: name, - :output => output)) - - # If we had errors, then we bail - raise Errors::ConfigUpgradeErrors if !config_errors.empty? - end - - # Get the provider configuration from the final loaded configuration - provider_config = config.vm.get_provider_config(provider) - # Create the machine and cache it for future calls. This will also # return the machine from this method. - @machines[cache_key] = Machine.new(name, provider, provider_cls, provider_config, - provider_options, config, machine_data_path, box, self) + @machines[cache_key] = vagrantfile.machine( + name, provider, boxes, machine_data_path, self) end # This returns a list of the configured machines for this environment. diff --git a/lib/vagrant/machine.rb b/lib/vagrant/machine.rb index e5c9651fb..dcfbd821f 100644 --- a/lib/vagrant/machine.rb +++ b/lib/vagrant/machine.rb @@ -34,7 +34,7 @@ module Vagrant # Name of the machine. This is assigned by the Vagrantfile. # - # @return [String] + # @return [Symbol] attr_reader :name # The provider backing this machine. diff --git a/lib/vagrant/vagrantfile.rb b/lib/vagrant/vagrantfile.rb index 68348abb0..af4d0fa9a 100644 --- a/lib/vagrant/vagrantfile.rb +++ b/lib/vagrant/vagrantfile.rb @@ -1,3 +1,5 @@ +require "vagrant/util/template_renderer" + module Vagrant # This class provides a way to load and access the contents # of a Vagrantfile. @@ -26,6 +28,54 @@ module Vagrant @config, _ = loader.load(keys) end + # Returns a {Machine} for the given name and provider that + # is represented by this Vagrantfile. + # + # @param [Symbol] name Name of the machine. + # @param [Symbol] provider The provider the machine should + # be backed by (required for provider overrides). + # @param [BoxCollection] boxes BoxCollection to look up the + # box Vagrantfile. + # @param [Pathname] data_path Path where local machine data + # can be stored. + # @param [Environment] env The environment running this machine + # @return [Machine] + def machine(name, provider, boxes, data_path, env) + # Load the configuration for the machine + results = machine_config(name, provider, boxes) + box = results[:box] + config = results[:config] + config_errors = results[:config_errors] + config_warnings = results[:config_warnings] + provider_cls = results[:provider_cls] + provider_options = results[:provider_options] + + # If there were warnings or errors we want to output them + if !config_warnings.empty? || !config_errors.empty? + # The color of the output depends on whether we have warnings + # or errors... + level = config_errors.empty? ? :warn : :error + output = Util::TemplateRenderer.render( + "config/messages", + :warnings => config_warnings, + :errors => config_errors).chomp + env.ui.send(level, I18n.t("vagrant.general.config_upgrade_messages", + name: name, + output: output)) + + # If we had errors, then we bail + raise Errors::ConfigUpgradeErrors if !config_errors.empty? + end + + # Get the provider configuration from the final loaded configuration + provider_config = config.vm.get_provider_config(provider) + + # Create the machine and cache it for future calls. This will also + # return the machine from this method. + return Machine.new(name, provider, provider_cls, provider_config, + provider_options, config, data_path, box, env) + end + # Returns the configuration for a single machine. # # When loading a box Vagrantfile, it will be prepended to the @@ -38,11 +88,23 @@ module Vagrant # - sub-machine # - provider # + # The return value is a hash with the following keys (symbols) + # and values: + # + # - box: the {Box} backing the machine + # - config: the actual configuration + # - config_errors: list of errors, if any + # - config_warnings: list of warnings, if any + # - provider_cls: class of the provider backing the machine + # - provider_options: options for the provider + # # @param [Symbol] name Name of the machine. # @param [Symbol] provider The provider the machine should # be backed by (required for provider overrides). # @param [BoxCollection] boxes BoxCollection to look up the # box Vagrantfile. + # @return [Hash] Various configuration parameters for a + # machine. See the main documentation body for more info. def machine_config(name, provider, boxes) keys = @keys.dup diff --git a/test/unit/vagrant/vagrantfile_test.rb b/test/unit/vagrant/vagrantfile_test.rb index 22b6bf9b9..1f727afce 100644 --- a/test/unit/vagrant/vagrantfile_test.rb +++ b/test/unit/vagrant/vagrantfile_test.rb @@ -1,5 +1,8 @@ require File.expand_path("../../base", __FILE__) +require "pathname" +require "tmpdir" + require "vagrant/vagrantfile" describe Vagrant::Vagrantfile do @@ -13,15 +16,30 @@ describe Vagrant::Vagrantfile do subject { described_class.new(loader, keys) } + before do + keys << :test + end + + def configure(&block) + loader.set(:test, [["2", block]]) + end + + # A helper to register a provider for use in tests. + 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, options) { provider_cls } + + if config_class + p.config(name, :provider) { config_class } + end + end + + provider_cls + end + describe "#config" do - before do - keys << :test - end - - def configure(&block) - loader.set(:test, [["2", block]]) - end - it "exposes the global configuration" do configure do |config| config.vm.box = "what" @@ -31,33 +49,59 @@ describe Vagrant::Vagrantfile do end end - describe "#machine_config" do - let(:iso_env) { isolated_environment } + describe "#machine" do let(:boxes) { Vagrant::BoxCollection.new(iso_env.boxes_dir) } + let(:data_path) { Pathname.new(Dir.mktmpdir) } + let(:env) { iso_env.create_vagrant_env } + let(:iso_env) { isolated_environment } + + subject { super().machine(:default, :foo, boxes, data_path, env) } before do - keys << :test - end + @foo_config_cls = Class.new(Vagrant.plugin("2", "config")) do + attr_accessor :value + end - def configure(&block) - loader.set(:test, [["2", block]]) - end + @provider_cls = register_provider("foo", @foo_config_cls) - # A helper to register a provider for use in tests. - 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, options) { provider_cls } - - if config_class - p.config(name, :provider) { config_class } + configure do |config| + config.vm.box = "foo" + config.vm.provider "foo" do |p| + p.value = "rawr" end end - provider_cls + iso_env.box3("foo", "1.0", :foo, vagrantfile: <<-VF) + Vagrant.configure("2") do |config| + config.ssh.port = 123 + end + VF end + its(:data_dir) { should eq(data_path) } + its(:env) { should equal(env) } + its(:name) { should eq(:default) } + its(:provider) { should be_kind_of(@provider_cls) } + its(:provider_name) { should eq(:foo) } + + it "has the proper box" do + expect(subject.box.name).to eq("foo") + end + + it "has the valid configuration" do + expect(subject.config.vm.box).to eq("foo") + end + + it "loads the provider-specific configuration" do + expect(subject.provider_config).to be_kind_of(@foo_config_cls) + expect(subject.provider_config.value).to eq("rawr") + end + end + + describe "#machine_config" do + let(:iso_env) { isolated_environment } + let(:boxes) { Vagrant::BoxCollection.new(iso_env.boxes_dir) } + it "should return a basic configured machine" do provider_cls = register_provider("foo") @@ -232,14 +276,6 @@ describe Vagrant::Vagrantfile do end describe "#machine_names" do - before do - keys << :test - end - - def configure(&block) - loader.set(:test, [["2", block]]) - end - it "returns the default name when single-VM" do configure { |config| } @@ -258,14 +294,6 @@ describe Vagrant::Vagrantfile do end describe "#primary_machine_name" do - before do - keys << :test - end - - def configure(&block) - loader.set(:test, [["2", block]]) - end - it "returns the default name when single-VM" do configure { |config| }