class BoxGrinder::ImageHelper

Public Class Methods

new(config, appliance_config, options = {}) click to toggle source
# File lib/boxgrinder-build/helpers/image-helper.rb, line 25
def initialize(config, appliance_config, options = {})
  @config = config
  @appliance_config = appliance_config

  @log = options[:log] || LogHelper.new
  @exec_helper = options[:exec_helper] || ExecHelper.new(:log => @log)
end

Public Instance Methods

convert_disk(disk, format, destination) click to toggle source
# File lib/boxgrinder-build/helpers/image-helper.rb, line 37
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 += (%xqemu-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
create_disk(disk, size) click to toggle source
# File lib/boxgrinder-build/helpers/image-helper.rb, line 118
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).to_i}M"
  @log.trace "Disk prepared"
end
customize(disks, options = {}) { |guestfs, guestfs_helper| ... } click to toggle source
# File lib/boxgrinder-build/helpers/image-helper.rb, line 124
def customize(disks, options = {})
  options = {
      :ide_disk => ((@appliance_config.os.name == 'rhel' or @appliance_config.os.name == 'centos') and @appliance_config.os.version == '5') ? true : false
  }.merge(options)

  GuestFSHelper.new(disks, @appliance_config, @config, :log => @log).customize(options) do |guestfs, guestfs_helper|
    yield guestfs, guestfs_helper
  end
end
disk_info(disk) click to toggle source
# File lib/boxgrinder-build/helpers/image-helper.rb, line 33
def disk_info(disk)
  YAML.load(@exec_helper.execute("qemu-img info '#{disk}'"))
end
sync_filesystem(guestfs, guestfs_helper) click to toggle source

Synchronizes filesystem from one image with an empty disk image. Input image can be a partioned image or a partition image itself. Output disk is a partition image.

See also bugzilla.redhat.com/show_bug.cgi?id=690819

# File lib/boxgrinder-build/helpers/image-helper.rb, line 66
def sync_filesystem(guestfs, guestfs_helper)
  devices = guestfs.list_devices
  in_device = devices.first
  out_device = devices.last
  partitions = guestfs.list_partitions.reject { |i| !(i =~ /^#{in_device}/) }

  @log.debug "Loading SELinux policy to sync filesystem..."
  partitions.size > 0 ? guestfs_helper.mount_partitions(in_device) : guestfs_helper.mount_partition(in_device, '/')
  guestfs_helper.load_selinux_policy
  partitions.size > 0 ? guestfs_helper.umount_partitions(in_device) : guestfs_helper.umount_partition(in_device)
  @log.debug "SELinux policy was loaded, we're ready to sync filesystem."

  @log.info "Synchronizing filesystems..."

  # Create mount points in libguestfs
  guestfs.mkmountpoint('/in')
  guestfs.mkmountpoint('/out')
  guestfs.mkmountpoint('/out/in')

  # Create filesystem on destination device
  # https://issues.jboss.org/browse/BGBUILD-321
  guestfs.mkfs(@appliance_config.hardware.partitions['/']['type'], out_device)
  # Set root partition label
  guestfs.set_e2label(out_device, '79d3d2d4') # This is a CRC32 from /

  # Mount empty EC2 disk to /out
  guestfs_helper.mount_partition(out_device, '/out/in')
  partitions.size > 0 ? guestfs_helper.mount_partitions(in_device, '/in') : guestfs_helper.mount_partition(in_device, '/in')

  @log.debug "Copying files..."

  # Copy the filesystem
  guestfs.cp_a('/in/', '/out')

  @log.debug "Files copied."

  # Better make sure...
  guestfs.sync

  guestfs_helper.umount_partition(out_device)
  partitions.size > 0 ? guestfs_helper.umount_partitions(in_device) : guestfs_helper.umount_partition(in_device)

  guestfs.rmmountpoint('/out/in')
  guestfs.rmmountpoint('/out')
  guestfs.rmmountpoint('/in')

  @log.info "Filesystems synchronized."

  # Remount the destination disk
  guestfs_helper.mount_partition(out_device, '/')
end