core: Vagrant::Environment uses new host settings

This commit is contained in:
Mitchell Hashimoto 2014-01-07 19:11:08 -08:00
parent 21a610b59b
commit 93e365bb33
6 changed files with 118 additions and 24 deletions

View File

@ -487,22 +487,33 @@ module Vagrant
def host
return @host if defined?(@host)
# Attempt to figure out the host class. Note that the order
# matters here, so please don't touch. Specifically: The symbol
# check is done after the detect check because the symbol check
# will return nil, and we don't want to trigger a detect load.
# Determine the host class to use. ":detect" is an old Vagrant config
# that shouldn't be valid anymore, but we respect it here by assuming
# its old behavior. No need to deprecate this because I thin it is
# fairly harmless.
host_klass = config_global.vagrant.host
if host_klass.nil? || host_klass == :detect
hosts = Vagrant.plugin("2").manager.hosts.to_hash
host_klass = nil if host_klass == :detect
# Get the flattened list of available hosts
host_klass = Hosts.detect(hosts)
begin
@host = Host.new(
host_klass,
Vagrant.plugin("2").manager.hosts,
Vagrant.plugin("2").manager.host_capabilities)
rescue Errors::CapabilityHostNotDetected
# If the auto-detect failed, then we create a brand new host
# with no capabilities and use that. This should almost never happen
# since Vagrant works on most host OS's now, so this is a "slow path"
klass = Class.new(Vagrant.plugin("2", :host)) do
def detect?; true; end
end
# If no host class is detected, we use the base class.
host_klass ||= Vagrant.plugin("2", :host)
hosts = { generic: [klass, nil] }
host_caps = {}
@host ||= host_klass.new(@ui)
@host = Host.new(:generic, hosts, host_caps)
rescue Errors::CapabilityHostExplicitNotDetected => e
raise Errors::HostExplicitNotDetected, e.extra_data
end
end
# Action runner for executing actions in the context of this environment.

View File

@ -333,6 +333,10 @@ module Vagrant
error_key(:guest_not_detected)
end
class HostExplicitNotDetected < VagrantError
error_key(:host_explicit_not_detected)
end
class LinuxMountFailed < VagrantError
error_key(:linux_mount_failed)
end

View File

@ -14,16 +14,6 @@ module Vagrant
false
end
# Initializes a new host class.
#
# The only required parameter is a UI object so that the host
# objects have some way to communicate with the outside world.
#
# @param [UI] ui UI for the hosts to output to.
def initialize(ui)
@ui = ui
end
# Returns true of false denoting whether or not this host supports
# NFS shared folder setup. This method ideally should verify that
# NFS is installed.

View File

@ -5,6 +5,15 @@ module VagrantPlugins
class VagrantConfig < Vagrant.plugin("2", :config)
attr_accessor :host
def initialize
@host = UNSET_VALUE
end
def finalize!
@host = nil if @host == UNSET_VALUE
@host = @host.to_sym if @host
end
def to_s
"Vagrant"
end

View File

@ -412,6 +412,11 @@ en:
directory that Vagrant uses must be both readable and writable.
You specified: %{home_path}
host_explicit_not_detected: |-
The host implementation explicitly specified in your Vagrantfile
("%{value}") could not be found. Please verify that the plugin is
installed which implements this host and that the value you used
for `config.vagrant.host` is correct.
interrupted: |-
Vagrant exited after cleanup due to external interrupt.
local_data_dir_not_accessible: |-

View File

@ -8,6 +8,7 @@ require "vagrant/util/file_mode"
describe Vagrant::Environment do
include_context "unit"
include_context "capability_helpers"
let(:env) do
isolated_environment.tap do |e|
@ -21,9 +22,83 @@ describe Vagrant::Environment do
end
let(:instance) { env.create_vagrant_env }
subject { instance }
describe "#host" do
let(:plugin_hosts) { {} }
let(:plugin_host_caps) { {} }
before do
m = Vagrant.plugin("2").manager
m.stub(hosts: plugin_hosts)
m.stub(host_capabilities: plugin_host_caps)
end
it "should default to some host even if there are none" do
env.vagrantfile <<-VF
Vagrant.configure("2") do |config|
config.vagrant.host = nil
end
VF
expect(subject.host).to be
end
it "should attempt to detect a host if no host is set" do
env.vagrantfile <<-VF
Vagrant.configure("2") do |config|
config.vagrant.host = nil
end
VF
plugin_hosts[:foo] = [detect_class(true), nil]
plugin_host_caps[:foo] = { bar: Class }
result = subject.host
expect(result.capability?(:bar)).to be_true
end
it "should attempt to detect a host if host is :detect" do
env.vagrantfile <<-VF
Vagrant.configure("2") do |config|
config.vagrant.host = :detect
end
VF
plugin_hosts[:foo] = [detect_class(true), nil]
plugin_host_caps[:foo] = { bar: Class }
result = subject.host
expect(result.capability?(:bar)).to be_true
end
it "should use an exact host if specified" do
env.vagrantfile <<-VF
Vagrant.configure("2") do |config|
config.vagrant.host = "foo"
end
VF
plugin_hosts[:foo] = [detect_class(false), nil]
plugin_hosts[:bar] = [detect_class(true), nil]
plugin_host_caps[:foo] = { bar: Class }
result = subject.host
expect(result.capability?(:bar)).to be_true
end
it "should raise an error if an exact match was specified but not found" do
env.vagrantfile <<-VF
Vagrant.configure("2") do |config|
config.vagrant.host = "bar"
end
VF
expect { subject.host }.
to raise_error(Vagrant::Errors::HostExplicitNotDetected)
end
end
describe "active machines" do
it "should be empty if the machines folder doesn't exist" do
folder = instance.local_data_path.join("machines")