From 09ff31e3a317e7c334933cd7b229965ee8a1881d Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Mon, 14 Apr 2014 20:04:17 -0700 Subject: [PATCH] commands/global-status: add --prune flag --- lib/vagrant/machine_index.rb | 10 ++++- plugins/commands/global-status/command.rb | 41 ++++++++++++++++++ .../commands/global-status/command_test.rb | 43 ++++++++++++++++++- 3 files changed, 92 insertions(+), 2 deletions(-) diff --git a/lib/vagrant/machine_index.rb b/lib/vagrant/machine_index.rb index e19b09cd0..fa9739b11 100644 --- a/lib/vagrant/machine_index.rb +++ b/lib/vagrant/machine_index.rb @@ -87,7 +87,15 @@ module Vagrant # Iterate over every machine in the index. The yielded {Entry} objects # will NOT be locked, so you'll have to call {#get} manually to acquire # the lock on them. - def each + def each(reload=false) + if reload + @lock.synchronize do + with_index_lock do + unlocked_reload + end + end + end + @machines.each do |uuid, data| yield Entry.new(uuid, data.merge("id" => uuid)) end diff --git a/plugins/commands/global-status/command.rb b/plugins/commands/global-status/command.rb index a602c344f..c97368db1 100644 --- a/plugins/commands/global-status/command.rb +++ b/plugins/commands/global-status/command.rb @@ -8,8 +8,14 @@ module VagrantPlugins end def execute + options = {} + opts = OptionParser.new do |o| o.banner = "Usage: vagrant global-status" + o.separator "" + o.on("--prune", "Prune invalid entries.") do |p| + options[:prune] = true + end end # Parse the options @@ -32,7 +38,15 @@ module VagrantPlugins widths[:vagrantfile_path] = 35 entries = [] + prune = [] @env.machine_index.each do |entry| + # If we're pruning and this entry is invalid, skip it + # and prune it later. + if options[:prune] && invalid?(entry) + prune << entry + next + end + entries << entry columns.each do |_, method| @@ -45,6 +59,12 @@ module VagrantPlugins end end + # Prune all the entries to prune + prune.each do |entry| + deletable = @env.machine_index.get(entry.id) + @env.machine_index.delete(deletable) if deletable + end + total_width = 0 columns.each do |header, method| header = header.ljust(widths[method]) if widths[method] @@ -75,6 +95,27 @@ module VagrantPlugins # Success, exit status 0 0 end + + protected + + # Tests if a entry is invalid and should be pruned + def invalid?(entry) + return true if !entry.vagrantfile_path.file? + + # Create an environment so we can determine the active + # machines... + env = Vagrant::Environment.new( + cwd: entry.vagrantfile_path.dirname, + home_path: @env.home_path, + ) + + env.active_machines.each do |name, provider| + return false if name.to_s == entry.name.to_s && + provider.to_s == entry.provider.to_s + end + + true + end end end end diff --git a/test/unit/plugins/commands/global-status/command_test.rb b/test/unit/plugins/commands/global-status/command_test.rb index b6deac029..1107a3464 100644 --- a/test/unit/plugins/commands/global-status/command_test.rb +++ b/test/unit/plugins/commands/global-status/command_test.rb @@ -27,7 +27,7 @@ describe VagrantPlugins::CommandGlobalStatus::Command do subject { described_class.new(argv, iso_env) } - describe "execute" do + describe "execute with no args" do it "succeeds" do # Let's put some things in the index iso_env.machine_index.set(new_entry("foo")) @@ -36,4 +36,45 @@ describe VagrantPlugins::CommandGlobalStatus::Command do expect(subject.execute).to eq(0) end end + + describe "execute with --prune" do + let(:argv) { ["--prune"] } + + it "removes invalid entries" do + # Invalid entry because vagrantfile path is gone + entryA = new_entry("A") + entryA.vagrantfile_path = "/i/dont/exist" + locked = iso_env.machine_index.set(entryA) + iso_env.machine_index.release(locked) + + # Invalid entry because that specific machine doesn't exist anymore. + entryB_env = isolated_environment + entryB_env.vagrantfile("") + entryB = new_entry("B") + entryB.vagrantfile_path = entryB_env.workdir.join("Vagrantfile") + locked = iso_env.machine_index.set(entryB) + iso_env.machine_index.release(locked) + + # Valid entry because the machine does exist + entryC_env = isolated_environment + entryC_env.vagrantfile("") + entryC_venv = entryC_env.create_vagrant_env + entryC_machine = entryC_venv.machine(entryC_venv.machine_names[0], :dummy) + entryC_machine.id = "foo" + entryC = new_entry(entryC_machine.name) + entryC.provider = "dummy" + entryC.vagrantfile_path = entryC_env.workdir.join("Vagrantfile") + locked = iso_env.machine_index.set(entryC) + iso_env.machine_index.release(locked) + + expect(subject.execute).to eq(0) + + # Reload the data and see that we got things correct + entries = [] + iso_env.machine_index.each(true) { |e| entries << e } + + expect(entries.length).to eq(1) + expect(entries[0].name).to eq(entryC_machine.name.to_s) + end + end end