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 "json"
require "log4r"
require "vagrant/util/platform"
module Vagrant module Vagrant
# Represents a "box," which is a package Vagrant environment that is used # Represents a "box," which is a package Vagrant environment that is used
@ -38,6 +44,8 @@ module Vagrant
@provider = provider @provider = provider
@directory = directory @directory = directory
@metadata = JSON.parse(directory.join("metadata.json").read) @metadata = JSON.parse(directory.join("metadata.json").read)
@logger = Log4r::Logger.new("vagrant::box")
end end
# This deletes the box. This is NOT undoable. # This deletes the box. This is NOT undoable.
@ -52,6 +60,41 @@ module Vagrant
return true return true
end 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 for comparison with other boxes. Comparison is
# implemented by comparing names and providers. # implemented by comparing names and providers.
def <=>(other) def <=>(other)

View File

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

View File

@ -7,6 +7,8 @@ describe Vagrant::Box do
let(:environment) { isolated_environment } let(:environment) { isolated_environment }
let(:box_collection) { Vagrant::BoxCollection.new(environment.boxes_dir) }
let(:name) { "foo" } let(:name) { "foo" }
let(:provider) { :virtualbox } let(:provider) { :virtualbox }
let(:directory) { environment.box2("foo", :virtualbox) } let(:directory) { environment.box2("foo", :virtualbox) }
@ -60,6 +62,27 @@ describe Vagrant::Box do
end end
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 describe "comparison and ordering" do
it "should be equal if the name and provider match" do it "should be equal if the name and provider match" do
a = described_class.new("a", :foo, directory) a = described_class.new("a", :foo, directory)