Class BoxGrinder::GuestFSHelper
In: lib/boxgrinder-build/helpers/guestfs-helper.rb
lib/boxgrinder-build/helpers/guestfs-helper.rb
Parent: Object

Methods

Attributes

guestfs  [R] 
guestfs  [R] 

Public Class methods

[Source]

    # 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

[Source]

    # 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

Public Instance methods

[Source]

     # 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

[Source]

     # 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

[Source]

     # 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

[Source]

     # 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

[Source]

     # 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

[Source]

     # 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

[Source]

     # 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

[Source]

     # 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

[Source]

    # 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

[Source]

    # 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

[Source]

     # 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

[Source]

     # 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

[Source]

     # 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

[Source]

     # 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

[Source]

    # 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

[Source]

    # 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…

[Source]

     # 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…

[Source]

     # 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

[Source]

     # 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

[Source]

     # 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.

[Source]

     # 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.

[Source]

     # 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

[Source]

     # 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

[Source]

     # 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

[Source]

     # 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

[Source]

     # 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

[Source]

     # 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

[Source]

     # 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

[Source]

     # 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

[Source]

     # 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.

[Source]

     # 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.

[Source]

     # 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

[Validate]