Skip to content

Commit

Permalink
Add a check for VM accessibility before every action
Browse files Browse the repository at this point in the history
  • Loading branch information
mitchellh committed Aug 29, 2011
1 parent 2efe1f9 commit 327a6f9
Show file tree
Hide file tree
Showing 6 changed files with 96 additions and 0 deletions.
1 change: 1 addition & 0 deletions lib/vagrant/action/builtin.rb
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ def self.builtin!
# now, these are limited to what are needed internally.
register(:before_action_run, Builder.new do
use General::Validate
use VM::CheckAccessible
end)
end
end
Expand Down
1 change: 1 addition & 0 deletions lib/vagrant/action/vm.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ module Vagrant
class Action
module VM
autoload :Boot, 'vagrant/action/vm/boot'
autoload :CheckAccessible, 'vagrant/action/vm/check_accessible'
autoload :CheckBox, 'vagrant/action/vm/check_box'
autoload :CheckGuestAdditions, 'vagrant/action/vm/check_guest_additions'
autoload :CleanMachineFolder, 'vagrant/action/vm/clean_machine_folder'
Expand Down
23 changes: 23 additions & 0 deletions lib/vagrant/action/vm/check_accessible.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
module Vagrant
class Action
module VM
class CheckAccessible
def initialize(app, env)
@app = app
end

def call(env)
if env["vm"] && env["vm"].created? && !env["vm"].vm.accessible?
# The VM we are attempting to manipulate is inaccessible. This
# is a very bad situation and can only be fixed by the user. It
# also prohibits us from actually doing anything with the virtual
# machine, so we raise an error.
raise Errors::VMInaccessible
end

@app.call(env)
end
end
end
end
end
5 changes: 5 additions & 0 deletions lib/vagrant/errors.rb
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,11 @@ class VMImportFailure < VagrantError
error_key(:failure, "vagrant.actions.vm.import")
end

class VMInaccessible < VagrantError
status_code(54)
error_key(:vm_inaccessible)
end

class VMNotCreatedError < VagrantError
status_code(6)
error_key(:vm_creation_required)
Expand Down
5 changes: 5 additions & 0 deletions templates/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,11 @@ en:
http://vagrantup.com/docs/getting-started/setup/windows_x64.html
vm_creation_required: "VM must be created before running this command. Run `vagrant up` first."
vm_inaccessible: |-
Your VM has become "inaccessible." Unfortunately, this is a critical error
with VirtualBox that Vagrant can not cleanly recover from. Please open VirtualBox
and clear out your inaccessible virtual machines or find a way to fix
them.
vm_not_found: "A VM by the name of %{name} was not found."
vm_not_running: "VM must be running to open SSH connection."

Expand Down
61 changes: 61 additions & 0 deletions test/vagrant/action/vm/check_accessible_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
require 'test_helper'

class CheckAccessibleVMActionTest < Test::Unit::TestCase
setup do
@klass = Vagrant::Action::VM::CheckAccessible
end

context "calling" do
setup do
@app, @env = action_env
@instance = @klass.new(@app, @env)
end

should "continue up the chain if the VM is nil" do
@env["vm"] = nil

@app.expects(:call).once

assert_nothing_raised {
@instance.call(@env)
}
end

should "continue up the chain if the VM is not created" do
@env["vm"] = mock("vm")
@env["vm"].stubs(:created?).returns(false)

@app.expects(:call).once

assert_nothing_raised {
@instance.call(@env)
}
end

should "continue up the chain if the VM is created and accessible" do
@env["vm"] = mock("vm")
@env["vm"].stubs(:created?).returns(true)
@env["vm"].stubs(:vm).returns(mock("real_vm"))
@env["vm"].vm.stubs(:accessible?).returns(true)

@app.expects(:call).once

assert_nothing_raised {
@instance.call(@env)
}
end

should "fail if the VM is not accessible" do
@env["vm"] = mock("vm")
@env["vm"].stubs(:created?).returns(true)
@env["vm"].stubs(:vm).returns(mock("real_vm"))
@env["vm"].vm.stubs(:accessible?).returns(false)

@app.expects(:call).never

assert_raises(Vagrant::Errors::VMInaccessible) {
@instance.call(@env)
}
end
end
end

0 comments on commit 327a6f9

Please sign in to comment.