Reworked `vagrant package` to use the new tmp directory.

This commit is contained in:
Mitchell Hashimoto 2010-02-24 00:30:58 -08:00
parent 2ee850011b
commit 26f9eca141
9 changed files with 143 additions and 64 deletions

View File

@ -18,7 +18,7 @@ GitStyleBinary.command do
banner <<-EOS
Usage: #{command.full_name} #{all_options_string}
Package the current vagrant environment
Package the current vagrant environment into a box.
EOS
run do |command|

View File

@ -2,13 +2,28 @@ module Vagrant
module Actions
module VM
class Export < Base
def execute!(name=Vagrant.config.package.name, to=FileUtils.pwd)
folder = FileUtils.mkpath(File.join(to, name))
attr_reader :temp_dir
logger.info "Creating export directory: #{folder} ..."
ovf_path = File.join(folder, "#{name}.ovf")
def execute!
setup_temp_dir
export
end
logger.info "Exporting required VM files to directory: #{folder} ..."
def setup_temp_dir
@temp_dir = File.join(Env.tmp_path, Time.now.to_i.to_s)
logger.info "Creating temporary directory for export..."
FileUtils.mkpath(temp_dir)
@runner.invoke_callback(:set_export_temp_path, @temp_dir)
end
def ovf_path
File.join(temp_dir, Vagrant.config.vm.box_ovf)
end
def export
logger.info "Exporting VM to #{ovf_path} ..."
@runner.export(ovf_path)
end
end

View File

@ -2,48 +2,47 @@ module Vagrant
module Actions
module VM
class Package < Base
attr_accessor :name, :to
attr_accessor :out_path
attr_accessor :temp_path
def initialize(vm, *args)
super vm
@name = args[0]
@to = args[1]
def initialize(vm, out_path = nil, *args)
super
@out_path = out_path || "package"
@temp_path = nil
end
def execute!
logger.info "Packaging VM into #{tar_path} ..."
compress
logger.info "Removing working directory ..."
clean
tar_path
end
def clean
FileUtils.rm_r(working_dir)
end
def working_dir
FileUtils.mkpath(File.join(@to, @name))
logger.info "Removing temporary directory ..."
FileUtils.rm_r(temp_path)
end
def tar_path
"#{working_dir}#{Vagrant.config.package.extension}"
File.join(FileUtils.pwd, "#{out_path}#{Vagrant.config.package.extension}")
end
def compress
logger.info "Packaging VM into #{tar_path} ..."
Tar.open(tar_path, File::CREAT | File::WRONLY, 0644, Tar::GNU) do |tar|
begin
# Append tree will append the entire directory tree unless a relative folder reference is used
current_dir = FileUtils.pwd
FileUtils.cd(@to)
tar.append_tree(@name)
FileUtils.cd(temp_path)
tar.append_tree(".")
ensure
FileUtils.cd(current_dir)
end
end
end
# This is a callback by Actions::VM::Export
def set_export_temp_path(temp_path)
@temp_path = temp_path
end
end
end
end

View File

@ -113,17 +113,14 @@ error
# Export and package the current vm
#
# This command requires that an instance be powered off
def package(name=nil)
def package(out_path=nil)
Env.load!
Env.require_persisted_vm
error_and_exit(<<-error) unless Env.persisted_vm.powered_off?
The vagrant virtual environment you are trying to package must be powered off
error
# TODO allow directory specification
act_on_vm do |vm|
vm.add_action(Actions::VM::Export)
vm.add_action(Actions::VM::Package, name || Vagrant.config[:package][:name], FileUtils.pwd)
end
Env.persisted_vm.package(out_path)
end
# Manages the `vagrant box` command, allowing the user to add

View File

@ -19,6 +19,12 @@ module Vagrant
@vm = vm
end
def package(out_path)
add_action(Actions::VM::Export)
add_action(Actions::VM::Package, out_path)
execute!
end
def destroy
execute!(Actions::VM::Stop) if @vm.running?

View File

@ -2,20 +2,66 @@ require File.join(File.dirname(__FILE__), '..', '..', '..', 'test_helper')
class ExportActionTest < Test::Unit::TestCase
setup do
@wrapper_vm, @vm, @action = mock_action(Vagrant::Actions::VM::Export)
@runner, @vm, @action = mock_action(Vagrant::Actions::VM::Export)
mock_config
end
should "setup and correct working directory and export to it" do
new_dir = File.join(FileUtils.pwd, Vagrant.config.package.name)
FileUtils.expects(:mkpath).with(new_dir).returns(new_dir)
@wrapper_vm.expects(:export).with(File.join(new_dir, "#{Vagrant.config.package.name}.ovf"))
@action.execute!
context "executing" do
should "setup the temp dir then export" do
exec_seq = sequence('execute')
@action.expects(:setup_temp_dir).once.in_sequence(exec_seq)
@action.expects(:export).once.in_sequence(exec_seq)
@action.execute!
end
end
context "setting up the temporary directory" do
setup do
@time_now = Time.now.to_i.to_s
Time.stubs(:now).returns(@time_now)
#FileUtils.expects(:rm_r).with(new_dir)
@tmp_path = "foo"
Vagrant::Env.stubs(:tmp_path).returns(@tmp_path)
@temp_dir = File.join(Vagrant::Env.tmp_path, @time_now)
end
# assert_equal Vagrant::VM.new(@mock_vm).package(name, location), "#{new_dir}.box"
should "create the temporary directory using the current time" do
FileUtils.expects(:mkpath).with(@temp_dir).once
@action.setup_temp_dir
end
should "set the temporary directory to the temp_dir variable" do
@action.setup_temp_dir
assert_equal @temp_dir, @action.temp_dir
end
should "call the set_export_temp_path callback" do
@runner.expects(:invoke_callback).with(:set_export_temp_path, @temp_dir).once
@action.setup_temp_dir
end
end
context "path to OVF file" do
setup do
@temp_dir = "foo"
@action.stubs(:temp_dir).returns(@temp_dir)
end
should "be the temporary directory joined with the OVF filename" do
assert_equal File.join(@temp_dir, Vagrant.config.vm.box_ovf), @action.ovf_path
end
end
context "exporting" do
setup do
@ovf_path = mock("ovf_path")
@action.stubs(:ovf_path).returns(@ovf_path)
end
should "call export on the runner with the ovf path" do
@runner.expects(:export).with(@ovf_path).once
@action.export
end
end
end

