Class | BoxGrinder::GuestFSHelper |
In: |
lib/boxgrinder-build/helpers/guestfs-helper.rb
lib/boxgrinder-build/helpers/guestfs-helper.rb |
Parent: | Object |
guestfs | [R] | |
guestfs | [R] |
# File lib/boxgrinder-build/helpers/guestfs-helper.rb, line 29 29: def initialize(disks, appliance_config, config, options = {}) 30: @disks = disks 31: @appliance_config = appliance_config 32: @config = config 33: @log = options[:log] || LogHelper.new 34: end
# File lib/boxgrinder-build/helpers/guestfs-helper.rb, line 29 29: def initialize(disks, appliance_config, config, options = {}) 30: @disks = disks 31: @appliance_config = appliance_config 32: @config = config 33: @log = options[:log] || LogHelper.new 34: end
# File lib/boxgrinder-build/helpers/guestfs-helper.rb, line 299 299: def augeas(&block) 300: AugeasHelper.new(@guestfs, self, :log => @log).edit(&block) 301: end
# File lib/boxgrinder-build/helpers/guestfs-helper.rb, line 299 299: def augeas(&block) 300: AugeasHelper.new(@guestfs, self, :log => @log).edit(&block) 301: end
# File lib/boxgrinder-build/helpers/guestfs-helper.rb, line 231 231: def clean_close 232: @log.trace "Closing guestfs..." 233: 234: @guestfs.sync 235: @guestfs.umount_all 236: @guestfs.close 237: 238: @log.trace "Guestfs closed." 239: end
# File lib/boxgrinder-build/helpers/guestfs-helper.rb, line 231 231: def clean_close 232: @log.trace "Closing guestfs..." 233: 234: @guestfs.sync 235: @guestfs.umount_all 236: @guestfs.close 237: 238: @log.trace "Guestfs closed." 239: end
# File lib/boxgrinder-build/helpers/guestfs-helper.rb, line 172 172: def customize(options = {}) 173: initialize_guestfs(options) do 174: helper = execute(options) 175: 176: yield @guestfs, helper 177: 178: clean_close 179: end 180: end
# File lib/boxgrinder-build/helpers/guestfs-helper.rb, line 172 172: def customize(options = {}) 173: initialize_guestfs(options) do 174: helper = execute(options) 175: 176: yield @guestfs, helper 177: 178: clean_close 179: end 180: end
# File lib/boxgrinder-build/helpers/guestfs-helper.rb, line 182 182: def execute(options = {}) 183: options = { 184: :ide_disk => false, 185: :mount_prefix => '', 186: :automount => true, 187: :load_selinux_policy => true 188: }.merge(options) 189: 190: @log.debug "Launching guestfs..." 191: @guestfs.launch 192: 193: if options[:automount] 194: device = @guestfs.list_devices.first 195: 196: if @guestfs.list_partitions.size == 0 197: mount_partition(device, '/', options[:mount_prefix]) 198: else 199: mount_partitions(device, options[:mount_prefix]) 200: end 201: 202: load_selinux_policy if options[:load_selinux_policy] 203: end 204: 205: @log.trace "Guestfs launched." 206: 207: self 208: end
# File lib/boxgrinder-build/helpers/guestfs-helper.rb, line 182 182: def execute(options = {}) 183: options = { 184: :ide_disk => false, 185: :mount_prefix => '', 186: :automount => true, 187: :load_selinux_policy => true 188: }.merge(options) 189: 190: @log.debug "Launching guestfs..." 191: @guestfs.launch 192: 193: if options[:automount] 194: device = @guestfs.list_devices.first 195: 196: if @guestfs.list_partitions.size == 0 197: mount_partition(device, '/', options[:mount_prefix]) 198: else 199: mount_partitions(device, options[:mount_prefix]) 200: end 201: 202: load_selinux_policy if options[:load_selinux_policy] 203: end 204: 205: @log.trace "Guestfs launched." 206: 207: self 208: end
# File lib/boxgrinder-build/helpers/guestfs-helper.rb, line 38 38: def hw_virtualization_available? 39: @log.trace "Checking if HW virtualization is available..." 40: 41: ec2 = false 42: 43: begin 44: Timeout::timeout(2) { ec2 = Net::HTTP.get_response(URI.parse('http://169.254.169.254/latest/meta-data/ami-id')).code.eql?("200") } 45: rescue Exception 46: end 47: 48: if `egrep '^flags.*(vmx|svm)' /proc/cpuinfo | wc -l`.chomp.strip.to_i > 0 and !ec2 49: @log.trace "HW acceleration available." 50: return true 51: end 52: 53: @log.trace "HW acceleration not available." 54: 55: false 56: end
# File lib/boxgrinder-build/helpers/guestfs-helper.rb, line 38 38: def hw_virtualization_available? 39: @log.trace "Checking if HW virtualization is available..." 40: 41: ec2 = false 42: 43: begin 44: Timeout::timeout(2) { ec2 = Net::HTTP.get_response(URI.parse('http://169.254.169.254/latest/meta-data/ami-id')).code.eql?("200") } 45: rescue Exception 46: end 47: 48: if `egrep '^flags.*(vmx|svm)' /proc/cpuinfo | wc -l`.chomp.strip.to_i > 0 and !ec2 49: @log.trace "HW acceleration available." 50: return true 51: end 52: 53: @log.trace "HW acceleration not available." 54: 55: false 56: end
# File lib/boxgrinder-build/helpers/guestfs-helper.rb, line 112 112: def initialize_guestfs(options = {}) 113: @log.debug "Preparing guestfs..." 114: @log.trace "Setting libguestfs temporary directory to '#{@config.dir.tmp}'..." 115: 116: FileUtils.mkdir_p(@config.dir.tmp) 117: ENV['TMPDIR'] = @config.dir.tmp 118: 119: @guestfs = Guestfs::create 120: 121: if @guestfs.respond_to?(:set_event_callback) 122: @log.trace "We have event callbacks available!" 123: log_callback { prepare_guestfs(options) { yield } } 124: else 125: @log.trace "We don't have event callbacks available :( Falling back to proxy." 126: log_hack { prepare_guestfs(options) { yield } } 127: end 128: end
# File lib/boxgrinder-build/helpers/guestfs-helper.rb, line 112 112: def initialize_guestfs(options = {}) 113: @log.debug "Preparing guestfs..." 114: @log.trace "Setting libguestfs temporary directory to '#{@config.dir.tmp}'..." 115: 116: FileUtils.mkdir_p(@config.dir.tmp) 117: ENV['TMPDIR'] = @config.dir.tmp 118: 119: @guestfs = Guestfs::create 120: 121: if @guestfs.respond_to?(:set_event_callback) 122: @log.trace "We have event callbacks available!" 123: log_callback { prepare_guestfs(options) { yield } } 124: else 125: @log.trace "We don't have event callbacks available :( Falling back to proxy." 126: log_hack { prepare_guestfs(options) { yield } } 127: end 128: end
# File lib/boxgrinder-build/helpers/guestfs-helper.rb, line 210 210: def load_selinux_policy 211: return unless @guestfs.exists('/etc/sysconfig/selinux') != 0 212: 213: @log.trace "Loading SElinux policy..." 214: 215: @guestfs.aug_init("/", 32) 216: @guestfs.aug_rm("/augeas/load//incl[. != '/etc/sysconfig/selinux']") 217: @guestfs.aug_load 218: 219: selinux = @guestfs.aug_get("/files/etc/sysconfig/selinux/SELINUX") 220: 221: begin 222: @guestfs.sh("/usr/sbin/load_policy") if !selinux.nil? and !selinux.eql?('disabled') 223: @log.trace "SElinux policy loaded." 224: rescue 225: @log.warn "Loading SELinux policy failed. SELinux may be not fully initialized." 226: ensure 227: @guestfs.aug_close 228: end 229: end
# File lib/boxgrinder-build/helpers/guestfs-helper.rb, line 210 210: def load_selinux_policy 211: return unless @guestfs.exists('/etc/sysconfig/selinux') != 0 212: 213: @log.trace "Loading SElinux policy..." 214: 215: @guestfs.aug_init("/", 32) 216: @guestfs.aug_rm("/augeas/load//incl[. != '/etc/sysconfig/selinux']") 217: @guestfs.aug_load 218: 219: selinux = @guestfs.aug_get("/files/etc/sysconfig/selinux/SELINUX") 220: 221: begin 222: @guestfs.sh("/usr/sbin/load_policy") if !selinux.nil? and !selinux.eql?('disabled') 223: @log.trace "SElinux policy loaded." 224: rescue 225: @log.warn "Loading SELinux policy failed. SELinux may be not fully initialized." 226: ensure 227: @guestfs.aug_close 228: end 229: end
issues.jboss.org/browse/BGBUILD-83
# File lib/boxgrinder-build/helpers/guestfs-helper.rb, line 59 59: def log_callback 60: default_callback = Proc.new do |event, event_handle, buf, array| 61: buf.chomp! 62: 63: if event == 64 64: @log.debug "GFS: #{buf}" 65: else 66: @log.trace "GFS: #{buf}" unless buf.start_with?('recv_from_daemon', 'send_to_daemon') 67: end 68: end 69: 70: # Guestfs::EVENT_APPLIANCE => 16 71: # Guestfs::EVENT_LIBRARY => 32 72: # Guestfs::EVENT_TRACE => 64 73: 74: # Referencing int instead of constants make it easier to test 75: @guestfs.set_event_callback(default_callback, 16 | 32 | 64) 76: 77: yield if block_given? 78: end
issues.jboss.org/browse/BGBUILD-83
# File lib/boxgrinder-build/helpers/guestfs-helper.rb, line 59 59: def log_callback 60: default_callback = Proc.new do |event, event_handle, buf, array| 61: buf.chomp! 62: 63: if event == 64 64: @log.debug "GFS: #{buf}" 65: else 66: @log.trace "GFS: #{buf}" unless buf.start_with?('recv_from_daemon', 'send_to_daemon') 67: end 68: end 69: 70: # Guestfs::EVENT_APPLIANCE => 16 71: # Guestfs::EVENT_LIBRARY => 32 72: # Guestfs::EVENT_TRACE => 64 73: 74: # Referencing int instead of constants make it easier to test 75: @guestfs.set_event_callback(default_callback, 16 | 32 | 64) 76: 77: yield if block_given? 78: end
If log callback aren‘t available we will fail to this, which sucks…
# File lib/boxgrinder-build/helpers/guestfs-helper.rb, line 81 81: def log_hack 82: read_stderr, write_stderr = IO.pipe 83: 84: fork do 85: write_stderr.close 86: 87: read_stderr.each do |l| 88: @log.trace "GFS: #{l.chomp.strip}" 89: end 90: 91: read_stderr.close 92: end 93: 94: old_stderr = STDERR.clone 95: 96: STDERR.reopen(write_stderr) 97: STDERR.sync = true 98: 99: begin 100: # Execute all tasks 101: yield if block_given? 102: ensure 103: STDERR.reopen(old_stderr) 104: end 105: 106: write_stderr.close 107: read_stderr.close 108: 109: Process.wait 110: end
If log callback aren‘t available we will fail to this, which sucks…
# File lib/boxgrinder-build/helpers/guestfs-helper.rb, line 81 81: def log_hack 82: read_stderr, write_stderr = IO.pipe 83: 84: fork do 85: write_stderr.close 86: 87: read_stderr.each do |l| 88: @log.trace "GFS: #{l.chomp.strip}" 89: end 90: 91: read_stderr.close 92: end 93: 94: old_stderr = STDERR.clone 95: 96: STDERR.reopen(write_stderr) 97: STDERR.sync = true 98: 99: begin 100: # Execute all tasks 101: yield if block_given? 102: ensure 103: STDERR.reopen(old_stderr) 104: end 105: 106: write_stderr.close 107: read_stderr.close 108: 109: Process.wait 110: end
# File lib/boxgrinder-build/helpers/guestfs-helper.rb, line 241 241: def mount_partition(part, mount_point, mount_prefix = '') 242: @log.trace "Mounting #{part} partition to #{mount_point}..." 243: @guestfs.mount_options("", part, "#{mount_prefix}#{mount_point}") 244: # By the way - update the labels so we don't have to muck again with partitions 245: # this will be done for every mount, but shouldn't hurt too much. 246: @guestfs.set_e2label(part, Zlib.crc32(mount_point).to_s(16)) 247: @log.trace "Partition mounted." 248: end
# File lib/boxgrinder-build/helpers/guestfs-helper.rb, line 241 241: def mount_partition(part, mount_point, mount_prefix = '') 242: @log.trace "Mounting #{part} partition to #{mount_point}..." 243: @guestfs.mount_options("", part, "#{mount_prefix}#{mount_point}") 244: # By the way - update the labels so we don't have to muck again with partitions 245: # this will be done for every mount, but shouldn't hurt too much. 246: @guestfs.set_e2label(part, Zlib.crc32(mount_point).to_s(16)) 247: @log.trace "Partition mounted." 248: end
This mount partitions. We assume that the first partition is a root partition.
# File lib/boxgrinder-build/helpers/guestfs-helper.rb, line 252 252: def mount_partitions(device, mount_prefix = '') 253: @log.trace "Mounting partitions..." 254: 255: partitions = mountable_partitions(device) 256: mount_points = LinuxHelper.new(:log => @log).partition_mount_points(@appliance_config.hardware.partitions) 257: # https://issues.jboss.org/browse/BGBUILD-307 258: # We don't want to mount swap partitions at all... 259: mount_points.delete("swap") 260: partitions.each_index { |i| mount_partition(partitions[i], mount_points[i], mount_prefix) } 261: end
This mount partitions. We assume that the first partition is a root partition.
# File lib/boxgrinder-build/helpers/guestfs-helper.rb, line 252 252: def mount_partitions(device, mount_prefix = '') 253: @log.trace "Mounting partitions..." 254: 255: partitions = mountable_partitions(device) 256: mount_points = LinuxHelper.new(:log => @log).partition_mount_points(@appliance_config.hardware.partitions) 257: # https://issues.jboss.org/browse/BGBUILD-307 258: # We don't want to mount swap partitions at all... 259: mount_points.delete("swap") 260: partitions.each_index { |i| mount_partition(partitions[i], mount_points[i], mount_prefix) } 261: end
# File lib/boxgrinder-build/helpers/guestfs-helper.rb, line 263 263: def mountable_partitions(device, options = {}) 264: options = {:list_swap => false}.merge(options) 265: 266: partitions = @guestfs.list_partitions 267: 268: # we need to remove extended partition 269: # extended partition is always #3 270: partitions.delete_at(3) if partitions.size > 4 271: 272: partitions.reject { |i| !(i =~ /^#{device}/) or (@guestfs.vfs_type(i) == 'swap' and !options[:list_swap]) } 273: end
# File lib/boxgrinder-build/helpers/guestfs-helper.rb, line 263 263: def mountable_partitions(device, options = {}) 264: options = {:list_swap => false}.merge(options) 265: 266: partitions = @guestfs.list_partitions 267: 268: # we need to remove extended partition 269: # extended partition is always #3 270: partitions.delete_at(3) if partitions.size > 4 271: 272: partitions.reject { |i| !(i =~ /^#{device}/) or (@guestfs.vfs_type(i) == 'swap' and !options[:list_swap]) } 273: end
# File lib/boxgrinder-build/helpers/guestfs-helper.rb, line 130 130: def prepare_guestfs(options = {}) 131: @log.trace "Setting debug + trace..." 132: @guestfs.set_verbose(1) 133: @guestfs.set_trace(1) 134: 135: # https://issues.jboss.org/browse/BGBUILD-246 136: memsize = ENV['LIBGUESTFS_MEMSIZE'].nil? ? 300 : ENV['LIBGUESTFS_MEMSIZE'].to_i 137: @guestfs.set_memsize(memsize) 138: 139: # https://bugzilla.redhat.com/show_bug.cgi?id=502058 140: @guestfs.set_append("noapic") 141: 142: @log.trace "Enabling SElinux support in guestfs..." 143: @guestfs.set_selinux(1) 144: 145: unless hw_virtualization_available? 146: # This wrapper is required especially for EC2 where running qemu-kvm crashes libguestfs 147: qemu_wrapper = "#{File.dirname(__FILE__)}/qemu.wrapper" 148: 149: @log.trace "Setting QEMU wrapper to #{qemu_wrapper}..." 150: @guestfs.set_qemu(qemu_wrapper) 151: @log.trace "QEMU wrapper set." 152: end 153: 154: @disks.each do |disk| 155: @log.trace "Adding drive '#{disk}'..." 156: if options[:ide_disk] 157: @guestfs.add_drive_with_if(disk, 'ide') 158: else 159: @guestfs.add_drive(disk) 160: end 161: @log.trace "Drive added." 162: end 163: 164: if @guestfs.respond_to?('set_network') 165: @log.debug "Enabling networking for GuestFS..." 166: @guestfs.set_network(1) 167: end 168: 169: yield 170: end
# File lib/boxgrinder-build/helpers/guestfs-helper.rb, line 130 130: def prepare_guestfs(options = {}) 131: @log.trace "Setting debug + trace..." 132: @guestfs.set_verbose(1) 133: @guestfs.set_trace(1) 134: 135: # https://issues.jboss.org/browse/BGBUILD-246 136: memsize = ENV['LIBGUESTFS_MEMSIZE'].nil? ? 300 : ENV['LIBGUESTFS_MEMSIZE'].to_i 137: @guestfs.set_memsize(memsize) 138: 139: # https://bugzilla.redhat.com/show_bug.cgi?id=502058 140: @guestfs.set_append("noapic") 141: 142: @log.trace "Enabling SElinux support in guestfs..." 143: @guestfs.set_selinux(1) 144: 145: unless hw_virtualization_available? 146: # This wrapper is required especially for EC2 where running qemu-kvm crashes libguestfs 147: qemu_wrapper = "#{File.dirname(__FILE__)}/qemu.wrapper" 148: 149: @log.trace "Setting QEMU wrapper to #{qemu_wrapper}..." 150: @guestfs.set_qemu(qemu_wrapper) 151: @log.trace "QEMU wrapper set." 152: end 153: 154: @disks.each do |disk| 155: @log.trace "Adding drive '#{disk}'..." 156: if options[:ide_disk] 157: @guestfs.add_drive_with_if(disk, 'ide') 158: else 159: @guestfs.add_drive(disk) 160: end 161: @log.trace "Drive added." 162: end 163: 164: if @guestfs.respond_to?('set_network') 165: @log.debug "Enabling networking for GuestFS..." 166: @guestfs.set_network(1) 167: end 168: 169: yield 170: end
# File lib/boxgrinder-build/helpers/guestfs-helper.rb, line 291 291: def sh(cmd, options = {}) 292: arch = options[:arch] || `uname -m`.chomp.strip 293: 294: @log.debug "Executing '#{cmd}' command..." 295: @guestfs.sh("setarch #{arch} << 'SETARCH_EOF'\n#{cmd}\nSETARCH_EOF") 296: @log.debug "Command '#{cmd}' executed." 297: end
# File lib/boxgrinder-build/helpers/guestfs-helper.rb, line 291 291: def sh(cmd, options = {}) 292: arch = options[:arch] || `uname -m`.chomp.strip 293: 294: @log.debug "Executing '#{cmd}' command..." 295: @guestfs.sh("setarch #{arch} << 'SETARCH_EOF'\n#{cmd}\nSETARCH_EOF") 296: @log.debug "Command '#{cmd}' executed." 297: end
# File lib/boxgrinder-build/helpers/guestfs-helper.rb, line 275 275: def umount_partition(part) 276: @log.trace "Unmounting partition #{part}..." 277: @guestfs.umount(part) 278: @log.trace "Partition unmounted." 279: end
# File lib/boxgrinder-build/helpers/guestfs-helper.rb, line 275 275: def umount_partition(part) 276: @log.trace "Unmounting partition #{part}..." 277: @guestfs.umount(part) 278: @log.trace "Partition unmounted." 279: end
Unmounts partitions in reverse order.
# File lib/boxgrinder-build/helpers/guestfs-helper.rb, line 283 283: def umount_partitions(device) 284: partitions = mountable_partitions(device) 285: 286: @log.trace "Unmounting partitions..." 287: partitions.reverse.each { |part| umount_partition(part) } 288: @log.trace "All partitions unmounted." 289: end
Unmounts partitions in reverse order.
# File lib/boxgrinder-build/helpers/guestfs-helper.rb, line 283 283: def umount_partitions(device) 284: partitions = mountable_partitions(device) 285: 286: @log.trace "Unmounting partitions..." 287: partitions.reverse.each { |part| umount_partition(part) } 288: @log.trace "All partitions unmounted." 289: end