core: MachineIndex updates existing entry if name, provider, path match
This commit is contained in:
parent
d72c18a8b1
commit
9b22ccbd32
|
@ -171,27 +171,40 @@ module Vagrant
|
|||
id = entry.id
|
||||
|
||||
@lock.synchronize do
|
||||
# Verify the machine is locked so we can safely write
|
||||
# to it.
|
||||
if !id
|
||||
id = SecureRandom.uuid.gsub("-", "")
|
||||
lock_file = lock_machine(id)
|
||||
if !lock_file
|
||||
raise "Failed to lock new machine: #{entry.name}"
|
||||
with_index_lock do
|
||||
# Reload so we have the latest machine data. This allows other
|
||||
# processes to update their own machines without conflicting
|
||||
# with our own.
|
||||
unlocked_reload
|
||||
|
||||
# If we don't have a machine ID, try to look one up
|
||||
if !id
|
||||
self.each do |other|
|
||||
if entry.name == other.name &&
|
||||
entry.provider == other.provider &&
|
||||
entry.vagrantfile_path.to_s == other.vagrantfile_path.to_s
|
||||
id = other.id
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
# If we still don't have an ID, generate a random one
|
||||
id = SecureRandom.uuid.gsub("-", "") if !id
|
||||
|
||||
# Get a lock on this machine
|
||||
lock_file = lock_machine(id)
|
||||
if !lock_file
|
||||
raise "Failed to lock new machine: #{entry.name}"
|
||||
end
|
||||
|
||||
@machine_locks[id] = lock_file
|
||||
end
|
||||
|
||||
@machine_locks[id] = lock_file
|
||||
end
|
||||
if !@machine_locks[id]
|
||||
raise "Unlocked write on machine: #{id}"
|
||||
end
|
||||
|
||||
if !@machine_locks[id]
|
||||
raise "Unlocked write on machine: #{id}"
|
||||
end
|
||||
|
||||
with_index_lock do
|
||||
# Reload so we have the latest machine data, then update
|
||||
# this particular machine, then write. This allows other processes
|
||||
# to update their own machines without conflicting with our own.
|
||||
unlocked_reload
|
||||
# Set our machine and save
|
||||
@machines[id] = struct
|
||||
unlocked_save
|
||||
end
|
||||
|
@ -218,6 +231,8 @@ module Vagrant
|
|||
#
|
||||
# If the lock cannot be acquired, then nil is returned.
|
||||
#
|
||||
# This should be called within an index lock.
|
||||
#
|
||||
# @return [File]
|
||||
def lock_machine(uuid)
|
||||
lock_path = @data_dir.join("#{uuid}.lock")
|
||||
|
|
|
@ -227,5 +227,39 @@ describe Vagrant::MachineIndex do
|
|||
"foo" => "bar",
|
||||
})
|
||||
end
|
||||
|
||||
it "updates an existing directory if the name, provider, and path are the same" do
|
||||
entry = entry_klass.new
|
||||
entry.name = "foo"
|
||||
entry.provider = "bar"
|
||||
entry.vagrantfile_path = "/bar"
|
||||
entry.state = "foo"
|
||||
|
||||
result = subject.set(entry)
|
||||
expect(result.id).to_not be_empty
|
||||
|
||||
# Release it so we can modify it
|
||||
subject.release(result)
|
||||
|
||||
entry2 = entry_klass.new
|
||||
entry2.name = entry.name
|
||||
entry2.provider = entry.provider
|
||||
entry2.vagrantfile_path = entry.vagrantfile_path
|
||||
entry2.state = "bar"
|
||||
expect(entry2.id).to be_nil
|
||||
|
||||
nextresult = subject.set(entry2)
|
||||
expect(nextresult.id).to eq(result.id)
|
||||
|
||||
# Release it so we can test the contents
|
||||
subject.release(nextresult)
|
||||
|
||||
# Get it from a new class and check the results
|
||||
subject = described_class.new(data_dir)
|
||||
entry = subject.get(result.id)
|
||||
expect(entry).to_not be_nil
|
||||
expect(entry.name).to eq(entry2.name)
|
||||
expect(entry.state).to eq(entry2.state)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue