armsultan
11/1/2013 - 3:42 PM

Script to package a VMware Vagrant box from an existing Vagrant box instance

Script to package a VMware Vagrant box from an existing Vagrant box instance

# Creates a new VMWare base box from an existing Vagrant VMWare box
# This script assumes it lives in the directory above where you store cookbooks (i.e. ~/src)
#
# Usage:
# ruby export_vmware_box.rb daptiv_dev_ppm_workstation vagrant-vmware-windows2008r2sp1.box

require 'fileutils'

#.vagrant/machines/default/vmware_fusion/0f721388-a327-4ba3-b203-c09f69016b43/
box_root_path = "#{Dir.pwd}/#{ARGV[0]}/.vagrant/machines/default/vmware_fusion"
box_file = ARGV[1]

# find the subdir that is a UUID
sub_dir = Dir["#{box_root_path}/*/"]
  .map { |d| File.basename(d) }
  .find { |d| d =~ /[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/ }

box_path = "#{box_root_path}/#{sub_dir}"
tar_list_path = "#{box_path}/boxfilelist.txt"
completed_box_path = "#{Dir.pwd}/#{box_file}"

puts "Setting cwd to: #{box_path}"
Dir.chdir(box_path) {
  vmdk_file = File.expand_path(Dir.glob("*.vmdk").first())
  vdiskmanager_path = '/Applications/VMware Fusion.app/Contents/Library/vmware-vdiskmanager'
  
  args = [vdiskmanager_path]
  args << '-d'
  args << vmdk_file
  puts "Defragging #{vmdk_file}"
  system(*args)
  
  args = [vdiskmanager_path]
  args << '-k'
  args << vmdk_file
  puts "Skrinking #{vmdk_file}"
  system(*args)
  
  puts "Creating manifest #{tar_list_path}"
  FileUtils.rm(tar_list_path) if File.exists?(tar_list_path)

  files = Dir.glob("*.{vmdk,nvram,plist,vmsd,vmx,vmxf,json}").join("\n")
  IO.write(tar_list_path, files)
  puts "Found the following files to pack: #{files}" 
  puts "Packing box #{box_file}"
  tar_cmd = "tar -czvf #{box_file} -T #{tar_list_path}"
  %x[#{tar_cmd}]
  FileUtils.rm(completed_box_path) if File.exists?(completed_box_path)
  FileUtils.mv(box_file, completed_box_path)
}

puts "Done creating box #{completed_box_path}"