Introduce support for handling box architecture. Adds a new `box_architecture` setting that defaults to `:auto` which will perform automatic detection of the host system, but can be overridden with a custom value. Can also be set to `nil` which will result in it fetching the box flagged with the default architecture within the metadata. Box collection has been modified to allow existing boxes already downloaded and unpacked to still function as expected when architecture information is not available.
113 lines
4.3 KiB
Ruby
113 lines
4.3 KiB
Ruby
# Copyright (c) HashiCorp, Inc.
|
|
# SPDX-License-Identifier: BUSL-1.1
|
|
|
|
require "thread"
|
|
|
|
require "log4r"
|
|
|
|
module Vagrant
|
|
module Action
|
|
module Builtin
|
|
# 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.
|
|
class HandleBox
|
|
@@big_lock = Mutex.new
|
|
@@small_locks = Hash.new { |h,k| h[k] = Mutex.new }
|
|
|
|
def initialize(app, env)
|
|
@app = app
|
|
@logger = Log4r::Logger.new("vagrant::action::builtin::handle_box")
|
|
end
|
|
|
|
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
|
|
|
|
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_download_disable_ssl_revoke_best_effort = machine.config.vm.box_download_disable_ssl_revoke_best_effort
|
|
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_architecture: machine.config.vm.box_architecture,
|
|
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_download_disable_ssl_revoke_best_effort: box_download_disable_ssl_revoke_best_effort,
|
|
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
|
|
end
|
|
end
|
|
end
|
|
end
|