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