Move hosts to a plugin system

This commit is contained in:
Mitchell Hashimoto 2012-04-18 22:20:45 -07:00
parent 1cbac3167f
commit 661f20bb91
23 changed files with 211 additions and 73 deletions

View File

@ -114,16 +114,6 @@ module Vagrant
def self.commands
@commands ||= Registry.new
end
# Global registry of available host classes and shortcut symbols
# associated with them.
#
# This registry is used to look up the shorcuts for `config.vagrant.host`,
# or to query all hosts for automatically detecting the host system.
# The registry is global to all of Vagrant.
def self.hosts
@hosts ||= Registry.new
end
end
# # Default I18n to load the en locale
@ -157,13 +147,3 @@ Vagrant.commands.register(:"ssh-config") { Vagrant::Command::SSHConfig }
Vagrant.commands.register(:status) { Vagrant::Command::Status }
Vagrant.commands.register(:suspend) { Vagrant::Command::Suspend }
Vagrant.commands.register(:up) { Vagrant::Command::Up }
# Register the built-in hosts
Vagrant.hosts.register(:arch) { Vagrant::Hosts::Arch }
Vagrant.hosts.register(:bsd) { Vagrant::Hosts::BSD }
Vagrant.hosts.register(:fedora) { Vagrant::Hosts::Fedora }
Vagrant.hosts.register(:opensuse) { Vagrant::Hosts::OpenSUSE }
Vagrant.hosts.register(:freebsd) { Vagrant::Hosts::FreeBSD }
Vagrant.hosts.register(:gentoo) { Vagrant::Hosts::Gentoo }
Vagrant.hosts.register(:linux) { Vagrant::Hosts::Linux }
Vagrant.hosts.register(:windows) { Vagrant::Hosts::Windows }

View File

@ -178,7 +178,15 @@ module Vagrant
# check is done after the detect check because the symbol check
# will return nil, and we don't want to trigger a detect load.
host_klass = config.global.vagrant.host
host_klass = Hosts.detect(Vagrant.hosts) if host_klass.nil? || host_klass == :detect
if host_klass.nil? || host_klass == :detect
hosts = {}
Vagrant.plugin("1").registered.each do |plugin|
hosts = hosts.merge(plugin.host.to_hash)
end
# Get the flattened list of available hosts
host_klass = Hosts.detect(hosts)
end
host_klass = Vagrant.hosts.get(host_klass) if host_klass.is_a?(Symbol)
# If no host class is detected, we use the base class.

View File

@ -14,12 +14,13 @@ module Vagrant
# This method detects the correct host based on the `match?` methods
# implemented in the registered hosts.
#
# @param [Hash] registry Hash mapping key to host class
def self.detect(registry)
logger = Log4r::Logger.new("vagrant::hosts")
# Sort the hosts by their precedence
host_klasses = registry.to_hash.values
host_klasses = host_klasses.sort_by { |a| a.precedence }.reverse
host_klasses = registry.values.sort_by { |a| a.precedence }.reverse
logger.debug("Host path search classes: #{host_klasses.inspect}")
# Test for matches and return the host class that matches

View File

@ -72,6 +72,20 @@ module Vagrant
data[:guests]
end
# Defines an additionally available host implementation with
# the given key.
#
# @param [String] name Name of the host.
def self.host(name=UNSET_VALUE, &block)
data[:hosts] ||= Registry.new
# Register a new host class only if a name was given
data[:hosts].register(name.to_sym, &block) if name != UNSET_VALUE
# Return the registry
data[:hosts]
end
# Registers additional provisioners to be available.
#
# @param [String] name Name of the provisioner.

View File

@ -1,6 +1,6 @@
module Vagrant
module Hosts
class Arch < Linux
module VagrantPlugins
module HostArch
class Host < VagrantPlugins::HostLinux::Host
def self.match?
File.exist?("/etc/rc.conf") && File.exist?("/etc/pacman.conf")
end

View File

@ -0,0 +1,14 @@
require "vagrant"
module VagrantPlugins
module HostArch
autoload :Host, File.expand_path("../host", __FILE__)
class Plugin < Vagrant.plugin("1")
name "Arch host"
description "Arch host support."
host("arch") { Host }
end
end
end

