| 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