lib/boxgrinder-build/helpers/image-helper.rb in boxgrinder-build-0.7.1 vs lib/boxgrinder-build/helpers/image-helper.rb in boxgrinder-build-0.8.0
- old
+ new
@@ -15,42 +15,43 @@
# License along with this software; if not, write to the Free
# Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
# 02110-1301 USA, or see the FSF site: http://www.fsf.org.
require 'fileutils'
+require 'boxgrinder-core/helpers/log-helper'
require 'boxgrinder-build/helpers/guestfs-helper'
module BoxGrinder
class ImageHelper
def initialize(config, appliance_config, options = {})
- @config = config
- @appliance_config = appliance_config
+ @config = config
+ @appliance_config = appliance_config
- @log = options[:log] || Logger.new(STDOUT)
- @exec_helper = options[:exec_helper] || ExecHelper.new(:log => @log)
+ @log = options[:log] || LogHelper.new
+ @exec_helper = options[:exec_helper] || ExecHelper.new(:log => @log)
end
def mount_image(disk, mount_dir)
- offsets = calculate_disk_offsets(disk)
+ offsets = calculate_disk_offsets(disk)
@log.debug "Mounting image #{File.basename(disk)} in #{mount_dir}..."
FileUtils.mkdir_p(mount_dir)
- mounts = {}
+ mounts = {}
offsets.each do |offset|
- loop_device = get_loop_device
- @exec_helper.execute("losetup -o #{offset.to_s} #{loop_device} #{disk}")
- label = @exec_helper.execute("e2label #{loop_device}").strip.chomp.gsub('_', '')
+ loop_device = get_loop_device
+ @exec_helper.execute("losetup -o #{offset.to_s} #{loop_device} '#{disk}'")
+ label = @exec_helper.execute("e2label #{loop_device}").strip.chomp.gsub('_', '')
label = '/' if label == ''
mounts[label] = loop_device
end
- @exec_helper.execute("mount #{mounts['/']} #{mount_dir}")
+ @exec_helper.execute("mount #{mounts['/']} '#{mount_dir}'")
mounts.reject { |key, value| key == '/' }.each do |mount_point, loop_device|
- @exec_helper.execute("mount #{loop_device} #{mount_dir}#{mount_point}")
+ @exec_helper.execute("mount #{loop_device} '#{mount_dir}#{mount_point}'")
end
@log.trace "Mounts:\n#{mounts}"
mounts
@@ -64,10 +65,37 @@
@exec_helper.execute("umount -d #{mounts['/']}")
FileUtils.rm_rf(mount_dir)
end
+ def disk_info(disk)
+ YAML.load(@exec_helper.execute("qemu-img info '#{disk}'"))
+ end
+
+ def convert_disk(disk, format, destination)
+ @log.debug "Conveting '#{disk}' disk to #{format} format and moving it to '#{destination}'..."
+
+ unless File.exists?(destination)
+ info = disk_info(disk)
+
+ if info['file format'] == format.to_s
+ @exec_helper.execute "cp '#{disk}' '#{destination}'"
+ else
+
+ format_with_options = format.to_s
+
+ if format == :vmdk
+ format_with_options += (`qemu-img --help | grep '\\-6'`.strip.chomp.empty? ? ' -o compat6' : ' -6')
+ end
+
+ @exec_helper.execute "qemu-img convert -f #{info['file format']} -O #{format_with_options} '#{disk}' '#{destination}'"
+ end
+ else
+ @log.debug "Destination already exists, skipping disk conversion."
+ end
+ end
+
def get_loop_device
begin
loop_device = @exec_helper.execute("losetup -f 2>&1").strip
rescue
raise "No free loop devices available, please free at least one. See 'losetup -d' command."
@@ -78,12 +106,12 @@
def calculate_disk_offsets(disk)
@log.debug "Calculating offsets for '#{File.basename(disk)}' disk..."
loop_device = get_loop_device
- @exec_helper.execute("losetup #{loop_device} #{disk}")
- offsets = @exec_helper.execute("parted #{loop_device} 'unit B print' | grep -e '^ [0-9]' | awk '{ print $2 }'").scan(/\d+/)
+ @exec_helper.execute("losetup #{loop_device} '#{disk}'")
+ offsets = @exec_helper.execute("parted #{loop_device} 'unit B print' | grep -e '^ [0-9]' | awk '{ print $2 }'").scan(/\d+/)
# wait one secont before freeing loop device
sleep 1
@exec_helper.execute("losetup -d #{loop_device}")
@log.trace "Offsets:\n#{offsets}"
@@ -91,39 +119,39 @@
offsets
end
def create_disk(disk, size)
@log.trace "Preparing disk..."
- @exec_helper.execute "dd if=/dev/zero of=#{disk} bs=1 count=0 seek=#{size * 1024}M"
+ @exec_helper.execute "dd if=/dev/zero of='#{disk}' bs=1 count=0 seek=#{size * 1024}M"
@log.trace "Disk prepared"
end
- def create_filesystem(disk, options = {})
+ def create_filesystem(loop_device, options = {})
options = {
- :type => @appliance_config.hardware.partitions['/']['type'],
- :label => '/'
+ :type => @appliance_config.hardware.partitions['/']['type'],
+ :label => '/'
}.merge(options)
@log.trace "Creating filesystem..."
case options[:type]
when 'ext3', 'ext4'
- @exec_helper.execute "mke2fs -T #{options[:type]} -L '#{options[:label]}' -F #{disk}"
+ @exec_helper.execute "mke2fs -T #{options[:type]} -L '#{options[:label]}' -F #{loop_device}"
else
raise "Unsupported filesystem specified: #{options[:type]}"
end
@log.trace "Filesystem created"
end
def sync_files(from_dir, to_dir)
@log.debug "Syncing files between #{from_dir} and #{to_dir}..."
- @exec_helper.execute "rsync -Xura #{from_dir}/* #{to_dir}"
+ @exec_helper.execute "rsync -Xura #{from_dir.gsub(' ', '\ ')}/* '#{to_dir}'"
@log.debug "Sync finished."
end
def customize(disk_path)
- GuestFSHelper.new(disk_path, :log => @log).customize do |guestfs, guestfs_helper|
+ GuestFSHelper.new(disk_path, :log => @log).customize(:ide_disk => ((@appliance_config.os.name == 'rhel' or @appliance_config.os.name == 'centos') and @appliance_config.os.version == '5') ? true : false) do |guestfs, guestfs_helper|
yield guestfs, guestfs_helper
end
end
end
end