From c2151681ecdc6421648823e153fd60e5afb6b597 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Sat, 30 Jun 2012 16:29:08 -0700 Subject: [PATCH] Box collection can add a new box. This is the happy path only. --- lib/vagrant/box_collection2.rb | 31 ++++++++++++ test/unit/support/isolated_environment.rb | 59 +++++++++++++++++++++++ test/unit/vagrant/box_collection2_test.rb | 16 ++++++ 3 files changed, 106 insertions(+) diff --git a/lib/vagrant/box_collection2.rb b/lib/vagrant/box_collection2.rb index 06ee2e8b6..77fbd0f60 100644 --- a/lib/vagrant/box_collection2.rb +++ b/lib/vagrant/box_collection2.rb @@ -1,5 +1,6 @@ require "digest/sha1" +require "archive/tar/minitar" require "log4r" module Vagrant @@ -19,6 +20,36 @@ module Vagrant @logger = Log4r::Logger.new("vagrant::box_collection") end + # This adds a new box to the system. + # + # There are some exceptional cases: + # + # Preconditions: + # * File given in `path` must exist. + # + # @param [Pathname] path Path to the box file on disk. + # @param [String] name Logical name for the box. + # @param [Symbol] provider The provider that the box should be for. This + # will be verified with the `metadata.json` file in the box and is + # meant as a basic check. + def add(path, name, provider) + box_dir = @directory.join(name, provider.to_s) + @logger.debug("Adding box: #{path}") + @logger.debug("Box directory: #{box_dir}") + + # Create the directory that'll store our box + box_dir.mkpath + + # Change directory to the box directory and unpackage the tar + Dir.chdir(box_dir) do + @logger.debug("Unpacking box file into box directory...") + Archive::Tar::Minitar.unpack(path.to_s, box_dir.to_s) + end + + # Return the box + find(name, provider) + end + # This returns an array of all the boxes on the system, given by # their name and their provider. # diff --git a/test/unit/support/isolated_environment.rb b/test/unit/support/isolated_environment.rb index b5b56d369..84d752c0a 100644 --- a/test/unit/support/isolated_environment.rb +++ b/test/unit/support/isolated_environment.rb @@ -1,9 +1,14 @@ require "fileutils" require "pathname" +require "tempfile" +require "archive/tar/minitar" require "log4r" +require "vagrant/util/platform" + require "support/isolated_environment" +require "support/tempdir" module Unit class IsolatedEnvironment < ::IsolatedEnvironment @@ -70,6 +75,60 @@ module Unit box_dir end + # This creates a "box" file with the given name and provider. + # + # @param [String] name Name of the box. + # @param [Symbol] provider Provider for the box. + # @return [Pathname] Path to the newly created box. + def box2_file(name, provider) + # This is the metadata we want to store in our file + metadata = { + "type" => "v2_box", + "provider" => provider + } + + # Create a temporary directory to store our data we will tar up + td_source = Tempdir.new + td_dest = Tempdir.new + + # Store the temporary directory so it is not deleted until + # this instance is garbage collected. + @_box2_file_temp ||= [] + @_box2_file_temp << td_dest + + # The source as a Pathname, which is easier to work with + source = Pathname.new(td_source.path) + + # The destination file + result = Pathname.new(td_dest.path).join("temporary.box") + + File.open(result, Vagrant::Util::Platform.tar_file_options) do |tar| + Archive::Tar::Minitar::Output.open(tar) do |output| + begin + # Switch to the source directory so that Archive::Tar::Minitar + # can tar things up. + current_dir = FileUtils.pwd + FileUtils.cd(source) + + # Put the metadata.json in here. + source.join("metadata.json").open("w") do |f| + f.write(JSON.generate(metadata)) + end + + # Add all the files + Dir.glob(File.join(".", "**", "*")).each do |entry| + Archive::Tar::Minitar.pack_file(entry, output) + end + ensure + FileUtils.cd(current_dir) + end + end + end + + # Resulting box + result + end + def boxes_dir dir = @homedir.join("boxes") dir.mkpath diff --git a/test/unit/vagrant/box_collection2_test.rb b/test/unit/vagrant/box_collection2_test.rb index d412354fb..52abf797d 100644 --- a/test/unit/vagrant/box_collection2_test.rb +++ b/test/unit/vagrant/box_collection2_test.rb @@ -9,6 +9,22 @@ describe Vagrant::BoxCollection2 do let(:environment) { isolated_environment } let(:instance) { described_class.new(environment.boxes_dir) } + describe "adding" do + it "should add a valid box to the system" do + box_path = environment.box2_file("foo", :virtualbox) + + # Add the box + box = instance.add(box_path, "foo", :virtualbox) + box.should be_kind_of(box_class) + box.name.should == "foo" + box.provider.should == :virtualbox + + # Verify we can find it as well + box = instance.find("foo", :virtualbox) + box.should_not be_nil + end + end + describe "listing all" do it "should return an empty array when no boxes are there" do instance.all.should == []