package command
This commit is contained in:
parent
1316a9ac17
commit
9e3a57fc36
|
@ -21,10 +21,7 @@ Usage: #{command.full_name} #{all_options_string}
|
||||||
Package the current vagrant environment
|
Package the current vagrant environment
|
||||||
|
|
||||||
EOS
|
EOS
|
||||||
|
|
||||||
opt :file, "the name of the resulting packaged file"
|
|
||||||
|
|
||||||
run do |command|
|
run do |command|
|
||||||
Vagrant::VM.package((command.argv[0] || 'vagrant.box'))
|
Vagrant::Commands.package(command.argv[0])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -14,6 +14,9 @@ Vagrant::Config.run do |config|
|
||||||
config.vm.base_mac = "0800279C2E41"
|
config.vm.base_mac = "0800279C2E41"
|
||||||
config.vm.project_directory = "/vagrant"
|
config.vm.project_directory = "/vagrant"
|
||||||
config.vm.forward_port("ssh", 22, 2222)
|
config.vm.forward_port("ssh", 22, 2222)
|
||||||
|
config.vm.disk_image_format = 'VMDK'
|
||||||
|
|
||||||
|
config.package.name = 'vagrant'
|
||||||
|
|
||||||
config.chef.cookbooks_path = "cookbooks"
|
config.chef.cookbooks_path = "cookbooks"
|
||||||
config.chef.provisioning_path = "/tmp/vagrant-chef"
|
config.chef.provisioning_path = "/tmp/vagrant-chef"
|
||||||
|
|
|
@ -6,7 +6,6 @@ module Vagrant
|
||||||
class Commands
|
class Commands
|
||||||
extend Vagrant::Util
|
extend Vagrant::Util
|
||||||
|
|
||||||
|
|
||||||
class << self
|
class << self
|
||||||
# Initializes a directory for use with vagrant. This command copies an
|
# Initializes a directory for use with vagrant. This command copies an
|
||||||
# initial `Vagrantfile` into the current working directory so you can
|
# initial `Vagrantfile` into the current working directory so you can
|
||||||
|
@ -98,6 +97,18 @@ suspended state.
|
||||||
error
|
error
|
||||||
Env.persisted_vm.start
|
Env.persisted_vm.start
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Export and package the current vm
|
||||||
|
#
|
||||||
|
# This command requires that an instance be powered off
|
||||||
|
def package(name=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
|
||||||
|
Env.persisted_vm.package(name || Vagrant.config[:package][:name], FileUtils.pwd)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -51,6 +51,8 @@ module Vagrant
|
||||||
attr_accessor :project_directory
|
attr_accessor :project_directory
|
||||||
attr_reader :forwarded_ports
|
attr_reader :forwarded_ports
|
||||||
attr_accessor :hd_location
|
attr_accessor :hd_location
|
||||||
|
attr_accessor :disk_image_format
|
||||||
|
|
||||||
|
|
||||||
def initialize
|
def initialize
|
||||||
@forwarded_ports = {}
|
@forwarded_ports = {}
|
||||||
|
@ -70,6 +72,10 @@ module Vagrant
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
class PackageConfig < Base
|
||||||
|
attr_accessor :name
|
||||||
|
end
|
||||||
|
|
||||||
class ChefConfig < Base
|
class ChefConfig < Base
|
||||||
attr_accessor :cookbooks_path
|
attr_accessor :cookbooks_path
|
||||||
attr_accessor :provisioning_path
|
attr_accessor :provisioning_path
|
||||||
|
@ -82,6 +88,7 @@ module Vagrant
|
||||||
|
|
||||||
class Top < Base
|
class Top < Base
|
||||||
attr_accessor :dotfile_name
|
attr_accessor :dotfile_name
|
||||||
|
attr_reader :package
|
||||||
attr_reader :ssh
|
attr_reader :ssh
|
||||||
attr_reader :vm
|
attr_reader :vm
|
||||||
attr_reader :chef
|
attr_reader :chef
|
||||||
|
@ -92,6 +99,7 @@ module Vagrant
|
||||||
@vm = VMConfig.new
|
@vm = VMConfig.new
|
||||||
@chef = ChefConfig.new
|
@chef = ChefConfig.new
|
||||||
@vagrant = VagrantConfig.new
|
@vagrant = VagrantConfig.new
|
||||||
|
@package = PackageConfig.new
|
||||||
|
|
||||||
@loaded = false
|
@loaded = false
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,51 +0,0 @@
|
||||||
module Vagrant
|
|
||||||
class Packaged
|
|
||||||
attr_reader :vm, :file, :name
|
|
||||||
|
|
||||||
def initialize(name, params)
|
|
||||||
@vm = params[:vm]
|
|
||||||
@file = params[:file]
|
|
||||||
@name = name
|
|
||||||
end
|
|
||||||
|
|
||||||
def compressed?
|
|
||||||
@file
|
|
||||||
end
|
|
||||||
|
|
||||||
def decompress(to)
|
|
||||||
# move folder unless compressed?
|
|
||||||
# decompress
|
|
||||||
# return File object of ovf for import
|
|
||||||
end
|
|
||||||
|
|
||||||
def compress(to)
|
|
||||||
folder = FileUtils.mkpath(File.join(to, @name))
|
|
||||||
|
|
||||||
return @file if compressed?
|
|
||||||
|
|
||||||
ovf_path = File.join(folder, "#{@name}.ovf")
|
|
||||||
tar_path = "#{folder}.tar"
|
|
||||||
|
|
||||||
@vm.export(ovf_path)
|
|
||||||
|
|
||||||
# TODO use zlib ...
|
|
||||||
Tar.open(tar_path, File::CREAT | File::WRONLY, 0644, Tar::GNU) do |tar|
|
|
||||||
begin
|
|
||||||
working_dir = FileUtils.pwd
|
|
||||||
FileUtils.cd(to)
|
|
||||||
tar.append_tree(@name)
|
|
||||||
ensure
|
|
||||||
FileUtils.cd(working_dir)
|
|
||||||
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# TODO remove directory
|
|
||||||
|
|
||||||
|
|
||||||
tar_path
|
|
||||||
end
|
|
||||||
|
|
||||||
def ovf; "#{@name}.ovf" end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,5 +1,9 @@
|
||||||
module Vagrant
|
module Vagrant
|
||||||
module Util
|
module Util
|
||||||
|
def self.included?(base)
|
||||||
|
base.extend Vagrant::Util
|
||||||
|
end
|
||||||
|
|
||||||
def error_and_exit(error)
|
def error_and_exit(error)
|
||||||
puts <<-error
|
puts <<-error
|
||||||
=====================================================================
|
=====================================================================
|
||||||
|
|
|
@ -1,10 +1,7 @@
|
||||||
module Vagrant
|
module Vagrant
|
||||||
class VM
|
class VM
|
||||||
HD_EXT_DEFAULT = 'VMDK'
|
|
||||||
attr_reader :vm
|
|
||||||
|
|
||||||
extend Vagrant::Util
|
|
||||||
include Vagrant::Util
|
include Vagrant::Util
|
||||||
|
attr_reader :vm
|
||||||
|
|
||||||
class << self
|
class << self
|
||||||
# Bring up the virtual machine. Imports the base image and
|
# Bring up the virtual machine. Imports the base image and
|
||||||
|
@ -20,15 +17,6 @@ module Vagrant
|
||||||
return nil if vm.nil?
|
return nil if vm.nil?
|
||||||
new(vm)
|
new(vm)
|
||||||
end
|
end
|
||||||
|
|
||||||
def package(name, to=FileUtils.pwd)
|
|
||||||
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
|
|
||||||
|
|
||||||
Packaged.new(name, :vm => Env.persisted_vm).compress(to)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def initialize(vm=nil)
|
def initialize(vm=nil)
|
||||||
|
@ -76,7 +64,7 @@ error
|
||||||
|
|
||||||
logger.info "Cloning current VM Disk to new location (#{ new_image_file })..."
|
logger.info "Cloning current VM Disk to new location (#{ new_image_file })..."
|
||||||
# TODO image extension default?
|
# TODO image extension default?
|
||||||
new_image = hd.image.clone(new_image_file , HD_EXT_DEFAULT, true)
|
new_image = hd.image.clone(new_image_file , Vagrant.config[:vm][:disk_image_format], true)
|
||||||
hd.image = new_image
|
hd.image = new_image
|
||||||
|
|
||||||
logger.info "Attaching new disk to VM ..."
|
logger.info "Attaching new disk to VM ..."
|
||||||
|
@ -183,6 +171,37 @@ error
|
||||||
@vm.save_state(true)
|
@vm.save_state(true)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# TODO the longest method, needs to be split up
|
||||||
|
def package(name, to)
|
||||||
|
folder = FileUtils.mkpath(File.join(to, name))
|
||||||
|
logger.info "Creating working directory: #{folder} ..."
|
||||||
|
|
||||||
|
ovf_path = File.join(folder, "#{name}.ovf")
|
||||||
|
tar_path = "#{folder}.box"
|
||||||
|
|
||||||
|
logger.info "Exporting required VM files to working directory ..."
|
||||||
|
@vm.export(ovf_path)
|
||||||
|
|
||||||
|
# TODO use zlib ...
|
||||||
|
logger.info "Packaging VM into #{name}.box ..."
|
||||||
|
Tar.open(tar_path, File::CREAT | File::WRONLY, 0644, Tar::GNU) do |tar|
|
||||||
|
begin
|
||||||
|
# appending the expanded file path adds the whole folder tree
|
||||||
|
# to the tar archive there must be a better way
|
||||||
|
working_dir = FileUtils.pwd
|
||||||
|
FileUtils.cd(to)
|
||||||
|
tar.append_tree(name)
|
||||||
|
ensure
|
||||||
|
FileUtils.cd(working_dir)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
logger.info "Removiding working directory ..."
|
||||||
|
FileUtils.rm_r(folder)
|
||||||
|
|
||||||
|
tar_path
|
||||||
|
end
|
||||||
|
|
||||||
# TODO need a better way to which controller is the hd
|
# TODO need a better way to which controller is the hd
|
||||||
def hd
|
def hd
|
||||||
@vm.storage_controllers.first.devices.first
|
@vm.storage_controllers.first.devices.first
|
||||||
|
|
|
@ -131,4 +131,33 @@ class CommandsTest < Test::Unit::TestCase
|
||||||
Vagrant::Commands.resume
|
Vagrant::Commands.resume
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context "package" do
|
||||||
|
setup do
|
||||||
|
@persisted_vm.stubs(:package)
|
||||||
|
@persisted_vm.stubs(:powered_off?).returns(true)
|
||||||
|
end
|
||||||
|
|
||||||
|
should "require a persisted vm" do
|
||||||
|
Vagrant::Env.expects(:require_persisted_vm).once
|
||||||
|
Vagrant::Commands.package
|
||||||
|
end
|
||||||
|
|
||||||
|
should "error and exit if the VM is not powered off" do
|
||||||
|
@persisted_vm.stubs(:powered_off?).returns(false)
|
||||||
|
Vagrant::Commands.expects(:error_and_exit).once
|
||||||
|
@persisted_vm.expects(:package).never
|
||||||
|
Vagrant::Commands.package
|
||||||
|
end
|
||||||
|
|
||||||
|
should "package the vm with the default name and the current directory" do
|
||||||
|
@persisted_vm.expects(:package).with(Vagrant.config[:package][:name], FileUtils.pwd).once
|
||||||
|
Vagrant::Commands.package
|
||||||
|
end
|
||||||
|
|
||||||
|
should "package the vm with the specified name" do
|
||||||
|
@persisted_vm.expects(:package).with('foo', FileUtils.pwd).once
|
||||||
|
Vagrant::Commands.package('foo')
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,18 +0,0 @@
|
||||||
require File.join(File.dirname(__FILE__), '..', 'test_helper')
|
|
||||||
|
|
||||||
class BoxedTest< Test::Unit::TestCase
|
|
||||||
context "exporting a vm" do
|
|
||||||
should "create a tar in the specified directory" do
|
|
||||||
vm = mock('vm')
|
|
||||||
location = '/Users/johnbender/Desktop'
|
|
||||||
name = 'my_box'
|
|
||||||
new_dir = File.join(location, name)
|
|
||||||
vm.expects(:export).with(File.join(new_dir, "#{name}.ovf"))
|
|
||||||
FileUtils.expects(:mkpath).with(new_dir).returns(new_dir)
|
|
||||||
Tar.expects(:open)
|
|
||||||
|
|
||||||
# TODO test whats passed to the open tar.append_tree
|
|
||||||
assert_equal Vagrant::Packaged.new(name, :vm => vm).compress(location), "#{new_dir}.tar"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -226,7 +226,7 @@ class VMTest < Test::Unit::TestCase
|
||||||
image, hd = mock('image'), mock('hd')
|
image, hd = mock('image'), mock('hd')
|
||||||
|
|
||||||
Vagrant.config[:vm].expects(:hd_location).at_least_once.returns('/locations/')
|
Vagrant.config[:vm].expects(:hd_location).at_least_once.returns('/locations/')
|
||||||
image.expects(:clone).with(Vagrant.config[:vm][:hd_location] + 'foo', Vagrant::VM::HD_EXT_DEFAULT, true).returns(image)
|
image.expects(:clone).with(Vagrant.config[:vm][:hd_location] + 'foo', Vagrant.config[:vm][:disk_image_format], true).returns(image)
|
||||||
image.expects(:filename).twice.returns('foo')
|
image.expects(:filename).twice.returns('foo')
|
||||||
image.expects(:destroy)
|
image.expects(:destroy)
|
||||||
|
|
||||||
|
@ -241,4 +241,19 @@ class VMTest < Test::Unit::TestCase
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context "packaging a vm" do
|
||||||
|
should "dump the three necessary files to a tar in the current working dir" do
|
||||||
|
location = FileUtils.pwd
|
||||||
|
name = 'vagrant'
|
||||||
|
new_dir = File.join(location, name)
|
||||||
|
@mock_vm.expects(:export).with(File.join(new_dir, "#{name}.ovf"))
|
||||||
|
FileUtils.expects(:mkpath).with(new_dir).returns(new_dir)
|
||||||
|
FileUtils.expects(:rm_r).with(new_dir)
|
||||||
|
Tar.expects(:open)
|
||||||
|
|
||||||
|
# TODO test whats passed to the open tar.append_tree
|
||||||
|
assert_equal Vagrant::VM.new(@mock_vm).package(name, location), "#{new_dir}.box"
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue