Chris Roberts 51adb12547 Add architecture support for boxes
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.
2023-09-14 16:15:03 -07:00

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