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
# 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
#
# def follows; [Reload] end
# 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]"
def follows; [] end
# 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]
def precedes; [] end
@ -102,6 +102,17 @@ module Vagrant
# {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
# 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

View File

@ -10,7 +10,7 @@ module Vagrant
class Add < Base
def prepare
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
@runner.add_action(Download)

View File

@ -25,7 +25,7 @@ module Vagrant
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
@downloader.prepare(@runner.uri)

View File

@ -9,17 +9,7 @@ module Vagrant
vm.forwarded_ports.each do |fp|
Vagrant.config.vm.forwarded_ports.each do |name, options|
if fp.hostport.to_s == options[:hostport].to_s
raise ActionException.new(<<-msg)
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
raise ActionException.new(:vm_port_collision, :name => name, :hostport => fp.hostport.to_s, :guestport => options[:guestport].to_s)
end
end
end

View File

@ -3,7 +3,7 @@ module Vagrant
module VM
class Halt < Base
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..."
@runner.vm.stop(true)

View File

@ -8,7 +8,7 @@ module Vagrant
logger.info "Importing base VM (#{Vagrant::Env.box.ovf_file})..."
# Use the first argument passed to the action
@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

View File

@ -16,12 +16,12 @@ module Vagrant
def prepare
# Verify the existance of all the additional files, if any
@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
# Get the export action and store a reference to it
@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
def execute!

View File

@ -20,7 +20,7 @@ module Vagrant
if provisioner.is_a?(Class)
@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)
# We have a few hard coded provisioners for built-ins
mapping = {
@ -29,7 +29,7 @@ module Vagrant
}
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
end

View File

@ -4,7 +4,7 @@ module Vagrant
class Resume < Base
def execute!
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
logger.info "Resuming suspended VM..."

View File

@ -71,7 +71,7 @@ module Vagrant
break unless result
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
end
end

View File

@ -4,7 +4,7 @@ module Vagrant
class Suspend < Base
def execute!
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
logger.info "Saving VM state and suspending execution..."

View File

@ -5,17 +5,7 @@ module Vagrant
def prepare
# If the dotfile is not a file, raise error
if File.exist?(Env.dotfile_path) && !File.file?(Env.dotfile_path)
raise ActionException.new(<<-msg)
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
raise ActionException.new(:dotfile_error)
end
# Up is a "meta-action" so it really just queues up a bunch

View File

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

View File

@ -66,7 +66,7 @@ module Vagrant
Config.configures :chef, ChefConfig
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
def chown_provisioning_folder

View File

@ -5,25 +5,13 @@ module Vagrant
class ChefServer < Chef
def prepare
if Vagrant.config.chef.validation_key_path.nil?
raise Actions::ActionException.new(<<-msg)
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
raise Actions::ActionException.new(:chef_server_validation_key_required)
elsif !File.file?(Vagrant.config.chef.validation_key_path)
raise Actions::ActionException.new(<<-msg)
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
raise Actions::ActionException.new(:chef_server_validation_key_doesnt_exist)
end
if Vagrant.config.chef.chef_server_url.nil?
raise Actions::ActionException.new(<<-msg)
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
raise Actions::ActionException.new(:chef_server_url_required)
end
end

View File

@ -27,7 +27,8 @@ module Vagrant
#
# @return [String]
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

View File

@ -1,5 +1,7 @@
:box_already_exists: "This box appears to already exist! Please call `vagrant box remove <%= box_name %>`
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_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
for every vagrant virtual machine. Please specify one in your Vagrantfile
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
`add` or `remove`. Examples:
vagrant box add name uri
vagrant box remove name
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
already be created, but unfortunately this vagrant still appears to
have no box! You can setup the environment by setting up your
<%= 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 %>
already exists.)"
: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
to manage. Please create a `<%= Vagrant::Env::ROOTFILE_NAME %>` and place it in your project
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!
Vagrant requires that you use at least VirtualBox version 3.1. Please install
a more recent version of VirtualBox to continue."
@ -52,8 +81,21 @@
VirtualBox::Global.vboxconfig = \"/path/to/VirtualBox.xml\""
: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_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,
the two most common are: private key path is incorrect or you're using a box
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
File.expects(:exists?).once.returns(true)
@runner.expects(:name).twice.returns('foo')
@runner.expects(:name).once.returns('foo')
@runner.expects(:add_action).never
assert_raise Vagrant::Actions::ActionException do
@action.prepare

View File

@ -212,11 +212,10 @@ class ActionRunnerTest < Test::Unit::TestCase
end
should "call error_and_exit if it is an ActionException" do
msg = "Message"
@exception = Vagrant::Actions::ActionException.new(msg)
@exception = Vagrant::Actions::ActionException.new("foo")
@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!
end
end
@ -243,7 +242,7 @@ class ActionRunnerTest < Test::Unit::TestCase
setup do
@runner = Vagrant::Actions::Runner.new
end
should "should be raised when a duplicate is added" do
action = mock_fake_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
@runner.actions << mock_fake_action(Vagrant::Actions::Base, @runner)
@runner.actions << mock_fake_action(Vagrant::Actions::VM::Halt, @runner)
assert_nothing_raised { @runner.execute! }
end

View File

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