core: commands can use the IDs from anywhere to control
This commit is contained in:
parent
9a16af10ad
commit
a0e9f46251
|
@ -108,9 +108,11 @@ module Vagrant
|
|||
|
||||
@lock.synchronize do
|
||||
with_index_lock do
|
||||
return nil if !@machines[uuid]
|
||||
data = find_by_prefix(uuid)
|
||||
return nil if !data
|
||||
uuid = data["id"]
|
||||
|
||||
entry = Entry.new(uuid, @machines[uuid].merge("id" => uuid))
|
||||
entry = Entry.new(uuid, data)
|
||||
|
||||
# Lock this machine
|
||||
lock_file = lock_machine(uuid)
|
||||
|
@ -127,6 +129,14 @@ module Vagrant
|
|||
entry
|
||||
end
|
||||
|
||||
# Tests if the index has the given UUID.
|
||||
#
|
||||
# @param [String] uuid
|
||||
# @return [Boolean]
|
||||
def include?(uuid)
|
||||
!!find_by_prefix(uuid)
|
||||
end
|
||||
|
||||
# Releases an entry, unlocking it.
|
||||
#
|
||||
# This is an idempotent operation. It is safe to call this even if you're
|
||||
|
@ -192,6 +202,17 @@ module Vagrant
|
|||
|
||||
protected
|
||||
|
||||
# Finds a machine where the UUID is prefixed by the given string.
|
||||
#
|
||||
# @return [Hash]
|
||||
def find_by_prefix(prefix)
|
||||
@machines.each do |uuid, data|
|
||||
return data.merge("id" => uuid) if uuid.start_with?(prefix)
|
||||
end
|
||||
|
||||
nil
|
||||
end
|
||||
|
||||
# Locks a machine exclusively to us, returning the file handle
|
||||
# that holds the lock.
|
||||
#
|
||||
|
|
|
@ -82,9 +82,6 @@ module Vagrant
|
|||
@logger.debug(" -- names: #{names.inspect}")
|
||||
@logger.debug(" -- options: #{options.inspect}")
|
||||
|
||||
# Using VMs requires a Vagrant environment to be properly setup
|
||||
raise Errors::NoEnvironmentError if !@env.root_path
|
||||
|
||||
# Setup the options hash
|
||||
options ||= {}
|
||||
|
||||
|
@ -92,6 +89,21 @@ module Vagrant
|
|||
names ||= []
|
||||
names = [names] if !names.is_a?(Array)
|
||||
|
||||
# Determine if we require a local Vagrant environment. There are
|
||||
# two cases that we require a local environment:
|
||||
#
|
||||
# * We're asking for ANY/EVERY VM (no names given).
|
||||
#
|
||||
# * We're asking for specific VMs, at least once of which
|
||||
# is NOT in the local machine index.
|
||||
#
|
||||
requires_local_env = false
|
||||
requires_local_env = true if names.empty?
|
||||
requires_local_env ||= names.any? { |n|
|
||||
!@env.machine_index.include?(n)
|
||||
}
|
||||
raise Errors::NoEnvironmentError if requires_local_env && !@env.root_path
|
||||
|
||||
# Cache the active machines outside the loop
|
||||
active_machines = @env.active_machines
|
||||
|
||||
|
@ -112,6 +124,20 @@ module Vagrant
|
|||
provider_to_use = options[:provider]
|
||||
provider_to_use = provider_to_use.to_sym if provider_to_use
|
||||
|
||||
# If we have this machine in our index, load that.
|
||||
entry = @env.machine_index.get(name.to_s)
|
||||
if entry
|
||||
@env.machine_index.release(entry)
|
||||
|
||||
# Create an environment for this location and yield the
|
||||
# machine in that environment.
|
||||
env = Vagrant::Environment.new(
|
||||
cwd: entry.vagrantfile_path,
|
||||
home_path: @env.home_path,
|
||||
)
|
||||
next env.machine(entry.name.to_sym, entry.provider.to_sym)
|
||||
end
|
||||
|
||||
active_machines.each do |active_name, active_provider|
|
||||
if name == active_name
|
||||
# We found an active machine with the same name
|
||||
|
|
|
@ -800,9 +800,11 @@ en:
|
|||
|
||||
%{types}
|
||||
no_env: |-
|
||||
A Vagrant environment is required to run this command. Run `vagrant init`
|
||||
to set one up in this directory, or change to a directory with a
|
||||
Vagrantfile and try again.
|
||||
A Vagrant environment or target machine is required to run this
|
||||
command. Run `vagrant init` to create a new Vagrant environment. Or,
|
||||
get an ID of a target machine from `vagrant global-status` to run
|
||||
this command on. A final option is to change to a directory with a
|
||||
Vagrantfile and to try again.
|
||||
plugin_gem_not_found: |-
|
||||
The plugin '%{name}' could not be installed because it could not
|
||||
be found. Please double check the name and try again.
|
||||
|
|
|
@ -12,6 +12,13 @@ describe Vagrant::MachineIndex do
|
|||
let(:data_dir) { temporary_dir }
|
||||
let(:entry_klass) { Vagrant::MachineIndex::Entry }
|
||||
|
||||
let(:new_entry) do
|
||||
entry_klass.new.tap do |e|
|
||||
e.name = "foo"
|
||||
e.vagrantfile_path = "/bar"
|
||||
end
|
||||
end
|
||||
|
||||
subject { described_class.new(data_dir) }
|
||||
|
||||
it "raises an exception if the data file is corrupt" do
|
||||
|
@ -96,6 +103,17 @@ describe Vagrant::MachineIndex do
|
|||
expect(result.updated_at).to eq("foo")
|
||||
end
|
||||
|
||||
it "returns a valid entry by unique prefix" do
|
||||
result = subject.get("b")
|
||||
|
||||
expect(result).to_not be_nil
|
||||
expect(result.id).to eq("bar")
|
||||
end
|
||||
|
||||
it "should include? by prefix" do
|
||||
expect(subject.include?("b")).to be_true
|
||||
end
|
||||
|
||||
it "locks the entry so subsequent gets fail" do
|
||||
result = subject.get("bar")
|
||||
expect(result).to_not be_nil
|
||||
|
@ -114,14 +132,22 @@ describe Vagrant::MachineIndex do
|
|||
end
|
||||
end
|
||||
|
||||
describe "#set and #get and #delete" do
|
||||
let(:new_entry) do
|
||||
entry_klass.new.tap do |e|
|
||||
e.name = "foo"
|
||||
e.vagrantfile_path = "/bar"
|
||||
end
|
||||
describe "#include" do
|
||||
it "should not include non-existent things" do
|
||||
expect(subject.include?("foo")).to be_false
|
||||
end
|
||||
|
||||
it "should include created entries" do
|
||||
result = subject.set(new_entry)
|
||||
expect(result.id).to_not be_empty
|
||||
subject.release(result)
|
||||
|
||||
subject = described_class.new(data_dir)
|
||||
expect(subject.include?(result.id)).to be_true
|
||||
end
|
||||
end
|
||||
|
||||
describe "#set and #get and #delete" do
|
||||
it "adds a new entry" do
|
||||
result = subject.set(new_entry)
|
||||
expect(result.id).to_not be_empty
|
||||
|
|
|
@ -2,6 +2,8 @@ require File.expand_path("../../../../base", __FILE__)
|
|||
require 'optparse'
|
||||
|
||||
describe Vagrant::Plugin::V2::Command do
|
||||
include_context "unit"
|
||||
|
||||
describe "parsing options" do
|
||||
let(:klass) do
|
||||
Class.new(described_class) do
|
||||
|
@ -53,18 +55,17 @@ describe Vagrant::Plugin::V2::Command do
|
|||
end
|
||||
end
|
||||
|
||||
let(:default_provider) { :virtualbox }
|
||||
|
||||
let(:environment) do
|
||||
env = double("environment")
|
||||
env.stub(:active_machines => [])
|
||||
env.stub(:default_provider => default_provider)
|
||||
env.stub(:root_path => "foo")
|
||||
env
|
||||
# We have to create a Vagrantfile so there is a root path
|
||||
test_iso_env.vagrantfile("")
|
||||
test_iso_env.create_vagrant_env
|
||||
end
|
||||
let(:test_iso_env) { isolated_environment }
|
||||
|
||||
let(:instance) { klass.new([], environment) }
|
||||
|
||||
subject { instance }
|
||||
|
||||
it "should raise an exception if a root_path is not available" do
|
||||
environment.stub(:root_path => nil)
|
||||
|
||||
|
@ -82,8 +83,8 @@ describe Vagrant::Plugin::V2::Command do
|
|||
bar_vm.stub(ui: Vagrant::UI::Silent.new)
|
||||
|
||||
environment.stub(:machine_names => [:foo, :bar])
|
||||
allow(environment).to receive(:machine).with(:foo, default_provider).and_return(foo_vm)
|
||||
allow(environment).to receive(:machine).with(:bar, default_provider).and_return(bar_vm)
|
||||
allow(environment).to receive(:machine).with(:foo, environment.default_provider).and_return(foo_vm)
|
||||
allow(environment).to receive(:machine).with(:bar, environment.default_provider).and_return(bar_vm)
|
||||
|
||||
vms = []
|
||||
instance.with_target_vms do |vm|
|
||||
|
@ -106,7 +107,7 @@ describe Vagrant::Plugin::V2::Command do
|
|||
foo_vm.stub(:name => "foo", :provider => :foobarbaz)
|
||||
foo_vm.stub(ui: Vagrant::UI::Silent.new)
|
||||
|
||||
allow(environment).to receive(:machine).with(:foo, default_provider).and_return(foo_vm)
|
||||
allow(environment).to receive(:machine).with(:foo, environment.default_provider).and_return(foo_vm)
|
||||
|
||||
vms = []
|
||||
instance.with_target_vms("foo") { |vm| vms << vm }
|
||||
|
@ -167,8 +168,8 @@ describe Vagrant::Plugin::V2::Command do
|
|||
name = :foo
|
||||
machine = double("machine")
|
||||
|
||||
allow(environment).to receive(:machine).with(name, default_provider).and_return(machine)
|
||||
machine.stub(:name => name, :provider => default_provider)
|
||||
allow(environment).to receive(:machine).with(name, environment.default_provider).and_return(machine)
|
||||
machine.stub(:name => name, :provider => environment.default_provider)
|
||||
machine.stub(ui: Vagrant::UI::Silent.new)
|
||||
|
||||
results = []
|
||||
|
@ -198,16 +199,37 @@ describe Vagrant::Plugin::V2::Command do
|
|||
machine = double("machine")
|
||||
|
||||
environment.stub(:active_machines => [])
|
||||
allow(environment).to receive(:machine).with(name, default_provider).and_return(machine)
|
||||
allow(environment).to receive(:machine).with(name, environment.default_provider).and_return(machine)
|
||||
environment.stub(:machine_names => [])
|
||||
environment.stub(:primary_machine_name => name)
|
||||
machine.stub(:name => name, :provider => default_provider)
|
||||
machine.stub(:name => name, :provider => environment.default_provider)
|
||||
machine.stub(ui: Vagrant::UI::Silent.new)
|
||||
|
||||
vms = []
|
||||
instance.with_target_vms(nil, :single_target => true) { |vm| vms << machine }
|
||||
expect(vms).to eq([machine])
|
||||
end
|
||||
|
||||
it "should yield machines from another environment" do
|
||||
iso_env = isolated_environment
|
||||
iso_env.vagrantfile("")
|
||||
other_env = iso_env.create_vagrant_env(
|
||||
home_path: environment.home_path)
|
||||
other_machine = other_env.machine(
|
||||
other_env.machine_names[0], other_env.default_provider)
|
||||
|
||||
# Set an ID on it so that it is "created" in the index
|
||||
other_machine.id = "foo"
|
||||
|
||||
# Make sure we don't have a root path, to test
|
||||
environment.stub(root_path: nil)
|
||||
|
||||
results = []
|
||||
subject.with_target_vms(other_machine.index_uuid) { |m| results << m }
|
||||
|
||||
expect(results.length).to eq(1)
|
||||
expect(results[0].id).to eq(other_machine.id)
|
||||
end
|
||||
end
|
||||
|
||||
describe "splitting the main and subcommand args" do
|
||||
|
|
Loading…
Reference in New Issue