Box#repackage to repackage a box.

This commit is contained in:
Mitchell Hashimoto 2012-07-10 22:16:43 -07:00
parent 798ffc93bd
commit cc076e5ee5
3 changed files with 70 additions and 1 deletions

View File

@ -1,4 +1,10 @@
require 'fileutils'
require 'archive/tar/minitar'
require "json"
require "log4r"
require "vagrant/util/platform"
module Vagrant
# Represents a "box," which is a package Vagrant environment that is used
@ -38,6 +44,8 @@ module Vagrant
@provider = provider
@directory = directory
@metadata = JSON.parse(directory.join("metadata.json").read)
@logger = Log4r::Logger.new("vagrant::box")
end
# This deletes the box. This is NOT undoable.
@ -52,6 +60,41 @@ module Vagrant
return true
end
# This repackages this box and outputs it to the given path.
#
# @param [Pathname] path The full path (filename included) of where
# to output this box.
# @return [Boolean] true if this succeeds.
def repackage(path)
@logger.debug("Repackaging box '#{@name}' to: #{path}")
path.open(Util::Platform.tar_file_options) do |f|
Archive::Tar::Minitar::Output.open(f) do |output|
# Store the current working directory since we need to change
# for the tar library.
current_dir = FileUtils.pwd
begin
FileUtils.cd(@directory)
# Find all the files in our current directory and tar it up!
Dir.glob(File.join(".", "**", "*")).each do |entry|
@logger.debug("Packing file: #{entry}")
Archive::Tar::Minitar.pack_file(entry, output)
end
ensure
# Make sure we always cd back into our previous working
# directory.
FileUtils.cd(current_dir)
end
end
end
@logger.info("Repackaged box '#{@name}' successfully: #{path}")
true
end
# Implemented for comparison with other boxes. Comparison is
# implemented by comparing names and providers.
def <=>(other)

View File

@ -3,6 +3,7 @@ require "pathname"
require "tempfile"
require "archive/tar/minitar"
require "json"
require "log4r"
require "vagrant/util/platform"
@ -73,7 +74,9 @@ module Unit
# Create a metadata.json file
box_metadata_file = box_dir.join("metadata.json")
box_metadata_file.open("w") do |f|
f.write("{}")
f.write(JSON.generate({
:provider => provider.to_s
}))
end
# Create a Vagrantfile

View File

@ -7,6 +7,8 @@ describe Vagrant::Box do
let(:environment) { isolated_environment }
let(:box_collection) { Vagrant::BoxCollection.new(environment.boxes_dir) }
let(:name) { "foo" }
let(:provider) { :virtualbox }
let(:directory) { environment.box2("foo", :virtualbox) }
@ -60,6 +62,27 @@ describe Vagrant::Box do
end
end
describe "repackaging" do
it "should repackage the box" do
test_file_contents = "hello, world!"
# Put a file in the box directory to verify it is packaged properly
# later.
directory.join("test_file").open("w") do |f|
f.write(test_file_contents)
end
# Repackage our box to some temporary directory
box_output_path = temporary_dir.join("package.box")
instance.repackage(box_output_path).should be
# Let's now add this box again under a different name, and then
# verify that we get the proper result back.
new_box = box_collection.add(box_output_path, "foo2")
new_box.directory.join("test_file").read.should == test_file_contents
end
end
describe "comparison and ordering" do
it "should be equal if the name and provider match" do
a = described_class.new("a", :foo, directory)