Refactor box collection to support looking for boxes multi-provider

This commit is contained in:
Mitchell Hashimoto 2013-07-18 22:28:18 -04:00
parent cf0e302e34
commit f3bbad8c2e
2 changed files with 41 additions and 60 deletions

View File

@ -220,39 +220,43 @@ module Vagrant
# Find a box in the collection with the given name and provider. # Find a box in the collection with the given name and provider.
# #
# @param [String] name Name of the box (logical name). # @param [String] name Name of the box (logical name).
# @Param [String] provider Provider that the box implements. # @param [String] provider Provider that the box implements.
# @return [Box] The box found, or `nil` if not found. # @return [Box] The box found, or `nil` if not found.
def find(name, provider) def find(name, providers)
with_collection_lock do providers = [providers].flatten
# First look directly for the box we're asking for.
box_directory = @directory.join(name, provider.to_s, "metadata.json")
@logger.info("Searching for box: #{name} (#{provider}) in #{box_directory}")
if box_directory.file?
@logger.info("Box found: #{name} (#{provider})")
return Box.new(name, provider, box_directory.dirname)
end
# If we're looking for a VirtualBox box, then we check if there is with_collection_lock do
# a V1 box. providers.each do |provider|
if provider.to_sym == :virtualbox # First look directly for the box we're asking for.
# Check if a V1 version of this box exists, and if so, raise an box_directory = @directory.join(name, provider.to_s, "metadata.json")
# exception notifying the caller that the box exists but needs @logger.info("Searching for box: #{name} (#{provider}) in #{box_directory}")
# to be upgraded. We don't do the upgrade here because it can be if box_directory.file?
# a fairly intensive activity and don't want to immediately degrade @logger.info("Box found: #{name} (#{provider})")
# user performance on a find. return Box.new(name, provider, box_directory.dirname)
# end
# To determine if it is a V1 box we just do a simple heuristic
# based approach. # If we're looking for a VirtualBox box, then we check if there is
@logger.info("Searching for V1 box: #{name}") # a V1 box.
if v1_box?(@directory.join(name)) if provider.to_sym == :virtualbox
@logger.warn("V1 box found: #{name}") # Check if a V1 version of this box exists, and if so, raise an
raise Errors::BoxUpgradeRequired, :name => name # exception notifying the caller that the box exists but needs
# to be upgraded. We don't do the upgrade here because it can be
# a fairly intensive activity and don't want to immediately degrade
# user performance on a find.
#
# To determine if it is a V1 box we just do a simple heuristic
# based approach.
@logger.info("Searching for V1 box: #{name}")
if v1_box?(@directory.join(name))
@logger.warn("V1 box found: #{name}")
raise Errors::BoxUpgradeRequired, :name => name
end
end end
end end
end end
# Didn't find it, return nil # Didn't find it, return nil
@logger.info("Box not found: #{name} (#{provider})") @logger.info("Box not found: #{name} (#{providers.join(", ")})")
nil nil
end end

View File

@ -339,7 +339,17 @@ module Vagrant
box_changed = false box_changed = false
load_box_and_overrides = lambda do load_box_and_overrides = lambda do
box = find_box(config.vm.box, box_formats) if config.vm.box box = nil
if config.vm.box
begin
box = boxes.find(config.vm.box, box_formats)
rescue Errors::BoxUpgradeRequired
# Upgrade the box if we must
@logger.info("Upgrading box during config load: #{config.vm.box}")
boxes.upgrade(config.vm.box)
retry
end
end
# If a box was found, then we attempt to load the Vagrantfile for # If a box was found, then we attempt to load the Vagrantfile for
# that box. We don't require a box since we allow providers to download # that box. We don't require a box since we allow providers to download
@ -694,39 +704,6 @@ module Vagrant
Pathname.new(path) Pathname.new(path)
end end
# This finds a box for the given name and formats, or returns nil
# if the box isn't found.
#
# @param [String] name Name of the box
# @param [Array<Symbol>] formats The formats to search for the box.
# @return [Box]
def find_box(name, formats)
# Determine the box formats we support
formats = [formats] if !formats.is_a?(Array)
@logger.info("Provider-supported box formats: #{formats.inspect}")
formats.each do |format|
box = nil
begin
box = boxes.find(name, format.to_s)
rescue Errors::BoxUpgradeRequired
# Upgrade the box if we must
@logger.info("Upgrading box during config load: #{name}")
boxes.upgrade(name)
retry
end
# If a box was found, we exit
if box
@logger.info("Box found with format: #{format}")
return box
end
end
nil
end
# Finds the Vagrantfile in the given directory. # Finds the Vagrantfile in the given directory.
# #
# @param [Pathname] path Path to search in. # @param [Pathname] path Path to search in.