ActionExceptions all use the new error strings by key

This commit is contained in:
Mitchell Hashimoto 2010-03-17 21:38:38 -07:00
parent 18f761b015
commit f59b255085
20 changed files with 87 additions and 65 deletions

View File

@ -84,15 +84,15 @@ module Vagrant
def rescue(exception); end def rescue(exception); end
# The following two methods are used for declaring action dependencies. # The following two methods are used for declaring action dependencies.
# For example, you require that the reload action be in place before # For example, you require that the reload action be in place before
# a your new FooAction you might do the following # a your new FooAction you might do the following
# #
# def follows; [Reload] end # def follows; [Reload] end
# This method is called when the runner is determining the actions that # This method is called when the runner is determining the actions that
# must precede a given action. You would say "This action follows [Action1, Action2]" # must precede a given action. You would say "This action follows [Action1, Action2]"
def follows; [] end def follows; [] end
# This method is called when the runner is determining the actions that # This method is called when the runner is determining the actions that
# must follow a given action. You would say "This action precedes [Action3, Action4] # must follow a given action. You would say "This action precedes [Action3, Action4]
def precedes; [] end def precedes; [] end
@ -102,6 +102,17 @@ module Vagrant
# {Vagrant::Util#error_and_exit error_and_exit}, since it allows the {Runner} to call # {Vagrant::Util#error_and_exit error_and_exit}, since it allows the {Runner} to call
# {Base#rescue rescue} on all the actions and properly exit. Any message # {Base#rescue rescue} on all the actions and properly exit. Any message
# passed into the {ActionException} is then shown and and vagrant exits. # passed into the {ActionException} is then shown and and vagrant exits.
class ActionException < Exception; end class ActionException < Exception
attr_reader :key
attr_reader :data
def initialize(key, data = {})
@key = key
@data = data
message = Vagrant::Util::Errors.error_string(key, data)
super(message)
end
end
end end
end end

View File

@ -10,7 +10,7 @@ module Vagrant
class Add < Base class Add < Base
def prepare def prepare
if File.exists?(@runner.directory) if File.exists?(@runner.directory)
raise ActionException.new("A box with the name '#{@runner.name}' already exists, please use another name or use `vagrant box remove #{@runner.name}`") raise ActionException.new(:box_add_already_exists, :box_name => @runner.name)
end end
@runner.add_action(Download) @runner.add_action(Download)

View File

@ -25,7 +25,7 @@ module Vagrant
end end
end end
raise ActionException.new("Unknown URI type for box download.") unless @downloader raise ActionException.new(:box_download_unknown_type) unless @downloader
# Prepare the downloader # Prepare the downloader
@downloader.prepare(@runner.uri) @downloader.prepare(@runner.uri)

View File

