Skip to content

Commit

Permalink
Merge pull request #13239 from chrisroberts/architecture-aware
Browse files Browse the repository at this point in the history
Add architecture support
  • Loading branch information
chrisroberts authored Sep 27, 2023
2 parents 2809ef9 + 74b4a2b commit d5f12fd
Show file tree
Hide file tree
Showing 53 changed files with 2,762 additions and 528 deletions.
2 changes: 2 additions & 0 deletions lib/vagrant.rb
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,8 @@ def << msg
rescue => err
global_logger.warn("unexpected failure loading ssl providers, attempting to continue (#{err})")
end
else
global_logger.warn("vagrant ssl helper was not found, continuing...")
end

# We need these components always so instead of an autoload we
Expand Down
92 changes: 75 additions & 17 deletions lib/vagrant/action/builtin/box_add.rb
Original file line number Diff line number Diff line change
Expand Up @@ -68,17 +68,29 @@ def call(env)
# If we received a shorthand URL ("mitchellh/precise64"),
# then expand it properly.
expanded = false
url.each_index do |i|
next if url[i] !~ /^[^\/]+\/[^\/]+$/
# Mark if only a single url entry was provided
single_entry = url.size == 1

if !File.file?(url[i])
url = url.map do |url_entry|
if url_entry =~ /^[^\/]+\/[^\/]+$/ && !File.file?(url_entry)
server = Vagrant.server_url env[:box_server_url]
raise Errors::BoxServerNotSet if !server

expanded = true
url[i] = "#{server}/#{url[i]}"
# If only a single entry, expand to both the API endpoint and
# the direct shorthand endpoint.
if single_entry
url_entry = [
"#{server}/api/v2/vagrant/#{url_entry}",
"#{server}/#{url_entry}"
]
else
url_entry = "#{server}/#{url_entry}"
end
end
end

url_entry
end.flatten

# Call the hook to transform URLs into authenticated URLs.
# In the case we don't have a plugin that does this, then it
Expand All @@ -99,6 +111,21 @@ def call(env)
end
end

# If only a single entry was provided, and it was expanded,
# inspect the metadata check results and extract the one that
# was successful, with preference to the API endpoint
if single_entry && expanded
idx = is_metadata_results.index { |v| v === true }
# If none of the urls were successful, set the index
# as the last entry
idx = is_metadata_results.size - 1 if idx.nil?

# Now reset collections with single value
is_metadata_results = [is_metadata_results[idx]]
authed_urls = [authed_urls[idx]]
url = [url[idx]]
end

if expanded && url.length == 1
is_error = is_metadata_results.find do |b|
b.is_a?(Errors::DownloaderError)
Expand Down Expand Up @@ -165,6 +192,7 @@ def add_direct(urls, env)
env,
checksum: env[:box_checksum],
checksum_type: env[:box_checksum_type],
architecture: env[:architecture]
)
end

Expand All @@ -179,6 +207,9 @@ def add_direct(urls, env)
# a Atlas server URL.
def add_from_metadata(url, env, expanded)
original_url = env[:box_url]
architecture = env[:box_architecture]
display_architecture = architecture == :auto ?
Util::Platform.architecture : architecture
provider = env[:box_provider]
provider = Array(provider) if provider
version = env[:box_version]
Expand Down Expand Up @@ -228,12 +259,17 @@ def add_from_metadata(url, env, expanded)
end

metadata_version = metadata.version(
version || ">= 0", provider: provider)
version || ">= 0",
provider: provider,
architecture: architecture,
)
if !metadata_version
if provider && !metadata.version(">= 0", provider: provider)
if provider && !metadata.version(">= 0", provider: provider, architecture: architecture)
raise Errors::BoxAddNoMatchingProvider,
name: metadata.name,
requested: provider,
requested: [provider,
display_architecture ? "(#{display_architecture})" : nil
].compact.join(" "),
url: display_url
else
raise Errors::BoxAddNoMatchingVersion,
Expand All @@ -249,16 +285,16 @@ def add_from_metadata(url, env, expanded)
# If a provider was specified, make sure we get that specific
# version.
provider.each do |p|
metadata_provider = metadata_version.provider(p)
metadata_provider = metadata_version.provider(p, architecture)
break if metadata_provider
end
elsif metadata_version.providers.length == 1
elsif metadata_version.providers(architecture).length == 1
# If we have only one provider in the metadata, just use that
# provider.
metadata_provider = metadata_version.provider(
metadata_version.providers.first)
metadata_version.providers.first, architecture)
else
providers = metadata_version.providers.sort
providers = metadata_version.providers(architecture).sort

choice = 0
options = providers.map do |p|
Expand All @@ -279,7 +315,7 @@ def add_from_metadata(url, env, expanded)
end

metadata_provider = metadata_version.provider(
providers[choice-1])
providers[choice-1], architecture)
end

provider_url = metadata_provider.url
Expand All @@ -293,6 +329,17 @@ def add_from_metadata(url, env, expanded)
provider_url = authed_urls[0]
end

# The architecture name used when adding the box should be
# the value extracted from the metadata provider
arch_name = metadata_provider.architecture

# In the special case where the architecture name is "unknown" and
# it is listed as the default architecture, unset the architecture
# name so it is installed without architecture information
if arch_name == "unknown" && metadata_provider.default_architecture
arch_name = nil
end

box_add(
[[provider_url, metadata_provider.url]],
metadata.name,
Expand All @@ -302,6 +349,7 @@ def add_from_metadata(url, env, expanded)
env,
checksum: metadata_provider.checksum,
checksum_type: metadata_provider.checksum_type,
architecture: arch_name,
)
end

Expand All @@ -317,16 +365,21 @@ def add_from_metadata(url, env, expanded)
# @param [Hash] env
# @return [Box]
def box_add(urls, name, version, provider, md_url, env, **opts)
display_architecture = opts[:architecture] == :auto ?
Util::Platform.architecture : opts[:architecture]
env[:ui].output(I18n.t(
"vagrant.box_add_with_version",
name: name,
version: version,
providers: Array(provider).join(", ")))
providers: [
provider,
display_architecture ? "(#{display_architecture})" : nil
].compact.join(" ")))

# Verify the box we're adding doesn't already exist
if provider && !env[:box_force]
box = env[:box_collection].find(
name, provider, version)
name, provider, version, opts[:architecture])
if box
raise Errors::BoxAlreadyExists,
name: name,
Expand Down Expand Up @@ -377,7 +430,9 @@ def box_add(urls, name, version, provider, md_url, env, **opts)
box_url, name, version,
force: env[:box_force],
metadata_url: md_url,
providers: provider)
providers: provider,
architecture: opts[:architecture]
)
ensure
# Make sure we delete the temporary file after we add it,
# unless we were interrupted, in which case we keep it around
Expand All @@ -396,7 +451,10 @@ def box_add(urls, name, version, provider, md_url, env, **opts)
"vagrant.box_added",
name: box.name,
version: box.version,
provider: box.provider))
provider: [
provider,
display_architecture ? "(#{display_architecture})" : nil
].compact.join(" ")))

# Store the added box in the env for future middleware
env[:box_added] = box
Expand Down
Loading

0 comments on commit d5f12fd

Please sign in to comment.