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