From a29f5d7e0167aeca8b1aa2deeaa00642c4e74a23 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Fri, 14 Mar 2014 14:55:38 -0700 Subject: [PATCH] core: Add MachineIndex#delete --- lib/vagrant/machine_index.rb | 50 ++++++++++++++++++--- test/unit/vagrant/machine_directory_test.rb | 18 +++++++- 2 files changed, 62 insertions(+), 6 deletions(-) diff --git a/lib/vagrant/machine_index.rb b/lib/vagrant/machine_index.rb index ffa0f1dc0..9be88dbb5 100644 --- a/lib/vagrant/machine_index.rb +++ b/lib/vagrant/machine_index.rb @@ -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. # diff --git a/test/unit/vagrant/machine_directory_test.rb b/test/unit/vagrant/machine_directory_test.rb index d340e9a65..7828f45e7 100644 --- a/test/unit/vagrant/machine_directory_test.rb +++ b/test/unit/vagrant/machine_directory_test.rb @@ -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"