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
|
id = entry.id
|
||||||
|
|
||||||
@lock.synchronize do
|
@lock.synchronize do
|
||||||
# Verify the machine is locked so we can safely write
|
with_index_lock do
|
||||||
# to it.
|
# Reload so we have the latest machine data. This allows other
|
||||||
if !id
|
# processes to update their own machines without conflicting
|
||||||
id = SecureRandom.uuid.gsub("-", "")
|
# with our own.
|
||||||
lock_file = lock_machine(id)
|
unlocked_reload
|
||||||
if !lock_file
|
|
||||||
raise "Failed to lock new machine: #{entry.name}"
|
# 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
|
end
|
||||||
|
|
||||||
@machine_locks[id] = lock_file
|
if !@machine_locks[id]
|
||||||
end
|
raise "Unlocked write on machine: #{id}"
|
||||||
|
end
|
||||||
|
|
||||||
if !@machine_locks[id]
|
# Set our machine and save
|
||||||
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
|
|
||||||
@machines[id] = struct
|
@machines[id] = struct
|
||||||
unlocked_save
|
unlocked_save
|
||||||
end
|
end
|
||||||
|
@ -218,6 +231,8 @@ module Vagrant
|
||||||
#
|
#
|
||||||
# If the lock cannot be acquired, then nil is returned.
|
# If the lock cannot be acquired, then nil is returned.
|
||||||
#
|
#
|
||||||
|
# This should be called within an index lock.
|
||||||
|
#
|
||||||
# @return [File]
|
# @return [File]
|
||||||
def lock_machine(uuid)
|
def lock_machine(uuid)
|
||||||
lock_path = @data_dir.join("#{uuid}.lock")
|
lock_path = @data_dir.join("#{uuid}.lock")
|
||||||
|
|
|
@ -227,5 +227,39 @@ describe Vagrant::MachineIndex do
|
||||||
"foo" => "bar",
|
"foo" => "bar",
|
||||||
})
|
})
|
||||||
end
|
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
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue