lib/vagrant/driver/virtualbox_base.rb in vagrant-0.9.7 vs lib/vagrant/driver/virtualbox_base.rb in vagrant-1.0.0

- old
+ new

@@ -1,9 +1,10 @@ require 'log4r' require 'vagrant/util/busy' require 'vagrant/util/platform' +require 'vagrant/util/retryable' require 'vagrant/util/subprocess' module Vagrant module Driver # Base class for all VirtualBox drivers. @@ -11,10 +12,11 @@ # This class provides useful tools for things such as executing # VBoxManage and handling SIGINTs and so on. class VirtualBoxBase # Include this so we can use `Subprocess` more easily. include Vagrant::Util + include Vagrant::Util::Retryable def initialize @logger = Log4r::Logger.new("vagrant::driver::virtualbox_base") # This flag is used to keep track of interrupted state (SIGINT) @@ -230,10 +232,16 @@ # Suspend the virtual machine. def suspend end + # Verifies that the driver is ready to accept work. + # + # This should raise a VagrantError if things are not ready. + def verify! + end + # Verifies that an image can be imported properly. # # @param [String] path Path to an OVF file. # @return [Boolean] def verify_image(path) @@ -243,31 +251,41 @@ # # @return [Boolean] def vm_exists?(uuid) end - protected - # Execute the given subcommand for VBoxManage and return the output. def execute(*command, &block) - # Execute the command - r = raw(*command, &block) + # Get the options hash if it exists + opts = {} + opts = command.pop if command.last.is_a?(Hash) - # If the command was a failure, then raise an exception that is - # nicely handled by Vagrant. - if r.exit_code != 0 - if @interrupted - @logger.info("Exit code != 0, but interrupted. Ignoring.") + tries = 0 + tries = 3 if opts[:retryable] + + # Variable to store our execution result + r = nil + + retryable(:on => Errors::VBoxManageError, :tries => tries, :sleep => 1) do + # Execute the command + r = raw(*command, &block) + + # If the command was a failure, then raise an exception that is + # nicely handled by Vagrant. + if r.exit_code != 0 + if @interrupted + @logger.info("Exit code != 0, but interrupted. Ignoring.") + else + raise Errors::VBoxManageError, :command => command.inspect + end else - raise Errors::VBoxManageError, :command => command.inspect - end - else - # Sometimes, VBoxManage fails but doesn't actual return a non-zero - # exit code. For this we inspect the output and determine if an error - # occurred. - if r.stderr =~ /VBoxManage: error:/ - @logger.info("VBoxManage error text found, assuming error.") - raise Errors::VBoxManageError, :command => command.inspect + # Sometimes, VBoxManage fails but doesn't actual return a non-zero + # exit code. For this we inspect the output and determine if an error + # occurred. + if r.stderr =~ /VBoxManage: error:/ + @logger.info("VBoxManage error text found, assuming error.") + raise Errors::VBoxManageError, :command => command.inspect + end end end # Return the output, making sure to replace any Windows-style # newlines with Unix-style.