BoxCollection#all returns all boxes, including V1 boxes

This commit is contained in:
Mitchell Hashimoto 2012-06-27 22:21:27 -07:00
parent 9d1924811e
commit 4386ff9887
3 changed files with 102 additions and 2 deletions

View File

@ -1,3 +1,5 @@
require "log4r"
module Vagrant module Vagrant
# Represents a collection a boxes found on disk. This provides methods # Represents a collection a boxes found on disk. This provides methods
# for accessing/finding individual boxes, adding new boxes, or deleting # for accessing/finding individual boxes, adding new boxes, or deleting
@ -12,6 +14,46 @@ module Vagrant
# of boxes. # of boxes.
def initialize(directory) def initialize(directory)
@directory = directory @directory = directory
@logger = Log4r::Logger.new("vagrant::box_collection")
end
# This returns an array of all the boxes on the system, given by
# their name and their provider.
#
# @return [Array] Array of `[name, provider]` pairs of the boxes
# installed on this system. An optional third element in the array
# may specify `:v1` if the box is a version 1 box.
def all
results = []
@logger.debug("Finding all boxes in: #{@directory}")
@directory.children(true).each do |child|
box_name = child.basename.to_s
# If this is a V1 box, we still return that name, but specify
# that the box is a V1 box.
if v1_box?(child)
@logger.debug("V1 box found: #{box_name}")
results << [box_name, :virtualbox, :v1]
next
end
# Otherwise, traverse the subdirectories and see what providers
# we have.
child.children(true).each do |provider|
# Verify this is a potentially valid box. If it looks
# correct enough then include it.
if provider.directory? && provider.join("metadata.json").file?
provider_name = provider.basename.to_s.to_sym
@logger.debug("Box: #{box_name} (#{provider_name})")
results << [box_name, provider_name]
else
@logger.debug("Invalid box, ignoring: #{provider}")
end
end
end
results
end end
# Find a box in the collection with the given name and provider. # Find a box in the collection with the given name and provider.
@ -22,7 +64,11 @@ module Vagrant
def find(name, provider) def find(name, provider)
# First look directly for the box we're asking for. # First look directly for the box we're asking for.
box_directory = @directory.join(name, provider.to_s, "metadata.json") box_directory = @directory.join(name, provider.to_s, "metadata.json")
return Box2.new(name, provider, box_directory.dirname) if box_directory.file? @logger.info("Searching for box: #{name} (#{provider}) in #{box_directory}")
if box_directory.file?
@logger.debug("Box found: #{name} (#{provider})")
return Box2.new(name, provider, box_directory.dirname)
end
# Check if a V1 version of this box exists, and if so, raise an # Check if a V1 version of this box exists, and if so, raise an
# exception notifying the caller that the box exists but needs # exception notifying the caller that the box exists but needs
@ -32,12 +78,26 @@ module Vagrant
# #
# To determine if it is a V1 box we just do a simple heuristic # To determine if it is a V1 box we just do a simple heuristic
# based approach. # based approach.
if @directory.join(name, "box.ovf").file? @logger.info("Searching for V1 box: #{name}")
if v1_box?(name)
@logger.warn("V1 box found: #{name}")
raise Errors::BoxUpgradeRequired, :name => name raise Errors::BoxUpgradeRequired, :name => name
end end
# Didn't find it, return nil # Didn't find it, return nil
@logger.info("Box not found: #{name} (#{provider})")
nil nil
end end
protected
# This checks if the given name represents a V1 box on the system.
#
# @return [Boolean]
def v1_box?(name)
# We detect a V1 box given by whether there is a "box.ovf" which
# is a heuristic but is pretty accurate.
@directory.join(name, "box.ovf").file?
end
end end
end end

View File

@ -32,12 +32,24 @@ module Unit
end end
def box(name, vagrantfile_contents="") def box(name, vagrantfile_contents="")
# Create the box directory
box_dir = boxes_dir.join(name) box_dir = boxes_dir.join(name)
box_dir.mkpath box_dir.mkpath
# Create the "box.ovf" file because that is how Vagrant heuristically
# determines a box is a V1 box.
box_dir.join("box.ovf").open("w") { |f| f.write("") }
# Populate the vagrantfile
vagrantfile(vagrantfile_contents, box_dir) vagrantfile(vagrantfile_contents, box_dir)
# Return the directory
box_dir box_dir
end end
# Create an alias because "box" makes a V1 box, so "box1"
alias :box1 :box
# Creates a fake box to exist in this environment. # Creates a fake box to exist in this environment.
# #
# @param [String] name Name of the box # @param [String] name Name of the box

View File

@ -9,6 +9,34 @@ describe Vagrant::BoxCollection2 do
let(:environment) { isolated_environment } let(:environment) { isolated_environment }
let(:instance) { described_class.new(environment.boxes_dir) } let(:instance) { described_class.new(environment.boxes_dir) }
describe "listing all" do
it "should return an empty array when no boxes are there" do
instance.all.should == []
end
it "should return the boxes and their providers" do
# Create some boxes
environment.box2("foo", :virtualbox)
environment.box2("foo", :vmware)
environment.box2("bar", :ec2)
# Verify some output
results = instance.all.sort
results.length.should == 3
results.should == [["foo", :virtualbox], ["foo", :vmware], ["bar", :ec2]].sort
end
it "should return V1 boxes as well" do
# Create some boxes, including a V1 box
environment.box1("bar")
environment.box2("foo", :vmware)
# Verify some output
results = instance.all.sort
results.should == [["bar", :virtualbox, :v1], ["foo", :vmware]]
end
end
describe "finding" do describe "finding" do
it "should return nil if the box does not exist" do it "should return nil if the box does not exist" do
instance.find("foo", :i_dont_exist).should be_nil instance.find("foo", :i_dont_exist).should be_nil