View File

@ -2,15 +2,15 @@ require 'log4r'
require 'vagrant/util/platform'
module Vagrant
module Hosts
module VagrantPlugins
module HostBSD
# Represents a BSD host, such as FreeBSD and Darwin (Mac OS X).
class BSD < Base
include Util
include Util::Retryable
class Host < Vagrant::Hosts::Base
include Vagrant::Util
include Vagrant::Util::Retryable
def self.match?
Util::Platform.darwin? || Util::Platform.bsd?
Vagrant::Util::Platform.darwin? || Vagrant::Util::Platform.bsd?
end
def self.precedence

View File

@ -0,0 +1,14 @@
require "vagrant"
module VagrantPlugins
module HostBSD
autoload :Host, File.expand_path("../host", __FILE__)
class Plugin < Vagrant.plugin("1")
name "BSD host"
description "BSD host support."
host("bsd") { Host }
end
end
end

View File

@ -1,8 +1,8 @@
require 'pathname'
require "pathname"
module Vagrant
module Hosts
class Fedora < Linux
module VagrantPlugins
module HostFedora
class Host < VagrantPlugins::HostLinux::Host
def self.match?
release_file = Pathname.new("/etc/redhat-release")

View File

@ -0,0 +1,14 @@
require "vagrant"
module VagrantPlugins
module HostFedora
autoload :Host, File.expand_path("../host", __FILE__)
class Plugin < Vagrant.plugin("1")
name "Fedora host"
description "Fedora host support."
host("fedora") { Host }
end
end
end

View File

@ -1,18 +1,17 @@
require 'vagrant/util/platform'
module Vagrant
module Hosts
# Represents a FreeBSD host
class FreeBSD < BSD
class FreeBSDHostError < Errors::VagrantError
module VagrantPlugins
module HostFreeBSD
class Host < VagrantPlugins::HostBSD::Host
class FreeBSDHostError < Vagrant::Errors::VagrantError
error_namespace("vagrant.hosts.freebsd")
end
include Util
include Util::Retryable
include Vagrant::Util
include Vagrant::Util::Retryable
def self.match?
Util::Platform.freebsd?
Vagrant::Util::Platform.freebsd?
end
# Normal, mid-range precedence.

View File

@ -0,0 +1,14 @@
require "vagrant"
module VagrantPlugins
module HostFreeBSD
autoload :Host, File.expand_path("../host", __FILE__)
class Plugin < Vagrant.plugin("1")
name "FreeBSD host"
description "FreeBSD host support."
host("freebsd") { Host }
end
end
end

View File

@ -1,6 +1,6 @@
module Vagrant
module Hosts
class Gentoo < Linux
module VagrantPlugins
module HostGentoo
class Host < VagrantPlugins::HostLinux::Host
def self.match?
return File.exists?("/etc/gentoo-release")
end

View File

@ -0,0 +1,14 @@
require "vagrant"
module VagrantPlugins
module HostGentoo
autoload :Host, File.expand_path("../host", __FILE__)
class Plugin < Vagrant.plugin("1")
name "Gentoo host"
description "Gentoo host support."
host("gentoo") { Host }
end
end
end

View File

@ -2,15 +2,15 @@ require 'log4r'
require 'vagrant/util/platform'
module Vagrant
module Hosts
module VagrantPlugins
module HostLinux
# Represents a Linux based host, such as Ubuntu.
class Linux < Base
include Util
include Util::Retryable
class Host < Vagrant::Hosts::Base
include Vagrant::Util
include Vagrant::Util::Retryable
def self.match?
Util::Platform.linux?
Vagrant::Util::Platform.linux?
end
def self.precedence

View File

@ -0,0 +1,14 @@
require "vagrant"
module VagrantPlugins
module HostLinux
autoload :Host, File.expand_path("../host", __FILE__)
class Plugin < Vagrant.plugin("1")
name "Linux host"
description "Linux host support."
host("linux") { Host }
end
end
end

View File

