unpackage added, still uses zlib
This commit is contained in:
parent
8d9e53fe27
commit
a690b13f78
|
@ -1,11 +1,18 @@
|
||||||
module Vagrant
|
module Vagrant
|
||||||
module Actions
|
module Actions
|
||||||
class Import < Base
|
class Import < Base
|
||||||
|
#First arg should be the ovf_file location for import
|
||||||
|
def initialize(vm, *args)
|
||||||
|
super vm
|
||||||
|
@ovf_file = args[0]
|
||||||
|
end
|
||||||
|
|
||||||
def execute!
|
def execute!
|
||||||
@vm.invoke_around_callback(:import) do
|
@vm.invoke_around_callback(:import) do
|
||||||
Busy.busy do
|
Busy.busy do
|
||||||
logger.info "Importing base VM (#{Vagrant.config[:vm][:base]})..."
|
logger.info "Importing base VM (#{Vagrant.config[:vm][:base]})..."
|
||||||
@vm.vm = VirtualBox::VM.import(File.expand_path(Vagrant.config[:vm][:base]))
|
# Use the first argument passed to the action
|
||||||
|
@vm.vm = VirtualBox::VM.import(@ovf_file || File.expand_path(Vagrant.config[:vm][:base]))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -12,9 +12,17 @@ error
|
||||||
destroy_drive_after { clone_and_attach }
|
destroy_drive_after { clone_and_attach }
|
||||||
end
|
end
|
||||||
|
|
||||||
# TODO: Better way to detect main bootup drive?
|
|
||||||
def hard_drive
|
def hard_drive
|
||||||
@vm.storage_controllers.first.devices.first
|
@hard_drive ||= find_hard_drive
|
||||||
|
end
|
||||||
|
|
||||||
|
# TODO won't work if the first disk is not the boot disk or even if there are multiple disks
|
||||||
|
def find_hard_drive
|
||||||
|
@vm.storage_controllers.each do |sc|
|
||||||
|
sc.devices.each do |d|
|
||||||
|
return d if d.image.is_a?(VirtualBox::HardDrive)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def clone_and_attach
|
def clone_and_attach
|
||||||
|
|
|
@ -19,7 +19,7 @@ module Vagrant
|
||||||
Zlib::GzipWriter.open(compressed_file_name) do |gz|
|
Zlib::GzipWriter.open(compressed_file_name) do |gz|
|
||||||
files_to_compress.each do |file|
|
files_to_compress.each do |file|
|
||||||
# Delimit the files, and guarantee new line for next file if not the first
|
# Delimit the files, and guarantee new line for next file if not the first
|
||||||
gz.write "#{delimiter}#{file}#{delimiter}"
|
gz.write "#{delimiter}#{File.basename(file)}#{delimiter}"
|
||||||
File.open(file).each { |line| gz.write(line) }
|
File.open(file).each { |line| gz.write(line) }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,71 @@
|
||||||
|
module Vagrant
|
||||||
|
module Actions
|
||||||
|
class Unpackage < Base
|
||||||
|
def initialize(vm, *args)
|
||||||
|
super vm
|
||||||
|
@package_file_path = args[0]
|
||||||
|
end
|
||||||
|
|
||||||
|
def execute!
|
||||||
|
# Exit if folder of same name exists
|
||||||
|
# TODO provide a way for them to specify the directory name
|
||||||
|
error_and_exit(<<-error) if File.exists?(new_base_dir)
|
||||||
|
The directory `#{file_name_without_extension}` already exists under #{Vagrant.config[:vagrant][:home]}. Please
|
||||||
|
remove it, rename your packaged VM file, or (TODO) specifiy an
|
||||||
|
alternate directory
|
||||||
|
error
|
||||||
|
|
||||||
|
logger.info "Creating working new base directory: #{new_base_dir} ..."
|
||||||
|
FileUtils.mkpath(new_base_dir)
|
||||||
|
|
||||||
|
logger.info "Decompressing the packaged VM: #{package_file_path} to: #{new_base_dir}..."
|
||||||
|
decompress_to new_base_dir
|
||||||
|
|
||||||
|
#Return the ovf file for importation
|
||||||
|
Dir["#{new_base_dir}/*.ovf"].first
|
||||||
|
end
|
||||||
|
|
||||||
|
def new_base_dir
|
||||||
|
File.join(Vagrant.config[:vagrant][:home], file_name_without_extension)
|
||||||
|
end
|
||||||
|
|
||||||
|
def file_name_without_extension
|
||||||
|
File.basename(package_file_path, '.*')
|
||||||
|
end
|
||||||
|
|
||||||
|
def package_file_path
|
||||||
|
File.expand_path(@package_file_path)
|
||||||
|
end
|
||||||
|
|
||||||
|
def decompress_to(dir, file_delimeter=Vagrant.config[:package][:delimiter_regex])
|
||||||
|
file = nil
|
||||||
|
Zlib::GzipReader.open(package_file_path) do |gz|
|
||||||
|
begin
|
||||||
|
gz.each_line do |line|
|
||||||
|
|
||||||
|
# If the line is a file delimiter create new file and write to it
|
||||||
|
if line =~ file_delimeter
|
||||||
|
|
||||||
|
#Write the the part of the line belonging to the previous file
|
||||||
|
if file
|
||||||
|
file.write $1
|
||||||
|
file.close
|
||||||
|
end
|
||||||
|
|
||||||
|
#Open a new file with the name contained in the delimiter
|
||||||
|
file = File.open(File.join(dir, $2), 'w')
|
||||||
|
|
||||||
|
#Write the rest of the line to the new file
|
||||||
|
file.write $3
|
||||||
|
else
|
||||||
|
file.write line
|
||||||
|
end
|
||||||
|
end
|
||||||
|
ensure
|
||||||
|
file.close if file
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,12 +1,20 @@
|
||||||
module Vagrant
|
module Vagrant
|
||||||
module Actions
|
module Actions
|
||||||
class Up < Base
|
class Up < Base
|
||||||
|
#First arg should be the ovf_file location for import
|
||||||
|
def initialize(vm, *args)
|
||||||
|
super vm
|
||||||
|
@ovf_file = args[0]
|
||||||
|
end
|
||||||
|
|
||||||
def prepare
|
def prepare
|
||||||
# Up is a "meta-action" so it really just queues up a bunch
|
# Up is a "meta-action" so it really just queues up a bunch
|
||||||
# of other actions in its place:
|
# of other actions in its place:
|
||||||
steps = [Import, ForwardPorts, SharedFolders, Start]
|
@vm.add_action(Import, @ovf_file)
|
||||||
|
|
||||||
|
steps = [ForwardPorts, SharedFolders, Start]
|
||||||
steps << Provision if Vagrant.config.chef.enabled
|
steps << Provision if Vagrant.config.chef.enabled
|
||||||
steps.insert(1, MoveHardDrive) if Vagrant.config.vm.hd_location
|
steps.insert(0, MoveHardDrive) if Vagrant.config.vm.hd_location
|
||||||
|
|
||||||
steps.each do |action_klass|
|
steps.each do |action_klass|
|
||||||
@vm.add_action(action_klass)
|
@vm.add_action(action_klass)
|
||||||
|
|
|
@ -130,12 +130,11 @@ error
|
||||||
error_and_exit(<<-error) unless name
|
error_and_exit(<<-error) unless name
|
||||||
Please specify a target package to unpack and import
|
Please specify a target package to unpack and import
|
||||||
error
|
error
|
||||||
VM.up(VM.unpackage(name))
|
|
||||||
|
VM.execute!(Actions::Up, VM.execute!(Actions::Unpackage, name))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def act_on_vm(&block)
|
def act_on_vm(&block)
|
||||||
yield Env.persisted_vm
|
yield Env.persisted_vm
|
||||||
Env.persisted_vm.execute!
|
Env.persisted_vm.execute!
|
||||||
|
|
|
@ -14,62 +14,6 @@ module Vagrant
|
||||||
vm.execute!
|
vm.execute!
|
||||||
end
|
end
|
||||||
|
|
||||||
# Unpack the specified vm package
|
|
||||||
def unpackage(package_path)
|
|
||||||
working_dir = package_path.chomp(File.extname(package_path))
|
|
||||||
new_base_dir = File.join(Vagrant.config[:vagrant][:home], File.basename(package_path, '.*'))
|
|
||||||
|
|
||||||
# Exit if folder of same name exists
|
|
||||||
# TODO provide a way for them to specify the directory name
|
|
||||||
error_and_exit(<<-error) if File.exists?(new_base_dir)
|
|
||||||
The directory `#{File.basename(package_path, '.*')}` already exists under #{Vagrant.config[:vagrant][:home]}. Please
|
|
||||||
remove it, rename your packaged VM file, or (TODO) specifiy an
|
|
||||||
alternate directory
|
|
||||||
error
|
|
||||||
|
|
||||||
logger.info "Creating working dir: #{working_dir} ..."
|
|
||||||
FileUtils.mkpath(working_dir)
|
|
||||||
|
|
||||||
logger.info "Decompressing the packaged VM: #{package_path} ..."
|
|
||||||
decompress(package_path, working_dir)
|
|
||||||
|
|
||||||
logger.info "Moving the unpackaged VM to #{new_base_dir} ..."
|
|
||||||
FileUtils.mv(working_dir, Vagrant.config[:vagrant][:home])
|
|
||||||
|
|
||||||
#Return the ovf file for importation
|
|
||||||
Dir["#{new_base_dir}/*.ovf"].first
|
|
||||||
end
|
|
||||||
|
|
||||||
def decompress(path, dir, file_delimeter=Vagrant.config[:package][:delimiter_regex])
|
|
||||||
file = nil
|
|
||||||
Zlib::GzipReader.open(path) do |gz|
|
|
||||||
begin
|
|
||||||
gz.each_line do |line|
|
|
||||||
|
|
||||||
# If the line is a file delimiter create new file and write to it
|
|
||||||
if line =~ file_delimeter
|
|
||||||
|
|
||||||
#Write the the part of the line belonging to the previous file
|
|
||||||
if file
|
|
||||||
file.write $1
|
|
||||||
file.close
|
|
||||||
end
|
|
||||||
|
|
||||||
#Open a new file with the name contained in the delimiter
|
|
||||||
file = File.open(File.join(dir, $2), 'w')
|
|
||||||
|
|
||||||
#Write the rest of the line to the new file
|
|
||||||
file.write $3
|
|
||||||
else
|
|
||||||
file.write line
|
|
||||||
end
|
|
||||||
end
|
|
||||||
ensure
|
|
||||||
file.close if file
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# Finds a virtual machine by a given UUID and either returns
|
# Finds a virtual machine by a given UUID and either returns
|
||||||
# a Vagrant::VM object or returns nil.
|
# a Vagrant::VM object or returns nil.
|
||||||
def find(uuid)
|
def find(uuid)
|
||||||
|
@ -96,11 +40,13 @@ error
|
||||||
|
|
||||||
# Call the prepare method on each once its
|
# Call the prepare method on each once its
|
||||||
# initialized, then call the execute! method
|
# initialized, then call the execute! method
|
||||||
|
return_value = nil
|
||||||
[:prepare, :execute!].each do |method|
|
[:prepare, :execute!].each do |method|
|
||||||
@actions.each do |action|
|
@actions.each do |action|
|
||||||
action.send(method)
|
return_value = action.send(method)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
return_value
|
||||||
end
|
end
|
||||||
|
|
||||||
# Invokes an "around callback" which invokes before_name and
|
# Invokes an "around callback" which invokes before_name and
|
||||||
|
@ -141,5 +87,7 @@ error
|
||||||
def powered_off?; @vm.powered_off? end
|
def powered_off?; @vm.powered_off? end
|
||||||
|
|
||||||
def export(filename); @vm.export(filename, {}, true) end
|
def export(filename); @vm.export(filename, {}, true) end
|
||||||
|
|
||||||
|
def storage_controllers; @vm.storage_controllers end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -10,6 +10,21 @@ class MoveHardDriveActionTest < Test::Unit::TestCase
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
should "be able to identifiy a hard drive within the storage controllers" do
|
||||||
|
hd = mock('hd')
|
||||||
|
hd_image = mock('hd_image')
|
||||||
|
hd_image.expects(:is_a?).returns(true)
|
||||||
|
hd.expects(:image).returns(hd_image)
|
||||||
|
|
||||||
|
dvd = mock('dvd')
|
||||||
|
controller = mock('controller')
|
||||||
|
controller.expects(:devices).returns([hd, dvd])
|
||||||
|
|
||||||
|
@mock_vm.expects(:storage_controllers).once.returns([controller])
|
||||||
|
assert_equal @action.find_hard_drive, hd
|
||||||
|
end
|
||||||
|
|
||||||
context "execution" do
|
context "execution" do
|
||||||
should "error and exit if the vm is not powered off" do
|
should "error and exit if the vm is not powered off" do
|
||||||
@mock_vm.expects(:powered_off?).returns(false)
|
@mock_vm.expects(:powered_off?).returns(false)
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
require File.join(File.dirname(__FILE__), '..', '..', 'test_helper')
|
||||||
|
|
||||||
|
class UnpackageActionTest < Test::Unit::TestCase
|
||||||
|
setup do
|
||||||
|
@wrapper_vm, @vm, @action = mock_action(Vagrant::Actions::Unpackage)
|
||||||
|
mock_config
|
||||||
|
end
|
||||||
|
|
||||||
|
# TODO test actual decompression
|
||||||
|
should "call decompress with the path to the file and the directory to decompress to" do
|
||||||
|
new_base_dir = File.join Vagrant.config[:vagrant][:home], 'something'
|
||||||
|
file = File.join(FileUtils.pwd, 'something.box')
|
||||||
|
FileUtils.expects(:mkpath).with(new_base_dir).once
|
||||||
|
Dir.expects(:[]).returns(File.join new_base_dir, 'something.ovf')
|
||||||
|
@action.expects(:decompress_to).with(new_base_dir).once
|
||||||
|
@action.stubs(:package_file_path).returns(file)
|
||||||
|
@action.execute!
|
||||||
|
end
|
||||||
|
end
|
|
@ -8,11 +8,12 @@ class UpActionTest < Test::Unit::TestCase
|
||||||
|
|
||||||
context "sub-actions" do
|
context "sub-actions" do
|
||||||
setup do
|
setup do
|
||||||
@default_order = [Vagrant::Actions::Import, Vagrant::Actions::ForwardPorts, Vagrant::Actions::SharedFolders, Vagrant::Actions::Start]
|
@default_order = [Vagrant::Actions::ForwardPorts, Vagrant::Actions::SharedFolders, Vagrant::Actions::Start]
|
||||||
end
|
end
|
||||||
|
|
||||||
def setup_action_expectations
|
def setup_action_expectations
|
||||||
default_seq = sequence("default_seq")
|
default_seq = sequence("default_seq")
|
||||||
|
@mock_vm.expects(:add_action).with(Vagrant::Actions::Import, nil).once.in_sequence(default_seq)
|
||||||
@default_order.each do |action|
|
@default_order.each do |action|
|
||||||
@mock_vm.expects(:add_action).with(action).once.in_sequence(default_seq)
|
@mock_vm.expects(:add_action).with(action).once.in_sequence(default_seq)
|
||||||
end
|
end
|
||||||
|
@ -39,7 +40,7 @@ class UpActionTest < Test::Unit::TestCase
|
||||||
config.vm.hd_location = "foo"
|
config.vm.hd_location = "foo"
|
||||||
end
|
end
|
||||||
|
|
||||||
@default_order.insert(1, Vagrant::Actions::MoveHardDrive)
|
@default_order.insert(0, Vagrant::Actions::MoveHardDrive)
|
||||||
setup_action_expectations
|
setup_action_expectations
|
||||||
@action.prepare
|
@action.prepare
|
||||||
end
|
end
|
||||||
|
|
|
@ -197,18 +197,4 @@ class VMTest < Test::Unit::TestCase
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context "unpackaging a vm" do
|
|
||||||
|
|
||||||
# TODO test actual decompression
|
|
||||||
should "call decompress with the path to the file and the directory to decompress to" do
|
|
||||||
working_dir = File.join FileUtils.pwd, 'something'
|
|
||||||
file = File.join(FileUtils.pwd, 'something.box')
|
|
||||||
FileUtils.expects(:mkpath).with(working_dir).once
|
|
||||||
FileUtils.expects(:mv).with(working_dir, Vagrant.config[:vagrant][:home]).once
|
|
||||||
Vagrant::VM.expects(:decompress).with(file, working_dir).once
|
|
||||||
Vagrant::VM.unpackage(file)
|
|
||||||
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue