Building up the `destroy` action again using new provider API.

This shows me moving the built-in middleware sequences to the provider
and how I'm organizing all that.
This commit is contained in:
Mitchell Hashimoto 2012-07-26 22:39:27 -07:00
parent 5f8a654393
commit 5eed3b8417
10 changed files with 81 additions and 53 deletions

View File

@ -1,28 +0,0 @@
module Vagrant
module Action
module General
# Checks that virtualbox is installed and ready to be used.
class CheckVirtualbox
def initialize(app, env)
@app = app
end
def call(env)
# Certain actions may not actually have a VM, and thus no
# driver, so we have to be clever about obtaining an instance
# of the driver.
driver = nil
driver = env[:vm].driver if env[:vm]
driver = Driver::VirtualBox.new(nil) if !driver
# Verify that it is ready to go! This will raise an exception
# if anything goes wrong.
driver.verify!
# Carry on.
@app.call(env)
end
end
end
end
end

View File

@ -9,7 +9,10 @@ module Vagrant
end end
def call(env) def call(env)
env[:vm].config.validate!(env[:vm].env) if !env.has_key?("validate") || env["validate"] if !env.has_key?(:validate) || env[:validate]
env[:machine].config.validate!(env[:machine].env)
end
@app.call(env) @app.call(env)
end end
end end

View File

@ -19,6 +19,9 @@ module VagrantPlugins
@logger.debug("'Destroy' each target VM...") @logger.debug("'Destroy' each target VM...")
with_target_vms(argv, :reverse => true) do |vm| with_target_vms(argv, :reverse => true) do |vm|
vm.action(:destroy)
next
if vm.created? if vm.created?
# Boolean whether we should actually go through with the destroy # Boolean whether we should actually go through with the destroy
# or not. This is true only if the "--force" flag is set or if the # or not. This is true only if the "--force" flag is set or if the

View File

@ -0,0 +1,20 @@
require "vagrant/action/builder"
module VagrantPlugins
module ProviderVirtualBox
module Action
autoload :CheckAccessible, File.expand_path("../action/check_accessible", __FILE__)
autoload :CheckVirtualbox, File.expand_path("../action/check_virtualbox", __FILE__)
# This is the action that is primarily responsible for completely
# freeing the resources of the underlying virtual machine.
def self.action_destroy
Vagrant::Action::Builder.new.tap do |b|
b.use CheckVirtualbox
b.use Vagrant::Action::General::Validate
b.use CheckAccessible
end
end
end
end
end

View File

@ -1,18 +1,18 @@
module Vagrant module VagrantPlugins
module Action module ProviderVirtualBox
module VM module Action
class CheckAccessible class CheckAccessible
def initialize(app, env) def initialize(app, env)
@app = app @app = app
end end
def call(env) def call(env)
if env[:vm].state == :inaccessible if env[:machine].state == :inaccessible
# The VM we are attempting to manipulate is inaccessible. This # The VM we are attempting to manipulate is inaccessible. This
# is a very bad situation and can only be fixed by the user. It # is a very bad situation and can only be fixed by the user. It
# also prohibits us from actually doing anything with the virtual # also prohibits us from actually doing anything with the virtual
# machine, so we raise an error. # machine, so we raise an error.
raise Errors::VMInaccessible raise Vagrant::Errors::VMInaccessible
end end
@app.call(env) @app.call(env)

View File

@ -0,0 +1,22 @@
module VagrantPlugins
module ProviderVirtualBox
module Action
# Checks that VirtualBox is installed and ready to be used.
class CheckVirtualbox
def initialize(app, env)
@app = app
end
def call(env)
# This verifies that VirtualBox is installed and the driver is
# ready to function. If not, then an exception will be raised
# which will break us out of execution of the middleware sequence.
Driver::Meta.new.verify!
# Carry on.
@app.call(env)
end
end
end
end
end

View File

@ -15,6 +15,8 @@ module VagrantPlugins
end end
end end
autoload :Action, File.expand_path("../action", __FILE__)
# Drop some autoloads in here to optimize the performance of loading # Drop some autoloads in here to optimize the performance of loading
# our drivers only when they are needed. # our drivers only when they are needed.
module Driver module Driver

View File

@ -6,8 +6,30 @@ module VagrantPlugins
@driver = Driver::Meta.new(@machine.id) @driver = Driver::Meta.new(@machine.id)
end end
# @see Vagrant::Plugin::V1::Provider#action
def action(name)
# Attempt to get the action method from the Action class if it
# exists, otherwise return nil to show that we don't support the
# given action.
action_method = "action_#{name}"
return Action.send(action_method) if Action.respond_to?(action_method)
nil
end
# Returns a human-friendly string version of this provider which
# includes the machine's ID that this provider represents, if it
# has one.
#
# @return [String]
def to_s
id = @machine.id ? @machine.id : "new VM"
"VirtualBox (#{id})"
end
# Return the state of VirtualBox virtual machine by actually # Return the state of VirtualBox virtual machine by actually
# querying VBoxManage. # querying VBoxManage.
#
# @return [Symbol]
def state def state
return :not_created if !@driver.uuid return :not_created if !@driver.uuid
state = @driver.read_state state = @driver.read_state

View File

@ -1,13 +1,7 @@
require File.expand_path("../../../base", __FILE__) require File.expand_path("../../../base", __FILE__)
describe Vagrant::Action::Runner do describe Vagrant::Action::Runner do
let(:registry) do let(:instance) { described_class.new }
d = double("registry")
d.stub(:get)
d
end
let(:instance) { described_class.new(registry) }
it "should raise an error if an invalid callable is given" do it "should raise an error if an invalid callable is given" do
expect { instance.run(7) }.to raise_error(ArgumentError, /must be a callable/) expect { instance.run(7) }.to raise_error(ArgumentError, /must be a callable/)
@ -47,7 +41,7 @@ describe Vagrant::Action::Runner do
result = env["data"] result = env["data"]
end end
instance = described_class.new(registry, "data" => "bar") instance = described_class.new("data" => "bar")
instance.run(callable) instance.run(callable)
result.should == "bar" result.should == "bar"
end end
@ -58,7 +52,7 @@ describe Vagrant::Action::Runner do
result = env["data"] result = env["data"]
end end
instance = described_class.new(registry) { { "data" => "bar" } } instance = described_class.new { { "data" => "bar" } }
instance.run(callable) instance.run(callable)
result.should == "bar" result.should == "bar"
end end

View File

@ -93,16 +93,6 @@ describe Vagrant::Environment do
end end
end end
describe "action registry" do
it "has an action registry" do
instance.action_registry.should be_kind_of(Vagrant::Registry)
end
it "should have the built-in actions in the registry" do
instance.action_registry.get(:provision).should_not be_nil
end
end
describe "primary VM" do describe "primary VM" do
it "should be the only VM if not a multi-VM environment" do it "should be the only VM if not a multi-VM environment" do
instance.primary_vm.should == instance.vms.values.first instance.primary_vm.should == instance.vms.values.first