@ -1,8 +1,8 @@
require 'pathname'
require "pathname"
module Vagrant
module Hosts
class OpenSUSE < Linux
module VagrantPlugins
module HostOpenSUSE
class Host < VagrantPlugins::HostLinux::Host
def self.match?
release_file = Pathname.new("/etc/SuSE-release")

View File

@ -0,0 +1,14 @@
require "vagrant"
module VagrantPlugins
module HostOpenSUSE
autoload :Host, File.expand_path("../host", __FILE__)
class Plugin < Vagrant.plugin("1")
name "OpenSUSE host"
description "OpenSUSE host support."
host("opensuse") { Host }
end
end
end

View File

@ -1,10 +1,10 @@
require 'vagrant/util/platform'
module Vagrant
module Hosts
class Windows < Base
module VagrantPlugins
module HostWindows
class Host < Vagrant::Hosts::Base
def self.match?
Util::Platform.windows?
Vagrant::Util::Platform.windows?
end
# Windows does not support NFS

View File

@ -0,0 +1,14 @@
require "vagrant"
module VagrantPlugins
module HostWindows
autoload :Host, File.expand_path("../host", __FILE__)
class Plugin < Vagrant.plugin("1")
name "Windows host"
description "Windows host support."
host("windows") { Host }
end
end
end

View File

@ -1,7 +1,7 @@
require File.expand_path("../../base", __FILE__)
describe Vagrant::Hosts do
let(:registry) { Vagrant::Registry.new }
let(:registry) { Hash.new }
it "detects the host that matches true" do
foo_klass = Class.new(Vagrant::Hosts::Base) do
@ -12,8 +12,8 @@ describe Vagrant::Hosts do
def self.match?; true; end
end
registry.register(:foo, foo_klass)
registry.register(:bar, bar_klass)
registry[:foo] = foo_klass
registry[:bar] = bar_klass
described_class.detect(registry).should == bar_klass
end
@ -28,8 +28,8 @@ describe Vagrant::Hosts do
def self.precedence; 9; end
end
registry.register(:foo, foo_klass)
registry.register(:bar, bar_klass)
registry[:foo] = foo_klass
registry[:bar] = bar_klass
described_class.detect(registry).should == bar_klass
end

View File

@ -60,8 +60,8 @@ describe Vagrant::Plugin::V1 do
plugin.guest[:foo].should == "bar"
end
it "should lazily register configuration classes" do
# Below would raise an error if the value of the config class was
it "should lazily register guest classes" do
# Below would raise an error if the value of the guest class was
# evaluated immediately. By asserting that this does not raise an
# error, we verify that the value is actually lazily loaded
plugin = nil
@ -71,7 +71,7 @@ describe Vagrant::Plugin::V1 do
end
}.to_not raise_error
# Now verify when we actually get the configuration key that
# Now verify when we actually get the guest key that
# a proper error is raised.
expect {
plugin.guest[:foo]
@ -79,6 +79,34 @@ describe Vagrant::Plugin::V1 do
end
end
describe "hosts" do
it "should register host classes" do
plugin = Class.new(described_class) do
host("foo") { "bar" }
end
plugin.host[:foo].should == "bar"
end
it "should lazily register host classes" do
# Below would raise an error if the value of the host class was
# evaluated immediately. By asserting that this does not raise an
# error, we verify that the value is actually lazily loaded
plugin = nil
expect {
plugin = Class.new(described_class) do
host("foo") { raise StandardError, "FAIL!" }
end
}.to_not raise_error
# Now verify when we actually get the host key that
# a proper error is raised.
expect {
plugin.host[:foo]
}.to raise_error(StandardError)
end
end
describe "provisioners" do
it "should register provisioner classes" do
plugin = Class.new(described_class) do

View File

@ -9,10 +9,6 @@ describe Vagrant do
described_class.commands.should be_a(Vagrant::Registry)
end
it "has a registry for hosts" do
described_class.hosts.should be_a(Vagrant::Registry)
end
describe "plugin superclass" do
it "returns the proper class for version 1" do
described_class.plugin("1").should == Vagrant::Plugin::V1