name User entry memory Editable cpus Editable arch Detected: cpuflags contains lm (long mode) features Detected: apic, acpi, pae disks Editable, default to all
device Detected path Detected is_block 1 format raw
removables Editable, default to all
device Detected type Detected
nics Editable, default to all connected
mac Detected, option to generate new vnet Set to nic name vnet_type bridge
# File lib/virt-p2v/converter.rb, line 96 def initialize() @profile = nil @connection = nil @connection_listeners = [] @debug = false # Initialize basic system information @name = '' # There's no reasonable default for this # Get total memory from /proc/meminfo File.open('/proc/meminfo', 'r') do |fd| fd.each { |line| next unless line =~ /^MemTotal:\s+(\d+)\b/ @memory = Integer($~[1]) * 1024 break } end # Get the total number of cpu threads from hwloc-info hwloc = Document.new %xhwloc-info --of xml` @cpus = XPath.match(hwloc, "//object[@type='PU']").length # Get cpu architecture and features from the first flags entry in # /proc/cpuinfo File.open('/proc/cpuinfo', 'r') do |fd| fd.each { |line| next unless line =~ /^flags\s*:\s(.*)$/ flags = $~[1] # x86_64 if flags contains lm (long mode), i686 otherwise. We # don't support anything else. @arch = flags =~ /\blm\b/ ? 'x86_64' : 'i686' # Pull some select features from cpu flags @features = [] [ 'apic', 'acpi', 'pae' ].each { |f| @features << f if flags =~ /\b#{f}\b/ } break } end # Initialise empty lists for optional devices. These will be added # according to the user's selection @disks = [] @removables = [] @nics = [] @debug = false end
# File lib/virt-p2v/converter.rb, line 58 def connection=(connection) @connection = connection @connection_listeners.each { |cb| cb.call(connection) } end
# File lib/virt-p2v/converter.rb, line 65 def convert(status, progress, &completion) iterate([ lambda { |cb| @connection.set_profile(@profile, &cb) }, lambda { |cb| @connection.metadata(meta, &cb) }, lambda { |cb| iterate(@disks.map { |dev| lambda { |cb2| disk(dev, status, progress, cb2) } }, cb) }, lambda { |cb| if @debug begin @connection.options({ "DEBUG" => 1 }, &cb) rescue VirtV2V::Connection::UnsupportedOperationError cb.call(true) end else cb.call(true) end }, lambda { |cb| status.call('Converting') @connection.convert(&cb) } ], completion) end
# File lib/virt-p2v/converter.rb, line 54 def on_connection(&cb) @connection_listeners << cb end
# File lib/virt-p2v/converter.rb, line 149 def disk(dev, status, progress, completion) path = "/dev/#{dev}" size = FixedBlockDevice[dev].size status.call("Transferring #{dev}") iterate([ lambda { |cb| @connection.path(size, path, &cb) }, lambda { |cb| @connection.container('RAW', &cb) }, lambda { |cb| io = nil begin io = File.new(path, 'r') rescue => ex cb.call(ex) end pc = 0 @connection.send_data(io, size, lambda { |total| npc = Float(total) * 100 / size # Only update the progress if it has increased by # at least 1% if Integer(npc) > pc then pc = Integer(npc) progress.call(dev, pc) end }, &cb) } ], completion) end
# File lib/virt-p2v/converter.rb, line 177 def iterate(stages, completion) i = 0 cb = lambda { |result| if result.kind_of?(Exception) then completion.call(result) else i += 1 if i == stages.length then completion.call(true) else stages[i].call(cb) end end } stages[0].call(cb) end
# File lib/virt-p2v/converter.rb, line 194 def meta { 'name' => @name, 'cpus' => @cpus, 'memory' => @memory, 'arch' => @arch, 'features' => @features, 'disks' => @disks.map { |device| { 'device' => device, 'path' => "/dev/#{device}" } }, 'removables' => @removables.map { |device| removable = RemovableBlockDevice[device] { 'device' => removable.device, 'type' => removable.type } }, 'nics' => @nics.map { |device| nic = NetworkDevice[device] { 'mac' => nic.mac, 'vnet' => nic.name, 'vnet_type' => 'bridge' } } } end