core: Add MachineIndex#delete

This commit is contained in:
Mitchell Hashimoto 2014-03-14 14:55:38 -07:00
parent 69a290eb9d
commit a29f5d7e01
2 changed files with 62 additions and 6 deletions

View File

@ -50,6 +50,38 @@ module Vagrant
end
end
# Deletes a machine by UUID.
#
# The machine being deleted with this UUID must either be locked
# by this index or must be unlocked.
#
# @param [Entry] entry The entry to delete.
# @return [Boolean] true if delete is successful
def delete(entry)
return true if !entry.id
@lock.synchronize do
with_index_lock do
return true if !@machines[entry.id]
# If we don't have the lock, then we need to acquire it.
if !@machine_locks[entry.id]
raise "Unlocked delete on machine: #{entry.id}"
end
# Reload so we have the latest data, then delete and save
unlocked_reload
@machines.delete(entry.id)
unlocked_save
# Release acccess on this machine
unlocked_release(entry.id)
end
end
true
end
# Accesses a machine by UUID and returns a {MachineIndex::Entry}
#
# The entry returned is locked and can't be read again or updated by
@ -94,11 +126,7 @@ module Vagrant
# @param [Entry] entry
def release(entry)
@lock.synchronize do
lock_file = @machine_locks[entry.id]
if lock_file
lock_file.close
@machine_locks.delete(entry.id)
end
unlocked_release(entry.id)
end
end
@ -170,6 +198,18 @@ module Vagrant
lock_file
end
# Releases a local lock on a machine. This does not acquire any locks
# so make sure to lock around it.
#
# @param [String] id
def unlocked_release(id)
lock_file = @machine_locks[id]
if lock_file
lock_file.close
@machine_locks.delete(id)
end
end
# This will reload the data without locking the index. It is assumed
# the caller with lock the index outside of this call.
#

View File

@ -84,7 +84,7 @@ describe Vagrant::MachineIndex do
end
end
describe "#set and #get" do
describe "#set and #get and #delete" do
let(:entry_klass) { Vagrant::MachineIndex::Entry }
let(:new_entry) do
@ -112,6 +112,22 @@ describe Vagrant::MachineIndex do
# TODO: test that updated_at is set
end
it "can delete an entry" do
result = subject.set(new_entry)
expect(result.id).to_not be_empty
subject.delete(result)
# Get it from a new class and check the results
subject = described_class.new(data_dir)
entry = subject.get(result.id)
expect(entry).to be_nil
end
it "can delete an entry that doesn't exist" do
e = entry_klass.new
expect(subject.delete(e)).to be_true
end
it "updates an existing entry" do
entry = entry_klass.new
entry.name = "foo"