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) @_boxes ||= BoxCollection.new(boxes_path)
end 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. # Returns the VMs associated with this environment.
# #
# @return [Hash<Symbol,VM>] # @return [Hash<Symbol,VM>]

View File

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

View File

@ -12,9 +12,15 @@ module VagrantPlugins
def execute def execute
options = {} options = {}
opts = OptionParser.new do |o| 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 "" o.separator ""
build_start_options(o, options) build_start_options(o, options)
o.on("--provider provider", String,
"Back the machine with a specific provider.") do |provider|
options["provider"] = provider
end
end end
# Parse the options # Parse the options

View File

@ -163,7 +163,6 @@ module VagrantPlugins
elsif type == :hostonly elsif type == :hostonly
# Validate the host-only network # Validate the host-only network
ip = args[0] ip = args[0]
options = args[1] || {}
if !ip if !ip
errors.add(I18n.t("vagrant.config.vm.network_ip_required")) 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 Guest-specific operations were attempted on a machine that is not
ready for guest communication. This should not happen and a bug ready for guest communication. This should not happen and a bug
should be reported. should be reported.
machine_not_found: |-
The machine with the name '%{name}' was not found configured for
this Vagrant environment.
multi_vm_required: |- multi_vm_required: |-
A multi-vm environment is required for name specification to this command. A multi-vm environment is required for name specification to this command.
multi_vm_target_required: |- multi_vm_target_required: |-
@ -105,6 +108,9 @@ en:
for you but VirtualBox only allows forwarded ports to change if the VM is 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 powered off. Therefore, please reload your VM or halt the other running
VMs to continue. 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: |- scp_permission_denied: |-
Failed to upload a file to the guest VM via SCP due to a permissions 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 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) instance.ui.should be_kind_of(CustomUI)
end end
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 end