diff --git a/lib/vagrant.rb b/lib/vagrant.rb index 839068211..6d3b38b18 100644 --- a/lib/vagrant.rb +++ b/lib/vagrant.rb @@ -9,6 +9,7 @@ module Vagrant # start small, but slowly move everything over. autoload :CLI, 'vagrant/cli' + autoload :Config, 'vagrant/config' autoload :Errors, 'vagrant/errors' module Command @@ -40,7 +41,7 @@ I18n.load_path << File.expand_path("templates/locales/en.yml", Vagrant.source_ro # is not that day. Low hanging fruit for anyone wishing to do it. libdir = File.expand_path("lib/vagrant", Vagrant.source_root) Vagrant::GlobLoader.glob_require(libdir, %w{util/stacked_proc_runner - downloaders/base config provisioners/base provisioners/chef systems/base + downloaders/base provisioners/base provisioners/chef systems/base hosts/base}) # Initialize the built-in actions diff --git a/lib/vagrant/config.rb b/lib/vagrant/config.rb index 1bac67f8c..abe270351 100644 --- a/lib/vagrant/config.rb +++ b/lib/vagrant/config.rb @@ -1,8 +1,6 @@ -module Vagrant - def self.config - Config.config - end +require 'vagrant/config/base' +module Vagrant class Config extend Util::StackedProcRunner @@ -37,169 +35,6 @@ module Vagrant config_object end end - end - - class Config - class Base - attr_accessor :env - - def [](key) - send(key) - end - - def to_json(*a) - instance_variables_hash.to_json(*a) - end - - def instance_variables_hash - instance_variables.inject({}) do |acc, iv| - acc[iv.to_s[1..-1].to_sym] = instance_variable_get(iv) unless iv.to_sym == :@env - acc - end - end - end - - class SSHConfig < Base - attr_accessor :username - attr_accessor :host - attr_accessor :port - attr_accessor :forwarded_port_key - attr_accessor :max_tries - attr_accessor :timeout - attr_writer :private_key_path - attr_accessor :forward_agent - - # The attribute(s) below do nothing. They are just kept here to - # prevent syntax errors for backwards compat. - attr_accessor :password - - def private_key_path - File.expand_path(@private_key_path, env.root_path) - end - end - - class NFSConfig < Base - attr_accessor :map_uid - attr_accessor :map_gid - end - - class VMConfig < Base - include Util::StackedProcRunner - - attr_accessor :auto_port_range - attr_accessor :box - attr_accessor :box_url - attr_accessor :box_ovf - attr_accessor :base_mac - attr_accessor :boot_mode - attr_reader :forwarded_ports - attr_reader :shared_folders - attr_reader :network_options - attr_reader :hd_location - attr_accessor :disk_image_format - attr_accessor :provisioner - attr_writer :shared_folder_uid - attr_writer :shared_folder_gid - attr_accessor :system - - # Represents a SubVM. This class is only used here in the VMs - # hash. - class SubVM - include Util::StackedProcRunner - - def options - @options ||= {} - end - end - - def initialize - @forwarded_ports = {} - @shared_folders = {} - @provisioner = nil - @network_options = [] - end - - def forward_port(name, guestport, hostport, options=nil) - options = { - :guestport => guestport, - :hostport => hostport, - :protocol => "TCP", - :adapter => 0, - :auto => false - }.merge(options || {}) - - forwarded_ports[name] = options - end - - def share_folder(name, guestpath, hostpath, opts=nil) - @shared_folders[name] = { - :guestpath => guestpath, - :hostpath => hostpath - }.merge(opts || {}) - end - - def network(ip, options=nil) - options = { - :ip => ip, - :netmask => "255.255.255.0", - :adapter => 1, - :name => nil - }.merge(options || {}) - - @network_options[options[:adapter]] = options - end - - def hd_location=(val) - raise Exception.new("disk_storage must be set to a directory") unless File.directory?(val) - @hd_location=val - end - - def shared_folder_uid - @shared_folder_uid || env.config.ssh.username - end - - def shared_folder_gid - @shared_folder_gid || env.config.ssh.username - end - - def customize(&block) - push_proc(&block) - end - - def has_multi_vms? - !defined_vms.empty? - end - - def defined_vms - @defined_vms ||= {} - end - - def define(name, options=nil, &block) - options ||= {} - defined_vms[name.to_sym] ||= SubVM.new - defined_vms[name.to_sym].options.merge!(options) - defined_vms[name.to_sym].push_proc(&block) - end - end - - class PackageConfig < Base - attr_accessor :name - end - - class VagrantConfig < Base - attr_accessor :dotfile_name - attr_accessor :log_output - attr_writer :home - attr_accessor :host - - def initialize - @home = nil - end - - def home - @home ? File.expand_path(@home) : nil - end - end class Top < Base @@configures = [] @@ -215,13 +50,6 @@ module Vagrant end end - # Setup default configures - configures :package, PackageConfig - configures :nfs, NFSConfig - configures :ssh, SSHConfig - configures :vm, VMConfig - configures :vagrant, VagrantConfig - def initialize(env=nil) self.class.configures_list.each do |key, klass| config = klass.new @@ -249,3 +77,10 @@ module Vagrant end end end + +# The built-in configuration classes +require 'vagrant/config/vagrant' +require 'vagrant/config/ssh' +require 'vagrant/config/nfs' +require 'vagrant/config/vm' +require 'vagrant/config/package' diff --git a/lib/vagrant/config/base.rb b/lib/vagrant/config/base.rb new file mode 100644 index 000000000..c7cd3e26c --- /dev/null +++ b/lib/vagrant/config/base.rb @@ -0,0 +1,25 @@ +module Vagrant + class Config + # The base class for all configuration classes. This implements + # basic things such as the environment instance variable which all + # config classes need as well as a basic `to_json` implementation. + class Base + attr_accessor :env + + def [](key) + send(key) + end + + def to_json(*a) + { 'json_class' => self.class.name }.merge(instance_variables_hash).to_json(*a) + end + + def instance_variables_hash + instance_variables.inject({}) do |acc, iv| + acc[iv.to_s[1..-1]] = instance_variable_get(iv) unless iv.to_sym == :@env + acc + end + end + end + end +end diff --git a/lib/vagrant/config/nfs.rb b/lib/vagrant/config/nfs.rb new file mode 100644 index 000000000..68a222f9c --- /dev/null +++ b/lib/vagrant/config/nfs.rb @@ -0,0 +1,10 @@ +module Vagrant + class Config + class NFSConfig < Base + Config.configures :nfs, self + + attr_accessor :map_uid + attr_accessor :map_gid + end + end +end diff --git a/lib/vagrant/config/package.rb b/lib/vagrant/config/package.rb new file mode 100644 index 000000000..2833ed641 --- /dev/null +++ b/lib/vagrant/config/package.rb @@ -0,0 +1,9 @@ +module Vagrant + class Config + class PackageConfig < Base + Config.configures :package, self + + attr_accessor :name + end + end +end diff --git a/lib/vagrant/config/ssh.rb b/lib/vagrant/config/ssh.rb new file mode 100644 index 000000000..32bf31a00 --- /dev/null +++ b/lib/vagrant/config/ssh.rb @@ -0,0 +1,24 @@ +module Vagrant + class Config + class SSHConfig < Base + Config.configures :ssh, self + + attr_accessor :username + attr_accessor :host + attr_accessor :port + attr_accessor :forwarded_port_key + attr_accessor :max_tries + attr_accessor :timeout + attr_writer :private_key_path + attr_accessor :forward_agent + + # The attribute(s) below do nothing. They are just kept here to + # prevent syntax errors for backwards compat. + attr_accessor :password + + def private_key_path + File.expand_path(@private_key_path, env.root_path) + end + end + end +end diff --git a/lib/vagrant/config/vagrant.rb b/lib/vagrant/config/vagrant.rb new file mode 100644 index 000000000..79ccfa35a --- /dev/null +++ b/lib/vagrant/config/vagrant.rb @@ -0,0 +1,20 @@ +module Vagrant + class Config + class VagrantConfig < Base + Config.configures :vagrant, self + + attr_accessor :dotfile_name + attr_accessor :log_output + attr_writer :home + attr_accessor :host + + def initialize + @home = nil + end + + def home + @home ? File.expand_path(@home) : nil + end + end + end +end diff --git a/lib/vagrant/config/vm.rb b/lib/vagrant/config/vm.rb new file mode 100644 index 000000000..823eccbb0 --- /dev/null +++ b/lib/vagrant/config/vm.rb @@ -0,0 +1,104 @@ +module Vagrant + class Config + class VMConfig < Base + Config.configures :vm, self + + include Util::StackedProcRunner + + attr_accessor :auto_port_range + attr_accessor :box + attr_accessor :box_url + attr_accessor :box_ovf + attr_accessor :base_mac + attr_accessor :boot_mode + attr_reader :forwarded_ports + attr_reader :shared_folders + attr_reader :network_options + attr_reader :hd_location + attr_accessor :disk_image_format + attr_accessor :provisioner + attr_writer :shared_folder_uid + attr_writer :shared_folder_gid + attr_accessor :system + + # Represents a SubVM. This class is only used here in the VMs + # hash. + class SubVM + include Util::StackedProcRunner + + def options + @options ||= {} + end + end + + def initialize + @forwarded_ports = {} + @shared_folders = {} + @provisioner = nil + @network_options = [] + end + + def forward_port(name, guestport, hostport, options=nil) + options = { + :guestport => guestport, + :hostport => hostport, + :protocol => "TCP", + :adapter => 0, + :auto => false + }.merge(options || {}) + + forwarded_ports[name] = options + end + + def share_folder(name, guestpath, hostpath, opts=nil) + @shared_folders[name] = { + :guestpath => guestpath, + :hostpath => hostpath + }.merge(opts || {}) + end + + def network(ip, options=nil) + options = { + :ip => ip, + :netmask => "255.255.255.0", + :adapter => 1, + :name => nil + }.merge(options || {}) + + @network_options[options[:adapter]] = options + end + + def hd_location=(val) + raise Exception.new("disk_storage must be set to a directory") unless File.directory?(val) + @hd_location=val + end + + def shared_folder_uid + @shared_folder_uid || env.config.ssh.username + end + + def shared_folder_gid + @shared_folder_gid || env.config.ssh.username + end + + def customize(&block) + push_proc(&block) + end + + def has_multi_vms? + !defined_vms.empty? + end + + def defined_vms + @defined_vms ||= {} + end + + def define(name, options=nil, &block) + options ||= {} + defined_vms[name.to_sym] ||= SubVM.new + defined_vms[name.to_sym].options.merge!(options) + defined_vms[name.to_sym].push_proc(&block) + end + end + end +end diff --git a/lib/vagrant/provisioners/chef.rb b/lib/vagrant/provisioners/chef.rb index e0a6dc591..d6466c6e4 100644 --- a/lib/vagrant/provisioners/chef.rb +++ b/lib/vagrant/provisioners/chef.rb @@ -116,12 +116,12 @@ module Vagrant run_list << name end - def to_json(*a) + def instance_variables_hash # Overridden so that the 'json' key could be removed, since its just # merged into the config anyways - data = instance_variables_hash - data.delete(:json) - data.to_json(*a) + result = super + result.delete("json") + result end end diff --git a/test/vagrant/config/base_test.rb b/test/vagrant/config/base_test.rb new file mode 100644 index 000000000..74e1b1241 --- /dev/null +++ b/test/vagrant/config/base_test.rb @@ -0,0 +1,42 @@ +require "test_helper" + +class ConfigBaseTest < Test::Unit::TestCase + setup do + @base = Vagrant::Config::Base.new + end + + should "forward [] access to methods" do + @base.expects(:foo).once + @base[:foo] + end + + should "return a hash of instance variables" do + data = { "foo" => "bar", "bar" => "baz" } + + data.each do |iv, value| + @base.instance_variable_set("@#{iv}".to_sym, value) + end + + result = @base.instance_variables_hash + assert_equal data.length, result.length + + data.each do |iv, value| + assert_equal value, result[iv] + end + end + + context "converting to JSON" do + should "convert instance variable hash to json" do + @iv_hash = { "foo" => "bar" } + @base.expects(:instance_variables_hash).returns(@iv_hash) + @json = { "json_class" => @base.class.name }.merge(@iv_hash).to_json + assert_equal @json, @base.to_json + end + + should "not include env in the JSON hash" do + @base.env = "FOO" + hash = @base.instance_variables_hash + assert !hash.has_key?(:env) + end + end +end diff --git a/test/vagrant/config/ssh_test.rb b/test/vagrant/config/ssh_test.rb new file mode 100644 index 000000000..1d88e951a --- /dev/null +++ b/test/vagrant/config/ssh_test.rb @@ -0,0 +1,13 @@ +require "test_helper" + +class ConfigSSHTest < Test::Unit::TestCase + setup do + @env = mock_environment + @env.stubs(:root_path).returns("foo") + end + + should "expand any path when requesting the value" do + result = File.expand_path(@env.config.ssh[:private_key_path], @env.root_path) + assert_equal result, @env.config.ssh.private_key_path + end +end diff --git a/test/vagrant/config/vagrant_test.rb b/test/vagrant/config/vagrant_test.rb new file mode 100644 index 000000000..87da78ebe --- /dev/null +++ b/test/vagrant/config/vagrant_test.rb @@ -0,0 +1,18 @@ +require "test_helper" + +class ConfigVagrantTest < Test::Unit::TestCase + setup do + @config = Vagrant::Config::VagrantConfig.new + end + + should "return nil if home is nil" do + File.expects(:expand_path).never + assert @config.home.nil? + end + + should "expand the path if home is not nil" do + @config.home = "foo" + File.expects(:expand_path).with("foo").once.returns("result") + assert_equal "result", @config.home + end +end diff --git a/test/vagrant/config/vm_test.rb b/test/vagrant/config/vm_test.rb new file mode 100644 index 000000000..f5a1478e1 --- /dev/null +++ b/test/vagrant/config/vm_test.rb @@ -0,0 +1,70 @@ +require "test_helper" + +class ConfigVMTest < Test::Unit::TestCase + setup do + @username = "mitchellh" + + @env = mock_environment + @config = @env.config.vm + @env.config.ssh.username = @username + end + + context "defining VMs" do + should "store the proc by name but not run it" do + foo = mock("proc") + foo.expects(:call).never + + proc = Proc.new { foo.call } + @config.define(:name, &proc) + assert @config.defined_vms[:name].proc_stack.include?(proc) + end + + should "store the options" do + @config.define(:name, :set => true) + assert @config.defined_vms[:name].options[:set] + end + + should "not have multi-VMs by default" do + assert !@config.has_multi_vms? + end + + should "have multi-VMs once one is specified" do + @config.define(:foo) {} + assert @config.has_multi_vms? + end + end + + context "customizing" do + should "include the stacked proc runner module" do + assert @config.class.included_modules.include?(Vagrant::Util::StackedProcRunner) + end + + should "add the customize proc to the proc stack" do + proc = Proc.new {} + @config.customize(&proc) + assert_equal [proc], @config.proc_stack + end + end + + context "uid/gid" do + should "return the shared folder UID if set" do + @config.shared_folder_uid = "foo" + assert_equal "foo", @config.shared_folder_uid + end + + should "return the SSH username if UID not set" do + @config.shared_folder_uid = nil + assert_equal @username, @config.shared_folder_uid + end + + should "return the shared folder GID if set" do + @config.shared_folder_gid = "foo" + assert_equal "foo", @config.shared_folder_gid + end + + should "return the SSH username if GID not set" do + @config.shared_folder_gid = nil + assert_equal @username, @config.shared_folder_gid + end + end +end diff --git a/test/vagrant/config_test.rb b/test/vagrant/config_test.rb index 2ec8c585f..f8ec1b5b5 100644 --- a/test/vagrant/config_test.rb +++ b/test/vagrant/config_test.rb @@ -1,18 +1,6 @@ require "test_helper" class ConfigTest < Test::Unit::TestCase - context "the ssh config" do - setup do - @env = mock_environment - @env.stubs(:root_path).returns("foo") - end - - should "expand any path when requesting the value" do - result = File.expand_path(@env.config.ssh[:private_key_path], @env.root_path) - assert_equal result, @env.config.ssh.private_key_path - end - end - context "adding configures" do should "forward the method to the Top class" do key = mock("key") @@ -92,48 +80,6 @@ class ConfigTest < Test::Unit::TestCase end end - context "base class" do - setup do - @base = Vagrant::Config::Base.new - end - - should "forward [] access to methods" do - @base.expects(:foo).once - @base[:foo] - end - - should "return a hash of instance variables" do - data = { :foo => "bar", :bar => "baz" } - - data.each do |iv, value| - @base.instance_variable_set("@#{iv}".to_sym, value) - end - - result = @base.instance_variables_hash - assert_equal data.length, result.length - - data.each do |iv, value| - assert_equal value, result[iv] - end - end - - context "converting to JSON" do - should "convert instance variable hash to json" do - @json = mock("json") - @iv_hash = mock("iv_hash") - @iv_hash.expects(:to_json).once.returns(@json) - @base.expects(:instance_variables_hash).returns(@iv_hash) - assert_equal @json, @base.to_json - end - - should "not include env in the JSON hash" do - @base.env = "FOO" - hash = @base.instance_variables_hash - assert !hash.has_key?(:env) - end - end - end - context "top config class" do setup do @configures_list = [] @@ -220,90 +166,4 @@ class ConfigTest < Test::Unit::TestCase end end end - - context "vagrant configuration" do - setup do - @config = Vagrant::Config::VagrantConfig.new - end - - should "return nil if home is nil" do - File.expects(:expand_path).never - assert @config.home.nil? - end - - should "expand the path if home is not nil" do - @config.home = "foo" - File.expects(:expand_path).with("foo").once.returns("result") - assert_equal "result", @config.home - end - end - - context "VM configuration" do - setup do - @username = "mitchellh" - - @env = mock_environment - @config = @env.config.vm - @env.config.ssh.username = @username - end - - context "defining VMs" do - should "store the proc by name but not run it" do - foo = mock("proc") - foo.expects(:call).never - - proc = Proc.new { foo.call } - @config.define(:name, &proc) - assert @config.defined_vms[:name].proc_stack.include?(proc) - end - - should "store the options" do - @config.define(:name, :set => true) - assert @config.defined_vms[:name].options[:set] - end - - should "not have multi-VMs by default" do - assert !@config.has_multi_vms? - end - - should "have multi-VMs once one is specified" do - @config.define(:foo) {} - assert @config.has_multi_vms? - end - end - - context "customizing" do - should "include the stacked proc runner module" do - assert @config.class.included_modules.include?(Vagrant::Util::StackedProcRunner) - end - - should "add the customize proc to the proc stack" do - proc = Proc.new {} - @config.customize(&proc) - assert_equal [proc], @config.proc_stack - end - end - - context "uid/gid" do - should "return the shared folder UID if set" do - @config.shared_folder_uid = "foo" - assert_equal "foo", @config.shared_folder_uid - end - - should "return the SSH username if UID not set" do - @config.shared_folder_uid = nil - assert_equal @username, @config.shared_folder_uid - end - - should "return the shared folder GID if set" do - @config.shared_folder_gid = "foo" - assert_equal "foo", @config.shared_folder_gid - end - - should "return the SSH username if GID not set" do - @config.shared_folder_gid = nil - assert_equal @username, @config.shared_folder_gid - end - end - end end