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

[Source]

    # 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

Public Instance methods

[Source]

     # 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

[Source]

     # 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

[Source]

     # 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

[Source]

     # 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

[Source]

     # 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

[Source]

     # 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

[Source]

     # 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

[Source]

     # 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

[Source]

     # 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

[Source]

     # 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

[Source]

     # 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

[Source]

     # 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

[Source]

     # 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

[Source]

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

[Source]

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

[Source]

     # 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

[Source]

     # 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

[Source]

     # 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

[Source]

     # 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

[Source]

     # 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

[Source]

     # 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

[Source]

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

[Source]

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

[Source]

     # 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

[Validate]