Add the Environment#machine method

This will eventually replace the Environment#vms method. Because of the
introduction of providers, the environment doesn't know what the backing
of the machines will be (and they're _machines_ now, not _vms_).
Instead, users of Environment will now call `#machine` on the
environment to retrieve a machine with the given backing provider as it
needs it.
This commit is contained in:
Mitchell Hashimoto 2012-11-07 21:45:09 -08:00
parent 83e99bbe4e
commit 67855be77b
6 changed files with 120 additions and 2 deletions

View File

@ -129,6 +129,38 @@ module Vagrant
@_boxes ||= BoxCollection.new(boxes_path)
end
# This returns a machine with the proper provider for this environment.
# The machine named by `name` must be in this environment.
#
# @param [Symbol] name Name of the machine (as configured in the
# Vagrantfile).
# @param [Symbol] provider The provider that this machine should be
# backed by.
# @return [Machine]
def machine(name, provider)
vm_config = config.for_vm(name)
if !vm_config
raise Errors::MachineNotFound, :name => name, :provider => provider
end
provider_cls = Vagrant.plugin("2").manager.providers[provider]
if !provider_cls
raise Errors::ProviderNotFound, :machine => name, :provider => provider
end
box = boxes.find(vm_config.vm.box, provider)
Machine.new(name, provider_cls, vm_config, box, self)
end
# This returns a list of the configured machines for this environment.
# Each of the names returned by this method is valid to be used with
# the {#machine} method.
#
# @return [Array<Symbol>] Configured machine names.
def machine_names
config.vms
end
# Returns the VMs associated with this environment.
#
# @return [Hash<Symbol,VM>]

View File

@ -234,6 +234,10 @@ module Vagrant
error_key(:machine_guest_not_ready)
end
class MachineNotFound < VagrantError
error_key(:machine_not_found)
end
class MultiVMEnvironmentRequired < VagrantError
status_code(5)
error_key(:multi_vm_required)
@ -314,6 +318,10 @@ module Vagrant
error_key(:dotfile_error, "vagrant.actions.vm.persist")
end
class ProviderNotFound < VagrantError
error_key(:provider_not_found)
end
class PluginLoadError < VagrantError
status_code(81)
error_key(:plugin_load_error)

View File

@ -12,9 +12,15 @@ module VagrantPlugins
def execute
options = {}
opts = OptionParser.new do |o|
o.banner = "Usage: vagrant up [vm-name] [--[no-]provision] [-h]"
o.banner = "Usage: vagrant up [vm-name] [--[no-]provision] [--provider provider] [-h]"
o.separator ""
build_start_options(o, options)
o.on("--provider provider", String,
"Back the machine with a specific provider.") do |provider|
options["provider"] = provider
end
end
# Parse the options

View File

@ -163,7 +163,6 @@ module VagrantPlugins
elsif type == :hostonly
# Validate the host-only network
ip = args[0]
options = args[1] || {}
if !ip
errors.add(I18n.t("vagrant.config.vm.network_ip_required"))

View File

@ -89,6 +89,9 @@ en:
Guest-specific operations were attempted on a machine that is not
ready for guest communication. This should not happen and a bug
should be reported.
machine_not_found: |-
The machine with the name '%{name}' was not found configured for
this Vagrant environment.
multi_vm_required: |-
A multi-vm environment is required for name specification to this command.
multi_vm_target_required: |-
@ -105,6 +108,9 @@ en:
for you but VirtualBox only allows forwarded ports to change if the VM is
powered off. Therefore, please reload your VM or halt the other running
VMs to continue.
provider_not_found: |-
The provider '%{provider}' could not be found, but was requested to
back the machine '%{machine}'. Please use a provider that exists.
scp_permission_denied: |-
Failed to upload a file to the guest VM via SCP due to a permissions
error. This is normally because the user running Vagrant doesn't have

View File

@ -236,4 +236,71 @@ VF
instance.ui.should be_kind_of(CustomUI)
end
end
describe "getting a machine" do
it "should return a machine object with the correct provider" do
# Create a provider
foo_provider = Class.new(Vagrant.plugin("2", :provider))
register_plugin("2") do |p|
p.provider("foo") { foo_provider }
end
# Create the configuration
isolated_env = isolated_environment do |e|
e.vagrantfile(<<-VF)
Vagrant.configure("2") do |config|
config.vm.box = "base"
config.vm.define "foo"
end
VF
end
# Verify that we can get the machine
env = isolated_env.create_vagrant_env
machine = env.machine(:foo, :foo)
machine.should be_kind_of(Vagrant::Machine)
machine.name.should == :foo
machine.provider.should be_kind_of(foo_provider)
end
it "should raise an error if the VM is not found" do
expect { instance.machine("i-definitely-dont-exist", :virtualbox) }.
to raise_error(Vagrant::Errors::MachineNotFound)
end
it "should raise an error if the provider is not found" do
expect { instance.machine(:default, :lol_no) }.
to raise_error(Vagrant::Errors::ProviderNotFound)
end
end
describe "getting machine names" do
it "should return the default machine if no multi-VM is used" do
# Create the config
isolated_env = isolated_environment do |e|
e.vagrantfile(<<-VF)
Vagrant.configure("2") do |config|
end
VF
end
env = isolated_env.create_vagrant_env
env.machine_names.should == [:default]
end
it "should return the machine names in order" do
# Create the config
isolated_env = isolated_environment do |e|
e.vagrantfile(<<-VF)
Vagrant.configure("2") do |config|
config.vm.define "foo"
config.vm.define "bar"
end
VF
end
env = isolated_env.create_vagrant_env
env.machine_names.should == [:foo, :bar]
end
end
end