View File

@ -2,19 +2,17 @@ require File.join(File.dirname(__FILE__), '..', '..', '..', 'test_helper')
class PackageActionTest < Test::Unit::TestCase
setup do
@wrapper_vm, @vm, @action = mock_action(Vagrant::Actions::VM::Package)
@action.to = '/foo/bar/baz'
@action.name = 'bing'
@wrapper_vm, @vm, @action = mock_action(Vagrant::Actions::VM::Package, "bing")
mock_config
@temp_path = "temp_path"
@action.temp_path = @temp_path
end
context "executing" do
setup do
@tar_path = "foo"
@action.stubs(:compress)
@action.stubs(:clean)
@action.stubs(:tar_path).returns(@tar_path)
end
should "compress and remove the working directory" do
@ -23,10 +21,6 @@ class PackageActionTest < Test::Unit::TestCase
@action.expects(:clean).in_sequence(package_seq)
@action.execute!
end
should "return the tar path" do
assert_equal @tar_path, @action.execute!
end
end
context "cleaning up" do
@ -36,22 +30,16 @@ class PackageActionTest < Test::Unit::TestCase
end
should "remove the working directory" do
FileUtils.expects(:rm_r).with(@working_dir).once
FileUtils.expects(:rm_r).with(@temp_path).once
@action.clean
end
end
context "working directory" do
should "create the directory" do
FileUtils.expects(:mkpath).with(File.join(@action.to, @action.name))
@action.working_dir
end
end
context "tar path" do
should "be the working directory with the extension attached" do
@action.expects(:working_dir).returns("foo")
assert_equal "foo#{Vagrant.config.package.extension}", @action.tar_path
should "be the temporary directory with the name and extension attached" do
pwd = "foo"
FileUtils.stubs(:pwd).returns(pwd)
assert_equal File.join(pwd, "#{@action.out_path}#{Vagrant.config.package.extension}"), @action.tar_path
end
end
@ -79,15 +67,15 @@ class PackageActionTest < Test::Unit::TestCase
should "cd to the directory and append the directory" do
compress_seq = sequence("compress_seq")
FileUtils.expects(:pwd).once.returns(@pwd).in_sequence(compress_seq)
FileUtils.expects(:cd).with(@action.to).in_sequence(compress_seq)
@tar.expects(:append_tree).with(@action.name).in_sequence(compress_seq)
FileUtils.expects(:cd).with(@temp_path).in_sequence(compress_seq)
@tar.expects(:append_tree).with(".").in_sequence(compress_seq)
FileUtils.expects(:cd).with(@pwd).in_sequence(compress_seq)
@action.compress
end
should "pop back to the current directory even if an exception is raised" do
cd_seq = sequence("cd_seq")
FileUtils.expects(:cd).with(@action.to).raises(Exception).in_sequence(cd_seq)
FileUtils.expects(:cd).with(@temp_path).raises(Exception).in_sequence(cd_seq)
FileUtils.expects(:cd).with(@pwd).in_sequence(cd_seq)
assert_raises(Exception) {
@ -95,4 +83,12 @@ class PackageActionTest < Test::Unit::TestCase
}
end
end
context "export callback to set temp path" do
should "save to the temp_path directory" do
foo = mock("foo")
@action.set_export_temp_path(foo)
assert foo.equal?(@action.temp_path)
end
end
end

View File

@ -155,8 +155,6 @@ class CommandsTest < Test::Unit::TestCase
setup do
@persisted_vm.stubs(:package)
@persisted_vm.stubs(:powered_off?).returns(true)
@persisted_vm.expects(:add_action).twice
@persisted_vm.expects(:execute!)
end
should "require a persisted vm" do
@ -170,6 +168,17 @@ class CommandsTest < Test::Unit::TestCase
@persisted_vm.expects(:package).never
Vagrant::Commands.package
end
should "call package on the persisted VM" do
@persisted_vm.expects(:package).once
Vagrant::Commands.package
end
should "pass in the out path to the package method" do
out_path = mock("out_path")
@persisted_vm.expects(:package).with(out_path).once
Vagrant::Commands.package(out_path)
end
end
context "box" do

View File

@ -37,6 +37,17 @@ class VMTest < Test::Unit::TestCase
@vm = Vagrant::VM.new(@mock_vm)
end
context "packaging" do
should "queue up the actions and execute" do
out_path = mock("out_path")
action_seq = sequence("actions")
@vm.expects(:add_action).with(Vagrant::Actions::VM::Export).once.in_sequence(action_seq)
@vm.expects(:add_action).with(Vagrant::Actions::VM::Package, out_path).once.in_sequence(action_seq)
@vm.expects(:execute!).in_sequence(action_seq)
@vm.package(out_path)
end
end
context "destroying" do
setup do
@mock_vm.stubs(:running?).returns(false)