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 88 88: def initialize(disks, appliance_config, config, options = {}) 89: @disks = disks 90: @appliance_config = appliance_config 91: @config = config 92: @log = options[:log] || LogHelper.new 93: end
# File lib/boxgrinder-build/helpers/guestfs-helper.rb, line 88 88: def initialize(disks, appliance_config, config, options = {}) 89: @disks = disks 90: @appliance_config = appliance_config 91: @config = config 92: @log = options[:log] || LogHelper.new 93: end
# File lib/boxgrinder-build/helpers/guestfs-helper.rb, line 303 303: def augeas(&block) 304: AugeasHelper.new(@guestfs, self, :log => @log).edit(&block) 305: end
# File lib/boxgrinder-build/helpers/guestfs-helper.rb, line 303 303: def augeas(&block) 304: AugeasHelper.new(@guestfs, self, :log => @log).edit(&block) 305: end
# File lib/boxgrinder-build/helpers/guestfs-helper.rb, line 235 235: def clean_close 236: @log.trace "Closing guestfs..." 237: 238: @guestfs.sync 239: @guestfs.umount_all 240: @guestfs.close 241: 242: @log.trace "Guestfs closed." 243: end
# File lib/boxgrinder-build/helpers/guestfs-helper.rb, line 235 235: def clean_close 236: @log.trace "Closing guestfs..." 237: 238: @guestfs.sync 239: @guestfs.umount_all 240: @guestfs.close 241: 242: @log.trace "Guestfs closed." 243: end
# File lib/boxgrinder-build/helpers/guestfs-helper.rb, line 116 116: def customize(options = {}) 117: read_pipe, write_pipe = IO.pipe 118: 119: fork do 120: read_pipe.each do |o| 121: if o.chomp.strip.eql?("<EOF>") 122: exit 123: else 124: @log.trace "GFS: #{o.chomp.strip}" 125: end 126: end 127: end 128: 129: helper = execute(write_pipe, options) 130: 131: yield @guestfs, helper 132: 133: clean_close 134: 135: write_pipe.puts "<EOF>" 136: 137: Process.wait 138: end
# File lib/boxgrinder-build/helpers/guestfs-helper.rb, line 116 116: def customize(options = {}) 117: read_pipe, write_pipe = IO.pipe 118: 119: fork do 120: read_pipe.each do |o| 121: if o.chomp.strip.eql?("<EOF>") 122: exit 123: else 124: @log.trace "GFS: #{o.chomp.strip}" 125: end 126: end 127: end 128: 129: helper = execute(write_pipe, options) 130: 131: yield @guestfs, helper 132: 133: clean_close 134: 135: write_pipe.puts "<EOF>" 136: 137: Process.wait 138: end
# File lib/boxgrinder-build/helpers/guestfs-helper.rb, line 140 140: def execute(pipe = nil, options = {}) 141: options = { 142: :ide_disk => false, 143: :mount_prefix => '', 144: :automount => true, 145: :load_selinux_policy => true 146: }.merge(options) 147: 148: @log.debug "Preparing guestfs..." 149: 150: @log.trace "Setting libguestfs temporary directory to '#{@config.dir.tmp}'..." 151: 152: FileUtils.mkdir_p(@config.dir.tmp) 153: 154: ENV['TMPDIR'] = @config.dir.tmp 155: 156: @guestfs = pipe.nil? ? Guestfs::create : Guestfs::create.redirect(pipe) 157: 158: # https://bugzilla.redhat.com/show_bug.cgi?id=502058 159: @guestfs.set_append("noapic") 160: 161: @log.trace "Setting debug + trace..." 162: @guestfs.set_verbose(1) 163: @guestfs.set_trace(1) 164: 165: @log.trace "Enabling SElinux support in guestfs..." 166: @guestfs.set_selinux(1) 167: 168: unless hw_virtualization_available? 169: # This wrapper is required especially for EC2 where running qemu-kvm crashes libguestfs 170: qemu_wrapper = (RbConfig::CONFIG['host_cpu'].eql?('x86_64') ? "/usr/bin/qemu-system-x86_64" : "/usr/bin/qemu") 171: 172: if File.exists?(qemu_wrapper) 173: @log.trace "Setting QEMU wrapper to #{qemu_wrapper}..." 174: @guestfs.set_qemu(qemu_wrapper) 175: @log.trace "QEMU wrapper set." 176: end 177: end 178: 179: @disks.each do |disk| 180: @log.trace "Adding drive '#{disk}'..." 181: if options[:ide_disk] 182: @guestfs.add_drive_with_if(disk, 'ide') 183: else 184: @guestfs.add_drive(disk) 185: end 186: @log.trace "Drive added." 187: end 188: 189: if @guestfs.respond_to?('set_network') 190: @log.debug "Enabling networking for GuestFS..." 191: @guestfs.set_network(1) 192: end 193: 194: @log.debug "Launching guestfs..." 195: @guestfs.launch 196: 197: if options[:automount] 198: device = @guestfs.list_devices.first 199: 200: if @guestfs.list_partitions.size == 0 201: mount_partition(device, '/', options[:mount_prefix]) 202: else 203: mount_partitions(device, options[:mount_prefix]) 204: end 205: 206: load_selinux_policy if options[:load_selinux_policy] 207: end 208: 209: @log.trace "Guestfs launched." 210: 211: self 212: end
# File lib/boxgrinder-build/helpers/guestfs-helper.rb, line 140 140: def execute(pipe = nil, options = {}) 141: options = { 142: :ide_disk => false, 143: :mount_prefix => '', 144: :automount => true, 145: :load_selinux_policy => true 146: }.merge(options) 147: 148: @log.debug "Preparing guestfs..." 149: 150: @log.trace "Setting libguestfs temporary directory to '#{@config.dir.tmp}'..." 151: 152: FileUtils.mkdir_p(@config.dir.tmp) 153: 154: ENV['TMPDIR'] = @config.dir.tmp 155: 156: @guestfs = pipe.nil? ? Guestfs::create : Guestfs::create.redirect(pipe) 157: 158: # https://bugzilla.redhat.com/show_bug.cgi?id=502058 159: @guestfs.set_append("noapic") 160: 161: @log.trace "Setting debug + trace..." 162: @guestfs.set_verbose(1) 163: @guestfs.set_trace(1) 164: 165: @log.trace "Enabling SElinux support in guestfs..." 166: @guestfs.set_selinux(1) 167: 168: unless hw_virtualization_available? 169: # This wrapper is required especially for EC2 where running qemu-kvm crashes libguestfs 170: qemu_wrapper = (RbConfig::CONFIG['host_cpu'].eql?('x86_64') ? "/usr/bin/qemu-system-x86_64" : "/usr/bin/qemu") 171: 172: if File.exists?(qemu_wrapper) 173: @log.trace "Setting QEMU wrapper to #{qemu_wrapper}..." 174: @guestfs.set_qemu(qemu_wrapper) 175: @log.trace "QEMU wrapper set." 176: end 177: end 178: 179: @disks.each do |disk| 180: @log.trace "Adding drive '#{disk}'..." 181: if options[:ide_disk] 182: @guestfs.add_drive_with_if(disk, 'ide') 183: else 184: @guestfs.add_drive(disk) 185: end 186: @log.trace "Drive added." 187: end 188: 189: if @guestfs.respond_to?('set_network') 190: @log.debug "Enabling networking for GuestFS..." 191: @guestfs.set_network(1) 192: end 193: 194: @log.debug "Launching guestfs..." 195: @guestfs.launch 196: 197: if options[:automount] 198: device = @guestfs.list_devices.first 199: 200: if @guestfs.list_partitions.size == 0 201: mount_partition(device, '/', options[:mount_prefix]) 202: else 203: mount_partitions(device, options[:mount_prefix]) 204: end 205: 206: load_selinux_policy if options[:load_selinux_policy] 207: end 208: 209: @log.trace "Guestfs launched." 210: 211: self 212: end
# File lib/boxgrinder-build/helpers/guestfs-helper.rb, line 97 97: def hw_virtualization_available? 98: @log.trace "Checking if HW virtualization is available..." 99: 100: begin 101: ec2 = Resolv.getname("169.254.169.254").include?(".ec2.internal") 102: rescue Resolv::ResolvError 103: ec2 = false 104: end 105: 106: if `cat /proc/cpuinfo | grep flags | grep vmx | wc -l`.chomp.strip.to_i > 0 and !ec2 107: @log.trace "HW acceleration available." 108: return true 109: end 110: 111: @log.trace "HW acceleration not available." 112: 113: false 114: end
# File lib/boxgrinder-build/helpers/guestfs-helper.rb, line 97 97: def hw_virtualization_available? 98: @log.trace "Checking if HW virtualization is available..." 99: 100: begin 101: ec2 = Resolv.getname("169.254.169.254").include?(".ec2.internal") 102: rescue Resolv::ResolvError 103: ec2 = false 104: end 105: 106: if `cat /proc/cpuinfo | grep flags | grep vmx | wc -l`.chomp.strip.to_i > 0 and !ec2 107: @log.trace "HW acceleration available." 108: return true 109: end 110: 111: @log.trace "HW acceleration not available." 112: 113: false 114: end
# File lib/boxgrinder-build/helpers/guestfs-helper.rb, line 214 214: def load_selinux_policy 215: return unless @guestfs.exists('/etc/sysconfig/selinux') != 0 216: 217: @log.trace "Loading SElinux policy..." 218: 219: @guestfs.aug_init("/", 32) 220: @guestfs.aug_rm("/augeas/load//incl[. != '/etc/sysconfig/selinux']") 221: @guestfs.aug_load 222: 223: selinux = @guestfs.aug_get("/files/etc/sysconfig/selinux/SELINUX") 224: 225: begin 226: @guestfs.sh("/usr/sbin/load_policy") if !selinux.nil? and !selinux.eql?('disabled') 227: @log.trace "SElinux policy loaded." 228: rescue 229: @log.warn "Loading SELinux policy failed. SELinux may be not fully initialized." 230: ensure 231: @guestfs.aug_close 232: end 233: end
# File lib/boxgrinder-build/helpers/guestfs-helper.rb, line 214 214: def load_selinux_policy 215: return unless @guestfs.exists('/etc/sysconfig/selinux') != 0 216: 217: @log.trace "Loading SElinux policy..." 218: 219: @guestfs.aug_init("/", 32) 220: @guestfs.aug_rm("/augeas/load//incl[. != '/etc/sysconfig/selinux']") 221: @guestfs.aug_load 222: 223: selinux = @guestfs.aug_get("/files/etc/sysconfig/selinux/SELINUX") 224: 225: begin 226: @guestfs.sh("/usr/sbin/load_policy") if !selinux.nil? and !selinux.eql?('disabled') 227: @log.trace "SElinux policy loaded." 228: rescue 229: @log.warn "Loading SELinux policy failed. SELinux may be not fully initialized." 230: ensure 231: @guestfs.aug_close 232: end 233: end
# File lib/boxgrinder-build/helpers/guestfs-helper.rb, line 245 245: def mount_partition(part, mount_point, mount_prefix = '') 246: @log.trace "Mounting #{part} partition to #{mount_point}..." 247: @guestfs.mount_options("", part, "#{mount_prefix}#{mount_point}") 248: @log.trace "Partition mounted." 249: end
# File lib/boxgrinder-build/helpers/guestfs-helper.rb, line 245 245: def mount_partition(part, mount_point, mount_prefix = '') 246: @log.trace "Mounting #{part} partition to #{mount_point}..." 247: @guestfs.mount_options("", part, "#{mount_prefix}#{mount_point}") 248: @log.trace "Partition mounted." 249: end
This mount partitions. We assume that the first partition is a root partition.
# File lib/boxgrinder-build/helpers/guestfs-helper.rb, line 253 253: def mount_partitions(device, mount_prefix = '') 254: @log.trace "Mounting partitions..." 255: 256: partitions = mountable_partitions(device) 257: 258: mount_points = LinuxHelper.new(:log => @log).partition_mount_points(@appliance_config.hardware.partitions) 259: 260: partitions.each_index do |i| 261: mount_partition(partitions[i], mount_points[i], mount_prefix) 262: 263: # By the way - update the labels so we don't have to muck again with partitions 264: # this will be done for every mount, but shouldn't hurt too much. 265: @guestfs.set_e2label(partitions[i], Zlib.crc32(mount_points[i]).to_s(16)) 266: end 267: end
This mount partitions. We assume that the first partition is a root partition.
# File lib/boxgrinder-build/helpers/guestfs-helper.rb, line 253 253: def mount_partitions(device, mount_prefix = '') 254: @log.trace "Mounting partitions..." 255: 256: partitions = mountable_partitions(device) 257: 258: mount_points = LinuxHelper.new(:log => @log).partition_mount_points(@appliance_config.hardware.partitions) 259: 260: partitions.each_index do |i| 261: mount_partition(partitions[i], mount_points[i], mount_prefix) 262: 263: # By the way - update the labels so we don't have to muck again with partitions 264: # this will be done for every mount, but shouldn't hurt too much. 265: @guestfs.set_e2label(partitions[i], Zlib.crc32(mount_points[i]).to_s(16)) 266: end 267: end
# File lib/boxgrinder-build/helpers/guestfs-helper.rb, line 269 269: def mountable_partitions(device) 270: partitions = @guestfs.list_partitions.reject { |i| !(i =~ /^#{device}/) } 271: 272: # we need to remove extended partition 273: # extended partition is always #3 274: partitions.delete_at(3) if partitions.size > 4 275: 276: partitions 277: end
# File lib/boxgrinder-build/helpers/guestfs-helper.rb, line 269 269: def mountable_partitions(device) 270: partitions = @guestfs.list_partitions.reject { |i| !(i =~ /^#{device}/) } 271: 272: # we need to remove extended partition 273: # extended partition is always #3 274: partitions.delete_at(3) if partitions.size > 4 275: 276: partitions 277: end
# File lib/boxgrinder-build/helpers/guestfs-helper.rb, line 295 295: def sh(cmd, options = {}) 296: arch = options[:arch] || `uname -m`.chomp.strip 297: 298: @log.debug "Executing '#{cmd}' command..." 299: @guestfs.sh("setarch #{arch} << 'SETARCH_EOF'\n#{cmd}\nSETARCH_EOF") 300: @log.debug "Command '#{cmd}' executed." 301: end
# File lib/boxgrinder-build/helpers/guestfs-helper.rb, line 295 295: def sh(cmd, options = {}) 296: arch = options[:arch] || `uname -m`.chomp.strip 297: 298: @log.debug "Executing '#{cmd}' command..." 299: @guestfs.sh("setarch #{arch} << 'SETARCH_EOF'\n#{cmd}\nSETARCH_EOF") 300: @log.debug "Command '#{cmd}' executed." 301: end
# File lib/boxgrinder-build/helpers/guestfs-helper.rb, line 279 279: def umount_partition(part) 280: @log.trace "Unmounting partition #{part}..." 281: @guestfs.umount(part) 282: @log.trace "Partition unmounted." 283: end
# File lib/boxgrinder-build/helpers/guestfs-helper.rb, line 279 279: def umount_partition(part) 280: @log.trace "Unmounting partition #{part}..." 281: @guestfs.umount(part) 282: @log.trace "Partition unmounted." 283: end
Unmounts partitions in reverse order.
# File lib/boxgrinder-build/helpers/guestfs-helper.rb, line 287 287: def umount_partitions(device) 288: partitions = @guestfs.list_partitions.reject { |i| !(i =~ /^#{device}/) } 289: 290: @log.trace "Unmounting partitions..." 291: partitions.reverse.each { |part| umount_partition(part) } 292: @log.trace "All partitions unmounted." 293: end
Unmounts partitions in reverse order.
# File lib/boxgrinder-build/helpers/guestfs-helper.rb, line 287 287: def umount_partitions(device) 288: partitions = @guestfs.list_partitions.reject { |i| !(i =~ /^#{device}/) } 289: 290: @log.trace "Unmounting partitions..." 291: partitions.reverse.each { |part| umount_partition(part) } 292: @log.trace "All partitions unmounted." 293: end