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

[Source]

    # 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

Public Instance methods

[Source]

     # 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

[Source]

     # 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

[Source]

     # 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

[Source]

     # 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

[Source]

     # 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

[Source]

     # 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

[Source]

     # 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

[Source]

     # 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

[Source]

    # 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

[Source]

    # 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

[Source]

     # 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

[Source]

     # 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

[Source]

     # 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

[Source]

     # 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

[Source]

    # 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

[Source]

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

[Source]

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

[Source]

     # 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

[Source]

     # 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

[Source]

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

[Source]

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

[Source]

     # 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

[Source]

     # 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

[Source]

     # 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

[Source]

     # 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

[Source]

     # 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

[Source]

     # 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

[Source]

     # 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

[Source]

     # 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

[Source]

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

[Source]

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

[Source]

     # 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

[Validate]