class Vagrant::Action::Builtin::HandleBox

This built-in middleware handles the ‘box` setting by verifying the box is already installed, downloading the box if it isn’t, updating the box if it is requested, etc.

Public Class Methods

new(app, env) click to toggle source
# File lib/vagrant/action/builtin/handle_box.rb, line 15
def initialize(app, env)
  @app = app
  @logger = Log4r::Logger.new("vagrant::action::builtin::handle_box")
end

Public Instance Methods

call(env) click to toggle source
# File lib/vagrant/action/builtin/handle_box.rb, line 20
def call(env)
  machine = env[:machine]

  if !machine.config.vm.box || machine.config.vm.box.to_s.empty?
    @logger.info("Skipping HandleBox because no box is set")
    return @app.call(env)
  end

  # Acquire a lock for this box to handle multi-threaded
  # environments.
  lock = nil
  @@big_lock.synchronize do
    lock = @@small_locks[machine.config.vm.box]
  end

  box_updated = false
  lock.synchronize do
    if machine.box
      @logger.info("Machine already has box. HandleBox will not run.")
      next
    end

    handle_box(env)
    box_updated = true
  end

  if box_updated
    # Reload the environment and set the VM to be the new loaded VM.
    new_machine = machine.vagrantfile.machine(
      machine.name, machine.provider_name,
      machine.env.boxes, machine.data_dir, machine.env)
    env[:machine].box = new_machine.box
    env[:machine].config = new_machine.config
    env[:machine].provider_config = new_machine.provider_config
  end

  @app.call(env)
end
handle_box(env) click to toggle source
# File lib/vagrant/action/builtin/handle_box.rb, line 59
def handle_box(env)
  machine = env[:machine]

  # Determine the set of formats that this box can be in
  box_download_ca_cert = machine.config.vm.box_download_ca_cert
  box_download_ca_path = machine.config.vm.box_download_ca_path
  box_download_client_cert = machine.config.vm.box_download_client_cert
  box_download_insecure = machine.config.vm.box_download_insecure
  box_download_checksum_type = machine.config.vm.box_download_checksum_type
  box_download_checksum = machine.config.vm.box_download_checksum
  box_download_location_trusted = machine.config.vm.box_download_location_trusted
  box_extra_download_options = machine.config.vm.box_extra_download_options
  box_formats = machine.provider_options[:box_format] ||
    machine.provider_name

  version_ui = machine.config.vm.box_version
  version_ui ||= ">= 0"

  env[:ui].output(I18n.t(
    "vagrant.box_auto_adding", name: machine.config.vm.box))
  env[:ui].detail("Box Provider: #{Array(box_formats).join(", ")}")
  env[:ui].detail("Box Version: #{version_ui}")

  begin
    env[:action_runner].run(Vagrant::Action.action_box_add, env.merge({
      box_name: machine.config.vm.box,
      box_url: machine.config.vm.box_url || machine.config.vm.box,
      box_server_url: machine.config.vm.box_server_url,
      box_provider: box_formats,
      box_version: machine.config.vm.box_version,
      box_download_client_cert: box_download_client_cert,
      box_download_ca_cert: box_download_ca_cert,
      box_download_ca_path: box_download_ca_path,
      box_download_insecure: box_download_insecure,
      box_checksum_type: box_download_checksum_type,
      box_checksum: box_download_checksum,
      box_download_location_trusted: box_download_location_trusted,
      box_extra_download_options: box_extra_download_options,
    }))
  rescue Errors::BoxAlreadyExists
    # Just ignore this, since it means the next part will succeed!
    # This can happen in a multi-threaded environment.
  end
end