Class: BoxGrinder::ImageHelper

Inherits:
Object
  • Object
show all
Defined in:
lib/boxgrinder-build/helpers/image-helper.rb

Instance Method Summary collapse

Constructor Details

#initialize(config, appliance_config, options = {}) ⇒ ImageHelper

Returns a new instance of ImageHelper.



25
26
27
28
29
30
31
# 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

Instance Method Details

#convert_disk(disk, format, destination) ⇒ Object



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# 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 += (`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

#create_disk(disk, size) ⇒ Object



118
119
120
121
122
# 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 = {}) ⇒ Object



124
125
126
127
128
129
130
131
132
# 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) ⇒ Object



33
34
35
# 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) ⇒ Object

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 https://bugzilla.redhat.com/show_bug.cgi?id=690819



66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# 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