@ -9,17 +9,7 @@ module Vagrant
vm.forwarded_ports.each do |fp| vm.forwarded_ports.each do |fp|
Vagrant.config.vm.forwarded_ports.each do |name, options| Vagrant.config.vm.forwarded_ports.each do |name, options|
if fp.hostport.to_s == options[:hostport].to_s if fp.hostport.to_s == options[:hostport].to_s
raise ActionException.new(<<-msg) raise ActionException.new(:vm_port_collision, :name => name, :hostport => fp.hostport.to_s, :guestport => options[:guestport].to_s)
Vagrant cannot forward the specified ports on this VM, since they
would collide with another VirtualBox virtual machine's forwarded
ports! The "#{name}" forwarded port (#{fp.hostport}) is already in use on the host
machine.
To fix this, modify your current projects Vagrantfile to use another
port. Example, where '1234' would be replaced by a unique host port:
config.vm.forward_port("#{name}", #{options[:guestport]}, 1234)
msg
end end
end end
end end

View File

@ -3,7 +3,7 @@ module Vagrant
module VM module VM
class Halt < Base class Halt < Base
def execute! def execute!
raise ActionException.new("VM is not running! Nothing to shut down!") unless @runner.vm.running? raise ActionException.new(:vm_not_running) unless @runner.vm.running?
logger.info "Forcing shutdown of VM..." logger.info "Forcing shutdown of VM..."
@runner.vm.stop(true) @runner.vm.stop(true)

View File

@ -8,7 +8,7 @@ module Vagrant
logger.info "Importing base VM (#{Vagrant::Env.box.ovf_file})..." logger.info "Importing base VM (#{Vagrant::Env.box.ovf_file})..."
# Use the first argument passed to the action # Use the first argument passed to the action
@runner.vm = VirtualBox::VM.import(Vagrant::Env.box.ovf_file) @runner.vm = VirtualBox::VM.import(Vagrant::Env.box.ovf_file)
raise ActionException.new("The VM import failed! Try running `VBoxManage import` on the box file manually for more verbose error output.") unless @runner.vm raise ActionException.new(:virtualbox_import_failure) unless @runner.vm
end end
end end
end end

View File

@ -16,12 +16,12 @@ module Vagrant
def prepare def prepare
# Verify the existance of all the additional files, if any # Verify the existance of all the additional files, if any
@include_files.each do |file| @include_files.each do |file|
raise ActionException.new("#{file} does not exist") unless File.exists?(file) raise ActionException.new(:package_include_file_doesnt_exist, :filename => file) unless File.exists?(file)
end end
# Get the export action and store a reference to it # Get the export action and store a reference to it
@export_action = @runner.find_action(Export) @export_action = @runner.find_action(Export)
raise ActionException.new("Package must be used in conjunction with export.") unless @export_action raise ActionException.new(:packaged_requires_export) unless @export_action
end end
def execute! def execute!

View File

@ -20,7 +20,7 @@ module Vagrant
if provisioner.is_a?(Class) if provisioner.is_a?(Class)
@provisioner = provisioner.new @provisioner = provisioner.new
raise ActionException.new("Provisioners must be an instance of Vagrant::Provisioners::Base") unless @provisioner.is_a?(Provisioners::Base) raise ActionException.new(:provisioner_invalid_class) unless @provisioner.is_a?(Provisioners::Base)
elsif provisioner.is_a?(Symbol) elsif provisioner.is_a?(Symbol)
# We have a few hard coded provisioners for built-ins # We have a few hard coded provisioners for built-ins
mapping = { mapping = {
@ -29,7 +29,7 @@ module Vagrant
} }
provisioner_klass = mapping[provisioner] provisioner_klass = mapping[provisioner]
raise ActionException.new("Unknown provisioner type: #{provisioner}") if provisioner_klass.nil? raise ActionException.new(:provisioner_unknown_type, :provisioner => provisioner.to_s) if provisioner_klass.nil?
@provisioner = provisioner_klass.new @provisioner = provisioner_klass.new
end end

View File

@ -4,7 +4,7 @@ module Vagrant
class Resume < Base class Resume < Base
def execute! def execute!
if !@runner.vm.saved? if !@runner.vm.saved?
raise ActionException.new("The vagrant virtual environment you are trying to resume is not in a suspended state.") raise ActionException.new(:vm_not_suspended)
end end
logger.info "Resuming suspended VM..." logger.info "Resuming suspended VM..."

View File

@ -71,7 +71,7 @@ module Vagrant
break unless result break unless result
attempts += 1 attempts += 1
raise ActionException.new("Failed to mount shared folders. vboxsf was not available.") if attempts >= 10 raise ActionException.new(:vm_mount_fail) if attempts >= 10
sleep sleeptime sleep sleeptime
end end
end end

View File

@ -4,7 +4,7 @@ module Vagrant
class Suspend < Base class Suspend < Base
def execute! def execute!
if !@runner.vm.running? if !@runner.vm.running?
raise ActionException.new("The vagrant virtual environment you are trying to suspend must be running to be suspended.") raise ActionException.new(:vm_not_running_for_suspend)
end end
logger.info "Saving VM state and suspending execution..." logger.info "Saving VM state and suspending execution..."

View File

@ -5,17 +5,7 @@ module Vagrant
def prepare def prepare
# If the dotfile is not a file, raise error # If the dotfile is not a file, raise error
if File.exist?(Env.dotfile_path) && !File.file?(Env.dotfile_path) if File.exist?(Env.dotfile_path) && !File.file?(Env.dotfile_path)
raise ActionException.new(<<-msg) raise ActionException.new(:dotfile_error)
The dotfile which Vagrant uses to store the UUID of the project's
virtual machine already exists and is not a file! The dotfile is
currently configured to be `#{Env.dotfile_path}`
To change this value, please see `config.vagrant.dotfile_name`
This often exists if you're trying to create a Vagrant virtual
environment from your home directory. To resolve this, you can either
modify the configuration a bit, or simply use a different directory.
msg
end end
# Up is a "meta-action" so it really just queues up a bunch # Up is a "meta-action" so it really just queues up a bunch

View File

@ -5,11 +5,7 @@ module Vagrant
class File < Base class File < Base
def prepare(source_url) def prepare(source_url)
if !::File.file?(source_url) if !::File.file?(source_url)
raise Actions::ActionException.new(<<-msg) raise Actions::ActionException.new(:downloader_file_doesnt_exist, :source_url => source_url)
The given box does not exist on the file system:
#{source_url}
msg
end end
end end

View File

@ -66,7 +66,7 @@ module Vagrant
Config.configures :chef, ChefConfig Config.configures :chef, ChefConfig
def prepare def prepare
raise Actions::ActionException.new("Vagrant::Provisioners::Chef is not a valid provisioner! Use ChefSolo or ChefServer instead.") raise Actions::ActionException.new(:chef_base_invalid_provisioner)
end end
def chown_provisioning_folder def chown_provisioning_folder

View File

@ -5,25 +5,13 @@ module Vagrant
class ChefServer < Chef class ChefServer < Chef
def prepare def prepare
if Vagrant.config.chef.validation_key_path.nil? if Vagrant.config.chef.validation_key_path.nil?
raise Actions::ActionException.new(<<-msg) raise Actions::ActionException.new(:chef_server_validation_key_required)
Chef server provisioning requires that the `config.chef.validation_key_path` configuration
be set to a path on your local machine of the validation key used to register the
VM with the chef server.
msg
elsif !File.file?(Vagrant.config.chef.validation_key_path) elsif !File.file?(Vagrant.config.chef.validation_key_path)
raise Actions::ActionException.new(<<-msg) raise Actions::ActionException.new(:chef_server_validation_key_doesnt_exist)
The validation key set for `config.chef.validation_key_path` does not exist! This
file needs to exist so it can be uploaded to the virtual machine. It is
currently set to "#{Vagrant.config.chef.validation_key_path}"
msg
end end
if Vagrant.config.chef.chef_server_url.nil? if Vagrant.config.chef.chef_server_url.nil?
raise Actions::ActionException.new(<<-msg) raise Actions::ActionException.new(:chef_server_url_required)
Chef server provisioning requires that the `config.chef.chef_server_url` be set to the
URL of your chef server. Examples include "http://12.12.12.12:4000" and
"http://myserver.com:4000" (the port of course can be different, but 4000 is the default)
msg
end end
end end

View File

@ -27,7 +27,8 @@ module Vagrant
# #
# @return [String] # @return [String]
def error_string(key, data = {}) def error_string(key, data = {})
TemplateRenderer.render_string(errors[key], data) template = errors[key] || "Unknown error key: #{key}"
TemplateRenderer.render_string(template, data)
end end
end end
end end

View File

@ -1,5 +1,7 @@
:box_already_exists: "This box appears to already exist! Please call `vagrant box remove <%= box_name %>` :box_already_exists: "This box appears to already exist! Please call `vagrant box remove <%= box_name %>`
and then try to add it again." and then try to add it again."
:box_add_already_exists: "A box with the name '<%= box_name %>' already exists, please use another name or use `vagrant box remove <%= box_name %>`"
:box_download_unknown_type: "Unknown URI type for box download."
:box_remove_doesnt_exist: "The box you're attempting to remove does not exist!" :box_remove_doesnt_exist: "The box you're attempting to remove does not exist!"
:box_specified_doesnt_exist: "Specified box `<%= box_name %>` does not exist! :box_specified_doesnt_exist: "Specified box `<%= box_name %>` does not exist!
@ -8,22 +10,49 @@
:box_not_specified: "No base box was specified! A base box is required as a staring point :box_not_specified: "No base box was specified! A base box is required as a staring point
for every vagrant virtual machine. Please specify one in your Vagrantfile for every vagrant virtual machine. Please specify one in your Vagrantfile
using `config.vm.box`" using `config.vm.box`"
:chef_base_invalid_provisioner: "Vagrant::Provisioners::Chef is not a valid provisioner! Use ChefSolo or ChefServer instead."
:chef_server_url_required: "Chef server provisioning requires that the `config.chef.chef_server_url` be set to the
URL of your chef server. Examples include \"http://12.12.12.12:4000\" and
\"http://myserver.com:4000\" (the port of course can be different, but 4000 is the default)"
:chef_server_validation_key_required: "Chef server provisioning requires that the `config.chef.validation_key_path` configuration
be set to a path on your local machine of the validation key used to register the
VM with the chef server."
:chef_server_validation_key_doesnt_exist: "The validation key set for `config.chef.validation_key_path` does not exist! This
file needs to exist so it can be uploaded to the virtual machine. It is
currently set to \"<%= Vagrant.config.chef.validation_key_path %>\""
:command_box_invalid: "Please specify a valid action to take on the boxes, either :command_box_invalid: "Please specify a valid action to take on the boxes, either
`add` or `remove`. Examples: `add` or `remove`. Examples:
vagrant box add name uri vagrant box add name uri
vagrant box remove name vagrant box remove name
vagrant box list" vagrant box list"
:dotfile_error: "The dotfile which Vagrant uses to store the UUID of the project's
virtual machine already exists and is not a file! The dotfile is
currently configured to be `<%= Vagrant::Env.dotfile_path %>`
To change this value, please see `config.vagrant.dotfile_name`
This often exists if you're trying to create a Vagrant virtual
environment from your home directory. To resolve this, you can either
modify the configuration a bit, or simply use a different directory."
:downloader_file_doesnt_exist: "The given box does not exist on the file system:
<%= source_url %>"
:environment_not_created: "The task you're trying to run requires that the vagrant environment :environment_not_created: "The task you're trying to run requires that the vagrant environment
already be created, but unfortunately this vagrant still appears to already be created, but unfortunately this vagrant still appears to
have no box! You can setup the environment by setting up your have no box! You can setup the environment by setting up your
<%= Vagrant::Env::ROOTFILE_NAME %> and running `vagrant up`" <%= Vagrant::Env::ROOTFILE_NAME %> and running `vagrant up`"
:package_include_file_doesnt_exist: "File specified to include: '<%= filename %>' does not exist!"
:package_requires_export: "Package must be used in conjunction with export."
:provisioner_invalid_class: "Provisioners must be an instance of Vagrant::Provisioners::Base"
:provisioner_unknown_type: "Unknown provisioner type: <%= provisioner %>"
:rootfile_already_exists: "It looks like this directory is already setup for vagrant! (A <%= Vagrant::Env::ROOTFILE_NAME %> :rootfile_already_exists: "It looks like this directory is already setup for vagrant! (A <%= Vagrant::Env::ROOTFILE_NAME %>
already exists.)" already exists.)"
:rootfile_not_found: "A `<%= Vagrant::Env::ROOTFILE_NAME %>` was not found! This file is required for vagrant to run :rootfile_not_found: "A `<%= Vagrant::Env::ROOTFILE_NAME %>` was not found! This file is required for vagrant to run
since it describes the expected environment that vagrant is supposed since it describes the expected environment that vagrant is supposed
to manage. Please create a `<%= Vagrant::Env::ROOTFILE_NAME %>` and place it in your project to manage. Please create a `<%= Vagrant::Env::ROOTFILE_NAME %>` and place it in your project
root." root."
:virtualbox_import_failure: "The VM import failed! Try running `VBoxManage import` on the box file manually for more verbose error output."
:virtualbox_invalid_version: "Vagrant has detected that you have VirtualBox version <%= version %> installed! :virtualbox_invalid_version: "Vagrant has detected that you have VirtualBox version <%= version %> installed!
Vagrant requires that you use at least VirtualBox version 3.1. Please install Vagrant requires that you use at least VirtualBox version 3.1. Please install
a more recent version of VirtualBox to continue." a more recent version of VirtualBox to continue."
@ -52,8 +81,21 @@
VirtualBox::Global.vboxconfig = \"/path/to/VirtualBox.xml\"" VirtualBox::Global.vboxconfig = \"/path/to/VirtualBox.xml\""
:vm_failed_to_boot: "Failed to connect to VM! Failed to boot?" :vm_failed_to_boot: "Failed to connect to VM! Failed to boot?"
:vm_not_running: "VM is not running! Nothing to shut down!"
:vm_not_running_for_suspend: "The vagrant virtual environment you are trying to suspend must be running to be suspended."
:vm_not_suspended: "The vagrant virtual environment you are trying to resume is not in a suspended state."
:vm_port_collision: "Vagrant cannot forward the specified ports on this VM, since they
would collide with another VirtualBox virtual machine's forwarded
ports! The \"<%= name %>\" forwarded port (<%= hostport %>) is already in use on the host
machine.
To fix this, modify your current projects Vagrantfile to use another
port. Example, where '1234' would be replaced by a unique host port:
config.vm.forward_port(\"<%= name %>\", <%= guestport %>, 1234)"
:vm_power_off_to_move_hd: "The virtual machine must be powered off to move its disk." :vm_power_off_to_move_hd: "The virtual machine must be powered off to move its disk."
:vm_power_off_to_package: "The vagrant virtual environment you are trying to package must be powered off." :vm_power_off_to_package: "The vagrant virtual environment you are trying to package must be powered off."
:vm_mount_fail: "Failed to mount shared folders. vboxsf was not available."
:vm_ssh_auth_failed: "SSH authentication failed! While this could be due to a variety of reasons, :vm_ssh_auth_failed: "SSH authentication failed! While this could be due to a variety of reasons,
the two most common are: private key path is incorrect or you're using a box the two most common are: private key path is incorrect or you're using a box
which was built for Vagrant 0.1.x. which was built for Vagrant 0.1.x.

View File

@ -27,7 +27,7 @@ class AddBoxActionTest < Test::Unit::TestCase
should "result in an action exception if the box already exists" do should "result in an action exception if the box already exists" do
File.expects(:exists?).once.returns(true) File.expects(:exists?).once.returns(true)
@runner.expects(:name).twice.returns('foo') @runner.expects(:name).once.returns('foo')
@runner.expects(:add_action).never @runner.expects(:add_action).never
assert_raise Vagrant::Actions::ActionException do assert_raise Vagrant::Actions::ActionException do
@action.prepare @action.prepare

View File

@ -212,11 +212,10 @@ class ActionRunnerTest < Test::Unit::TestCase
end end
should "call error_and_exit if it is an ActionException" do should "call error_and_exit if it is an ActionException" do
msg = "Message" @exception = Vagrant::Actions::ActionException.new("foo")
@exception = Vagrant::Actions::ActionException.new(msg)
@actions[0].stubs(:prepare).raises(@exception) @actions[0].stubs(:prepare).raises(@exception)
@runner.expects(:error_and_exit).with(msg).once @runner.expects(:error_and_exit).with(@exception.message).once
@runner.execute! @runner.execute!
end end
end end
@ -243,7 +242,7 @@ class ActionRunnerTest < Test::Unit::TestCase
setup do setup do
@runner = Vagrant::Actions::Runner.new @runner = Vagrant::Actions::Runner.new
end end
should "should be raised when a duplicate is added" do should "should be raised when a duplicate is added" do
action = mock_fake_action action = mock_fake_action
2.times {@runner.actions << action } 2.times {@runner.actions << action }
@ -255,7 +254,7 @@ class ActionRunnerTest < Test::Unit::TestCase
should "should not be raise when no duplicate actions are present" do should "should not be raise when no duplicate actions are present" do
@runner.actions << mock_fake_action(Vagrant::Actions::Base, @runner) @runner.actions << mock_fake_action(Vagrant::Actions::Base, @runner)
@runner.actions << mock_fake_action(Vagrant::Actions::VM::Halt, @runner) @runner.actions << mock_fake_action(Vagrant::Actions::VM::Halt, @runner)
assert_nothing_raised { @runner.execute! } assert_nothing_raised { @runner.execute! }
end end

View File

@ -48,5 +48,10 @@ class ErrorsUtilTest < Test::Unit::TestCase
TemplateRenderer.expects(:render_string).returns(result) TemplateRenderer.expects(:render_string).returns(result)
assert_equal result, Errors.error_string(:foo) assert_equal result, Errors.error_string(:foo)
end end
should "return an unknown if the key doesn't exist" do
result = Errors.error_string(:unknown)
assert result =~ /Unknown/i
end
end end
end end