virt-v2v/virt-v2v-0.8.1-00-44eb9021-modified.patch
2011-05-11 17:36:18 +01:00

9297 lines
332 KiB
Diff

diff -ruN virt-v2v-v0.8.1/Build.PL virt-v2v-v0.8.1.new/Build.PL
--- virt-v2v-v0.8.1/Build.PL 2011-04-26 20:58:33.000000000 +0100
+++ virt-v2v-v0.8.1.new/Build.PL 2011-05-11 17:20:21.000000000 +0100
@@ -26,7 +26,7 @@
{
my $self = shift;
- system($self->config('make'), '-C', 'p2v-image-builder') == 0
+ system($self->config('make'), '-C', 'p2v/image-builder') == 0
or return 1;
}
@@ -243,7 +243,7 @@
dist_version_from => 'lib/Sys/VirtConvert.pm',
confdoc_files => [ 'v2v/virt-v2v.conf.pod' ],
install_path => { 'locale' => '/usr/local/share/locale' },
- script_files => [ 'v2v/virt-v2v.pl', 'p2v-server/virt-p2v-server.pl' ],
+ script_files => [ 'v2v/virt-v2v.pl', 'p2v/server/virt-p2v-server.pl' ],
meta_add => {
resources => {
license => "http://www.gnu.org/licenses/gpl.html",
diff -ruN virt-v2v-v0.8.1/ChangeLog virt-v2v-v0.8.1.new/ChangeLog
--- virt-v2v-v0.8.1/ChangeLog 2011-04-26 20:58:33.000000000 +0100
+++ virt-v2v-v0.8.1.new/ChangeLog 2011-05-11 17:20:21.000000000 +0100
@@ -1,3 +1,33 @@
+2011-05-10 Matthew Booth <mbooth@redhat.com>
+
+ * Build.PL, MANIFEST, p2v-image-builder/Makefile, {p2v-client =>
+ p2v/client}/.gitignore, {p2v-client => p2v/client}/Manifest,
+ {p2v-client => p2v/client}/Rakefile, {p2v-client =>
+ p2v/client}/bin/virt-p2v, {p2v-client =>
+ p2v/client}/lib/virt-p2v/blockdevice.rb, {p2v-client =>
+ p2v/client}/lib/virt-p2v/connection.rb, {p2v-client =>
+ p2v/client}/lib/virt-p2v/converter.rb, {p2v-client =>
+ p2v/client}/lib/virt-p2v/gtk-queue.rb, {p2v-client =>
+ p2v/client}/lib/virt-p2v/netdevice.rb, {p2v-client =>
+ p2v/client}/lib/virt-p2v/ui/connect.rb, {p2v-client =>
+ p2v/client}/lib/virt-p2v/ui/convert.rb, {p2v-client =>
+ p2v/client}/lib/virt-p2v/ui/main.rb, {p2v-client =>
+ p2v/client}/lib/virt-p2v/ui/network.rb, {p2v-client =>
+ p2v/client}/lib/virt-p2v/ui/p2v.ui, {p2v-client =>
+ p2v/client}/lib/virt-p2v/ui/success.rb, {p2v-image-builder =>
+ p2v/image-builder}/.gitignore, p2v/image-builder/Makefile,
+ {p2v-image-builder => p2v/image-builder}/common-install.ks,
+ {p2v-image-builder => p2v/image-builder}/common-manifest-post.ks,
+ {p2v-image-builder => p2v/image-builder}/common-minimizer.ks,
+ {p2v-image-builder => p2v/image-builder}/common-pkgs.ks,
+ {p2v-image-builder => p2v/image-builder}/common-post-nochroot.ks,
+ {p2v-image-builder => p2v/image-builder}/common-post.ks,
+ {p2v-image-builder => p2v/image-builder}/virt-p2v-image-builder,
+ {p2v-image-builder => p2v/image-builder}/virt-p2v-image.ks,
+ {p2v-server => p2v/server}/run-p2v-locally, {p2v-server =>
+ p2v/server}/virt-p2v-server.pl, virt-v2v.spec.PL: Give p2v its own
+ subdirectory
+
2011-04-26 Matthew Booth <mbooth@redhat.com>
* lib/Sys/VirtConvert.pm: Bump version to 0.8.1
diff -ruN virt-v2v-v0.8.1/MANIFEST virt-v2v-v0.8.1.new/MANIFEST
--- virt-v2v-v0.8.1/MANIFEST 2011-04-26 20:58:33.000000000 +0100
+++ virt-v2v-v0.8.1.new/MANIFEST 2011-05-11 17:20:21.000000000 +0100
@@ -27,33 +27,33 @@
MANIFEST.SKIP
META.yml
metadata-format.txt
-p2v-client/bin/virt-p2v
-p2v-client/lib/virt-p2v/blockdevice.rb
-p2v-client/lib/virt-p2v/connection.rb
-p2v-client/lib/virt-p2v/converter.rb
-p2v-client/lib/virt-p2v/gtk-queue.rb
-p2v-client/lib/virt-p2v/netdevice.rb
-p2v-client/lib/virt-p2v/ui/connect.rb
-p2v-client/lib/virt-p2v/ui/convert.rb
-p2v-client/lib/virt-p2v/ui/main.rb
-p2v-client/lib/virt-p2v/ui/network.rb
-p2v-client/lib/virt-p2v/ui/p2v.ui
-p2v-client/lib/virt-p2v/ui/success.rb
-p2v-client/Manifest
-p2v-client/Rakefile
-p2v-client/virt-p2v.gemspec
-p2v-image-builder/common-install.ks
-p2v-image-builder/common-manifest-post.ks
-p2v-image-builder/common-minimizer.ks
-p2v-image-builder/common-pkgs.ks
-p2v-image-builder/common-post-nochroot.ks
-p2v-image-builder/common-post.ks
-p2v-image-builder/Makefile
-p2v-image-builder/version.ks
-p2v-image-builder/virt-p2v-image-builder
-p2v-image-builder/virt-p2v-image.ks
-p2v-server/run-p2v-locally
-p2v-server/virt-p2v-server.pl
+p2v/client/bin/virt-p2v
+p2v/client/lib/virt-p2v/blockdevice.rb
+p2v/client/lib/virt-p2v/connection.rb
+p2v/client/lib/virt-p2v/converter.rb
+p2v/client/lib/virt-p2v/gtk-queue.rb
+p2v/client/lib/virt-p2v/netdevice.rb
+p2v/client/lib/virt-p2v/ui/connect.rb
+p2v/client/lib/virt-p2v/ui/convert.rb
+p2v/client/lib/virt-p2v/ui/main.rb
+p2v/client/lib/virt-p2v/ui/network.rb
+p2v/client/lib/virt-p2v/ui/p2v.ui
+p2v/client/lib/virt-p2v/ui/success.rb
+p2v/client/Manifest
+p2v/client/Rakefile
+p2v/client/virt-p2v.gemspec
+p2v/image-builder/common-install.ks
+p2v/image-builder/common-manifest-post.ks
+p2v/image-builder/common-minimizer.ks
+p2v/image-builder/common-pkgs.ks
+p2v/image-builder/common-post-nochroot.ks
+p2v/image-builder/common-post.ks
+p2v/image-builder/Makefile
+p2v/image-builder/version.ks
+p2v/image-builder/virt-p2v-image-builder
+p2v/image-builder/virt-p2v-image.ks
+p2v/server/run-p2v-locally
+p2v/server/virt-p2v-server.pl
po/es.po
po/it.po
po/Makefile
diff -ruN virt-v2v-v0.8.1/p2v/client/bin/virt-p2v virt-v2v-v0.8.1.new/p2v/client/bin/virt-p2v
--- virt-v2v-v0.8.1/p2v/client/bin/virt-p2v 1970-01-01 01:00:00.000000000 +0100
+++ virt-v2v-v0.8.1.new/p2v/client/bin/virt-p2v 2011-05-11 17:20:21.000000000 +0100
@@ -0,0 +1,62 @@
+#!/usr/bin/env ruby
+
+# Copyright (C) 2011 Red Hat Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+require 'virt-p2v/ui/main'
+require 'virt-p2v/ui/network'
+require 'virt-p2v/ui/connect'
+require 'virt-p2v/ui/convert'
+require 'virt-p2v/ui/success'
+
+require 'virt-p2v/converter'
+require 'virt-p2v/netdevice'
+
+require 'gettext'
+
+include GetText
+
+bindtextdomain('virt-p2v')
+
+if Process.uid != 0
+ puts _("virt-p2v must be executed with root privileges.\n" +
+ "It is intended to be included in a custom Live image, not " +
+ "run from the command\nline.")
+ abort
+end
+
+converter = VirtP2V::Converter.new
+
+# Initialise the wizard UI
+ui = VirtP2V::UI::Main.new
+
+# Initialize wizard pages
+VirtP2V::UI::Network.init(ui)
+VirtP2V::UI::Connect.init(ui, converter)
+VirtP2V::UI::Convert.init(ui, converter)
+VirtP2V::UI::Success.init(ui)
+
+# Skip the network configuration screen if there is already an active network
+# connection
+VirtP2V::NetworkDevice.all_devices.each { |device|
+ if device.activated then
+ ui.active_page = 'server_win'
+ break
+ end
+}
+
+ui.show
+ui.main_loop
diff -ruN virt-v2v-v0.8.1/p2v/client/lib/virt-p2v/blockdevice.rb virt-v2v-v0.8.1.new/p2v/client/lib/virt-p2v/blockdevice.rb
--- virt-v2v-v0.8.1/p2v/client/lib/virt-p2v/blockdevice.rb 1970-01-01 01:00:00.000000000 +0100
+++ virt-v2v-v0.8.1.new/p2v/client/lib/virt-p2v/blockdevice.rb 2011-05-11 17:20:21.000000000 +0100
@@ -0,0 +1,112 @@
+# Copyright (C) 2011 Red Hat Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+module VirtP2V
+
+class NoSuchDeviceError < StandardError; end
+
+class FixedBlockDevice
+ @@devices = {}
+
+ def self.all_devices
+ @@devices.values
+ end
+
+ def self.[](device)
+ raise NoSuchDeviceError unless @@devices.has_key?(device)
+
+ @@devices[device]
+ end
+
+ attr_reader :device
+
+ def initialize(device)
+ @device = device
+ @@devices[device] = self
+ end
+end
+
+class RemovableBlockDevice
+ @@devices = {}
+
+ def self.all_devices
+ @@devices.values
+ end
+
+ def self.[](device)
+ raise NoSuchDeviceError unless @@devices.has_key?(device)
+
+ @@devices[device]
+ end
+
+ attr_reader :device, :type
+
+ def initialize(device, type)
+ @device = device
+ @type = type
+
+ @@devices[device] = self
+ end
+end
+
+# Detect and instantiate all fixed and removable block devices in the system
+begin
+ # Look for block devices
+ # Specifically, we look for entries in /sys/block which have a device
+ # symlink and no entries in their slaves subdirectory
+ Dir.foreach('/sys/block') { |dev|
+ next if dev == '.' || dev == '..'
+
+ # Skip if there's no device link
+ next unless File.exists?("/sys/block/#{dev}/device")
+
+ # Skip if the slaves subdirectory contains anything other than . and
+ # ..
+ begin
+ next if Dir.entries("/sys/block/#{dev}/slaves").length > 2
+ rescue Errno::ENOENT => ex
+ # This shouldn't happen, but if it did I guess it would mean
+ # there are no slave devices
+ end
+
+ # We've got a real block device. Check if it's removable or not
+ File.open("/sys/block/#{dev}/removable") { |fd|
+ removable = fd.gets.chomp
+ if removable == "0" then
+ FixedBlockDevice.new(dev)
+ else
+ # Look in device/modalias to work out what kind of removable
+ # device this is
+ type = File.open(
+ "/sys/block/#{dev}/device/modalias") \
+ { |modalias_f|
+ modalias = modalias_f.gets.chomp
+ if modalias =~ /floppy/ then
+ 'floppy'
+ elsif modalias =~ /cdrom/ then
+ 'cdrom'
+ else
+ # We don't know what this is, ignore it
+ end
+ }
+
+ RemovableBlockDevice.new(dev, type) unless type.nil?
+ end
+ }
+ }
+end
+
+end
diff -ruN virt-v2v-v0.8.1/p2v/client/lib/virt-p2v/connection.rb virt-v2v-v0.8.1.new/p2v/client/lib/virt-p2v/connection.rb
--- virt-v2v-v0.8.1/p2v/client/lib/virt-p2v/connection.rb 1970-01-01 01:00:00.000000000 +0100
+++ virt-v2v-v0.8.1.new/p2v/client/lib/virt-p2v/connection.rb 2011-05-11 17:20:21.000000000 +0100
@@ -0,0 +1,320 @@
+# Copyright (C) 2011 Red Hat Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+require 'gettext'
+require 'rubygems'
+require 'net/ssh'
+require 'thread'
+require 'yaml'
+
+require 'virt-p2v/gtk-queue'
+
+module VirtP2V
+
+class Connection
+ include GetText
+
+ attr_reader :connected
+
+ class InvalidHostnameError < StandardError; end
+ class InvalidCredentialsError < StandardError; end
+ class TransportError < StandardError; end
+ class NoP2VError < StandardError; end
+ class RemoteError < StandardError; end
+ class ProtocolError < StandardError; end
+ class NotConnectedError < StandardError; end
+
+ def on_connect(&cb)
+ @connection_listeners << cb
+ end
+
+ def initialize(hostname, username, password, &cb)
+ @mutex = Mutex.new
+ @connection_listeners = []
+
+ # Always send our version number on connection
+ @connection_listeners << Proc.new { |cb|
+ self.version { |result| cb.call(result) }
+ }
+
+ run(cb) {
+ error = nil
+ begin
+ @ssh = Net::SSH.start(hostname, username, :password => password)
+ rescue SocketError, Errno::EHOSTUNREACH => ex
+ raise InvalidHostnameError
+ raise ex
+ rescue Net::SSH::AuthenticationFailed => ex
+ raise InvalidCredentialsError
+ raise ex
+ end
+
+ @buffer = ""
+ @connected = false
+
+ Gtk.queue { cb.call(true) }
+ }
+ end
+
+ def connect(&cb)
+ run(cb) {
+ @ch = @ssh.open_channel do |ch|
+ ch.exec("virt-p2v-server") do |ch, success|
+ raise RemoteError,
+ "could not execute a remote command" unless success
+
+ ch.on_data do |ch, data|
+ @buffer << data
+ end
+
+ # If we get anything on stderr, raise it as a RemoteError
+ ch.on_extended_data do |ch, type, data|
+ close
+ raise RemoteError, data
+ end
+
+ # Clean up local resources if we get eof from the other end
+ ch.on_eof do |ch|
+ close
+ end
+
+ @connected = true
+ end
+
+ end
+
+ # Wait until we're connected
+ @ssh.loop do
+ !@connected
+ end
+
+ i = 0;
+ listener_result = lambda { |result|
+ if result.kind_of?(Exception)
+ cb.call(result)
+ else
+ i += 1
+ if i == @connection_listeners.length
+ cb.call(true)
+ else
+ Gtk.queue {
+ @connection_listeners[i].call(listener_result)
+ }
+ end
+ end
+ }
+ Gtk.queue { @connection_listeners[0].call(listener_result) }
+ }
+ end
+
+ def close
+ @connected = false
+ @buffer = ""
+ @ch.close
+ end
+
+ def version(&cb)
+ raise NotConnectedError unless @connected
+
+ run(cb) {
+ @ch.send_data("VERSION 0\n")
+ result = parse_return
+
+ Gtk.queue { cb.call(result) }
+ }
+ end
+
+ def lang(lang, &cb)
+ raise NotConnectedError unless @connected
+
+ run(cb) {
+ @ch.send_data("LANG #{lang}\n")
+ result = parse_return
+
+ Gtk.queue { cb.call(result) }
+ }
+ end
+
+ def metadata(meta, &cb)
+ raise NotConnectedError unless @connected
+
+ run(cb) {
+ payload = YAML::dump(meta)
+ @ch.send_data("METADATA #{payload.length}\n");
+ @ch.send_data(payload)
+ result = parse_return
+
+ Gtk.queue { cb.call(result) }
+ }
+ end
+
+ def path(length, path, &cb)
+ raise NotConnectedError unless @connected
+
+ run(cb) {
+ @ch.send_data("PATH #{length} #{path}\n")
+ result = parse_return
+
+ Gtk.queue { cb.call(result) }
+ }
+ end
+
+ def convert(&cb)
+ raise NotConnectedError unless @connected
+
+ run(cb) {
+ @ch.send_data("CONVERT\n")
+ result = parse_return
+
+ Gtk.queue { cb.call(result) }
+ }
+ end
+
+ def list_profiles(&cb)
+ raise NotConnectedError unless @connected
+
+ run(cb) {
+ @ch.send_data("LIST_PROFILES\n")
+ result = parse_return
+
+ Gtk.queue { cb.call(result) }
+ }
+ end
+
+ def set_profile(profile, &cb)
+ raise NotConnectedError unless @connected
+
+ run(cb) {
+ @ch.send_data("SET_PROFILE #{profile}\n")
+ result = parse_return
+
+ Gtk.queue { cb.call(result) }
+ }
+ end
+
+ def container(type, &cb)
+ raise NotConnectedError unless @connected
+
+ run(cb) {
+ @ch.send_data("CONTAINER #{type}\n")
+ result = parse_return
+
+ Gtk.queue { cb.call(result) }
+ }
+ end
+
+ def send_data(io, length, progress, &completion)
+ raise NotConnectedError unless @connected
+
+ run(completion) {
+ @ch.send_data("DATA #{length}\n")
+ total = 0
+ buffer = ''
+ begin
+ # This loop is in the habit of hanging in Net::SSH when sending
+ # a chunk larger than about 2M. Putting the 1 second wait
+ # timeout here kickstarts it if it stops.
+ @ssh.loop(1) {
+ if io.eof? || total == length then
+ false
+ else
+ if @ch.remote_window_size > 0 then
+ out = length - total
+ out = @ch.remote_window_size \
+ if out > @ch.remote_window_size
+
+ io.read(out, buffer)
+ @ch.send_data(buffer)
+
+ total += buffer.length
+
+ # Send a progress callback
+ Gtk.queue { progress.call(total) }
+ end
+
+ true
+ end
+ }
+ rescue => ex
+ Gtk.queue { completion.call(ex) }
+ end
+
+ result = parse_return
+
+ Gtk.queue { completion.call(result) }
+ }
+ end
+
+ private
+
+ def run(cb)
+ # Run the given block in a new thread
+ t = Thread.new {
+ begin
+ # We can't run more than 1 command simultaneously
+ @mutex.synchronize { yield }
+ rescue => ex
+ # Deliver exceptions to the caller, then re-raise them
+ Gtk.queue { cb.call(ex) }
+ raise ex
+ end
+ }
+ t.priority = 1
+ end
+
+ # Return a single line of output from the remote server
+ def readline
+ # Run the event loop until the buffer contains a newline
+ index = nil
+ @ssh.loop do
+ if !@ch.eof? then
+ index = @buffer.index("\n")
+ index.nil?
+ else
+ close
+ raise RemoteError, _('Server closed connection unexpectedly')
+ end
+ end
+
+ # Remove the line from the buffer and return it with the trailing
+ # newline removed
+ @buffer.slice!(0..index).chomp
+ end
+
+ def parse_return
+ line = readline
+ line =~ /^(OK|ERROR|LIST)(?:\s(.*))?$/ or
+ raise ProtocolError, "Invalid server response: #{line}"
+
+ return true if $~[1] == 'OK'
+ if $~[1] == 'ERROR' then
+ close
+ raise RemoteError, $~[2]
+ end
+
+ # LIST response. Get the number of items, and read that many lines
+ n = Integer($~[2])
+ ret = []
+ while n > 0 do
+ n -= 1
+ ret.push(readline)
+ end
+
+ ret
+ end
+end
+
+end
diff -ruN virt-v2v-v0.8.1/p2v/client/lib/virt-p2v/converter.rb virt-v2v-v0.8.1.new/p2v/client/lib/virt-p2v/converter.rb
--- virt-v2v-v0.8.1/p2v/client/lib/virt-p2v/converter.rb 1970-01-01 01:00:00.000000000 +0100
+++ virt-v2v-v0.8.1.new/p2v/client/lib/virt-p2v/converter.rb 2011-05-11 17:20:21.000000000 +0100
@@ -0,0 +1,218 @@
+# Copyright (C) 2011 Red Hat Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+require 'gettext'
+require 'rexml/document'
+include REXML
+
+require 'virt-p2v/netdevice'
+require 'virt-p2v/blockdevice'
+
+module VirtP2V
+
+# NIC
+# hostname
+# username
+# password
+
+# 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
+
+class Converter
+ include GetText
+
+ attr_accessor :profile, :name, :cpus, :memory, :arch
+ attr_reader :features, :disks, :removables, :nics
+
+ attr_reader :connection
+
+ def on_connection(&cb)
+ @connection_listeners << cb
+ end
+
+ def connection=(connection)
+ @connection = connection
+ @connection_listeners.each { |cb|
+ cb.call(connection)
+ }
+ end
+
+ 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|
+ status.call(_('Converting'))
+ @connection.convert(&cb)
+ }
+ ], completion)
+ end
+
+ private
+
+ def initialize()
+ @profile = nil
+ @connection = nil
+ @connection_listeners = []
+
+ # 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 `hwloc-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 = []
+ end
+
+ def disk(dev, status, progress, completion)
+ path = "/dev/#{dev}"
+ # XXX: No error checking of blockdev execution
+ size = Integer(`blockdev --getsize64 #{path}`.chomp)
+ 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 += 1
+ progress.call(dev, pc)
+ end
+ }, &cb)
+ }
+ ], completion)
+ end
+
+ 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
+
+ def meta
+ {
+ 'name' => @name,
+ 'cpus' => @cpus,
+ 'memory' => @memory,
+ 'arch' => @arch,
+ 'features' => @features,
+ 'disks' => @disks.map { |device|
+ {
+ 'device' => device,
+ 'path' => "/dev/#{device}",
+ 'is_block' => '1',
+ 'format' => 'raw'
+ }
+ },
+ '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
+end
+
+end
diff -ruN virt-v2v-v0.8.1/p2v/client/lib/virt-p2v/gtk-queue.rb virt-v2v-v0.8.1.new/p2v/client/lib/virt-p2v/gtk-queue.rb
--- virt-v2v-v0.8.1/p2v/client/lib/virt-p2v/gtk-queue.rb 1970-01-01 01:00:00.000000000 +0100
+++ virt-v2v-v0.8.1.new/p2v/client/lib/virt-p2v/gtk-queue.rb 2011-05-11 17:20:21.000000000 +0100
@@ -0,0 +1,52 @@
+# Copyright (C) 2011 Red Hat Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+# This code is taken from:
+# http://ruby-gnome2.sourceforge.jp/hiki.cgi?tips_threads
+# The author of the above page is given as Tal Liron
+# The above page is distributed under the terms of the GNU FDL, although I
+# consider this code to be too trivial to be copyrightable
+
+require 'gtk2'
+require 'thread'
+
+module Gtk
+ GTK_PENDING_BLOCKS = []
+ GTK_PENDING_BLOCKS_LOCK = Mutex.new
+
+ def Gtk.queue &block
+ if Thread.current == Thread.main
+ block.call
+ else
+ GTK_PENDING_BLOCKS_LOCK.synchronize do
+ GTK_PENDING_BLOCKS << block
+ end
+ end
+ end
+
+ def Gtk.main_with_queue timeout
+ Gtk.timeout_add timeout do
+ GTK_PENDING_BLOCKS_LOCK.synchronize do
+ for block in GTK_PENDING_BLOCKS
+ block.call
+ end
+ GTK_PENDING_BLOCKS.clear
+ end
+ true
+ end
+ Gtk.main
+ end
+end
diff -ruN virt-v2v-v0.8.1/p2v/client/lib/virt-p2v/netdevice.rb virt-v2v-v0.8.1.new/p2v/client/lib/virt-p2v/netdevice.rb
--- virt-v2v-v0.8.1/p2v/client/lib/virt-p2v/netdevice.rb 1970-01-01 01:00:00.000000000 +0100
+++ virt-v2v-v0.8.1.new/p2v/client/lib/virt-p2v/netdevice.rb 2011-05-11 17:20:21.000000000 +0100
@@ -0,0 +1,259 @@
+# Copyright (C) 2011 Red Hat Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+require 'dbus'
+require 'gettext'
+
+module VirtP2V
+
+class NetworkDevice
+ include GetText
+
+ attr_reader :name, :mac, :connected, :activated, :state
+
+ # Some NetworkManager names, for convenience
+ CONNECTION = 'org.freedesktop.NetworkManagerSettings.Connection'.freeze
+ DEVICE = 'org.freedesktop.NetworkManager.Device'.freeze
+ NETWORKMANAGER = 'org.freedesktop.NetworkManager'.freeze
+ PROPERTIES = 'org.freedesktop.DBus.Properties'.freeze
+ SETTINGS = 'org.freedesktop.NetworkManagerSettings'.freeze
+ WIRED = 'org.freedesktop.NetworkManager.Device.Wired'.freeze
+
+ # NetworkManager device types
+ # http://projects.gnome.org/NetworkManager/developers/spec-08.html
+ TYPE_UNKNOWN = 0
+ TYPE_ETHERNET = 1
+ TYPE_WIFI = 2
+ TYPE_GSM = 3
+ TYPE_CDMA = 4
+
+ # NetworkManager device states
+ STATE_UNKNOWN = 0
+ STATE_UNMANAGED = 1
+ STATE_UNAVAILABLE = 2
+ STATE_DISCONNECTED = 3
+ STATE_PREPARE = 4
+ STATE_CONFIG = 5
+ STATE_NEED_AUTH = 6
+ STATE_IP_CONFIG = 7
+ STATE_ACTIVATED = 8
+ STATE_FAILED = 9
+
+ # Human readable descriptions of NetworkManager Device States
+ STATES = {
+ 0 => _('Unknown').freeze, # For completeness
+ 1 => _('Unmanaged').freeze, # For completeness
+ 2 => _('No cable connected').freeze,
+ 3 => _('Not connected').freeze,
+ 4 => _('Preparing to connect').freeze,
+ 5 => _('Configuring').freeze,
+ 6 => _('Waiting for authentication').freeze,
+ 7 => _('Obtaining an IP address').freeze,
+ 8 => _('Connected').freeze,
+ 9 => _('Connection failed').freeze
+ }.freeze
+
+ def initialize(obj, device, props)
+ device.default_iface = WIRED
+
+ @nm_obj = obj
+ @name = props.Get(DEVICE, 'Interface')[0]
+ @mac = props.Get(WIRED, 'HwAddress')[0]
+ state = props.Get(WIRED, 'State')[0]
+
+ # Lookup by name
+ @@devices[@name] = self
+
+ state_updated(state)
+
+ # Register a listener for state changes
+ device.on_signal('PropertiesChanged') { |props|
+ if props.has_key?('State') then
+ state_updated(props['State'])
+
+ # Notify registered state change handlers
+ @@listeners.each { |cb| cb.call(self) }
+ end
+ }
+ end
+
+ def self.all_devices()
+ @@devices.values
+ end
+
+ def self.add_listener(cb)
+ @@listeners.push(cb)
+ end
+
+ def self.[](name)
+ @@devices[name]
+ end
+
+ def activate(auto, ip, prefix, gateway, dns)
+ # Get an IP config dependent on whether @ip_address is IPv4 or IPv6
+ ip_config = auto ? get_config_auto :
+ ip.ipv4? ? get_config_ipv4() : get_config_ipv6()
+
+ # Create a new NetworkManager connection object
+ settings = @@nm_service.object(
+ '/org/freedesktop/NetworkManagerSettings')
+ settings.introspect()
+ settings.default_iface = SETTINGS
+
+ uuid = `uuidgen`.chomp
+ settings.AddConnection(
+ 'connection' => {
+ 'uuid' => uuid,
+ 'id' => 'P2V',
+ 'type' => '802-3-ethernet',
+ 'autoconnect' => false
+ },
+ '802-3-ethernet' => {},
+ 'ipv4' => ip_config['ipv4'],
+ 'ipv6' => ip_config['ipv6']
+ )
+
+ # Find the connection we just created
+ # XXX: There must be a better way to get this!
+ conn = settings.ListConnections()[0].each { |i|
+ conn = @@nm_service.object(i)
+ conn.introspect
+ conn.default_iface = CONNECTION
+
+ break i if conn.GetSettings()[0]['connection']['uuid'] == uuid
+ }
+
+ nm = @@nm_service.object('/org/freedesktop/NetworkManager')
+ nm.introspect
+ nm.default_iface = NETWORKMANAGER
+ nm.ActivateConnection('org.freedesktop.NetworkManagerSystemSettings',
+ conn, @nm_obj, '/')
+ end
+
+ private
+
+ def state_updated(state)
+ @connected = state > 2
+ @state = STATES[state]
+
+ if state == STATE_ACTIVATED then
+ @activated = true
+ elsif state == STATE_FAILED then
+ @activated = false
+ else
+ @activated = nil
+ end
+ end
+
+ def get_config_auto
+ {
+ 'ipv4' => {
+ 'method' => 'auto'
+ },
+ 'ipv6' => {
+ 'method' => 'ignore'
+ }
+ }
+ end
+
+ def ipv4_to_nm(ipaddr)
+ ipaddr.hton().unpack("I")[0]
+ end
+
+ def get_config_ipv4
+ addresses = [[ ipv4_to_nm(@ip_address), @ip_prefix,
+ ipv4_to_nm(@ip_gateway) ]]
+
+ dns = []
+ @ip_dns.each{ |ipaddr|
+ # Only use IPv4 DNS servers
+ next unless ipaddr.ipv4?
+ dns.push(ipv4_to_nm(ipaddr))
+ }
+
+ {
+ 'ipv4' => {
+ 'method' => 'manual',
+ 'addresses' => [ 'aau', addresses ],
+ 'dns' => [ 'au', dns ]
+ },
+ 'ipv6' => {
+ 'method' => 'ignore'
+ }
+ }
+ end
+
+ def ipv6_to_nm(ipaddr)
+ ipaddr.hton().unpack("c*")
+ end
+
+ def get_config_ipv6
+ dns = []
+ @ip_dns.each { |ipaddr|
+ # Only use IPv6 DNS servers
+ next unless ipaddr.ipv6?
+ dns.push(ipv6_to_nm(ipaddr))
+ }
+
+ {
+ 'ipv4' => {
+ 'method' => 'disabled'
+ },
+ 'ipv6' => {
+ 'method' => 'manual',
+ 'addresses' => [ 'a(ayu)', [[
+ ipv6_to_nm(@ip_address),
+ @ip_prefix
+ ]] ],
+ 'routes' => [ 'a(ayuayu)', [[
+ [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], 0,
+ ipv6_to_nm(@ip_gateway), 1024
+ ]] ],
+ 'dns' => [ 'aay', dns ]
+ }
+ }
+ end
+
+ # Class initialization
+ begin
+ dbus = DBus::SystemBus.instance()
+ dbus.glibize()
+ @@nm_service = dbus.service(NETWORKMANAGER)
+
+ nm = @@nm_service.object('/org/freedesktop/NetworkManager')
+ nm.introspect
+ nm.default_iface = NETWORKMANAGER
+
+ @@devices = {}
+ nm.GetDevices()[0].each { |obj|
+ device = @@nm_service.object(obj)
+ device.introspect
+
+ props = device[PROPERTIES]
+ type = props.Get(DEVICE, 'DeviceType')[0]
+
+ # We only support ethernet devices
+ next unless type == TYPE_ETHERNET
+
+ # Constructor will add it to @@devices
+ self.new(obj, device, props)
+ }
+
+ @@listeners = []
+ end
+end
+
+end #module
diff -ruN virt-v2v-v0.8.1/p2v/client/lib/virt-p2v/ui/connect.rb virt-v2v-v0.8.1.new/p2v/client/lib/virt-p2v/ui/connect.rb
--- virt-v2v-v0.8.1/p2v/client/lib/virt-p2v/ui/connect.rb 1970-01-01 01:00:00.000000000 +0100
+++ virt-v2v-v0.8.1.new/p2v/client/lib/virt-p2v/ui/connect.rb 2011-05-11 17:20:21.000000000 +0100
@@ -0,0 +1,179 @@
+# Copyright (C) 2011 Red Hat Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+require 'gettext'
+require 'gtk2'
+
+require 'virt-p2v/connection'
+
+module VirtP2V::UI::Connect
+ include GetText
+
+ UI_STATE_INVALID = 0
+ UI_STATE_VALID = 1
+ UI_STATE_ACTIVATING = 2
+ UI_STATE_COMPLETE = 3
+
+ EV_HOSTNAME = 0
+ EV_USERNAME = 1
+ EV_PASSWORD = 2
+ EV_BUTTON = 3
+ EV_ACTIVATION = 4
+
+ def self.event(event, status)
+ case event
+ when EV_HOSTNAME
+ @hostname = status
+ when EV_USERNAME
+ @username = status
+ when EV_PASSWORD
+ @password = status
+ when EV_BUTTON, EV_ACTIVATION
+ # Persistent state not required
+ else
+ raise "Unexpected event: #{event}"
+ end
+
+ valid = @hostname && @username && @password
+
+ case @state
+ when UI_STATE_INVALID
+ set_state(UI_STATE_VALID) if valid
+ when UI_STATE_VALID
+ if !valid then
+ set_state(UI_STATE_INVALID)
+ elsif event == EV_BUTTON
+ set_state(UI_STATE_ACTIVATING)
+ end
+ when UI_STATE_ACTIVATING
+ # UI is disabled, so we shouldn't be getting any events other than
+ # EV_ACTIVATION
+ raise "Unexpected event: #{event}" unless event == EV_ACTIVATION
+
+ set_state(status ? UI_STATE_COMPLETE : UI_STATE_VALID)
+ else
+ raise "Unexpected UI state: #{@state}"
+ end
+ end
+
+ def self.init(ui, converter)
+ @hostname_ui = ui.get_object('server_hostname')
+ @username_ui = ui.get_object('server_username')
+ @password_ui = ui.get_object('server_password')
+ @connect_frame = ui.get_object('connect_frame')
+ @connect_button = ui.get_object('connect_button')
+ @connect_error = ui.get_object('connect_error')
+
+ ui.register_handler('server_hostname_changed',
+ method(:server_hostname_changed))
+ ui.register_handler('server_username_changed',
+ method(:server_username_changed))
+ ui.register_handler('server_password_changed',
+ method(:server_password_changed))
+ ui.register_handler('connect_button_clicked',
+ method(:connect_button_clicked))
+
+ @hostname = @hostname_ui.text.strip.length > 0
+ @username = @username_ui.text.strip.length > 0
+ @password = @password_ui.text.length > 0 # Allow spaces in passwords
+ @state = UI_STATE_INVALID
+
+ @ui = ui
+ @converter = converter
+ end
+
+ def self.set_state(state)
+ # Don't do anything if state hasn't changed
+ return if state == @state
+
+ case state
+ when UI_STATE_INVALID
+ @connect_frame.sensitive = true
+ @connect_button.sensitive = false
+
+ @state = UI_STATE_INVALID
+ when UI_STATE_VALID
+ @connect_frame.sensitive = true
+ @connect_button.sensitive = true
+
+ @state = UI_STATE_VALID
+ when UI_STATE_ACTIVATING
+ @connect_frame.sensitive = false
+ @connect_button.sensitive = false
+ @connect_error.text = ''
+
+ @state = UI_STATE_ACTIVATING
+ when UI_STATE_COMPLETE
+ # Activate the next page
+ @ui.active_page = 'conversion_win'
+
+ # ... then leave this one as we hope to find it if we come back here
+ set_state(UI_STATE_VALID)
+ else
+ raise "Attempt to set unexpected UI state: #{@state}"
+ end
+ end
+
+ def self.server_hostname_changed
+ event(EV_HOSTNAME, @hostname_ui.text.strip.length > 0)
+ end
+
+ def self.server_username_changed
+ event(EV_USERNAME, @username_ui.text.strip.length > 0)
+ end
+
+ def self.server_password_changed
+ event(EV_PASSWORD, @password_ui.text.length > 0)
+ end
+
+ def self.connect_button_clicked
+ event(EV_BUTTON, true)
+
+ hostname = @hostname_ui.text.strip
+ username = @username_ui.text.strip
+ password = @password_ui.text
+ connection = VirtP2V::Connection.new(hostname, username, password) \
+ { |result|
+ case result
+ when true
+ @converter.connection = connection
+ connection.connect { |result|
+ case result
+ when true
+ event(EV_ACTIVATION, true)
+ when VirtP2V::Connection::RemoteError
+ @connect_error.text = _('Failed to start ' +
+ 'virt-p2v-server on remote ' +
+ 'server')
+ event(EV_ACTIVATION, false)
+ else
+ @connect_error.text = result.message
+ event(EV_ACTIVATION, false)
+ end
+ }
+ when VirtP2V::Connection::InvalidHostnameError
+ @connect_error.text = _"Unable to connect to #{hostname}"
+ event(EV_ACTIVATION, false)
+ when VirtP2V::Connection::InvalidCredentialsError
+ @connect_error.text = _"Invalid username/password"
+ event(EV_ACTIVATION, false)
+ else
+ raise result
+ end
+ }
+ end
+
+end # module
diff -ruN virt-v2v-v0.8.1/p2v/client/lib/virt-p2v/ui/convert.rb virt-v2v-v0.8.1.new/p2v/client/lib/virt-p2v/ui/convert.rb
--- virt-v2v-v0.8.1/p2v/client/lib/virt-p2v/ui/convert.rb 1970-01-01 01:00:00.000000000 +0100
+++ virt-v2v-v0.8.1.new/p2v/client/lib/virt-p2v/ui/convert.rb 2011-05-11 17:20:21.000000000 +0100
@@ -0,0 +1,422 @@
+# Copyright (C) 2011 Red Hat Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+require 'gettext'
+require 'gtk2'
+
+require 'virt-p2v/blockdevice'
+require 'virt-p2v/netdevice'
+
+module VirtP2V::UI::Convert
+ include GetText
+
+ CONVERT_PROFILE_NAME = 0
+
+ CONVERT_NETWORK_CONVERT = 0
+ CONVERT_NETWORK_DEVICE = 1
+
+ CONVERT_FIXED_CONVERT = 0
+ CONVERT_FIXED_DEVICE = 1
+ CONVERT_FIXED_PROGRESS = 2
+
+ CONVERT_REMOVABLE_CONVERT = 0
+ CONVERT_REMOVABLE_DEVICE = 1
+ CONVERT_REMOVABLE_TYPE = 2
+
+ UI_STATE_INVALID = 0
+ UI_STATE_VALID = 1
+ UI_STATE_CONNECTING = 2
+ UI_STATE_CONVERTING = 3
+ UI_STATE_COMPLETE = 4
+
+ EV_VALID = 0
+ EV_BUTTON = 1
+ EV_CONNECTION = 2
+ EV_CONVERTED = 3
+
+ def self.init(ui, converter)
+ # ListStores
+ @profiles = ui.get_object('convert_profile_list')
+ @nics = ui.get_object('convert_network_list')
+ @fixeds = ui.get_object('convert_fixed_list')
+ @removables = ui.get_object('convert_removable_list')
+
+ # Widgets
+ @profile = ui.get_object('convert_profile')
+ @name = ui.get_object('convert_name')
+ @cpus = ui.get_object('convert_cpus')
+ @memory = ui.get_object('convert_memory')
+ @editable = ui.get_object('convert_editable')
+ @button = ui.get_object('convert_button')
+ @status = ui.get_object('convert_status')
+
+ # Get initial values from converter
+ @name.text = converter.name
+ @cpus.text = converter.cpus.to_s
+ @memory.text = (converter.memory / 1024 / 1024).to_s
+
+ # Populate profiles on connection
+ converter.on_connection { |conn|
+ conn.on_connect { |cb|
+ conn.list_profiles { |profiles|
+ cb.call(RuntimeError.new(_('Remote server does not ' +
+ 'define any profiles in ' +
+ '/etc/virt-v2v.conf'))) \
+ if profiles.kind_of?(Exception) or profiles.empty?
+
+ selected = @profile.active_iter
+ selected = selected[CONVERT_PROFILE_NAME] \
+ unless selected.nil?
+
+ @profiles.clear
+ profiles.each { |i|
+ profile = @profiles.append
+ profile[CONVERT_PROFILE_NAME] = i
+ @profile.active_iter = profile if i == selected
+ }
+
+ cb.call(true)
+ }
+ }
+ }
+
+ VirtP2V::FixedBlockDevice.all_devices.each { |dev|
+ fixed = @fixeds.append
+ fixed[CONVERT_FIXED_CONVERT] = true
+ fixed[CONVERT_FIXED_DEVICE] = dev.device
+ fixed[CONVERT_FIXED_PROGRESS] = 0
+ }
+
+ VirtP2V::RemovableBlockDevice.all_devices.each { |dev|
+ rem = @removables.append
+ rem[CONVERT_REMOVABLE_CONVERT] = true
+ rem[CONVERT_REMOVABLE_DEVICE] = dev.device
+ rem[CONVERT_REMOVABLE_TYPE] = dev.type
+ }
+
+ VirtP2V::NetworkDevice.all_devices.each { |dev|
+ nic = @nics.append
+ nic[CONVERT_NETWORK_CONVERT] = dev.connected
+ nic[CONVERT_NETWORK_DEVICE] = dev.name
+ }
+
+ # Event handlers
+ ui.register_handler('convert_profile_changed',
+ method(:update_values))
+ ui.register_handler('convert_name_changed',
+ method(:update_values))
+ ui.register_handler('convert_cpus_changed',
+ method(:convert_cpus_changed))
+ ui.register_handler('convert_memory_changed',
+ method(:convert_memory_changed))
+ ui.register_handler('convert_fixed_list_row_changed',
+ method(:convert_fixed_list_row_changed))
+ ui.register_handler('convert_removable_list_row_changed',
+ method(:update_values))
+ ui.register_handler('convert_network_list_row_changed',
+ method(:update_values))
+ ui.register_handler('convert_fixed_select_toggled',
+ method(:convert_fixed_select_toggled))
+ ui.register_handler('convert_removable_select_toggled',
+ method(:convert_removable_select_toggled))
+ ui.register_handler('convert_network_select_toggled',
+ method(:convert_network_select_toggled))
+ ui.register_handler('convert_button_clicked',
+ method(:convert_button_clicked))
+
+ @state = nil
+ set_state(UI_STATE_INVALID)
+ update_values
+
+ @ui = ui
+ @converter = converter
+ end
+
+ def self.event(event, status)
+ case @state
+ when UI_STATE_INVALID
+ case event
+ when EV_VALID
+ set_state(UI_STATE_VALID) if status
+ else
+ raise "Unexpected event: #{@state} #{event}"
+ end
+ when UI_STATE_VALID
+ case event
+ when EV_VALID
+ set_state(UI_STATE_INVALID) if !status
+ when EV_BUTTON
+ if @converter.connection.connected then
+ set_state(UI_STATE_CONVERTING)
+ convert
+ else
+ set_state(UI_STATE_CONNECTING)
+ reconnect
+ end
+ else
+ raise "Unexpected event: #{@state} #{event}"
+ end
+ when UI_STATE_CONNECTING
+ case event
+ when EV_CONNECTION
+ if status then
+ set_state(UI_STATE_CONVERTING)
+ convert
+ else
+ set_state(UI_STATE_VALID)
+ end
+ when EV_VALID
+ # update_values will be called when the profile list is cleared
+ # and repopulated during connection. Untidy, but ignore it.
+ else
+ raise "Unexpected event: #{@state} #{event}" \
+ unless event == EV_CONNECTION
+ end
+ when UI_STATE_CONVERTING
+ case event
+ when EV_CONVERTED
+ if status then
+ set_state(UI_STATE_COMPLETE)
+ else
+ set_state(UI_STATE_VALID)
+ end
+ when EV_VALID
+ # update_values will be called when the list stores are updated.
+ # Untidy, but ignore it
+ else
+ raise "Unexpected event: #{@state} #{event}"
+ end
+ else
+ raise "Unexpected UI state: #{@state}"
+ end
+ end
+
+ def self.set_state(state)
+ # Don't do anything if state hasn't changed
+ return if state == @state
+ @state = state
+
+ case @state
+ when UI_STATE_INVALID
+ @editable.sensitive = true
+ @button.sensitive = false
+ when UI_STATE_VALID
+ @editable.sensitive = true
+ @button.sensitive = true
+ when UI_STATE_CONNECTING
+ @status.text = _'Failed to start virt-p2v-server on remote server'
+ @editable.sensitive = false
+ @button.sensitive = false
+ when UI_STATE_CONVERTING
+ @editable.sensitive = false
+ @button.sensitive = false
+ when UI_STATE_COMPLETE
+ @ui.active_page = 'success_win'
+
+ # ... then leave this one as we hope to find it if we come back here
+ set_state(UI_STATE_VALID)
+ else
+ raise "Attempt to set unexpected UI state: #{@state}"
+ end
+ end
+
+ def self.convert
+ @converter.convert(
+ # status
+ lambda { |msg|
+ @status.text = msg
+ },
+ # progress
+ lambda { |dev, progress|
+ @fixeds.each { |model, path, iter|
+ next unless iter[CONVERT_FIXED_DEVICE] == dev
+
+ iter[CONVERT_FIXED_PROGRESS] = progress
+ break
+ }
+ }
+ ) { |result|
+ # N.B. Explicit test against true is required here, as result may be
+ # an Exception, which would also return true if evaluated alone
+ if result == true then
+ @status.text = ''
+ event(EV_CONVERTED, true)
+ else
+ @status.text = result.message
+ event(EV_CONVERTED, false)
+ end
+ }
+ end
+
+ def self.reconnect
+ @status.text = _('Reconnecting')
+ @converter.connection.connect { |result|
+ if result == true then
+ event(EV_CONNECTION, true)
+ else
+ @status.text =
+ _'Failed to start virt-p2v-server on remote server'
+ event(EV_CONNECTION, false)
+ end
+ }
+ end
+
+ def self.convert_fixed_list_row_changed(model, path, iter)
+ update_values
+ end
+
+ class InvalidUIState < StandardError; end
+
+ def self.update_values
+ valid = nil
+ begin
+ # Check there's a profile selected
+ profile = @profile.active_iter
+ raise InvalidUIState if profile.nil?
+ @converter.profile = profile[CONVERT_PROFILE_NAME]
+
+ # Check there's a name set
+ name = @name.text
+ raise InvalidUIState if name.nil? || name.strip.length == 0
+ @converter.name = name
+
+ # Check cpus and memory are set and numeric
+ cpus = @cpus.text
+ raise InvalidUIState if cpus.nil?
+ cpus = Integer(cpus) rescue nil
+ raise InvalidUIState if cpus.nil?
+ @converter.cpus = cpus
+
+ memory = @memory.text
+ raise InvalidUIState if memory.nil?
+ memory = Integer(memory) rescue nil
+ raise InvalidUIState if memory.nil?
+ @converter.memory = memory * 1024 * 1024
+
+ # Check that at least 1 fixed storage device is selected
+ fixed = false
+ @converter.disks.clear
+ @fixeds.each { |model, path, iter|
+ if iter[CONVERT_FIXED_CONVERT] then
+ fixed = true
+ @converter.disks << iter[CONVERT_FIXED_DEVICE]
+ end
+ }
+ raise InvalidUIState unless fixed
+
+ # Populate removables and nics, although these aren't required to be
+ # selected for the ui state to be valid
+ @converter.removables.clear
+ @removables.each { |model, path, iter|
+ if iter[CONVERT_REMOVABLE_CONVERT] then
+ @converter.removables << iter[CONVERT_REMOVABLE_DEVICE]
+ end
+ }
+ @converter.nics.clear
+ @nics.each { |model, path, iter|
+ if iter[CONVERT_NETWORK_CONVERT] then
+ @converter.nics << iter[CONVERT_NETWORK_DEVICE]
+ end
+ }
+ rescue InvalidUIState
+ valid = false
+ end
+ valid = true if valid.nil?
+
+ event(EV_VALID, valid)
+ end
+
+ def self.valid?
+ # Check there's a profile selected
+ profile = @profile.active_iter
+ return false if profile.nil?
+
+ # Check there's a name set
+ name = @name.text
+ return false if name.nil?
+ return false unless name.strip.length > 0
+
+ # Check cpus and memory are set and numeric
+ cpus = @cpus.text
+ return false if cpus.nil?
+ cpus = Integer(cpus) rescue nil
+ return false if cpus.nil?
+
+ memory = @memory.text
+ return false if memory.nil?
+ memory = Integer(memory) rescue nil
+ return false if memory.nil?
+
+ # Check that at least 1 fixed storage device is selected
+ fixed = false
+ @fixeds.each { |model, path, iter|
+ if iter[CONVERT_FIXED_CONVERT] then
+ fixed = true
+ break
+ end
+ }
+ return false unless fixed
+
+ return true
+ end
+
+ def self.convert_cpus_changed
+ check_numeric(@cpus)
+ end
+
+ def self.convert_memory_changed
+ check_numeric(@memory)
+ end
+
+ def self.check_numeric(widget)
+ value = widget.text
+ if value.nil? ? false : begin
+ value = Integer(value)
+ value > 0
+ rescue
+ false
+ end
+ then
+ widget.secondary_icon_name = nil
+ else
+ widget.secondary_icon_name = 'gtk-dialog-warning'
+ widget.secondary_icon_tooltip_text =
+ _('Value must be an integer greater than 0')
+ end
+
+ update_values
+ end
+
+ def self.convert_fixed_select_toggled(widget, path)
+ iter = @fixeds.get_iter(path)
+ iter[CONVERT_FIXED_CONVERT] = !iter[CONVERT_FIXED_CONVERT]
+ end
+
+ def self.convert_removable_select_toggled(widget, path)
+ iter = @removables.get_iter(path)
+ iter[CONVERT_REMOVABLE_CONVERT] = !iter[CONVERT_REMOVABLE_CONVERT]
+ end
+
+ def self.convert_network_select_toggled(widget, path)
+ iter = @nics.get_iter(path)
+ iter[CONVERT_NETWORK_CONVERT] = !iter[CONVERT_NETWORK_CONVERT]
+ end
+
+ def self.convert_button_clicked
+ event(EV_BUTTON, true)
+ end
+
+end # module
diff -ruN virt-v2v-v0.8.1/p2v/client/lib/virt-p2v/ui/main.rb virt-v2v-v0.8.1.new/p2v/client/lib/virt-p2v/ui/main.rb
--- virt-v2v-v0.8.1/p2v/client/lib/virt-p2v/ui/main.rb 1970-01-01 01:00:00.000000000 +0100
+++ virt-v2v-v0.8.1.new/p2v/client/lib/virt-p2v/ui/main.rb 2011-05-11 17:20:21.000000000 +0100
@@ -0,0 +1,110 @@
+# Copyright (C) 2011 Red Hat Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+require 'gtk2'
+require 'virt-p2v/gtk-queue'
+
+module VirtP2V
+module UI
+
+class Main
+ def get_object(name)
+ o = @builder.get_object(name)
+ raise "Object #{name} not found in ui" unless o != nil
+
+ return o
+ end
+
+ def show
+ @builder.connect_signals { |signal|
+ raise "No hander for signal #{signal}" \
+ unless @signal_handlers.has_key?(signal)
+
+ @signal_handlers[signal]
+ }
+
+ # Display the main window
+ main = self.get_object('main_window')
+ main.show_all()
+ end
+
+ def register_handler(signal, handler)
+ @signal_handlers[signal] = handler
+ end
+
+ def main_loop
+ Gtk.main_with_queue 100
+ end
+
+ def active_page=(name)
+ raise "Attempt to activate non-existent page #{name}" \
+ unless @pages.has_key?(name)
+
+ page = @pages[name]
+
+ @page_vbox = self.get_object('page_vbox') unless defined? @page_vbox
+ @page_vbox.remove(@selected) if defined? @selected
+ @page_vbox.add(page)
+ @selected = page
+ end
+
+ def active_page
+ return @selected
+ end
+
+ def quit
+ Gtk.main_quit()
+ end
+
+ private
+
+ def initialize
+ @builder = Gtk::Builder.new()
+
+ # Find the UI definition in $LOAD_PATH
+ i = $LOAD_PATH.index { |path|
+ File.exists?(path + '/virt-p2v/ui/p2v.ui')
+ }
+ @builder.add_from_file($LOAD_PATH[i] + '/virt-p2v/ui/p2v.ui')
+
+ @signal_handlers = {}
+ self.register_handler('gtk_main_quit', method(:quit))
+
+ # Configure the Wizard page frame
+ # Can't change these colours from glade for some reason
+ self.get_object('title_background').
+ modify_bg(Gtk::STATE_NORMAL, Gdk::Color.parse('#86ABD9'))
+ self.get_object('page_frame').
+ modify_fg(Gtk::STATE_NORMAL, Gdk::Color.parse('#86ABD9'))
+
+ # Load all pages from glade
+ @pages = {}
+ [ 'network_win', 'server_win',
+ 'conversion_win', 'success_win' ].each { |name|
+ page = self.get_object(name)
+
+ child = page.children[0]
+ page.remove(child)
+ @pages[name] = child
+ }
+
+ # Set a default first page
+ self.active_page = 'network_win'
+ end
+end
+
+end # UI
+end # VirtP2V
diff -ruN virt-v2v-v0.8.1/p2v/client/lib/virt-p2v/ui/network.rb virt-v2v-v0.8.1.new/p2v/client/lib/virt-p2v/ui/network.rb
--- virt-v2v-v0.8.1/p2v/client/lib/virt-p2v/ui/network.rb 1970-01-01 01:00:00.000000000 +0100
+++ virt-v2v-v0.8.1.new/p2v/client/lib/virt-p2v/ui/network.rb 2011-05-11 17:20:21.000000000 +0100
@@ -0,0 +1,317 @@
+# Copyright (C) 2011 Red Hat Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+require 'gettext'
+require 'gtk2'
+require 'ipaddr'
+require 'virt-p2v/netdevice'
+
+module VirtP2V::UI::Network
+ include GetText
+
+ # The indices of Device List colums, taken from glade
+ DEVCOL_NAME = 0
+ DEVCOL_MAC = 1
+ DEVCOL_STATUS = 2
+ DEVCOL_AVAILABLE = 3
+
+ UI_STATE_INVALID = 0
+ UI_STATE_VALID = 1
+ UI_STATE_ACTIVATING = 2
+ UI_STATE_COMPLETE = 3
+
+ EV_IP_CONFIG = 0
+ EV_SELECTION = 1
+ EV_BUTTON = 2
+ EV_ACTIVATION = 3
+
+ def self.event(event, status)
+ case event
+ when EV_IP_CONFIG
+ @ip_config = status
+ when EV_SELECTION
+ @selected = status
+ when EV_BUTTON, EV_ACTIVATION
+ # Persistent state not required
+ else
+ raise "Unexpected NetworkConfig event: #{event}"
+ end
+
+ case @state
+ when UI_STATE_INVALID
+ if @ip_config && @selected then
+ set_state(UI_STATE_VALID)
+ end
+ when UI_STATE_VALID
+ if !@ip_config || !@selected then
+ set_state(UI_STATE_INVALID)
+ elsif event == EV_BUTTON
+ set_state(UI_STATE_ACTIVATING)
+ end
+ when UI_STATE_ACTIVATING
+ # UI is disabled and we're waiting for EV_ACTIVATION, but we could
+ # also get events triggered by NetworkManager signals.
+
+ if event == EV_ACTIVATION then
+ if status then
+ set_state(UI_STATE_COMPLETE)
+ else
+ set_state(UI_STATE_VALID)
+ end
+ elsif !@ip_config || !@selected then
+ set_state(UI_STATE_INVALID)
+ end
+ else
+ raise "Unexpected NetworkConfig UI state: #{@state}"
+ end
+ end
+
+ def self.init(ui)
+ # Configure initial defaults
+ @manual_mode = false
+ @ip_address = nil
+ @ip_prefix = nil
+ @ip_gateway = nil
+ @ip_dns = nil
+ @state = UI_STATE_INVALID
+ @ip_config = false
+ @selected = false
+
+ @network_button = ui.get_object('network_button')
+ @device_list_frame = ui.get_object('device_list_frame')
+ @ipv4_config_frame = ui.get_object('ipv4_config_frame')
+ @dl_selection = ui.get_object('network_device_list_view').
+ selection
+ @device_list = ui.get_object('network_device_list')
+ @manual_ui = ui.get_object('ip_manual')
+ @ip_address_ui = ui.get_object('ip_address')
+ @ip_prefix_ui = ui.get_object('ip_prefix')
+ @ip_gateway_ui = ui.get_object('ip_gateway')
+ @ip_dns_ui = ui.get_object('ip_dns')
+
+ ui.register_handler('network_button_clicked',
+ method(:network_button_clicked))
+ ui.register_handler('ip_auto_toggled',
+ method(:ip_auto_toggled))
+ ui.register_handler('ip_address_changed',
+ method(:ip_address_changed))
+ ui.register_handler('ip_prefix_changed',
+ method(:ip_prefix_changed))
+ ui.register_handler('ip_gateway_changed',
+ method(:ip_gateway_changed))
+ ui.register_handler('ip_dns_changed',
+ method(:ip_dns_changed))
+
+ check_config_valid()
+
+ # The user may only select a single device
+ @dl_selection.mode = Gtk::SELECTION_SINGLE
+
+ @dl_selection.set_select_function { |selection, model, path, current|
+ iter = model.get_iter(path)
+
+ # This is a toggle event. The new state is the opposite of the
+ # current state
+ new_state = !current
+
+ # Don't allow the user to select an unavailable device
+ if new_state then
+ # Notify the config UI if we're selecting a device
+ if iter[DEVCOL_AVAILABLE] then
+ event(EV_SELECTION, true)
+ end
+
+ iter[DEVCOL_AVAILABLE]
+
+ # Always allow the user to unselect a device
+ else
+ # Notify the UI that we're unselecting the device
+ event(EV_SELECTION, false)
+ true
+ end
+ }
+
+ # Store a map of device names to row references
+ refs = {}
+
+ # Populate the device list with all detected network devices
+ VirtP2V::NetworkDevice.all_devices.each { |device|
+ iter = @device_list.append()
+
+ iter[DEVCOL_NAME] = device.name
+ iter[DEVCOL_MAC] = device.mac
+ iter[DEVCOL_STATUS] = device.state
+ iter[DEVCOL_AVAILABLE] = device.connected
+
+ # Store a stable reference to this row in the TreeModel
+ refs[device.name] =
+ Gtk::TreeRowReference.new(@device_list, iter.path)
+ }
+
+ # Listen for updates to device states
+ VirtP2V::NetworkDevice.add_listener( lambda { |device|
+ path = refs[device.name].path
+
+ iter = @device_list.get_iter(path)
+ iter[DEVCOL_STATUS] = device.state
+ iter[DEVCOL_AVAILABLE] = device.connected
+
+ # Notify the UI that a device was activated
+ event(EV_ACTIVATION, device.activated) \
+ unless device.activated.nil?
+
+ # Unselect the path if it was previously selected and is no
+ # longer available
+ if !device.connected && @dl_selection.iter_is_selected?(iter)
+ then
+ @dl_selection.unselect_all()
+ event(EV_SELECTION, false)
+ end
+ } )
+
+ @ui = ui
+ end
+
+ def self.set_state(state)
+ # Don't do anything if state hasn't changed
+ return if state == @state
+
+ case state
+ when UI_STATE_INVALID
+ @network_button.sensitive = false
+ @device_list_frame.sensitive = true
+ @ipv4_config_frame.sensitive = true
+
+ @state = UI_STATE_INVALID
+ when UI_STATE_VALID
+ @network_button.sensitive = true
+ @device_list_frame.sensitive = true
+ @ipv4_config_frame.sensitive = true
+
+ @state = UI_STATE_VALID
+ when UI_STATE_ACTIVATING
+ @network_button.sensitive = false
+ @device_list_frame.sensitive = false
+ @ipv4_config_frame.sensitive = false
+
+ @state = UI_STATE_ACTIVATING
+ when UI_STATE_COMPLETE
+ # Activate the next page
+ @ui.active_page = 'server_win'
+
+ # ... then leave this one as we hope to find it if we come back here
+ set_state(UI_STATE_VALID)
+ else
+ raise "Attempt to set unexected NetworkConfig UI state: #{@state}"
+ end
+ end
+
+ def self.network_button_clicked
+ event(EV_BUTTON, true)
+
+ iter = @dl_selection.selected
+ return if iter.nil? # Shouldn't be possible
+ name = iter[DEVCOL_NAME]
+
+ VirtP2V::NetworkDevice[name].activate(!@manual_mode, @ip_address,
+ @ip_prefix, @ip_gateway, @ip_dns)
+ end
+
+ def self.ip_auto_toggled
+ @manual_mode = !@manual_mode
+ @manual_ui.sensitive = @manual_mode
+
+ check_config_valid()
+ end
+
+ def self.ip_address_changed
+ @ip_address = parse_ip(@ip_address_ui)
+
+ check_config_valid()
+ end
+
+ # Check IP prefix is a positive integer
+ # We check that it's appropriate to the address class in use elsewhere
+ def self.ip_prefix_changed
+ begin
+ @ip_prefix = Integer(@ip_prefix_ui.text)
+ rescue ArgumentError => e
+ # Ignore the result if it didn't parse
+ @ip_prefix = nil
+ return
+ end
+
+ if @ip_prefix < 0 then
+ @ip_prefix = nil
+ end
+
+ check_config_valid()
+ end
+
+ def self.ip_gateway_changed
+ @ip_gateway = parse_ip(@ip_gateway_ui)
+
+ check_config_valid()
+ end
+
+ # Parse an IP address understood by IPAddr
+ def self.parse_ip(entry)
+ a = entry.text.strip
+
+ begin
+ ip = IPAddr.new(a)
+ rescue ArgumentError => e
+ # Ignore the result if it didn't parse
+ ip = nil
+ end
+
+ return ip
+ end
+
+ def self.ip_dns_changed
+ dns = @ip_dns_ui.text
+
+ @ip_dns = []
+ dns.split(/\s*,+\s*/).each { |entry|
+ begin
+ @ip_dns << IPAddr.new(entry)
+ rescue ArgumentError => e
+ @ip_dns = ()
+ break
+ end
+ }
+ end
+
+ def self.check_config_valid
+ if !@manual_mode || (!@ip_address.nil? &&
+ !@ip_prefix.nil? &&
+ !@ip_gateway.nil?) then
+ if @manual_mode then
+ # Check that IPv4/IPv6 is used consistently
+ if @ip_address.ipv4? then
+ event(EV_IP_CONFIG, @ip_gateway.ipv4? && @ip_prefix < 32)
+ else
+ event(EV_IP_CONFIG, @ip_gateway.ipv6? && @ip_prefix < 128)
+ end
+ else
+ event(EV_IP_CONFIG, true)
+ end
+ else
+ event(EV_IP_CONFIG, false)
+ end
+ end
+
+end # module
diff -ruN virt-v2v-v0.8.1/p2v/client/lib/virt-p2v/ui/p2v.ui virt-v2v-v0.8.1.new/p2v/client/lib/virt-p2v/ui/p2v.ui
--- virt-v2v-v0.8.1/p2v/client/lib/virt-p2v/ui/p2v.ui 1970-01-01 01:00:00.000000000 +0100
+++ virt-v2v-v0.8.1.new/p2v/client/lib/virt-p2v/ui/p2v.ui 2011-05-11 17:20:21.000000000 +0100
@@ -0,0 +1,1031 @@
+<?xml version="1.0"?>
+<interface>
+ <requires lib="gtk+" version="2.16"/>
+ <!-- interface-naming-policy project-wide -->
+ <object class="GtkWindow" id="main_window">
+ <property name="resizable">False</property>
+ <property name="window_position">center-always</property>
+ <property name="decorated">False</property>
+ <signal name="destroy" handler="gtk_main_quit"/>
+ <child>
+ <object class="GtkAlignment" id="alignment2">
+ <property name="visible">True</property>
+ <property name="xscale">0</property>
+ <property name="yscale">0</property>
+ <child>
+ <object class="GtkFrame" id="page_frame">
+ <property name="width_request">800</property>
+ <property name="height_request">600</property>
+ <property name="visible">True</property>
+ <property name="label_xalign">0</property>
+ <property name="label_yalign">0</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkVBox" id="page_vbox">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">2</property>
+ <child>
+ <object class="GtkEventBox" id="title_background">
+ <property name="visible">True</property>
+ <child>
+ <object class="GtkLabel" id="title_label">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0</property>
+ <property name="xpad">5</property>
+ <property name="ypad">5</property>
+ <property name="label">&lt;span weight='bold' foreground='white' size='xx-large'&gt;virt-p2v&lt;/span&gt;</property>
+ <property name="use_markup">True</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ </child>
+ <child type="label_item">
+ <placeholder/>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <object class="GtkListStore" id="network_device_list">
+ <columns>
+ <!-- column-name Name -->
+ <column type="gchararray"/>
+ <!-- column-name MAC -->
+ <column type="gchararray"/>
+ <!-- column-name Status -->
+ <column type="gchararray"/>
+ <!-- column-name Available -->
+ <column type="gboolean"/>
+ </columns>
+ </object>
+ <object class="GtkListStore" id="convert_network_list">
+ <columns>
+ <!-- column-name Convert -->
+ <column type="gboolean"/>
+ <!-- column-name Device -->
+ <column type="gchararray"/>
+ </columns>
+ <signal name="row_changed" handler="convert_network_list_row_changed"/>
+ </object>
+ <object class="GtkListStore" id="convert_fixed_list">
+ <columns>
+ <!-- column-name Convert -->
+ <column type="gboolean"/>
+ <!-- column-name Device -->
+ <column type="gchararray"/>
+ <!-- column-name Progress -->
+ <column type="gdouble"/>
+ </columns>
+ <signal name="row_changed" handler="convert_fixed_list_row_changed"/>
+ </object>
+ <object class="GtkListStore" id="convert_removable_list">
+ <columns>
+ <!-- column-name Convert -->
+ <column type="gboolean"/>
+ <!-- column-name Device -->
+ <column type="gchararray"/>
+ <!-- column-name Type -->
+ <column type="gchararray"/>
+ </columns>
+ <signal name="row_changed" handler="convert_removable_list_row_changed"/>
+ </object>
+ <object class="GtkListStore" id="convert_profile_list">
+ <columns>
+ <!-- column-name Name -->
+ <column type="gchararray"/>
+ </columns>
+ </object>
+ <object class="GtkWindow" id="network_win">
+ <property name="width_request">800</property>
+ <property name="height_request">550</property>
+ <child>
+ <object class="GtkVBox" id="vbox1">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="yalign">1</property>
+ <property name="ypad">11</property>
+ <property name="label" translatable="yes">Welcome to virt-p2v.</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="device_list_frame">
+ <property name="visible">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">out</property>
+ <child>
+ <object class="GtkScrolledWindow" id="scrolledwindow1">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hscrollbar_policy">automatic</property>
+ <property name="vscrollbar_policy">automatic</property>
+ <child>
+ <object class="GtkTreeView" id="network_device_list_view">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="model">network_device_list</property>
+ <property name="headers_clickable">False</property>
+ <property name="search_column">0</property>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn1">
+ <property name="title">Device</property>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderertext1"/>
+ <attributes>
+ <attribute name="sensitive">3</attribute>
+ <attribute name="text">0</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn3">
+ <property name="fixed_width">18</property>
+ <property name="title">MAC Address</property>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderertext3"/>
+ <attributes>
+ <attribute name="sensitive">3</attribute>
+ <attribute name="text">1</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn2">
+ <property name="title">Status</property>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderertext2"/>
+ <attributes>
+ <attribute name="sensitive">3</attribute>
+ <attribute name="text">2</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label5">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">&lt;b&gt;Select a network device&lt;/b&gt;</property>
+ <property name="use_markup">True</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="ipv4_config_frame">
+ <property name="visible">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkAlignment" id="alignment1">
+ <property name="visible">True</property>
+ <property name="left_padding">12</property>
+ <child>
+ <object class="GtkVBox" id="vbox2">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkCheckButton" id="ip_auto">
+ <property name="label" translatable="yes">Automatic configuration</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ <signal name="toggled" handler="ip_auto_toggled"/>
+ </object>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkTable" id="ip_manual">
+ <property name="visible">True</property>
+ <property name="sensitive">False</property>
+ <property name="n_rows">3</property>
+ <property name="n_columns">2</property>
+ <property name="column_spacing">2</property>
+ <child>
+ <object class="GtkLabel" id="label3">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">IP Address:</property>
+ </object>
+ <packing>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label8">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Gateway:</property>
+ </object>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label4">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">DNS Servers:</property>
+ </object>
+ <packing>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="ip_gateway">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="max_length">39</property>
+ <property name="width_chars">39</property>
+ <property name="truncate_multiline">True</property>
+ <signal name="changed" handler="ip_gateway_changed"/>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="ip_dns">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="width_chars">35</property>
+ <signal name="changed" handler="ip_dns_changed"/>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkHBox" id="hbox6">
+ <property name="visible">True</property>
+ <property name="spacing">2</property>
+ <child>
+ <object class="GtkEntry" id="ip_address">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="max_length">39</property>
+ <property name="width_chars">39</property>
+ <property name="truncate_multiline">True</property>
+ <signal name="changed" handler="ip_address_changed"/>
+ </object>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label7">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Prefix:</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="ip_prefix">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="max_length">2</property>
+ <property name="width_chars">2</property>
+ <property name="truncate_multiline">True</property>
+ <signal name="changed" handler="ip_prefix_changed"/>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">&lt;b&gt;IP Configuration&lt;/b&gt;</property>
+ <property name="use_markup">True</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkAlignment" id="alignment3">
+ <property name="visible">True</property>
+ <property name="xalign">1</property>
+ <property name="xscale">0</property>
+ <child>
+ <object class="GtkButton" id="network_button">
+ <property name="label" translatable="yes">Use these network settings</property>
+ <property name="visible">True</property>
+ <property name="sensitive">False</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <signal name="clicked" handler="network_button_clicked"/>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+ <object class="GtkWindow" id="server_win">
+ <child>
+ <object class="GtkVBox" id="vbox3">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkAlignment" id="alignment4">
+ <property name="visible">True</property>
+ <property name="xscale">0</property>
+ <property name="yscale">0</property>
+ <child>
+ <object class="GtkFrame" id="connect_frame">
+ <property name="visible">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkAlignment" id="alignment9">
+ <property name="visible">True</property>
+ <property name="left_padding">12</property>
+ <child>
+ <object class="GtkVBox" id="vbox5">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkTable" id="table1">
+ <property name="visible">True</property>
+ <property name="n_rows">3</property>
+ <property name="n_columns">2</property>
+ <property name="column_spacing">2</property>
+ <child>
+ <object class="GtkLabel" id="label9">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Hostname:</property>
+ </object>
+ <packing>
+ <property name="x_options"></property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label10">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Username:</property>
+ </object>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options"></property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label11">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Password:</property>
+ </object>
+ <packing>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="x_options"></property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="server_hostname">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="invisible_char">&#x2022;</property>
+ <property name="width_chars">40</property>
+ <signal name="changed" handler="server_hostname_changed"/>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="server_password">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="visibility">False</property>
+ <property name="invisible_char">&#x2022;</property>
+ <property name="width_chars">40</property>
+ <signal name="changed" handler="server_password_changed"/>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="server_username">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="invisible_char">&#x2022;</property>
+ <property name="width_chars">40</property>
+ <property name="text" translatable="yes">root</property>
+ <signal name="changed" handler="server_username_changed"/>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="connect_error">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0</property>
+ <property name="xpad">8</property>
+ <property name="ypad">8</property>
+ <attributes>
+ <attribute name="foreground" value="#ffff00000000"/>
+ </attributes>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label6">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">&lt;b&gt;Connect to conversion server&lt;/b&gt;</property>
+ <property name="use_markup">True</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkAlignment" id="alignment5">
+ <property name="visible">True</property>
+ <property name="xalign">1</property>
+ <property name="yalign">0</property>
+ <property name="xscale">0</property>
+ <property name="yscale">0</property>
+ <child>
+ <object class="GtkButton" id="connect_button">
+ <property name="label" translatable="yes">Connect</property>
+ <property name="visible">True</property>
+ <property name="sensitive">False</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <signal name="clicked" handler="connect_button_clicked"/>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+ <object class="GtkWindow" id="conversion_win">
+ <child>
+ <object class="GtkVBox" id="vbox4">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkHBox" id="convert_editable">
+ <property name="visible">True</property>
+ <child>
+ <object class="GtkFrame" id="frame2">
+ <property name="visible">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">out</property>
+ <child>
+ <object class="GtkAlignment" id="alignment6">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0</property>
+ <property name="xscale">0</property>
+ <property name="yscale">0</property>
+ <property name="left_padding">12</property>
+ <child>
+ <object class="GtkTable" id="table2">
+ <property name="visible">True</property>
+ <property name="n_rows">4</property>
+ <property name="n_columns">2</property>
+ <property name="column_spacing">2</property>
+ <child>
+ <object class="GtkLabel" id="label14">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Destination Profile:</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkComboBox" id="convert_profile">
+ <property name="visible">True</property>
+ <property name="model">convert_profile_list</property>
+ <signal name="changed" handler="convert_profile_changed"/>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderertext8"/>
+ <attributes>
+ <attribute name="text">0</attribute>
+ </attributes>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label16">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Memory (MB):</property>
+ </object>
+ <packing>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="convert_memory">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="invisible_char">&#x2022;</property>
+ <property name="truncate_multiline">True</property>
+ <signal name="changed" handler="convert_memory_changed"/>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label15">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Number of CPUs:</property>
+ </object>
+ <packing>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label18">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Name</property>
+ </object>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="convert_name">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="invisible_char">&#x2022;</property>
+ <property name="truncate_multiline">True</property>
+ <signal name="changed" handler="convert_name_changed"/>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="convert_cpus">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="invisible_char">&#x2022;</property>
+ <property name="truncate_multiline">True</property>
+ <signal name="changed" handler="convert_cpus_changed"/>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label13">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">&lt;b&gt;Target properties&lt;/b&gt;</property>
+ <property name="use_markup">True</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkVBox" id="vbox6">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkFrame" id="frame3">
+ <property name="visible">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">out</property>
+ <child>
+ <object class="GtkAlignment" id="alignment8">
+ <property name="visible">True</property>
+ <child>
+ <object class="GtkScrolledWindow" id="scrolledwindow2">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hscrollbar_policy">automatic</property>
+ <property name="vscrollbar_policy">automatic</property>
+ <child>
+ <object class="GtkTreeView" id="treeview1">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="model">convert_fixed_list</property>
+ <property name="headers_clickable">False</property>
+ <property name="search_column">0</property>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn4">
+ <property name="title">Convert</property>
+ <property name="clickable">True</property>
+ <child>
+ <object class="GtkCellRendererToggle" id="convert_fixed_select">
+ <signal name="toggled" handler="convert_fixed_select_toggled"/>
+ </object>
+ <attributes>
+ <attribute name="active">0</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn5">
+ <property name="title">Device</property>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderertext4"/>
+ <attributes>
+ <attribute name="text">1</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn8">
+ <property name="title">Transfer Progress</property>
+ <property name="expand">True</property>
+ <child>
+ <object class="GtkCellRendererProgress" id="cellrendererprogress1"/>
+ <attributes>
+ <attribute name="value">2</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label17">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">&lt;b&gt;Fixed Storage&lt;/b&gt;</property>
+ <property name="use_markup">True</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame4">
+ <property name="visible">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">out</property>
+ <child>
+ <object class="GtkAlignment" id="alignment11">
+ <property name="visible">True</property>
+ <child>
+ <object class="GtkScrolledWindow" id="scrolledwindow4">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hscrollbar_policy">automatic</property>
+ <property name="vscrollbar_policy">automatic</property>
+ <child>
+ <object class="GtkTreeView" id="treeview3">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="model">convert_removable_list</property>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn9">
+ <property name="title">Convert</property>
+ <child>
+ <object class="GtkCellRendererToggle" id="convert_removable_select">
+ <signal name="toggled" handler="convert_removable_select_toggled"/>
+ </object>
+ <attributes>
+ <attribute name="active">0</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn10">
+ <property name="title">Device</property>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderertext6"/>
+ <attributes>
+ <attribute name="text">1</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn11">
+ <property name="title">Type</property>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderertext7"/>
+ <attributes>
+ <attribute name="text">2</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label19">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">&lt;b&gt;Removable Media&lt;/b&gt;</property>
+ <property name="use_markup">True</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame1">
+ <property name="visible">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">out</property>
+ <child>
+ <object class="GtkAlignment" id="alignment10">
+ <property name="visible">True</property>
+ <property name="xalign">1</property>
+ <property name="yalign">1</property>
+ <child>
+ <object class="GtkScrolledWindow" id="scrolledwindow3">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hscrollbar_policy">automatic</property>
+ <property name="vscrollbar_policy">automatic</property>
+ <child>
+ <object class="GtkTreeView" id="treeview2">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="model">convert_network_list</property>
+ <property name="headers_clickable">False</property>
+ <property name="search_column">0</property>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn6">
+ <property name="title">Convert</property>
+ <child>
+ <object class="GtkCellRendererToggle" id="convert_network_select">
+ <signal name="toggled" handler="convert_network_select_toggled"/>
+ </object>
+ <attributes>
+ <attribute name="active">0</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn7">
+ <property name="title">Device</property>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderertext5"/>
+ <attributes>
+ <attribute name="text">1</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label12">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">&lt;b&gt;Network Interfaces&lt;/b&gt;</property>
+ <property name="use_markup">True</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkHBox" id="hbox1">
+ <property name="visible">True</property>
+ <child>
+ <object class="GtkLabel" id="convert_status">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="xpad">12</property>
+ <attributes>
+ <attribute name="foreground" value="#ffff00000000"/>
+ </attributes>
+ </object>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="convert_button">
+ <property name="label" translatable="yes">Convert</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <signal name="clicked" handler="convert_button_clicked"/>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+ <object class="GtkWindow" id="success_win">
+ <child>
+ <object class="GtkVBox" id="vbox7">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkLabel" id="label20">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">A guest has been successfully created on the target server.
+
+Remove the temporary boot device from this machine and press 'Reboot' to continue.</property>
+ <property name="justify">center</property>
+ </object>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkAlignment" id="alignment7">
+ <property name="visible">True</property>
+ <property name="xscale">0.25</property>
+ <property name="yscale">0.25</property>
+ <child>
+ <object class="GtkButton" id="reboot_button">
+ <property name="label" translatable="yes">Reboot</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <signal name="clicked" handler="reboot_button_clicked"/>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+</interface>
diff -ruN virt-v2v-v0.8.1/p2v/client/lib/virt-p2v/ui/success.rb virt-v2v-v0.8.1.new/p2v/client/lib/virt-p2v/ui/success.rb
--- virt-v2v-v0.8.1/p2v/client/lib/virt-p2v/ui/success.rb 1970-01-01 01:00:00.000000000 +0100
+++ virt-v2v-v0.8.1.new/p2v/client/lib/virt-p2v/ui/success.rb 2011-05-11 17:20:21.000000000 +0100
@@ -0,0 +1,33 @@
+# Copyright (C) 2011 Red Hat Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+require 'gettext'
+
+module VirtP2V::UI::Success
+ include GetText
+
+ def self.init(ui)
+ ui.register_handler('reboot_button_clicked',
+ method(:reboot_button_clicked))
+
+ @ui = ui
+ end
+
+ def self.reboot_button_clicked
+ @ui.quit
+ end
+
+end # module
diff -ruN virt-v2v-v0.8.1/p2v/client/Manifest virt-v2v-v0.8.1.new/p2v/client/Manifest
--- virt-v2v-v0.8.1/p2v/client/Manifest 1970-01-01 01:00:00.000000000 +0100
+++ virt-v2v-v0.8.1.new/p2v/client/Manifest 2011-05-11 17:20:21.000000000 +0100
@@ -0,0 +1,15 @@
+Rakefile
+bin/virt-p2v
+lib/virt-p2v/blockdevice.rb
+lib/virt-p2v/connection.rb
+lib/virt-p2v/converter.rb
+lib/virt-p2v/gtk-queue.rb
+lib/virt-p2v/netdevice.rb
+lib/virt-p2v/ui/connect.rb
+lib/virt-p2v/ui/convert.rb
+lib/virt-p2v/ui/main.rb
+lib/virt-p2v/ui/network.rb
+lib/virt-p2v/ui/p2v.ui
+lib/virt-p2v/ui/success.rb
+virt-p2v.gemspec
+Manifest
diff -ruN virt-v2v-v0.8.1/p2v/client/Rakefile virt-v2v-v0.8.1.new/p2v/client/Rakefile
--- virt-v2v-v0.8.1/p2v/client/Rakefile 1970-01-01 01:00:00.000000000 +0100
+++ virt-v2v-v0.8.1.new/p2v/client/Rakefile 2011-05-11 17:20:21.000000000 +0100
@@ -0,0 +1,37 @@
+# Copyright (C) 2011 Red Hat Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+require 'rubygems'
+require 'echoe'
+
+Echoe.new("virt-p2v") do |p|
+ p.project = "Virt P2V"
+ p.version = `../../Build version`
+ p.author = "Matthew Booth"
+ p.summary = "Send a machine's storage and metadata to virt-p2v-server"
+ p.description = <<EOF
+virt-p2v is a client which connects to a virt-p2v-server and transfer's the host
+machine's storage and metadata. virt-p2v is intended to be run from a live
+image, so it is unlikely you want to install it.
+EOF
+ p.url = "http://libguestfs.org"
+ p.email = "libguestfs@redhat.com"
+ p.runtime_dependencies = [
+ 'gtk2',
+ 'gettext',
+ 'net-ssh'
+ ]
+end
diff -ruN virt-v2v-v0.8.1/p2v/image-builder/common-install.ks virt-v2v-v0.8.1.new/p2v/image-builder/common-install.ks
--- virt-v2v-v0.8.1/p2v/image-builder/common-install.ks 1970-01-01 01:00:00.000000000 +0100
+++ virt-v2v-v0.8.1.new/p2v/image-builder/common-install.ks 2011-05-11 17:20:21.000000000 +0100
@@ -0,0 +1,54 @@
+lang C
+keyboard us
+timezone --utc UTC
+auth --useshadow --enablemd5
+selinux --disabled
+firewall --disabled
+# TODO: the sizing of the image needs to be more dynamic
+part / --size 1024 --fstype ext2
+services --enabled=NetworkManager --disabled=auditd
+bootloader --timeout=30
+rootpw --iscrypted $1$tQiZwocX$ghhurQEm56p/HqgN.XEtk1
+
+# add missing scsi modules to initramfs
+device 3w-9xxx
+device 3w-sas
+device 3w-xxxx
+device a100u2w
+device aacraid
+device aic79xx
+device aic94xx
+device arcmsr
+device atp870u
+device be2iscsi
+device bfa
+device BusLogic
+device cxgb3i
+device dc395x
+device fnic
+device gdth
+device hpsa
+device hptiop
+device imm
+device initio
+device ips
+device libosd
+device libsas
+device libsrp
+device lpfc
+device megaraid
+device megaraid_mbox
+device megaraid_mm
+device megaraid_sas
+device mpt2sas
+device mvsas
+device osd
+device osst
+device pm8001
+device pmcraid
+device qla1280
+device qla2xxx
+device qla4xxx
+device qlogicfas408
+device stex
+device tmscsim
diff -ruN virt-v2v-v0.8.1/p2v/image-builder/common-manifest-post.ks virt-v2v-v0.8.1.new/p2v/image-builder/common-manifest-post.ks
--- virt-v2v-v0.8.1/p2v/image-builder/common-manifest-post.ks 1970-01-01 01:00:00.000000000 +0100
+++ virt-v2v-v0.8.1.new/p2v/image-builder/common-manifest-post.ks 2011-05-11 17:20:21.000000000 +0100
@@ -0,0 +1,36 @@
+%post
+echo -n "Creating manifest"
+# Create post-image processing manifests
+rpm -qa --qf '%{name}-%{version}-%{release}.%{arch} (%{SIGGPG:pgpsig})\n' | \
+ sort > /manifest-rpm.txt
+rpm -qa --qf '%{sourcerpm}\n' | sort -u > /manifest-srpm.txt
+# collect all included licenses rhbz#601927
+rpm -qa --qf '%{license}\n' | sort -u > /manifest-license.txt
+# dependencies
+rpm -qa | xargs -n1 rpm -e --test 2> /manifest-deps.txt
+echo -n "."
+find / -xdev -print -exec rpm -qf {} \; > /manifest-owns.txt
+rpm -qa --qf '%{NAME}\t%{VERSION}\t%{RELEASE}\t%{BUILDTIME}\n' | \
+ sort > /rpm-qa.txt
+echo -n "."
+
+du -akx --exclude=/var/cache/yum / > /manifest-file.txt
+du -x --exclude=/var/cache/yum / > /manifest-dir.txt
+echo -n "."
+bzip2 /manifest-deps.txt /manifest-owns.txt /manifest-file.txt /manifest-dir.txt
+echo -n "."
+
+%end
+
+%post --nochroot
+# Move manifests to ISO
+mv $INSTALL_ROOT/manifest-* $LIVE_ROOT/isolinux
+echo "done"
+
+# only works on x86, x86_64
+if [ "$(uname -i)" = "i386" -o "$(uname -i)" = "x86_64" ]; then
+ if [ ! -d $LIVE_ROOT/LiveOS ]; then mkdir -p $LIVE_ROOT/LiveOS ; fi
+ cp /usr/bin/livecd-iso-to-disk $LIVE_ROOT/LiveOS
+ cp /usr/bin/livecd-iso-to-pxeboot $LIVE_ROOT/LiveOS
+fi
+%end
diff -ruN virt-v2v-v0.8.1/p2v/image-builder/common-minimizer.ks virt-v2v-v0.8.1.new/p2v/image-builder/common-minimizer.ks
--- virt-v2v-v0.8.1/p2v/image-builder/common-minimizer.ks 1970-01-01 01:00:00.000000000 +0100
+++ virt-v2v-v0.8.1.new/p2v/image-builder/common-minimizer.ks 2011-05-11 17:20:21.000000000 +0100
@@ -0,0 +1,239 @@
+# This file is only relatively lightly modified from the version copied from
+# oVirt, and certainly contains much which is irrelevant to this image. I have,
+# however, removed some obviously extraneous entries and added a few additional
+# entries.
+#
+# Matthew Booth <mbooth@redhat.com> - 18/4/2011
+
+%post --nochroot --interpreter image-minimizer
+# lokkit is just an install-time dependency; we can remove
+# it afterwards, which we do here
+droprpm system-config-*
+droprpm libsemanage-python
+droprpm python-libs
+droprpm python
+
+droprpm mkinitrd
+droprpm isomd5sum
+droprpm dmraid
+droprpm checkpolicy
+droprpm make
+droprpm policycoreutils-python
+droprpm setools-libs-python
+droprpm setools-libs
+
+droprpm gamin
+droprpm pm-utils
+droprpm kbd
+droprpm usermode
+droprpm vbetool
+droprpm ConsoleKit
+droprpm hdparm
+droprpm efibootmgr
+droprpm linux-atm-libs
+droprpm mtools
+droprpm syslinux
+droprpm wireless-tools
+droprpm radeontool
+droprpm libicu
+droprpm gnupg2
+droprpm fedora-release-notes
+droprpm fedora-logos
+
+# cronie pulls in exim (sendmail) which pulls in all kinds of perl deps
+droprpm exim
+droprpm perl*
+droprpm postfix
+droprpm mysql*
+
+droprpm sysklogd
+
+# unneeded rhn deps
+droprpm yum*
+
+# pam complains when this is missing
+keeprpm ConsoleKit-libs
+
+# kernel modules minimization
+
+# filesystems
+drop /lib/modules/*/kernel/fs
+keep /lib/modules/*/kernel/fs/ext*
+keep /lib/modules/*/kernel/fs/jbd*
+keep /lib/modules/*/kernel/fs/btrfs
+keep /lib/modules/*/kernel/fs/fat
+keep /lib/modules/*/kernel/fs/nfs
+keep /lib/modules/*/kernel/fs/nfs_common
+keep /lib/modules/*/kernel/fs/fscache
+keep /lib/modules/*/kernel/fs/lockd
+keep /lib/modules/*/kernel/fs/nls/nls_utf8.ko
+# autofs4 configfs exportfs *fat *jbd mbcache.ko nls xfs
+#*btrfs cramfs *ext2 *fscache *jbd2 *nfs squashfs
+# cachefiles dlm *ext3 fuse jffs2 *nfs_common ubifs
+# cifs ecryptfs *ext4 gfs2 *lockd nfsd udf
+
+# network
+drop /lib/modules/*/kernel/net
+keep /lib/modules/*/kernel/net/802*
+keep /lib/modules/*/kernel/net/bridge
+keep /lib/modules/*/kernel/net/core
+keep /lib/modules/*/kernel/net/ipv*
+keep /lib/modules/*/kernel/net/key
+keep /lib/modules/*/kernel/net/llc
+keep /lib/modules/*/kernel/net/netfilter
+keep /lib/modules/*/kernel/net/rds
+keep /lib/modules/*/kernel/net/sctp
+keep /lib/modules/*/kernel/net/sunrpc
+#*802 atm can ieee802154 *key *netfilter rfkill *sunrpc xfrm
+#*8021q bluetooth *core *ipv4 *llc phonet sched wimax
+# 9p *bridge dccp *ipv6 mac80211 *rds *sctp wireless
+
+drop /lib/modules/*/kernel/sound
+
+# drivers
+drop /lib/modules/*/kernel/drivers
+keep /lib/modules/*/kernel/drivers/ata
+keep /lib/modules/*/kernel/drivers/block
+keep /lib/modules/*/kernel/drivers/cdrom
+keep /lib/modules/*/kernel/drivers/char
+keep /lib/modules/*/kernel/drivers/cpufreq
+keep /lib/modules/*/kernel/drivers/dca
+keep /lib/modules/*/kernel/drivers/dma
+keep /lib/modules/*/kernel/drivers/edac
+keep /lib/modules/*/kernel/drivers/firmware
+keep /lib/modules/*/kernel/drivers/idle
+keep /lib/modules/*/kernel/drivers/infiniband
+keep /lib/modules/*/kernel/drivers/md
+keep /lib/modules/*/kernel/drivers/message
+keep /lib/modules/*/kernel/drivers/net
+drop /lib/modules/*/kernel/drivers/net/pcmcia
+drop /lib/modules/*/kernel/drivers/net/wireless
+drop /lib/modules/*/kernel/drivers/net/ppp*
+keep /lib/modules/*/kernel/drivers/pci
+keep /lib/modules/*/kernel/drivers/scsi
+keep /lib/modules/*/kernel/drivers/staging/ramzswap
+keep /lib/modules/*/kernel/drivers/uio
+keep /lib/modules/*/kernel/drivers/usb
+drop /lib/modules/*/kernel/drivers/usb/atm
+drop /lib/modules/*/kernel/drivers/usb/class
+drop /lib/modules/*/kernel/drivers/usb/image
+drop /lib/modules/*/kernel/drivers/usb/misc
+drop /lib/modules/*/kernel/drivers/usb/serial
+keep /lib/modules/*/kernel/drivers/vhost
+keep /lib/modules/*/kernel/drivers/virtio
+
+# acpi *cpufreq hid leds mtd ?regulator uwb
+#*ata crypto ?hwmon *md *net* rtc *vhost
+# atm *dca ?i2c media ?parport *scsi* video
+# auxdisplay *dma *idle memstick *pci ?serial *virtio
+#*block *edac ieee802154 *message pcmcia ?ssb watchdog
+# bluetooth firewire *infiniband ?mfd platform *staging xen
+#*cdrom *firmware input misc ?power ?uio
+#*char* ?gpu isdn mmc ?pps *usb
+
+drop /usr/share/zoneinfo
+keep /usr/share/zoneinfo/UTC
+
+drop /etc/alsa
+drop /usr/share/alsa
+drop /usr/share/awk
+drop /usr/share/vim
+drop /usr/share/anaconda
+drop /usr/share/backgrounds
+drop /usr/share/wallpapers
+drop /usr/share/kde-settings
+drop /usr/share/gnome-background-properties
+drop /usr/share/dracut
+drop /usr/share/plymouth
+drop /usr/share/setuptool
+drop /usr/share/hwdata/MonitorsDB
+drop /usr/share/hwdata/oui.txt
+drop /usr/share/hwdata/videoaliases
+drop /usr/share/hwdata/videodrivers
+drop /usr/share/firstboot
+drop /usr/share/lua
+drop /usr/share/kde4
+drop /usr/share/pixmaps
+drop /usr/share/icons
+drop /usr/share/fedora-release
+drop /usr/share/tabset
+
+drop /usr/share/tc
+drop /usr/share/emacs
+drop /usr/share/info
+drop /usr/src
+drop /usr/etc
+drop /usr/games
+drop /usr/include
+drop /usr/local
+drop /usr/sbin/dell*
+keep /usr/sbin/build-locale-archive
+drop /usr/sbin/glibc_post_upgrade.*
+drop /usr/lib*/tc
+drop /usr/lib*/tls
+drop /usr/lib*/sse2
+drop /usr/lib*/pkgconfig
+drop /usr/lib*/nss
+drop /usr/lib*/games
+drop /usr/lib*/alsa-lib
+drop /usr/lib*/krb5
+drop /usr/lib*/hal
+drop /usr/lib*/gio
+
+# syslinux
+drop /usr/share/syslinux
+# glibc-common locales
+drop /usr/lib/locale
+keep /usr/lib/locale/usr/share/locale/en_US
+# openssh
+drop /usr/bin/sftp
+drop /usr/bin/slogin
+drop /usr/bin/ssh-add
+drop /usr/bin/ssh-agent
+drop /usr/bin/ssh-keyscan
+# docs
+drop /usr/share/omf
+drop /usr/share/gnome
+drop /usr/share/doc
+keep /usr/share/doc/*-firmware-*
+drop /usr/share/locale/
+keep /usr/share/locale/en_US
+drop /usr/share/man
+drop /usr/share/i18n
+drop /boot/*
+drop /var/lib/builder
+
+drop /usr/lib*/libboost*
+keep /usr/lib*/libboost_program_options.so*
+keep /usr/lib*/libboost_filesystem.so*
+keep /usr/lib*/libboost_thread-mt.so*
+keep /usr/lib*/libboost_system.so*
+drop /usr/kerberos
+keep /usr/kerberos/bin/kinit
+keep /usr/kerberos/bin/klist
+drop /lib/firmware
+keep /lib/firmware/3com
+keep /lib/firmware/acenic
+keep /lib/firmware/adaptec
+keep /lib/firmware/advansys
+keep /lib/firmware/bnx2
+keep /lib/firmware/cxgb3
+keep /lib/firmware/e100
+keep /lib/firmware/myricom
+keep /lib/firmware/ql*
+keep /lib/firmware/sun
+keep /lib/firmware/tehuti
+keep /lib/firmware/tigon
+drop /lib/kbd/consolefonts
+drop /etc/pki/tls
+drop /etc/pki/java
+drop /etc/pki/nssdb
+drop /etc/pki/rpm-gpg
+%end
+
+%post
+echo "Removing python source files"
+find / -name '*.py' -exec rm -f {} \;
+find / -name '*.pyo' -exec rm -f {} \;
+
+%end
diff -ruN virt-v2v-v0.8.1/p2v/image-builder/common-pkgs.ks virt-v2v-v0.8.1.new/p2v/image-builder/common-pkgs.ks
--- virt-v2v-v0.8.1/p2v/image-builder/common-pkgs.ks 1970-01-01 01:00:00.000000000 +0100
+++ virt-v2v-v0.8.1.new/p2v/image-builder/common-pkgs.ks 2011-05-11 17:20:21.000000000 +0100
@@ -0,0 +1,48 @@
+# Direct requirements
+rubygem-virt-p2v
+bitstream-vera-sans-fonts
+xorg-x11-xinit
+xorg-x11-drivers
+xorg-x11-server-Xorg
+
+# Boot requirements
+device-mapper
+
+# Required for livecd creation
+passwd
+rpm
+/usr/sbin/lokkit
+
+# Remove unnecessary packages
+-audit-libs-python
+-ustr
+-authconfig
+-wireless-tools
+-setserial
+-prelink
+-newt-python
+-newt
+-libselinux-python
+-kbd
+-usermode
+-fedora-release
+-fedora-release-notes
+-dmraid
+-gzip
+-less
+-which
+-parted
+-tar
+-libuser
+-mtools
+-cpio
+-yum
+-numactl # Pulls in perl dependency
+-perl
+
+# qlogic firmware
+ql2100-firmware
+ql2200-firmware
+ql23xx-firmware
+ql2400-firmware
+ql2500-firmware
diff -ruN virt-v2v-v0.8.1/p2v/image-builder/common-post.ks virt-v2v-v0.8.1.new/p2v/image-builder/common-post.ks
--- virt-v2v-v0.8.1/p2v/image-builder/common-post.ks 1970-01-01 01:00:00.000000000 +0100
+++ virt-v2v-v0.8.1.new/p2v/image-builder/common-post.ks 2011-05-11 17:20:21.000000000 +0100
@@ -0,0 +1,43 @@
+# -*-Shell-script-*-
+echo "Starting Kickstart Post"
+PATH=/sbin:/usr/sbin:/bin:/usr/bin
+export PATH
+
+# cleanup rpmdb to allow non-matching host and chroot RPM versions
+rm -f /var/lib/rpm/__db*
+
+echo "Creating shadow files"
+# because we aren't installing authconfig, we aren't setting up shadow
+# and gshadow properly. Do it by hand here
+pwconv
+grpconv
+
+echo "Forcing C locale"
+# force logins (via ssh, etc) to use C locale, since we remove locales
+cat >> /etc/profile << \EOF
+# force our locale to C since we don't have locale stuff'
+export LC_ALL=C LANG=C
+EOF
+
+# remove errors from /sbin/dhclient-script
+DHSCRIPT=/sbin/dhclient-script
+sed -i 's/mv /cp -p /g' $DHSCRIPT
+sed -i '/rm -f.*${interface}/d' $DHSCRIPT
+sed -i '/rm -f \/etc\/localtime/d' $DHSCRIPT
+sed -i '/rm -f \/etc\/ntp.conf/d' $DHSCRIPT
+sed -i '/rm -f \/etc\/yp.conf/d' $DHSCRIPT
+
+# Lock root account
+#passwd -l root
+
+#strip out all unncesssary locales
+localedef --list-archive | grep -v -i -E 'en_US.utf8' |xargs localedef --delete-from-archive
+mv /usr/lib/locale/locale-archive /usr/lib/locale/locale-archive.tmpl
+/usr/sbin/build-locale-archive
+
+# Run virt-p2v
+cat >> /etc/rc.local <<EOF
+export HOME=/root # rubygem Net::SSH needs this
+/usr/bin/xinit /usr/bin/virt-p2v > /root/virt-p2v.log 2>&1
+poweroff
+EOF
diff -ruN virt-v2v-v0.8.1/p2v/image-builder/common-post-nochroot.ks virt-v2v-v0.8.1.new/p2v/image-builder/common-post-nochroot.ks
--- virt-v2v-v0.8.1/p2v/image-builder/common-post-nochroot.ks 1970-01-01 01:00:00.000000000 +0100
+++ virt-v2v-v0.8.1.new/p2v/image-builder/common-post-nochroot.ks 2011-05-11 17:20:21.000000000 +0100
@@ -0,0 +1,60 @@
+%include version.ks
+
+PRODUCT='Virt P2V'
+PRODUCT_SHORT='virt-p2v'
+PACKAGE='virt-p2v'
+RELEASE=${RELEASE:-devel.`date +%Y%m%d%H%M%S`}
+
+echo "Customizing boot menu"
+sed -i -e '
+# Put product information at the top of the file
+1 {
+ i '"say $PRODUCT $VERSION ($RELEASE)"'
+ i '"menu title $PRODUCT_SHORT $VERSION ($RELEASE)"'
+}
+
+# Remove any existing menu title
+/^menu title .*/d
+
+# Remove quiet bootparam
+#s/ quiet//
+
+# Disable selinux entirely. Required, as we dont install an SELinux policy.
+/^\s*append\s/ s/\s*$/ selinux=0/
+
+# Remove Verify and Boot option
+/label check0/{N;N;N;d;}
+
+# Set the default timeout to 15 seconds
+s/^timeout .*/timeout 15/
+' $LIVE_ROOT/isolinux/isolinux.cfg
+
+# TODO: Replace the splash screen with something P2V appropriate
+#cp $INSTALL_ROOT//syslinux-vesa-splash.jpg $LIVE_ROOT/isolinux/splash.jpg
+
+# store image version info in the ISO
+cat > $LIVE_ROOT/isolinux/version <<EOF
+PRODUCT='$PRODUCT'
+PRODUCT_SHORT='${PRODUCT_SHORT}'
+PRODUCT_CODE=$PRODUCT_CODE
+RECIPE_SHA256=$RECIPE_SHA256
+RECIPE_RPM=$RECIPE_RPM
+PACKAGE=$PACKAGE
+VERSION=$VERSION
+RELEASE=$RELEASE
+EOF
+
+# overwrite user visible banners with the image versioning info
+cat > $INSTALL_ROOT/etc/$PACKAGE-release <<EOF
+$PRODUCT release $VERSION ($RELEASE)
+EOF
+ln -snf $PACKAGE-release $INSTALL_ROOT/etc/redhat-release
+ln -snf $PACKAGE-release $INSTALL_ROOT/etc/system-release
+cp $INSTALL_ROOT/etc/$PACKAGE-release $INSTALL_ROOT/etc/issue
+echo "Kernel \r on an \m (\l)" >> $INSTALL_ROOT/etc/issue
+cp $INSTALL_ROOT/etc/issue $INSTALL_ROOT/etc/issue.net
+
+# replace initramfs if regenerated
+if [ -f "$INSTALL_ROOT/initrd0.img" ]; then
+ mv -v "$INSTALL_ROOT/initrd0.img" "$LIVE_ROOT/isolinux/initrd0.img"
+fi
diff -ruN virt-v2v-v0.8.1/p2v/image-builder/Makefile virt-v2v-v0.8.1.new/p2v/image-builder/Makefile
--- virt-v2v-v0.8.1/p2v/image-builder/Makefile 1970-01-01 01:00:00.000000000 +0100
+++ virt-v2v-v0.8.1.new/p2v/image-builder/Makefile 2011-05-11 17:20:21.000000000 +0100
@@ -0,0 +1,2 @@
+version.ks: ../../Build
+ echo VERSION=`../../Build version` > version.ks
diff -ruN virt-v2v-v0.8.1/p2v/image-builder/version.ks virt-v2v-v0.8.1.new/p2v/image-builder/version.ks
--- virt-v2v-v0.8.1/p2v/image-builder/version.ks 1970-01-01 01:00:00.000000000 +0100
+++ virt-v2v-v0.8.1.new/p2v/image-builder/version.ks 2011-05-11 17:20:21.000000000 +0100
@@ -0,0 +1 @@
+VERSION=0.8.1
diff -ruN virt-v2v-v0.8.1/p2v/image-builder/virt-p2v-image-builder virt-v2v-v0.8.1.new/p2v/image-builder/virt-p2v-image-builder
--- virt-v2v-v0.8.1/p2v/image-builder/virt-p2v-image-builder 1970-01-01 01:00:00.000000000 +0100
+++ virt-v2v-v0.8.1.new/p2v/image-builder/virt-p2v-image-builder 2011-05-11 17:20:21.000000000 +0100
@@ -0,0 +1,188 @@
+#!/bin/bash
+
+# Copyright (C) 2010-2011, Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301, USA. A copy of the GNU General Public License is
+# also available at http://www.gnu.org/copyleft/gpl.html.
+
+# Requires: sudo livecd-creator, sudo setenforce, ksflatten
+
+# Based on oVirt's node-creator
+
+# Current fedora data
+cur_rawhide=16
+cur_devel=15
+
+me=$(basename "$0")
+warn() { printf '%s: %s\n' "$me" "$*" >&2; }
+die() { warn "$*"; exit 1; }
+usage() {
+cat <<EOF
+usage: $me <options>
+
+Build a virt-p2v bootable image.
+
+OPTIONS:
+ -a Additional yum repository. Can be specified multiple times.
+ -c Yum cache directory.
+ -d Directory containing virt-p2v-image.ks.
+ -f Specific Fedora mirror to use if building a Fedora image.
+ -l Boot image label.
+ -r Primary yum repository.
+ -u Updates yum repository.
+ -h Show this message.
+EOF
+}
+
+onlyonce() {
+ warn "-$1 may only be specified once"
+ usage
+ exit 1
+}
+
+while getopts "a:d:f:hl:r:u:w:" OPTION
+do
+ case $OPTION in
+ a)
+ n_elems=${#extra_repos[*]}
+ extra_repos[$n_elems]="$OPTARG"
+ ;;
+ c)
+ [ -n "$cachedir" ] && onlyonce $OPTION
+ cachedir="$OPTARG"
+ ;;
+ d)
+ [ -n "$datadir" ] && onlyonce $OPTION
+ datadir="$OPTARG"
+ ;;
+ f)
+ [ -n "$fedora_url" ] && onlyonce $OPTION
+ fedora_url="$OPTARG"
+ ;;
+ l)
+ [ -n "$label" ] && onlyonce $OPTION
+ label="$OPTARG"
+ ;;
+ r)
+ [ -n "$repo" ] && onlyonce $OPTION
+ repo="$OPTARG"
+ ;;
+ u)
+ [ -n "$updates" ] && onlyonce $OPTION
+ updates="$OPTARG"
+ ;;
+ h)
+ usage
+ exit 0
+ ;;
+ ?)
+ usage
+ exit 1
+ ;;
+ esac
+done
+
+# Split out here for simple editing with sed during installation
+DEFAULT_DATADIR=.
+
+# Option defaults
+datadir="${datadir:-$DEFAULT_DATADIR}"
+cachedir="${cachedir:-/var/tmp/p2v-image-builder.$USER}"
+label="${label:-Virt-P2V}"
+
+arch=$(rpm --eval '%{_arch}')
+kstmp=$(mktemp --tmpdir p2v-image-builder.XXXXXXXX)
+
+if pgrep -xl nscd; then
+ die "Please stop nscd first"
+fi
+
+rm -f "$kstmp"
+# combine recipe includes
+ksflatten --config "$datadir/virt-p2v-image.ks" --output "$kstmp"
+# XXX broken ksflatten leaves %include
+sed -i 's/^%include /#&/' "$kstmp"
+
+if [ -z "$repo" ]; then
+ # Set defaults for Fedora if this is a fedora system
+ fedora=$(rpm --eval '%{fedora}' |grep [0-9])
+
+ mirrorlist="http://mirrors.fedoraproject.org/mirrorlist"
+
+ case "$fedora" in
+ $curr_rawhide)
+ if [ -z "$fedora_url" ]; then
+ repo="--mirrorlist=$mirrorlist?repo=rawhide&arch=$arch"
+ else
+ repo="--baseurl=$fedora_url/development/rawhide/$arch/os"
+ fi
+ ;;
+ $cur_devel)
+ if [ -z "$fedora_url" ]; then
+ repo="--mirrorlist=$mirrorlist?repo=fedora-$fedora&arch=$arch"
+ else
+ repo="--baseurl=$fedora_url/development/$fedora/$arch/os"
+ fi
+ ;;
+ ?*)
+ if [ -z "$fedora_url" ]; then
+ repo="--mirrorlist=$mirrorlist?repo=fedora-$fedora&arch=$arch"
+ updates="--mirrorlist=$mirrorlist?repo=updates-released-f${fedora}&arch=$arch"
+ else
+ repo="--baseurl=$fedora_url/releases/$fedora/Everything/$arch/os"
+ updates="--baseurl=$fedora_url/updates/$fedora/$arch"
+ fi
+ esac
+else
+ repo="--baseurl=$repo"
+ [ -n "$updates" ] && updates="--baseurl=$updates"
+fi
+
+if [ -n "$repo" ]; then
+ echo "repo --name=base $repo" >> "$kstmp"
+else
+ die "No repository specified, and no default available."
+fi
+if [ -n "$updates" ]; then
+ echo "repo --name=updates $updates" >> "$kstmp"
+fi
+i=0
+for extra in "${extra_repos[@]}"; do
+ ((i++))
+ [ -d "$extra" ] && extra="file://$extra"
+ echo "repo --name=extra$i --baseurl=$extra" >> "$kstmp"
+done
+
+selinux_enforcing=$(/usr/sbin/getenforce)
+case "$selinux_enforcing" in
+ Enforcing) sudo /usr/sbin/setenforce Permissive ;;
+ Permissive) ;;
+ *) if grep -q '^selinux --disabled' "$kstmp";
+ then
+ warn "WARNING: SELinux disabled in kickstart"
+ else
+ die "ERROR: SELinux enabled in kickstart, \
+ but disabled on the build machine"
+ fi ;;
+esac
+
+mkdir -p $cachedir
+sudo livecd-creator -c "$kstmp" -f "$label" --cache="$cachedir"
+
+# Clean up
+rm -f $kstmp
+if [ "$selinux_enforcing" = Enforcing ]; then
+ sudo /usr/sbin/setenforce Enforcing
+fi
diff -ruN virt-v2v-v0.8.1/p2v/image-builder/virt-p2v-image.ks virt-v2v-v0.8.1.new/p2v/image-builder/virt-p2v-image.ks
--- virt-v2v-v0.8.1/p2v/image-builder/virt-p2v-image.ks 1970-01-01 01:00:00.000000000 +0100
+++ virt-v2v-v0.8.1.new/p2v/image-builder/virt-p2v-image.ks 2011-05-11 17:20:21.000000000 +0100
@@ -0,0 +1,19 @@
+# virt-p2v Node image recipe
+
+%include common-install.ks
+
+%packages --excludedocs --nobase
+%include common-pkgs.ks
+%end
+
+%post
+%include common-post.ks
+%end
+
+%include common-minimizer.ks
+
+%post --nochroot
+%include common-post-nochroot.ks
+%end
+
+%include common-manifest-post.ks
diff -ruN virt-v2v-v0.8.1/p2v/server/run-p2v-locally virt-v2v-v0.8.1.new/p2v/server/run-p2v-locally
--- virt-v2v-v0.8.1/p2v/server/run-p2v-locally 1970-01-01 01:00:00.000000000 +0100
+++ virt-v2v-v0.8.1.new/p2v/server/run-p2v-locally 2011-05-11 17:20:21.000000000 +0100
@@ -0,0 +1,52 @@
+#!/bin/sh
+# virt-p2v
+# Copyright (C) 2010 Red Hat Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+# This script sets up the environment so you can run virt-v2v in place
+# without needing to do 'make install' first.
+#
+# Use it like this:
+# ./run-p2v-locally
+#
+# It requires the environment variable VIRTV2V_ROOT to be set. If using
+# libguestfs from source, LIBGUESTFS_ROOT must also be set.
+
+if [ -z "$VIRTV2V_ROOT" ]; then
+ echo "VIRTV2V_ROOT must be set"
+ exit 1
+fi
+
+if [ -z "$PERL5LIB" ]; then
+ PERL5LIB="$VIRTV2V_ROOT/blib/lib"
+else
+ PERL5LIB="$VIRTV2V_ROOT/blib/lib:$PERL5LIB"
+fi
+
+if [ ! -z "$LIBGUESTFS_ROOT" ]; then
+ if [ -z "$LD_LIBRARY_PATH" ]; then
+ LD_LIBRARY_PATH="$LIBGUESTFS_ROOT/src/.libs"
+ else
+ LD_LIBRARY_PATH="$LIBGUESTFS_ROOT/src/.libs:$LD_LIBRARY_PATH"
+ fi
+
+ LIBGUESTFS_PATH="$LIBGUESTFS_ROOT/appliance"
+ PERL5LIB="$LIBGUESTFS_ROOT/perl/blib/lib:$LIBGUESTFS_ROOT/perl/blib/arch:$PERL5LIB"
+fi
+
+export PERL5LIB LD_LIBRARY_PATH LIBGUESTFS_PATH
+
+exec perl "$VIRTV2V_ROOT/p2v-server/virt-p2v-server.pl" "$@"
diff -ruN virt-v2v-v0.8.1/p2v/server/virt-p2v-server.pl virt-v2v-v0.8.1.new/p2v/server/virt-p2v-server.pl
--- virt-v2v-v0.8.1/p2v/server/virt-p2v-server.pl 1970-01-01 01:00:00.000000000 +0100
+++ virt-v2v-v0.8.1.new/p2v/server/virt-p2v-server.pl 2011-05-11 17:20:21.000000000 +0100
@@ -0,0 +1,505 @@
+#!/usr/bin/perl
+# virt-p2v-server
+# Copyright (C) 2011 Red Hat Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+use warnings;
+use strict;
+
+use IO::Handle;
+use YAML::Any;
+
+use Locale::TextDomain 'virt-v2v';
+
+use Sys::Guestfs;
+
+use Sys::VirtConvert;
+use Sys::VirtConvert::Config;
+use Sys::VirtConvert::Converter;
+use Sys::VirtConvert::Connection::LibVirtTarget;
+use Sys::VirtConvert::Connection::RHEVTarget;
+use Sys::VirtConvert::GuestfsHandle;
+use Sys::VirtConvert::Util qw(:DEFAULT logmsg_init logmsg_level);
+
+=encoding utf8
+
+=head1 NAME
+
+virt-p2v-server - Receive data from virt-p2v
+
+=head1 DESCRIPTION
+
+virt-p2v-server is invoked over SSH by virt-p2v. It is not intended to be run
+manually.
+
+=cut
+
+# SIGPIPE will cause an untidy exit of the perl process, without calling
+# destructors. We don't rely on it anywhere, as we check for errors when reading
+# from or writing to a pipe.
+$SIG{'PIPE'} = 'IGNORE';
+
+# The protocol version we support
+use constant VERSION => 0;
+
+# Message types
+use constant MSG_VERSION => 'VERSION';
+use constant MSG_LANG => 'LANG';
+use constant MSG_METADATA => 'METADATA';
+use constant MSG_PATH => 'PATH';
+use constant MSG_CONVERT => 'CONVERT';
+use constant MSG_LIST_PROFILES => 'LIST_PROFILES';
+use constant MSG_SET_PROFILE => 'SET_PROFILE';
+use constant MSG_CONTAINER => 'CONTAINER';
+use constant MSG_DATA => 'DATA';
+
+# Container types
+use constant CONT_RAW => 'RAW';
+
+# Global state
+my $config;
+my $meta;
+my $target;
+
+# Initialize logging
+logmsg_init('syslog');
+#logmsg_level(DEBUG);
+
+logmsg NOTICE, __x("{program} started.", program => 'p2v-server');
+
+# Wrap everything in a big eval to catch any die(). N.B. $SIG{__DIE__} is no
+# good for this, as it catches every die(), even those inside an eval
+eval {
+ # Set the umask to a reasonable default
+ umask(0022);
+
+ # Don't buffer output
+ # While perl will use line buffering when STDOUT is connected to a tty, when
+ # not connected to a tty, for example when invoked directly over ssh, it
+ # will use a regular, large output buffer. This results in messages being
+ # held in the buffer indefinitely.
+ STDOUT->autoflush(1);
+
+ # Read the config file
+ eval {
+ $config = Sys::VirtConvert::Config->new('/etc/virt-v2v.conf');
+ };
+ v2vdie $@ if $@;
+
+ my $msg;
+ while ($msg = p2v_receive()) {
+ my $type = $msg->{type};
+
+ # VERSION n
+ if ($type eq MSG_VERSION) {
+ my $version = $msg->{args}[0];
+ if ($version <= VERSION) {
+ p2v_return_ok();
+ }
+
+ else {
+ err_and_die(__x('This version of virt-p2v-server does not '.
+ 'support protocol version {version}.',
+ version => $version));
+ }
+ }
+
+ # LANG lang
+ elsif ($type eq MSG_LANG) {
+ $ENV{LANG} = $msg->{args}[0];
+ p2v_return_ok();
+ }
+
+ # METADATA length
+ # length bytes of YAML
+ elsif ($type eq MSG_METADATA) {
+ my $yaml = p2v_read($msg->{args}[0]);
+ eval { $meta = Load($yaml); };
+ err_and_die('Error parsing metadata: '.$@) if $@;
+
+ p2v_return_ok();
+ }
+
+ # PATH length path
+ # N.B. path could theoretically include spaces
+ elsif ($type eq MSG_PATH) {
+ my $length = $msg->{args}[0];
+
+ my $path = join(' ', @{$msg->{args}}[1..$#{$msg->{args}}]);
+ receive_path($path, $length);
+ }
+
+ # CONVERT
+ elsif ($type eq MSG_CONVERT) {
+ convert();
+ }
+
+ # LIST_PROFILES
+ elsif ($type eq MSG_LIST_PROFILES) {
+ p2v_return_list($config->list_profiles());
+ }
+
+ # SET_PROFILE profile
+ elsif ($type eq MSG_SET_PROFILE) {
+ set_profile($msg->{args}[0]);
+ }
+
+ else {
+ unexpected_msg($type);
+ }
+ }
+};
+logmsg FATAL, $@ if $@;
+
+exit(0);
+
+# Receive an image file
+sub receive_path
+{
+ my ($path, $length) = @_;
+
+ err_and_die('PATH without prior SET_PROFILE command')
+ unless defined($target);
+ err_and_die('PATH without prior METADATA command')
+ unless defined($meta);
+
+ my ($disk) = grep { $_->{path} eq $path } @{$meta->{disks}};
+ err_and_die("$path not found in metadata") unless defined($disk);
+
+ # Construct a volume name based on the path and hostname
+ my $name = $meta->{name}.'-'.$disk->{device};
+ $name =~ s,/,_,g; # e.g. cciss devices have a directory structure
+
+ my $sopts = $config->get_storage_opts();
+
+ my $convert = 0;
+ my $format;
+ my $sparse;
+
+ # Default to raw. Conversion required for anything else.
+ if (!exists($sopts->{format}) || $sopts->{format} eq 'raw') {
+ $format = 'raw';
+ } else {
+ $format = $sopts->{format};
+ $convert = 1;
+ }
+
+ # Default to non-sparse
+ my $allocation = $sopts->{allocation};
+ if (!defined($allocation) || $allocation eq 'preallocated') {
+ $sparse = 0;
+ } elsif ($allocation eq 'sparse') {
+ $sparse = 1;
+ } else {
+ err_and_die(__x('Invalid allocation policy {policy} in profile.',
+ policy => $allocation));
+ }
+
+ # Create the target volume
+ my $vol;
+ eval {
+ $vol = $target->create_volume(
+ $name,
+ $format,
+ $length,
+ $sparse
+ );
+ };
+ err_and_die($@) if $@;
+ p2v_return_ok();
+
+ # Receive an initial container
+ my $msg = p2v_receive();
+ unexpected_msg($msg->{type}) unless $msg->{type} eq MSG_CONTAINER;
+
+ # We only support RAW container
+ my $ctype = $msg->{args}[0];
+ err_and_die("Received unknown container type: $ctype")
+ unless $ctype eq CONT_RAW;
+ p2v_return_ok();
+
+ # Update the disk entry with the new volume details
+ $disk->{local_path} = $vol->get_local_path();
+ $disk->{path} = $vol->get_path();
+ $disk->{is_block} = $vol->is_block();
+
+ my $writer = $vol->get_write_stream($convert);
+
+ # Receive volume data in chunks
+ my $received = 0;
+ while ($received < $length) {
+ my $data = p2v_receive();
+
+ unexpected_msg($data->command) unless $data->{type} eq MSG_DATA;
+
+ # Read the data message in chunks of up to 4M
+ my $remaining = $data->{args}[0];
+ while ($remaining > 0) {
+ my $chunk = $remaining > 4*1024*1024 ? 4*1024*1024 : $remaining;
+ my $buf = p2v_read($chunk);
+
+ $received += $chunk;
+ $remaining -= $chunk;
+
+ eval { $writer->write($buf); };
+ err_and_die($@) if $@;
+ }
+
+ p2v_return_ok();
+ }
+}
+
+# Use the specified profile
+sub set_profile
+{
+ my ($profile) = @_;
+
+ # Check the profile is in our list
+ my $found = 0;
+ for my $i ($config->list_profiles()) {
+ if ($i eq $profile) {
+ $found = 1;
+ last;
+ }
+ }
+ err_and_die(__x('Invalid profile: {profile}', profile => $profile))
+ unless ($found);
+
+ $config->use_profile($profile);
+
+ my $storage = $config->get_storage();
+ my $method = $config->get_method();
+ if ($method eq 'libvirt') {
+ $target = new Sys::VirtConvert::Connection::LibVirtTarget
+ ('qemu:///system', $storage);
+ } elsif ($method eq 'rhev') {
+ $target = new Sys::VirtConvert::Connection::RHEVTarget($storage);
+ } else {
+ err_and_die(__x('Profile {profile} specifies invalid method {method}.',
+ profile => $profile, method => $method));
+ }
+
+ p2v_return_ok();
+}
+
+sub convert
+{
+ err_and_die('CONVERT without prior SET_PROFILE command')
+ unless (defined($target));
+
+ err_and_die('CONVERT without prior METADATA command')
+ unless defined($meta);
+
+ my @localpaths = map { $_->{local_path} } @{$meta->{disks}};
+
+ my $g;
+ eval {
+ my $transferiso = $config->get_transfer_iso();
+
+ $g = new Sys::VirtConvert::GuestfsHandle(
+ \@localpaths,
+ $transferiso,
+ $target->isa('Sys::VirtConvert::Connection::RHEVTarget')
+ );
+
+ my $transferdev;
+ if (defined($transferiso)) {
+ my @devices = $g->list_devices();
+ $transferdev = pop(@devices);
+ }
+
+ my $root = inspect_guest($g, $transferdev);
+ my $guestcaps =
+ Sys::VirtConvert::Converter->convert($g, $config, $root, $meta);
+ $target->create_guest($g, $root, $meta, $config, $guestcaps,
+ $meta->{name});
+
+ if($guestcaps->{block} eq 'virtio' && $guestcaps->{net} eq 'virtio') {
+ logmsg NOTICE, __x('{name} configured with virtio drivers.',
+ name => $meta->{name});
+ } elsif ($guestcaps->{block} eq 'virtio') {
+ logmsg NOTICE, __x('{name} configured with virtio storage only.',
+ name => $meta->{name});
+ } elsif ($guestcaps->{net} eq 'virtio') {
+ logmsg NOTICE, __x('{name} configured with virtio networking only.',
+ name => $meta->{name});
+ } else {
+ logmsg NOTICE, __x('{name} configured without virtio drivers.',
+ name => $meta->{name});
+ }
+ };
+
+ # If any of the above commands result in failure, we need to ensure that
+ # the guestfs qemu process is cleaned up before further cleanup. Failure to
+ # do this can result in failure to umount RHEV export's temporary mount
+ # point.
+ if ($@) {
+ my $err = $@;
+ $g->close();
+
+ # We trust the error was already logged
+ p2v_return_err($err);
+ die($@);
+ }
+
+ p2v_return_ok();
+}
+
+sub unexpected_msg
+{
+ err_and_die('Received unexpected command: '.shift);
+}
+
+sub err_and_die
+{
+ my $err = shift;
+ p2v_return_err($err);
+ v2vdie $err;
+}
+
+END {
+ my $err = $?;
+
+ logmsg NOTICE, __x("{program} exited.", program => 'p2v-server');
+
+ # die() sets $? to 255, which is untidy.
+ $? = $err == 255 ? 1 : $err;
+}
+
+# Perform guest inspection using the libguestfs core inspection API.
+# Returns the root device of the os to be converted.
+sub inspect_guest
+{
+ my $g = shift;
+ my $transferdev = shift;
+
+ # Get list of roots, sorted
+ my @roots = $g->inspect_os();
+
+ # Filter out the transfer device from the results of inspect_os
+ # There's a libguestfs bug (fixed upstream) which meant the transfer ISO
+ # could be erroneously detected as an unknown Windows OS. As we know what it
+ # is, we can filter out the transfer device here. Even when the fix is
+ # released this is reasonable belt & braces.
+ @roots = grep(!/^\Q$transferdev\E$/, @roots);
+
+ @roots = sort @roots;
+
+ # Only work on single-root operating systems.
+ v2vdie __('No root device found in this operating system image.')
+ if @roots == 0;
+
+ v2vdie __('Multiboot operating systems are not supported.')
+ if @roots > 1;
+
+ return $roots[0];
+}
+
+sub p2v_receive
+{
+ my $in = <>;
+ v2vdie __('Client closed connection unexpectedly') unless defined($in);
+
+ # Messages consist of the message type followed by 0 or more arguments,
+ # terminated by a newline
+ chomp($in);
+ $in =~ /^([A-Z_]+)( .+)?$/ or err_and_die("Received invalid message: $in");
+
+ my %msg;
+ $msg{type} = $1;
+ if (defined($2)) {
+ my @args = split(' ', $2);
+ $msg{args} = \@args;
+ } else {
+ $msg{args} = [];
+ }
+
+ logmsg DEBUG, __x('Received: {command} {args}',
+ command => $msg{type},
+ args => join(' ', @{$msg{args}}));
+
+ return \%msg;
+}
+
+sub p2v_read
+{
+ my ($length) = @_;
+
+ my $buf;
+ my $total = 0;
+
+ while($total < $length) {
+ my $in = read(STDIN, $buf, $length, $total)
+ or err_and_die(__x('Error receiving data: {error}', error => $@));
+ logmsg DEBUG, "Read $in bytes";
+ $total += $in;
+ }
+
+ return $buf;
+}
+
+sub p2v_return_ok
+{
+ my $msg = "OK";
+ logmsg DEBUG, __x('Sent: {msg}', msg => $msg);
+ print $msg,"\n";
+}
+
+sub p2v_return_list
+{
+ my @values = @_;
+
+ my $msg = 'LIST '.scalar(@values);
+ foreach my $value (@values) {
+ $msg .= "\n$value";
+ }
+ logmsg DEBUG, __x('Sent: {msg}', msg => $msg);
+ print $msg,"\n";
+}
+
+sub p2v_return_err
+{
+ my $msg = 'ERROR '.shift;
+ logmsg DEBUG, __x('Sent: {msg}', msg => $msg);
+ print $msg,"\n";
+}
+
+=head1 SEE ALSO
+
+L<virt-v2v(1)>,
+L<http://libguestfs.org/>.
+
+=head1 AUTHOR
+
+Matthew Booth <mbooth@redhat.com>
+
+=head1 COPYRIGHT
+
+Copyright (C) 2011 Red Hat Inc.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
diff -ruN virt-v2v-v0.8.1/p2v-client/bin/virt-p2v virt-v2v-v0.8.1.new/p2v-client/bin/virt-p2v
--- virt-v2v-v0.8.1/p2v-client/bin/virt-p2v 2011-04-26 20:58:33.000000000 +0100
+++ virt-v2v-v0.8.1.new/p2v-client/bin/virt-p2v 1970-01-01 01:00:00.000000000 +0100
@@ -1,62 +0,0 @@
-#!/usr/bin/env ruby
-
-# Copyright (C) 2011 Red Hat Inc.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-require 'virt-p2v/ui/main'
-require 'virt-p2v/ui/network'
-require 'virt-p2v/ui/connect'
-require 'virt-p2v/ui/convert'
-require 'virt-p2v/ui/success'
-
-require 'virt-p2v/converter'
-require 'virt-p2v/netdevice'
-
-require 'gettext'
-
-include GetText
-
-bindtextdomain('virt-p2v')
-
-if Process.uid != 0
- puts _("virt-p2v must be executed with root privileges.\n" +
- "It is intended to be included in a custom Live image, not " +
- "run from the command\nline.")
- abort
-end
-
-converter = VirtP2V::Converter.new
-
-# Initialise the wizard UI
-ui = VirtP2V::UI::Main.new
-
-# Initialize wizard pages
-VirtP2V::UI::Network.init(ui)
-VirtP2V::UI::Connect.init(ui, converter)
-VirtP2V::UI::Convert.init(ui, converter)
-VirtP2V::UI::Success.init(ui)
-
-# Skip the network configuration screen if there is already an active network
-# connection
-VirtP2V::NetworkDevice.all_devices.each { |device|
- if device.activated then
- ui.active_page = 'server_win'
- break
- end
-}
-
-ui.show
-ui.main_loop
diff -ruN virt-v2v-v0.8.1/p2v-client/lib/virt-p2v/blockdevice.rb virt-v2v-v0.8.1.new/p2v-client/lib/virt-p2v/blockdevice.rb
--- virt-v2v-v0.8.1/p2v-client/lib/virt-p2v/blockdevice.rb 2011-04-26 20:58:33.000000000 +0100
+++ virt-v2v-v0.8.1.new/p2v-client/lib/virt-p2v/blockdevice.rb 1970-01-01 01:00:00.000000000 +0100
@@ -1,112 +0,0 @@
-# Copyright (C) 2011 Red Hat Inc.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-module VirtP2V
-
-class NoSuchDeviceError < StandardError; end
-
-class FixedBlockDevice
- @@devices = {}
-
- def self.all_devices
- @@devices.values
- end
-
- def self.[](device)
- raise NoSuchDeviceError unless @@devices.has_key?(device)
-
- @@devices[device]
- end
-
- attr_reader :device
-
- def initialize(device)
- @device = device
- @@devices[device] = self
- end
-end
-
-class RemovableBlockDevice
- @@devices = {}
-
- def self.all_devices
- @@devices.values
- end
-
- def self.[](device)
- raise NoSuchDeviceError unless @@devices.has_key?(device)
-
- @@devices[device]
- end
-
- attr_reader :device, :type
-
- def initialize(device, type)
- @device = device
- @type = type
-
- @@devices[device] = self
- end
-end
-
-# Detect and instantiate all fixed and removable block devices in the system
-begin
- # Look for block devices
- # Specifically, we look for entries in /sys/block which have a device
- # symlink and no entries in their slaves subdirectory
- Dir.foreach('/sys/block') { |dev|
- next if dev == '.' || dev == '..'
-
- # Skip if there's no device link
- next unless File.exists?("/sys/block/#{dev}/device")
-
- # Skip if the slaves subdirectory contains anything other than . and
- # ..
- begin
- next if Dir.entries("/sys/block/#{dev}/slaves").length > 2
- rescue Errno::ENOENT => ex
- # This shouldn't happen, but if it did I guess it would mean
- # there are no slave devices
- end
-
- # We've got a real block device. Check if it's removable or not
- File.open("/sys/block/#{dev}/removable") { |fd|
- removable = fd.gets.chomp
- if removable == "0" then
- FixedBlockDevice.new(dev)
- else
- # Look in device/modalias to work out what kind of removable
- # device this is
- type = File.open(
- "/sys/block/#{dev}/device/modalias") \
- { |modalias_f|
- modalias = modalias_f.gets.chomp
- if modalias =~ /floppy/ then
- 'floppy'
- elsif modalias =~ /cdrom/ then
- 'cdrom'
- else
- # We don't know what this is, ignore it
- end
- }
-
- RemovableBlockDevice.new(dev, type) unless type.nil?
- end
- }
- }
-end
-
-end
diff -ruN virt-v2v-v0.8.1/p2v-client/lib/virt-p2v/connection.rb virt-v2v-v0.8.1.new/p2v-client/lib/virt-p2v/connection.rb
--- virt-v2v-v0.8.1/p2v-client/lib/virt-p2v/connection.rb 2011-04-26 20:58:33.000000000 +0100
+++ virt-v2v-v0.8.1.new/p2v-client/lib/virt-p2v/connection.rb 1970-01-01 01:00:00.000000000 +0100
@@ -1,320 +0,0 @@
-# Copyright (C) 2011 Red Hat Inc.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-require 'gettext'
-require 'rubygems'
-require 'net/ssh'
-require 'thread'
-require 'yaml'
-
-require 'virt-p2v/gtk-queue'
-
-module VirtP2V
-
-class Connection
- include GetText
-
- attr_reader :connected
-
- class InvalidHostnameError < StandardError; end
- class InvalidCredentialsError < StandardError; end
- class TransportError < StandardError; end
- class NoP2VError < StandardError; end
- class RemoteError < StandardError; end
- class ProtocolError < StandardError; end
- class NotConnectedError < StandardError; end
-
- def on_connect(&cb)
- @connection_listeners << cb
- end
-
- def initialize(hostname, username, password, &cb)
- @mutex = Mutex.new
- @connection_listeners = []
-
- # Always send our version number on connection
- @connection_listeners << Proc.new { |cb|
- self.version { |result| cb.call(result) }
- }
-
- run(cb) {
- error = nil
- begin
- @ssh = Net::SSH.start(hostname, username, :password => password)
- rescue SocketError, Errno::EHOSTUNREACH => ex
- raise InvalidHostnameError
- raise ex
- rescue Net::SSH::AuthenticationFailed => ex
- raise InvalidCredentialsError
- raise ex
- end
-
- @buffer = ""
- @connected = false
-
- Gtk.queue { cb.call(true) }
- }
- end
-
- def connect(&cb)
- run(cb) {
- @ch = @ssh.open_channel do |ch|
- ch.exec("virt-p2v-server") do |ch, success|
- raise RemoteError,
- "could not execute a remote command" unless success
-
- ch.on_data do |ch, data|
- @buffer << data
- end
-
- # If we get anything on stderr, raise it as a RemoteError
- ch.on_extended_data do |ch, type, data|
- close
- raise RemoteError, data
- end
-
- # Clean up local resources if we get eof from the other end
- ch.on_eof do |ch|
- close
- end
-
- @connected = true
- end
-
- end
-
- # Wait until we're connected
- @ssh.loop do
- !@connected
- end
-
- i = 0;
- listener_result = lambda { |result|
- if result.kind_of?(Exception)
- cb.call(result)
- else
- i += 1
- if i == @connection_listeners.length
- cb.call(true)
- else
- Gtk.queue {
- @connection_listeners[i].call(listener_result)
- }
- end
- end
- }
- Gtk.queue { @connection_listeners[0].call(listener_result) }
- }
- end
-
- def close
- @connected = false
- @buffer = ""
- @ch.close
- end
-
- def version(&cb)
- raise NotConnectedError unless @connected
-
- run(cb) {
- @ch.send_data("VERSION 0\n")
- result = parse_return
-
- Gtk.queue { cb.call(result) }
- }
- end
-
- def lang(lang, &cb)
- raise NotConnectedError unless @connected
-
- run(cb) {
- @ch.send_data("LANG #{lang}\n")
- result = parse_return
-
- Gtk.queue { cb.call(result) }
- }
- end
-
- def metadata(meta, &cb)
- raise NotConnectedError unless @connected
-
- run(cb) {
- payload = YAML::dump(meta)
- @ch.send_data("METADATA #{payload.length}\n");
- @ch.send_data(payload)
- result = parse_return
-
- Gtk.queue { cb.call(result) }
- }
- end
-
- def path(length, path, &cb)
- raise NotConnectedError unless @connected
-
- run(cb) {
- @ch.send_data("PATH #{length} #{path}\n")
- result = parse_return
-
- Gtk.queue { cb.call(result) }
- }
- end
-
- def convert(&cb)
- raise NotConnectedError unless @connected
-
- run(cb) {
- @ch.send_data("CONVERT\n")
- result = parse_return
-
- Gtk.queue { cb.call(result) }
- }
- end
-
- def list_profiles(&cb)
- raise NotConnectedError unless @connected
-
- run(cb) {
- @ch.send_data("LIST_PROFILES\n")
- result = parse_return
-
- Gtk.queue { cb.call(result) }
- }
- end
-
- def set_profile(profile, &cb)
- raise NotConnectedError unless @connected
-
- run(cb) {
- @ch.send_data("SET_PROFILE #{profile}\n")
- result = parse_return
-
- Gtk.queue { cb.call(result) }
- }
- end
-
- def container(type, &cb)
- raise NotConnectedError unless @connected
-
- run(cb) {
- @ch.send_data("CONTAINER #{type}\n")
- result = parse_return
-
- Gtk.queue { cb.call(result) }
- }
- end
-
- def send_data(io, length, progress, &completion)
- raise NotConnectedError unless @connected
-
- run(completion) {
- @ch.send_data("DATA #{length}\n")
- total = 0
- buffer = ''
- begin
- # This loop is in the habit of hanging in Net::SSH when sending
- # a chunk larger than about 2M. Putting the 1 second wait
- # timeout here kickstarts it if it stops.
- @ssh.loop(1) {
- if io.eof? || total == length then
- false
- else
- if @ch.remote_window_size > 0 then
- out = length - total
- out = @ch.remote_window_size \
- if out > @ch.remote_window_size
-
- io.read(out, buffer)
- @ch.send_data(buffer)
-
- total += buffer.length
-
- # Send a progress callback
- Gtk.queue { progress.call(total) }
- end
-
- true
- end
- }
- rescue => ex
- Gtk.queue { completion.call(ex) }
- end
-
- result = parse_return
-
- Gtk.queue { completion.call(result) }
- }
- end
-
- private
-
- def run(cb)
- # Run the given block in a new thread
- t = Thread.new {
- begin
- # We can't run more than 1 command simultaneously
- @mutex.synchronize { yield }
- rescue => ex
- # Deliver exceptions to the caller, then re-raise them
- Gtk.queue { cb.call(ex) }
- raise ex
- end
- }
- t.priority = 1
- end
-
- # Return a single line of output from the remote server
- def readline
- # Run the event loop until the buffer contains a newline
- index = nil
- @ssh.loop do
- if !@ch.eof? then
- index = @buffer.index("\n")
- index.nil?
- else
- close
- raise RemoteError, _('Server closed connection unexpectedly')
- end
- end
-
- # Remove the line from the buffer and return it with the trailing
- # newline removed
- @buffer.slice!(0..index).chomp
- end
-
- def parse_return
- line = readline
- line =~ /^(OK|ERROR|LIST)(?:\s(.*))?$/ or
- raise ProtocolError, "Invalid server response: #{line}"
-
- return true if $~[1] == 'OK'
- if $~[1] == 'ERROR' then
- close
- raise RemoteError, $~[2]
- end
-
- # LIST response. Get the number of items, and read that many lines
- n = Integer($~[2])
- ret = []
- while n > 0 do
- n -= 1
- ret.push(readline)
- end
-
- ret
- end
-end
-
-end
diff -ruN virt-v2v-v0.8.1/p2v-client/lib/virt-p2v/converter.rb virt-v2v-v0.8.1.new/p2v-client/lib/virt-p2v/converter.rb
--- virt-v2v-v0.8.1/p2v-client/lib/virt-p2v/converter.rb 2011-04-26 20:58:33.000000000 +0100
+++ virt-v2v-v0.8.1.new/p2v-client/lib/virt-p2v/converter.rb 1970-01-01 01:00:00.000000000 +0100
@@ -1,218 +0,0 @@
-# Copyright (C) 2011 Red Hat Inc.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-require 'gettext'
-require 'rexml/document'
-include REXML
-
-require 'virt-p2v/netdevice'
-require 'virt-p2v/blockdevice'
-
-module VirtP2V
-
-# NIC
-# hostname
-# username
-# password
-
-# 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
-
-class Converter
- include GetText
-
- attr_accessor :profile, :name, :cpus, :memory, :arch
- attr_reader :features, :disks, :removables, :nics
-
- attr_reader :connection
-
- def on_connection(&cb)
- @connection_listeners << cb
- end
-
- def connection=(connection)
- @connection = connection
- @connection_listeners.each { |cb|
- cb.call(connection)
- }
- end
-
- 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|
- status.call(_('Converting'))
- @connection.convert(&cb)
- }
- ], completion)
- end
-
- private
-
- def initialize()
- @profile = nil
- @connection = nil
- @connection_listeners = []
-
- # 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 `hwloc-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 = []
- end
-
- def disk(dev, status, progress, completion)
- path = "/dev/#{dev}"
- # XXX: No error checking of blockdev execution
- size = Integer(`blockdev --getsize64 #{path}`.chomp)
- 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 += 1
- progress.call(dev, pc)
- end
- }, &cb)
- }
- ], completion)
- end
-
- 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
-
- def meta
- {
- 'name' => @name,
- 'cpus' => @cpus,
- 'memory' => @memory,
- 'arch' => @arch,
- 'features' => @features,
- 'disks' => @disks.map { |device|
- {
- 'device' => device,
- 'path' => "/dev/#{device}",
- 'is_block' => '1',
- 'format' => 'raw'
- }
- },
- '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
-end
-
-end
diff -ruN virt-v2v-v0.8.1/p2v-client/lib/virt-p2v/gtk-queue.rb virt-v2v-v0.8.1.new/p2v-client/lib/virt-p2v/gtk-queue.rb
--- virt-v2v-v0.8.1/p2v-client/lib/virt-p2v/gtk-queue.rb 2011-04-26 20:58:33.000000000 +0100
+++ virt-v2v-v0.8.1.new/p2v-client/lib/virt-p2v/gtk-queue.rb 1970-01-01 01:00:00.000000000 +0100
@@ -1,52 +0,0 @@
-# Copyright (C) 2011 Red Hat Inc.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-# This code is taken from:
-# http://ruby-gnome2.sourceforge.jp/hiki.cgi?tips_threads
-# The author of the above page is given as Tal Liron
-# The above page is distributed under the terms of the GNU FDL, although I
-# consider this code to be too trivial to be copyrightable
-
-require 'gtk2'
-require 'thread'
-
-module Gtk
- GTK_PENDING_BLOCKS = []
- GTK_PENDING_BLOCKS_LOCK = Mutex.new
-
- def Gtk.queue &block
- if Thread.current == Thread.main
- block.call
- else
- GTK_PENDING_BLOCKS_LOCK.synchronize do
- GTK_PENDING_BLOCKS << block
- end
- end
- end
-
- def Gtk.main_with_queue timeout
- Gtk.timeout_add timeout do
- GTK_PENDING_BLOCKS_LOCK.synchronize do
- for block in GTK_PENDING_BLOCKS
- block.call
- end
- GTK_PENDING_BLOCKS.clear
- end
- true
- end
- Gtk.main
- end
-end
diff -ruN virt-v2v-v0.8.1/p2v-client/lib/virt-p2v/netdevice.rb virt-v2v-v0.8.1.new/p2v-client/lib/virt-p2v/netdevice.rb
--- virt-v2v-v0.8.1/p2v-client/lib/virt-p2v/netdevice.rb 2011-04-26 20:58:33.000000000 +0100
+++ virt-v2v-v0.8.1.new/p2v-client/lib/virt-p2v/netdevice.rb 1970-01-01 01:00:00.000000000 +0100
@@ -1,259 +0,0 @@
-# Copyright (C) 2011 Red Hat Inc.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-require 'dbus'
-require 'gettext'
-
-module VirtP2V
-
-class NetworkDevice
- include GetText
-
- attr_reader :name, :mac, :connected, :activated, :state
-
- # Some NetworkManager names, for convenience
- CONNECTION = 'org.freedesktop.NetworkManagerSettings.Connection'.freeze
- DEVICE = 'org.freedesktop.NetworkManager.Device'.freeze
- NETWORKMANAGER = 'org.freedesktop.NetworkManager'.freeze
- PROPERTIES = 'org.freedesktop.DBus.Properties'.freeze
- SETTINGS = 'org.freedesktop.NetworkManagerSettings'.freeze
- WIRED = 'org.freedesktop.NetworkManager.Device.Wired'.freeze
-
- # NetworkManager device types
- # http://projects.gnome.org/NetworkManager/developers/spec-08.html
- TYPE_UNKNOWN = 0
- TYPE_ETHERNET = 1
- TYPE_WIFI = 2
- TYPE_GSM = 3
- TYPE_CDMA = 4
-
- # NetworkManager device states
- STATE_UNKNOWN = 0
- STATE_UNMANAGED = 1
- STATE_UNAVAILABLE = 2
- STATE_DISCONNECTED = 3
- STATE_PREPARE = 4
- STATE_CONFIG = 5
- STATE_NEED_AUTH = 6
- STATE_IP_CONFIG = 7
- STATE_ACTIVATED = 8
- STATE_FAILED = 9
-
- # Human readable descriptions of NetworkManager Device States
- STATES = {
- 0 => _('Unknown').freeze, # For completeness
- 1 => _('Unmanaged').freeze, # For completeness
- 2 => _('No cable connected').freeze,
- 3 => _('Not connected').freeze,
- 4 => _('Preparing to connect').freeze,
- 5 => _('Configuring').freeze,
- 6 => _('Waiting for authentication').freeze,
- 7 => _('Obtaining an IP address').freeze,
- 8 => _('Connected').freeze,
- 9 => _('Connection failed').freeze
- }.freeze
-
- def initialize(obj, device, props)
- device.default_iface = WIRED
-
- @nm_obj = obj
- @name = props.Get(DEVICE, 'Interface')[0]
- @mac = props.Get(WIRED, 'HwAddress')[0]
- state = props.Get(WIRED, 'State')[0]
-
- # Lookup by name
- @@devices[@name] = self
-
- state_updated(state)
-
- # Register a listener for state changes
- device.on_signal('PropertiesChanged') { |props|
- if props.has_key?('State') then
- state_updated(props['State'])
-
- # Notify registered state change handlers
- @@listeners.each { |cb| cb.call(self) }
- end
- }
- end
-
- def self.all_devices()
- @@devices.values
- end
-
- def self.add_listener(cb)
- @@listeners.push(cb)
- end
-
- def self.[](name)
- @@devices[name]
- end
-
- def activate(auto, ip, prefix, gateway, dns)
- # Get an IP config dependent on whether @ip_address is IPv4 or IPv6
- ip_config = auto ? get_config_auto :
- ip.ipv4? ? get_config_ipv4() : get_config_ipv6()
-
- # Create a new NetworkManager connection object
- settings = @@nm_service.object(
- '/org/freedesktop/NetworkManagerSettings')
- settings.introspect()
- settings.default_iface = SETTINGS
-
- uuid = `uuidgen`.chomp
- settings.AddConnection(
- 'connection' => {
- 'uuid' => uuid,
- 'id' => 'P2V',
- 'type' => '802-3-ethernet',
- 'autoconnect' => false
- },
- '802-3-ethernet' => {},
- 'ipv4' => ip_config['ipv4'],
- 'ipv6' => ip_config['ipv6']
- )
-
- # Find the connection we just created
- # XXX: There must be a better way to get this!
- conn = settings.ListConnections()[0].each { |i|
- conn = @@nm_service.object(i)
- conn.introspect
- conn.default_iface = CONNECTION
-
- break i if conn.GetSettings()[0]['connection']['uuid'] == uuid
- }
-
- nm = @@nm_service.object('/org/freedesktop/NetworkManager')
- nm.introspect
- nm.default_iface = NETWORKMANAGER
- nm.ActivateConnection('org.freedesktop.NetworkManagerSystemSettings',
- conn, @nm_obj, '/')
- end
-
- private
-
- def state_updated(state)
- @connected = state > 2
- @state = STATES[state]
-
- if state == STATE_ACTIVATED then
- @activated = true
- elsif state == STATE_FAILED then
- @activated = false
- else
- @activated = nil
- end
- end
-
- def get_config_auto
- {
- 'ipv4' => {
- 'method' => 'auto'
- },
- 'ipv6' => {
- 'method' => 'ignore'
- }
- }
- end
-
- def ipv4_to_nm(ipaddr)
- ipaddr.hton().unpack("I")[0]
- end
-
- def get_config_ipv4
- addresses = [[ ipv4_to_nm(@ip_address), @ip_prefix,
- ipv4_to_nm(@ip_gateway) ]]
-
- dns = []
- @ip_dns.each{ |ipaddr|
- # Only use IPv4 DNS servers
- next unless ipaddr.ipv4?
- dns.push(ipv4_to_nm(ipaddr))
- }
-
- {
- 'ipv4' => {
- 'method' => 'manual',
- 'addresses' => [ 'aau', addresses ],
- 'dns' => [ 'au', dns ]
- },
- 'ipv6' => {
- 'method' => 'ignore'
- }
- }
- end
-
- def ipv6_to_nm(ipaddr)
- ipaddr.hton().unpack("c*")
- end
-
- def get_config_ipv6
- dns = []
- @ip_dns.each { |ipaddr|
- # Only use IPv6 DNS servers
- next unless ipaddr.ipv6?
- dns.push(ipv6_to_nm(ipaddr))
- }
-
- {
- 'ipv4' => {
- 'method' => 'disabled'
- },
- 'ipv6' => {
- 'method' => 'manual',
- 'addresses' => [ 'a(ayu)', [[
- ipv6_to_nm(@ip_address),
- @ip_prefix
- ]] ],
- 'routes' => [ 'a(ayuayu)', [[
- [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], 0,
- ipv6_to_nm(@ip_gateway), 1024
- ]] ],
- 'dns' => [ 'aay', dns ]
- }
- }
- end
-
- # Class initialization
- begin
- dbus = DBus::SystemBus.instance()
- dbus.glibize()
- @@nm_service = dbus.service(NETWORKMANAGER)
-
- nm = @@nm_service.object('/org/freedesktop/NetworkManager')
- nm.introspect
- nm.default_iface = NETWORKMANAGER
-
- @@devices = {}
- nm.GetDevices()[0].each { |obj|
- device = @@nm_service.object(obj)
- device.introspect
-
- props = device[PROPERTIES]
- type = props.Get(DEVICE, 'DeviceType')[0]
-
- # We only support ethernet devices
- next unless type == TYPE_ETHERNET
-
- # Constructor will add it to @@devices
- self.new(obj, device, props)
- }
-
- @@listeners = []
- end
-end
-
-end #module
diff -ruN virt-v2v-v0.8.1/p2v-client/lib/virt-p2v/ui/connect.rb virt-v2v-v0.8.1.new/p2v-client/lib/virt-p2v/ui/connect.rb
--- virt-v2v-v0.8.1/p2v-client/lib/virt-p2v/ui/connect.rb 2011-04-26 20:58:33.000000000 +0100
+++ virt-v2v-v0.8.1.new/p2v-client/lib/virt-p2v/ui/connect.rb 1970-01-01 01:00:00.000000000 +0100
@@ -1,179 +0,0 @@
-# Copyright (C) 2011 Red Hat Inc.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-require 'gettext'
-require 'gtk2'
-
-require 'virt-p2v/connection'
-
-module VirtP2V::UI::Connect
- include GetText
-
- UI_STATE_INVALID = 0
- UI_STATE_VALID = 1
- UI_STATE_ACTIVATING = 2
- UI_STATE_COMPLETE = 3
-
- EV_HOSTNAME = 0
- EV_USERNAME = 1
- EV_PASSWORD = 2
- EV_BUTTON = 3
- EV_ACTIVATION = 4
-
- def self.event(event, status)
- case event
- when EV_HOSTNAME
- @hostname = status
- when EV_USERNAME
- @username = status
- when EV_PASSWORD
- @password = status
- when EV_BUTTON, EV_ACTIVATION
- # Persistent state not required
- else
- raise "Unexpected event: #{event}"
- end
-
- valid = @hostname && @username && @password
-
- case @state
- when UI_STATE_INVALID
- set_state(UI_STATE_VALID) if valid
- when UI_STATE_VALID
- if !valid then
- set_state(UI_STATE_INVALID)
- elsif event == EV_BUTTON
- set_state(UI_STATE_ACTIVATING)
- end
- when UI_STATE_ACTIVATING
- # UI is disabled, so we shouldn't be getting any events other than
- # EV_ACTIVATION
- raise "Unexpected event: #{event}" unless event == EV_ACTIVATION
-
- set_state(status ? UI_STATE_COMPLETE : UI_STATE_VALID)
- else
- raise "Unexpected UI state: #{@state}"
- end
- end
-
- def self.init(ui, converter)
- @hostname_ui = ui.get_object('server_hostname')
- @username_ui = ui.get_object('server_username')
- @password_ui = ui.get_object('server_password')
- @connect_frame = ui.get_object('connect_frame')
- @connect_button = ui.get_object('connect_button')
- @connect_error = ui.get_object('connect_error')
-
- ui.register_handler('server_hostname_changed',
- method(:server_hostname_changed))
- ui.register_handler('server_username_changed',
- method(:server_username_changed))
- ui.register_handler('server_password_changed',
- method(:server_password_changed))
- ui.register_handler('connect_button_clicked',
- method(:connect_button_clicked))
-
- @hostname = @hostname_ui.text.strip.length > 0
- @username = @username_ui.text.strip.length > 0
- @password = @password_ui.text.length > 0 # Allow spaces in passwords
- @state = UI_STATE_INVALID
-
- @ui = ui
- @converter = converter
- end
-
- def self.set_state(state)
- # Don't do anything if state hasn't changed
- return if state == @state
-
- case state
- when UI_STATE_INVALID
- @connect_frame.sensitive = true
- @connect_button.sensitive = false
-
- @state = UI_STATE_INVALID
- when UI_STATE_VALID
- @connect_frame.sensitive = true
- @connect_button.sensitive = true
-
- @state = UI_STATE_VALID
- when UI_STATE_ACTIVATING
- @connect_frame.sensitive = false
- @connect_button.sensitive = false
- @connect_error.text = ''
-
- @state = UI_STATE_ACTIVATING
- when UI_STATE_COMPLETE
- # Activate the next page
- @ui.active_page = 'conversion_win'
-
- # ... then leave this one as we hope to find it if we come back here
- set_state(UI_STATE_VALID)
- else
- raise "Attempt to set unexpected UI state: #{@state}"
- end
- end
-
- def self.server_hostname_changed
- event(EV_HOSTNAME, @hostname_ui.text.strip.length > 0)
- end
-
- def self.server_username_changed
- event(EV_USERNAME, @username_ui.text.strip.length > 0)
- end
-
- def self.server_password_changed
- event(EV_PASSWORD, @password_ui.text.length > 0)
- end
-
- def self.connect_button_clicked
- event(EV_BUTTON, true)
-
- hostname = @hostname_ui.text.strip
- username = @username_ui.text.strip
- password = @password_ui.text
- connection = VirtP2V::Connection.new(hostname, username, password) \
- { |result|
- case result
- when true
- @converter.connection = connection
- connection.connect { |result|
- case result
- when true
- event(EV_ACTIVATION, true)
- when VirtP2V::Connection::RemoteError
- @connect_error.text = _('Failed to start ' +
- 'virt-p2v-server on remote ' +
- 'server')
- event(EV_ACTIVATION, false)
- else
- @connect_error.text = result.message
- event(EV_ACTIVATION, false)
- end
- }
- when VirtP2V::Connection::InvalidHostnameError
- @connect_error.text = _"Unable to connect to #{hostname}"
- event(EV_ACTIVATION, false)
- when VirtP2V::Connection::InvalidCredentialsError
- @connect_error.text = _"Invalid username/password"
- event(EV_ACTIVATION, false)
- else
- raise result
- end
- }
- end
-
-end # module
diff -ruN virt-v2v-v0.8.1/p2v-client/lib/virt-p2v/ui/convert.rb virt-v2v-v0.8.1.new/p2v-client/lib/virt-p2v/ui/convert.rb
--- virt-v2v-v0.8.1/p2v-client/lib/virt-p2v/ui/convert.rb 2011-04-26 20:58:33.000000000 +0100
+++ virt-v2v-v0.8.1.new/p2v-client/lib/virt-p2v/ui/convert.rb 1970-01-01 01:00:00.000000000 +0100
@@ -1,422 +0,0 @@
-# Copyright (C) 2011 Red Hat Inc.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-require 'gettext'
-require 'gtk2'
-
-require 'virt-p2v/blockdevice'
-require 'virt-p2v/netdevice'
-
-module VirtP2V::UI::Convert
- include GetText
-
- CONVERT_PROFILE_NAME = 0
-
- CONVERT_NETWORK_CONVERT = 0
- CONVERT_NETWORK_DEVICE = 1
-
- CONVERT_FIXED_CONVERT = 0
- CONVERT_FIXED_DEVICE = 1
- CONVERT_FIXED_PROGRESS = 2
-
- CONVERT_REMOVABLE_CONVERT = 0
- CONVERT_REMOVABLE_DEVICE = 1
- CONVERT_REMOVABLE_TYPE = 2
-
- UI_STATE_INVALID = 0
- UI_STATE_VALID = 1
- UI_STATE_CONNECTING = 2
- UI_STATE_CONVERTING = 3
- UI_STATE_COMPLETE = 4
-
- EV_VALID = 0
- EV_BUTTON = 1
- EV_CONNECTION = 2
- EV_CONVERTED = 3
-
- def self.init(ui, converter)
- # ListStores
- @profiles = ui.get_object('convert_profile_list')
- @nics = ui.get_object('convert_network_list')
- @fixeds = ui.get_object('convert_fixed_list')
- @removables = ui.get_object('convert_removable_list')
-
- # Widgets
- @profile = ui.get_object('convert_profile')
- @name = ui.get_object('convert_name')
- @cpus = ui.get_object('convert_cpus')
- @memory = ui.get_object('convert_memory')
- @editable = ui.get_object('convert_editable')
- @button = ui.get_object('convert_button')
- @status = ui.get_object('convert_status')
-
- # Get initial values from converter
- @name.text = converter.name
- @cpus.text = converter.cpus.to_s
- @memory.text = (converter.memory / 1024 / 1024).to_s
-
- # Populate profiles on connection
- converter.on_connection { |conn|
- conn.on_connect { |cb|
- conn.list_profiles { |profiles|
- cb.call(RuntimeError.new(_('Remote server does not ' +
- 'define any profiles in ' +
- '/etc/virt-v2v.conf'))) \
- if profiles.kind_of?(Exception) or profiles.empty?
-
- selected = @profile.active_iter
- selected = selected[CONVERT_PROFILE_NAME] \
- unless selected.nil?
-
- @profiles.clear
- profiles.each { |i|
- profile = @profiles.append
- profile[CONVERT_PROFILE_NAME] = i
- @profile.active_iter = profile if i == selected
- }
-
- cb.call(true)
- }
- }
- }
-
- VirtP2V::FixedBlockDevice.all_devices.each { |dev|
- fixed = @fixeds.append
- fixed[CONVERT_FIXED_CONVERT] = true
- fixed[CONVERT_FIXED_DEVICE] = dev.device
- fixed[CONVERT_FIXED_PROGRESS] = 0
- }
-
- VirtP2V::RemovableBlockDevice.all_devices.each { |dev|
- rem = @removables.append
- rem[CONVERT_REMOVABLE_CONVERT] = true
- rem[CONVERT_REMOVABLE_DEVICE] = dev.device
- rem[CONVERT_REMOVABLE_TYPE] = dev.type
- }
-
- VirtP2V::NetworkDevice.all_devices.each { |dev|
- nic = @nics.append
- nic[CONVERT_NETWORK_CONVERT] = dev.connected
- nic[CONVERT_NETWORK_DEVICE] = dev.name
- }
-
- # Event handlers
- ui.register_handler('convert_profile_changed',
- method(:update_values))
- ui.register_handler('convert_name_changed',
- method(:update_values))
- ui.register_handler('convert_cpus_changed',
- method(:convert_cpus_changed))
- ui.register_handler('convert_memory_changed',
- method(:convert_memory_changed))
- ui.register_handler('convert_fixed_list_row_changed',
- method(:convert_fixed_list_row_changed))
- ui.register_handler('convert_removable_list_row_changed',
- method(:update_values))
- ui.register_handler('convert_network_list_row_changed',
- method(:update_values))
- ui.register_handler('convert_fixed_select_toggled',
- method(:convert_fixed_select_toggled))
- ui.register_handler('convert_removable_select_toggled',
- method(:convert_removable_select_toggled))
- ui.register_handler('convert_network_select_toggled',
- method(:convert_network_select_toggled))
- ui.register_handler('convert_button_clicked',
- method(:convert_button_clicked))
-
- @state = nil
- set_state(UI_STATE_INVALID)
- update_values
-
- @ui = ui
- @converter = converter
- end
-
- def self.event(event, status)
- case @state
- when UI_STATE_INVALID
- case event
- when EV_VALID
- set_state(UI_STATE_VALID) if status
- else
- raise "Unexpected event: #{@state} #{event}"
- end
- when UI_STATE_VALID
- case event
- when EV_VALID
- set_state(UI_STATE_INVALID) if !status
- when EV_BUTTON
- if @converter.connection.connected then
- set_state(UI_STATE_CONVERTING)
- convert
- else
- set_state(UI_STATE_CONNECTING)
- reconnect
- end
- else
- raise "Unexpected event: #{@state} #{event}"
- end
- when UI_STATE_CONNECTING
- case event
- when EV_CONNECTION
- if status then
- set_state(UI_STATE_CONVERTING)
- convert
- else
- set_state(UI_STATE_VALID)
- end
- when EV_VALID
- # update_values will be called when the profile list is cleared
- # and repopulated during connection. Untidy, but ignore it.
- else
- raise "Unexpected event: #{@state} #{event}" \
- unless event == EV_CONNECTION
- end
- when UI_STATE_CONVERTING
- case event
- when EV_CONVERTED
- if status then
- set_state(UI_STATE_COMPLETE)
- else
- set_state(UI_STATE_VALID)
- end
- when EV_VALID
- # update_values will be called when the list stores are updated.
- # Untidy, but ignore it
- else
- raise "Unexpected event: #{@state} #{event}"
- end
- else
- raise "Unexpected UI state: #{@state}"
- end
- end
-
- def self.set_state(state)
- # Don't do anything if state hasn't changed
- return if state == @state
- @state = state
-
- case @state
- when UI_STATE_INVALID
- @editable.sensitive = true
- @button.sensitive = false
- when UI_STATE_VALID
- @editable.sensitive = true
- @button.sensitive = true
- when UI_STATE_CONNECTING
- @status.text = _'Failed to start virt-p2v-server on remote server'
- @editable.sensitive = false
- @button.sensitive = false
- when UI_STATE_CONVERTING
- @editable.sensitive = false
- @button.sensitive = false
- when UI_STATE_COMPLETE
- @ui.active_page = 'success_win'
-
- # ... then leave this one as we hope to find it if we come back here
- set_state(UI_STATE_VALID)
- else
- raise "Attempt to set unexpected UI state: #{@state}"
- end
- end
-
- def self.convert
- @converter.convert(
- # status
- lambda { |msg|
- @status.text = msg
- },
- # progress
- lambda { |dev, progress|
- @fixeds.each { |model, path, iter|
- next unless iter[CONVERT_FIXED_DEVICE] == dev
-
- iter[CONVERT_FIXED_PROGRESS] = progress
- break
- }
- }
- ) { |result|
- # N.B. Explicit test against true is required here, as result may be
- # an Exception, which would also return true if evaluated alone
- if result == true then
- @status.text = ''
- event(EV_CONVERTED, true)
- else
- @status.text = result.message
- event(EV_CONVERTED, false)
- end
- }
- end
-
- def self.reconnect
- @status.text = _('Reconnecting')
- @converter.connection.connect { |result|
- if result == true then
- event(EV_CONNECTION, true)
- else
- @status.text =
- _'Failed to start virt-p2v-server on remote server'
- event(EV_CONNECTION, false)
- end
- }
- end
-
- def self.convert_fixed_list_row_changed(model, path, iter)
- update_values
- end
-
- class InvalidUIState < StandardError; end
-
- def self.update_values
- valid = nil
- begin
- # Check there's a profile selected
- profile = @profile.active_iter
- raise InvalidUIState if profile.nil?
- @converter.profile = profile[CONVERT_PROFILE_NAME]
-
- # Check there's a name set
- name = @name.text
- raise InvalidUIState if name.nil? || name.strip.length == 0
- @converter.name = name
-
- # Check cpus and memory are set and numeric
- cpus = @cpus.text
- raise InvalidUIState if cpus.nil?
- cpus = Integer(cpus) rescue nil
- raise InvalidUIState if cpus.nil?
- @converter.cpus = cpus
-
- memory = @memory.text
- raise InvalidUIState if memory.nil?
- memory = Integer(memory) rescue nil
- raise InvalidUIState if memory.nil?
- @converter.memory = memory * 1024 * 1024
-
- # Check that at least 1 fixed storage device is selected
- fixed = false
- @converter.disks.clear
- @fixeds.each { |model, path, iter|
- if iter[CONVERT_FIXED_CONVERT] then
- fixed = true
- @converter.disks << iter[CONVERT_FIXED_DEVICE]
- end
- }
- raise InvalidUIState unless fixed
-
- # Populate removables and nics, although these aren't required to be
- # selected for the ui state to be valid
- @converter.removables.clear
- @removables.each { |model, path, iter|
- if iter[CONVERT_REMOVABLE_CONVERT] then
- @converter.removables << iter[CONVERT_REMOVABLE_DEVICE]
- end
- }
- @converter.nics.clear
- @nics.each { |model, path, iter|
- if iter[CONVERT_NETWORK_CONVERT] then
- @converter.nics << iter[CONVERT_NETWORK_DEVICE]
- end
- }
- rescue InvalidUIState
- valid = false
- end
- valid = true if valid.nil?
-
- event(EV_VALID, valid)
- end
-
- def self.valid?
- # Check there's a profile selected
- profile = @profile.active_iter
- return false if profile.nil?
-
- # Check there's a name set
- name = @name.text
- return false if name.nil?
- return false unless name.strip.length > 0
-
- # Check cpus and memory are set and numeric
- cpus = @cpus.text
- return false if cpus.nil?
- cpus = Integer(cpus) rescue nil
- return false if cpus.nil?
-
- memory = @memory.text
- return false if memory.nil?
- memory = Integer(memory) rescue nil
- return false if memory.nil?
-
- # Check that at least 1 fixed storage device is selected
- fixed = false
- @fixeds.each { |model, path, iter|
- if iter[CONVERT_FIXED_CONVERT] then
- fixed = true
- break
- end
- }
- return false unless fixed
-
- return true
- end
-
- def self.convert_cpus_changed
- check_numeric(@cpus)
- end
-
- def self.convert_memory_changed
- check_numeric(@memory)
- end
-
- def self.check_numeric(widget)
- value = widget.text
- if value.nil? ? false : begin
- value = Integer(value)
- value > 0
- rescue
- false
- end
- then
- widget.secondary_icon_name = nil
- else
- widget.secondary_icon_name = 'gtk-dialog-warning'
- widget.secondary_icon_tooltip_text =
- _('Value must be an integer greater than 0')
- end
-
- update_values
- end
-
- def self.convert_fixed_select_toggled(widget, path)
- iter = @fixeds.get_iter(path)
- iter[CONVERT_FIXED_CONVERT] = !iter[CONVERT_FIXED_CONVERT]
- end
-
- def self.convert_removable_select_toggled(widget, path)
- iter = @removables.get_iter(path)
- iter[CONVERT_REMOVABLE_CONVERT] = !iter[CONVERT_REMOVABLE_CONVERT]
- end
-
- def self.convert_network_select_toggled(widget, path)
- iter = @nics.get_iter(path)
- iter[CONVERT_NETWORK_CONVERT] = !iter[CONVERT_NETWORK_CONVERT]
- end
-
- def self.convert_button_clicked
- event(EV_BUTTON, true)
- end
-
-end # module
diff -ruN virt-v2v-v0.8.1/p2v-client/lib/virt-p2v/ui/main.rb virt-v2v-v0.8.1.new/p2v-client/lib/virt-p2v/ui/main.rb
--- virt-v2v-v0.8.1/p2v-client/lib/virt-p2v/ui/main.rb 2011-04-26 20:58:33.000000000 +0100
+++ virt-v2v-v0.8.1.new/p2v-client/lib/virt-p2v/ui/main.rb 1970-01-01 01:00:00.000000000 +0100
@@ -1,110 +0,0 @@
-# Copyright (C) 2011 Red Hat Inc.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-require 'gtk2'
-require 'virt-p2v/gtk-queue'
-
-module VirtP2V
-module UI
-
-class Main
- def get_object(name)
- o = @builder.get_object(name)
- raise "Object #{name} not found in ui" unless o != nil
-
- return o
- end
-
- def show
- @builder.connect_signals { |signal|
- raise "No hander for signal #{signal}" \
- unless @signal_handlers.has_key?(signal)
-
- @signal_handlers[signal]
- }
-
- # Display the main window
- main = self.get_object('main_window')
- main.show_all()
- end
-
- def register_handler(signal, handler)
- @signal_handlers[signal] = handler
- end
-
- def main_loop
- Gtk.main_with_queue 100
- end
-
- def active_page=(name)
- raise "Attempt to activate non-existent page #{name}" \
- unless @pages.has_key?(name)
-
- page = @pages[name]
-
- @page_vbox = self.get_object('page_vbox') unless defined? @page_vbox
- @page_vbox.remove(@selected) if defined? @selected
- @page_vbox.add(page)
- @selected = page
- end
-
- def active_page
- return @selected
- end
-
- def quit
- Gtk.main_quit()
- end
-
- private
-
- def initialize
- @builder = Gtk::Builder.new()
-
- # Find the UI definition in $LOAD_PATH
- i = $LOAD_PATH.index { |path|
- File.exists?(path + '/virt-p2v/ui/p2v.ui')
- }
- @builder.add_from_file($LOAD_PATH[i] + '/virt-p2v/ui/p2v.ui')
-
- @signal_handlers = {}
- self.register_handler('gtk_main_quit', method(:quit))
-
- # Configure the Wizard page frame
- # Can't change these colours from glade for some reason
- self.get_object('title_background').
- modify_bg(Gtk::STATE_NORMAL, Gdk::Color.parse('#86ABD9'))
- self.get_object('page_frame').
- modify_fg(Gtk::STATE_NORMAL, Gdk::Color.parse('#86ABD9'))
-
- # Load all pages from glade
- @pages = {}
- [ 'network_win', 'server_win',
- 'conversion_win', 'success_win' ].each { |name|
- page = self.get_object(name)
-
- child = page.children[0]
- page.remove(child)
- @pages[name] = child
- }
-
- # Set a default first page
- self.active_page = 'network_win'
- end
-end
-
-end # UI
-end # VirtP2V
diff -ruN virt-v2v-v0.8.1/p2v-client/lib/virt-p2v/ui/network.rb virt-v2v-v0.8.1.new/p2v-client/lib/virt-p2v/ui/network.rb
--- virt-v2v-v0.8.1/p2v-client/lib/virt-p2v/ui/network.rb 2011-04-26 20:58:33.000000000 +0100
+++ virt-v2v-v0.8.1.new/p2v-client/lib/virt-p2v/ui/network.rb 1970-01-01 01:00:00.000000000 +0100
@@ -1,317 +0,0 @@
-# Copyright (C) 2011 Red Hat Inc.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-require 'gettext'
-require 'gtk2'
-require 'ipaddr'
-require 'virt-p2v/netdevice'
-
-module VirtP2V::UI::Network
- include GetText
-
- # The indices of Device List colums, taken from glade
- DEVCOL_NAME = 0
- DEVCOL_MAC = 1
- DEVCOL_STATUS = 2
- DEVCOL_AVAILABLE = 3
-
- UI_STATE_INVALID = 0
- UI_STATE_VALID = 1
- UI_STATE_ACTIVATING = 2
- UI_STATE_COMPLETE = 3
-
- EV_IP_CONFIG = 0
- EV_SELECTION = 1
- EV_BUTTON = 2
- EV_ACTIVATION = 3
-
- def self.event(event, status)
- case event
- when EV_IP_CONFIG
- @ip_config = status
- when EV_SELECTION
- @selected = status
- when EV_BUTTON, EV_ACTIVATION
- # Persistent state not required
- else
- raise "Unexpected NetworkConfig event: #{event}"
- end
-
- case @state
- when UI_STATE_INVALID
- if @ip_config && @selected then
- set_state(UI_STATE_VALID)
- end
- when UI_STATE_VALID
- if !@ip_config || !@selected then
- set_state(UI_STATE_INVALID)
- elsif event == EV_BUTTON
- set_state(UI_STATE_ACTIVATING)
- end
- when UI_STATE_ACTIVATING
- # UI is disabled and we're waiting for EV_ACTIVATION, but we could
- # also get events triggered by NetworkManager signals.
-
- if event == EV_ACTIVATION then
- if status then
- set_state(UI_STATE_COMPLETE)
- else
- set_state(UI_STATE_VALID)
- end
- elsif !@ip_config || !@selected then
- set_state(UI_STATE_INVALID)
- end
- else
- raise "Unexpected NetworkConfig UI state: #{@state}"
- end
- end
-
- def self.init(ui)
- # Configure initial defaults
- @manual_mode = false
- @ip_address = nil
- @ip_prefix = nil
- @ip_gateway = nil
- @ip_dns = nil
- @state = UI_STATE_INVALID
- @ip_config = false
- @selected = false
-
- @network_button = ui.get_object('network_button')
- @device_list_frame = ui.get_object('device_list_frame')
- @ipv4_config_frame = ui.get_object('ipv4_config_frame')
- @dl_selection = ui.get_object('network_device_list_view').
- selection
- @device_list = ui.get_object('network_device_list')
- @manual_ui = ui.get_object('ip_manual')
- @ip_address_ui = ui.get_object('ip_address')
- @ip_prefix_ui = ui.get_object('ip_prefix')
- @ip_gateway_ui = ui.get_object('ip_gateway')
- @ip_dns_ui = ui.get_object('ip_dns')
-
- ui.register_handler('network_button_clicked',
- method(:network_button_clicked))
- ui.register_handler('ip_auto_toggled',
- method(:ip_auto_toggled))
- ui.register_handler('ip_address_changed',
- method(:ip_address_changed))
- ui.register_handler('ip_prefix_changed',
- method(:ip_prefix_changed))
- ui.register_handler('ip_gateway_changed',
- method(:ip_gateway_changed))
- ui.register_handler('ip_dns_changed',
- method(:ip_dns_changed))
-
- check_config_valid()
-
- # The user may only select a single device
- @dl_selection.mode = Gtk::SELECTION_SINGLE
-
- @dl_selection.set_select_function { |selection, model, path, current|
- iter = model.get_iter(path)
-
- # This is a toggle event. The new state is the opposite of the
- # current state
- new_state = !current
-
- # Don't allow the user to select an unavailable device
- if new_state then
- # Notify the config UI if we're selecting a device
- if iter[DEVCOL_AVAILABLE] then
- event(EV_SELECTION, true)
- end
-
- iter[DEVCOL_AVAILABLE]
-
- # Always allow the user to unselect a device
- else
- # Notify the UI that we're unselecting the device
- event(EV_SELECTION, false)
- true
- end
- }
-
- # Store a map of device names to row references
- refs = {}
-
- # Populate the device list with all detected network devices
- VirtP2V::NetworkDevice.all_devices.each { |device|
- iter = @device_list.append()
-
- iter[DEVCOL_NAME] = device.name
- iter[DEVCOL_MAC] = device.mac
- iter[DEVCOL_STATUS] = device.state
- iter[DEVCOL_AVAILABLE] = device.connected
-
- # Store a stable reference to this row in the TreeModel
- refs[device.name] =
- Gtk::TreeRowReference.new(@device_list, iter.path)
- }
-
- # Listen for updates to device states
- VirtP2V::NetworkDevice.add_listener( lambda { |device|
- path = refs[device.name].path
-
- iter = @device_list.get_iter(path)
- iter[DEVCOL_STATUS] = device.state
- iter[DEVCOL_AVAILABLE] = device.connected
-
- # Notify the UI that a device was activated
- event(EV_ACTIVATION, device.activated) \
- unless device.activated.nil?
-
- # Unselect the path if it was previously selected and is no
- # longer available
- if !device.connected && @dl_selection.iter_is_selected?(iter)
- then
- @dl_selection.unselect_all()
- event(EV_SELECTION, false)
- end
- } )
-
- @ui = ui
- end
-
- def self.set_state(state)
- # Don't do anything if state hasn't changed
- return if state == @state
-
- case state
- when UI_STATE_INVALID
- @network_button.sensitive = false
- @device_list_frame.sensitive = true
- @ipv4_config_frame.sensitive = true
-
- @state = UI_STATE_INVALID
- when UI_STATE_VALID
- @network_button.sensitive = true
- @device_list_frame.sensitive = true
- @ipv4_config_frame.sensitive = true
-
- @state = UI_STATE_VALID
- when UI_STATE_ACTIVATING
- @network_button.sensitive = false
- @device_list_frame.sensitive = false
- @ipv4_config_frame.sensitive = false
-
- @state = UI_STATE_ACTIVATING
- when UI_STATE_COMPLETE
- # Activate the next page
- @ui.active_page = 'server_win'
-
- # ... then leave this one as we hope to find it if we come back here
- set_state(UI_STATE_VALID)
- else
- raise "Attempt to set unexected NetworkConfig UI state: #{@state}"
- end
- end
-
- def self.network_button_clicked
- event(EV_BUTTON, true)
-
- iter = @dl_selection.selected
- return if iter.nil? # Shouldn't be possible
- name = iter[DEVCOL_NAME]
-
- VirtP2V::NetworkDevice[name].activate(!@manual_mode, @ip_address,
- @ip_prefix, @ip_gateway, @ip_dns)
- end
-
- def self.ip_auto_toggled
- @manual_mode = !@manual_mode
- @manual_ui.sensitive = @manual_mode
-
- check_config_valid()
- end
-
- def self.ip_address_changed
- @ip_address = parse_ip(@ip_address_ui)
-
- check_config_valid()
- end
-
- # Check IP prefix is a positive integer
- # We check that it's appropriate to the address class in use elsewhere
- def self.ip_prefix_changed
- begin
- @ip_prefix = Integer(@ip_prefix_ui.text)
- rescue ArgumentError => e
- # Ignore the result if it didn't parse
- @ip_prefix = nil
- return
- end
-
- if @ip_prefix < 0 then
- @ip_prefix = nil
- end
-
- check_config_valid()
- end
-
- def self.ip_gateway_changed
- @ip_gateway = parse_ip(@ip_gateway_ui)
-
- check_config_valid()
- end
-
- # Parse an IP address understood by IPAddr
- def self.parse_ip(entry)
- a = entry.text.strip
-
- begin
- ip = IPAddr.new(a)
- rescue ArgumentError => e
- # Ignore the result if it didn't parse
- ip = nil
- end
-
- return ip
- end
-
- def self.ip_dns_changed
- dns = @ip_dns_ui.text
-
- @ip_dns = []
- dns.split(/\s*,+\s*/).each { |entry|
- begin
- @ip_dns << IPAddr.new(entry)
- rescue ArgumentError => e
- @ip_dns = ()
- break
- end
- }
- end
-
- def self.check_config_valid
- if !@manual_mode || (!@ip_address.nil? &&
- !@ip_prefix.nil? &&
- !@ip_gateway.nil?) then
- if @manual_mode then
- # Check that IPv4/IPv6 is used consistently
- if @ip_address.ipv4? then
- event(EV_IP_CONFIG, @ip_gateway.ipv4? && @ip_prefix < 32)
- else
- event(EV_IP_CONFIG, @ip_gateway.ipv6? && @ip_prefix < 128)
- end
- else
- event(EV_IP_CONFIG, true)
- end
- else
- event(EV_IP_CONFIG, false)
- end
- end
-
-end # module
diff -ruN virt-v2v-v0.8.1/p2v-client/lib/virt-p2v/ui/p2v.ui virt-v2v-v0.8.1.new/p2v-client/lib/virt-p2v/ui/p2v.ui
--- virt-v2v-v0.8.1/p2v-client/lib/virt-p2v/ui/p2v.ui 2011-04-26 20:58:33.000000000 +0100
+++ virt-v2v-v0.8.1.new/p2v-client/lib/virt-p2v/ui/p2v.ui 1970-01-01 01:00:00.000000000 +0100
@@ -1,1031 +0,0 @@
-<?xml version="1.0"?>
-<interface>
- <requires lib="gtk+" version="2.16"/>
- <!-- interface-naming-policy project-wide -->
- <object class="GtkWindow" id="main_window">
- <property name="resizable">False</property>
- <property name="window_position">center-always</property>
- <property name="decorated">False</property>
- <signal name="destroy" handler="gtk_main_quit"/>
- <child>
- <object class="GtkAlignment" id="alignment2">
- <property name="visible">True</property>
- <property name="xscale">0</property>
- <property name="yscale">0</property>
- <child>
- <object class="GtkFrame" id="page_frame">
- <property name="width_request">800</property>
- <property name="height_request">600</property>
- <property name="visible">True</property>
- <property name="label_xalign">0</property>
- <property name="label_yalign">0</property>
- <property name="shadow_type">in</property>
- <child>
- <object class="GtkVBox" id="page_vbox">
- <property name="visible">True</property>
- <property name="orientation">vertical</property>
- <property name="spacing">2</property>
- <child>
- <object class="GtkEventBox" id="title_background">
- <property name="visible">True</property>
- <child>
- <object class="GtkLabel" id="title_label">
- <property name="visible">True</property>
- <property name="xalign">0</property>
- <property name="yalign">0</property>
- <property name="xpad">5</property>
- <property name="ypad">5</property>
- <property name="label">&lt;span weight='bold' foreground='white' size='xx-large'&gt;virt-p2v&lt;/span&gt;</property>
- <property name="use_markup">True</property>
- </object>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <placeholder/>
- </child>
- </object>
- </child>
- <child type="label_item">
- <placeholder/>
- </child>
- </object>
- </child>
- </object>
- </child>
- </object>
- <object class="GtkListStore" id="network_device_list">
- <columns>
- <!-- column-name Name -->
- <column type="gchararray"/>
- <!-- column-name MAC -->
- <column type="gchararray"/>
- <!-- column-name Status -->
- <column type="gchararray"/>
- <!-- column-name Available -->
- <column type="gboolean"/>
- </columns>
- </object>
- <object class="GtkListStore" id="convert_network_list">
- <columns>
- <!-- column-name Convert -->
- <column type="gboolean"/>
- <!-- column-name Device -->
- <column type="gchararray"/>
- </columns>
- <signal name="row_changed" handler="convert_network_list_row_changed"/>
- </object>
- <object class="GtkListStore" id="convert_fixed_list">
- <columns>
- <!-- column-name Convert -->
- <column type="gboolean"/>
- <!-- column-name Device -->
- <column type="gchararray"/>
- <!-- column-name Progress -->
- <column type="gdouble"/>
- </columns>
- <signal name="row_changed" handler="convert_fixed_list_row_changed"/>
- </object>
- <object class="GtkListStore" id="convert_removable_list">
- <columns>
- <!-- column-name Convert -->
- <column type="gboolean"/>
- <!-- column-name Device -->
- <column type="gchararray"/>
- <!-- column-name Type -->
- <column type="gchararray"/>
- </columns>
- <signal name="row_changed" handler="convert_removable_list_row_changed"/>
- </object>
- <object class="GtkListStore" id="convert_profile_list">
- <columns>
- <!-- column-name Name -->
- <column type="gchararray"/>
- </columns>
- </object>
- <object class="GtkWindow" id="network_win">
- <property name="width_request">800</property>
- <property name="height_request">550</property>
- <child>
- <object class="GtkVBox" id="vbox1">
- <property name="visible">True</property>
- <property name="orientation">vertical</property>
- <child>
- <object class="GtkLabel" id="label1">
- <property name="visible">True</property>
- <property name="xalign">0</property>
- <property name="yalign">1</property>
- <property name="ypad">11</property>
- <property name="label" translatable="yes">Welcome to virt-p2v.</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkFrame" id="device_list_frame">
- <property name="visible">True</property>
- <property name="label_xalign">0</property>
- <property name="shadow_type">out</property>
- <child>
- <object class="GtkScrolledWindow" id="scrolledwindow1">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="hscrollbar_policy">automatic</property>
- <property name="vscrollbar_policy">automatic</property>
- <child>
- <object class="GtkTreeView" id="network_device_list_view">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="model">network_device_list</property>
- <property name="headers_clickable">False</property>
- <property name="search_column">0</property>
- <child>
- <object class="GtkTreeViewColumn" id="treeviewcolumn1">
- <property name="title">Device</property>
- <child>
- <object class="GtkCellRendererText" id="cellrenderertext1"/>
- <attributes>
- <attribute name="sensitive">3</attribute>
- <attribute name="text">0</attribute>
- </attributes>
- </child>
- </object>
- </child>
- <child>
- <object class="GtkTreeViewColumn" id="treeviewcolumn3">
- <property name="fixed_width">18</property>
- <property name="title">MAC Address</property>
- <child>
- <object class="GtkCellRendererText" id="cellrenderertext3"/>
- <attributes>
- <attribute name="sensitive">3</attribute>
- <attribute name="text">1</attribute>
- </attributes>
- </child>
- </object>
- </child>
- <child>
- <object class="GtkTreeViewColumn" id="treeviewcolumn2">
- <property name="title">Status</property>
- <child>
- <object class="GtkCellRendererText" id="cellrenderertext2"/>
- <attributes>
- <attribute name="sensitive">3</attribute>
- <attribute name="text">2</attribute>
- </attributes>
- </child>
- </object>
- </child>
- </object>
- </child>
- </object>
- </child>
- <child type="label">
- <object class="GtkLabel" id="label5">
- <property name="visible">True</property>
- <property name="label" translatable="yes">&lt;b&gt;Select a network device&lt;/b&gt;</property>
- <property name="use_markup">True</property>
- </object>
- </child>
- </object>
- <packing>
- <property name="position">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkFrame" id="ipv4_config_frame">
- <property name="visible">True</property>
- <property name="label_xalign">0</property>
- <property name="shadow_type">in</property>
- <child>
- <object class="GtkAlignment" id="alignment1">
- <property name="visible">True</property>
- <property name="left_padding">12</property>
- <child>
- <object class="GtkVBox" id="vbox2">
- <property name="visible">True</property>
- <property name="orientation">vertical</property>
- <child>
- <object class="GtkCheckButton" id="ip_auto">
- <property name="label" translatable="yes">Automatic configuration</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="active">True</property>
- <property name="draw_indicator">True</property>
- <signal name="toggled" handler="ip_auto_toggled"/>
- </object>
- <packing>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkTable" id="ip_manual">
- <property name="visible">True</property>
- <property name="sensitive">False</property>
- <property name="n_rows">3</property>
- <property name="n_columns">2</property>
- <property name="column_spacing">2</property>
- <child>
- <object class="GtkLabel" id="label3">
- <property name="visible">True</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">IP Address:</property>
- </object>
- <packing>
- <property name="x_options">GTK_FILL</property>
- <property name="y_options">GTK_FILL</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="label8">
- <property name="visible">True</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">Gateway:</property>
- </object>
- <packing>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="x_options">GTK_FILL</property>
- <property name="y_options">GTK_FILL</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="label4">
- <property name="visible">True</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">DNS Servers:</property>
- </object>
- <packing>
- <property name="top_attach">2</property>
- <property name="bottom_attach">3</property>
- <property name="x_options">GTK_FILL</property>
- <property name="y_options">GTK_FILL</property>
- </packing>
- </child>
- <child>
- <object class="GtkEntry" id="ip_gateway">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="max_length">39</property>
- <property name="width_chars">39</property>
- <property name="truncate_multiline">True</property>
- <signal name="changed" handler="ip_gateway_changed"/>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="y_options">GTK_FILL</property>
- </packing>
- </child>
- <child>
- <object class="GtkEntry" id="ip_dns">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="width_chars">35</property>
- <signal name="changed" handler="ip_dns_changed"/>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">2</property>
- <property name="bottom_attach">3</property>
- <property name="y_options">GTK_FILL</property>
- </packing>
- </child>
- <child>
- <object class="GtkHBox" id="hbox6">
- <property name="visible">True</property>
- <property name="spacing">2</property>
- <child>
- <object class="GtkEntry" id="ip_address">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="max_length">39</property>
- <property name="width_chars">39</property>
- <property name="truncate_multiline">True</property>
- <signal name="changed" handler="ip_address_changed"/>
- </object>
- <packing>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="label7">
- <property name="visible">True</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">Prefix:</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkEntry" id="ip_prefix">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="max_length">2</property>
- <property name="width_chars">2</property>
- <property name="truncate_multiline">True</property>
- <signal name="changed" handler="ip_prefix_changed"/>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="position">2</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="y_options">GTK_FILL</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- </child>
- </object>
- </child>
- <child type="label">
- <object class="GtkLabel" id="label2">
- <property name="visible">True</property>
- <property name="label" translatable="yes">&lt;b&gt;IP Configuration&lt;/b&gt;</property>
- <property name="use_markup">True</property>
- </object>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="position">2</property>
- </packing>
- </child>
- <child>
- <object class="GtkAlignment" id="alignment3">
- <property name="visible">True</property>
- <property name="xalign">1</property>
- <property name="xscale">0</property>
- <child>
- <object class="GtkButton" id="network_button">
- <property name="label" translatable="yes">Use these network settings</property>
- <property name="visible">True</property>
- <property name="sensitive">False</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <signal name="clicked" handler="network_button_clicked"/>
- </object>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="position">3</property>
- </packing>
- </child>
- </object>
- </child>
- </object>
- <object class="GtkWindow" id="server_win">
- <child>
- <object class="GtkVBox" id="vbox3">
- <property name="visible">True</property>
- <property name="orientation">vertical</property>
- <child>
- <object class="GtkAlignment" id="alignment4">
- <property name="visible">True</property>
- <property name="xscale">0</property>
- <property name="yscale">0</property>
- <child>
- <object class="GtkFrame" id="connect_frame">
- <property name="visible">True</property>
- <property name="label_xalign">0</property>
- <property name="shadow_type">in</property>
- <child>
- <object class="GtkAlignment" id="alignment9">
- <property name="visible">True</property>
- <property name="left_padding">12</property>
- <child>
- <object class="GtkVBox" id="vbox5">
- <property name="visible">True</property>
- <property name="orientation">vertical</property>
- <child>
- <object class="GtkTable" id="table1">
- <property name="visible">True</property>
- <property name="n_rows">3</property>
- <property name="n_columns">2</property>
- <property name="column_spacing">2</property>
- <child>
- <object class="GtkLabel" id="label9">
- <property name="visible">True</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">Hostname:</property>
- </object>
- <packing>
- <property name="x_options"></property>
- <property name="y_options"></property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="label10">
- <property name="visible">True</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">Username:</property>
- </object>
- <packing>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="x_options"></property>
- <property name="y_options"></property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="label11">
- <property name="visible">True</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">Password:</property>
- </object>
- <packing>
- <property name="top_attach">2</property>
- <property name="bottom_attach">3</property>
- <property name="x_options"></property>
- <property name="y_options"></property>
- </packing>
- </child>
- <child>
- <object class="GtkEntry" id="server_hostname">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="invisible_char">&#x2022;</property>
- <property name="width_chars">40</property>
- <signal name="changed" handler="server_hostname_changed"/>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="y_options"></property>
- </packing>
- </child>
- <child>
- <object class="GtkEntry" id="server_password">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="visibility">False</property>
- <property name="invisible_char">&#x2022;</property>
- <property name="width_chars">40</property>
- <signal name="changed" handler="server_password_changed"/>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">2</property>
- <property name="bottom_attach">3</property>
- <property name="y_options"></property>
- </packing>
- </child>
- <child>
- <object class="GtkEntry" id="server_username">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="invisible_char">&#x2022;</property>
- <property name="width_chars">40</property>
- <property name="text" translatable="yes">root</property>
- <signal name="changed" handler="server_username_changed"/>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="y_options"></property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="connect_error">
- <property name="visible">True</property>
- <property name="xalign">0</property>
- <property name="yalign">0</property>
- <property name="xpad">8</property>
- <property name="ypad">8</property>
- <attributes>
- <attribute name="foreground" value="#ffff00000000"/>
- </attributes>
- </object>
- <packing>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- </child>
- </object>
- </child>
- <child type="label">
- <object class="GtkLabel" id="label6">
- <property name="visible">True</property>
- <property name="label" translatable="yes">&lt;b&gt;Connect to conversion server&lt;/b&gt;</property>
- <property name="use_markup">True</property>
- </object>
- </child>
- </object>
- </child>
- </object>
- <packing>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkAlignment" id="alignment5">
- <property name="visible">True</property>
- <property name="xalign">1</property>
- <property name="yalign">0</property>
- <property name="xscale">0</property>
- <property name="yscale">0</property>
- <child>
- <object class="GtkButton" id="connect_button">
- <property name="label" translatable="yes">Connect</property>
- <property name="visible">True</property>
- <property name="sensitive">False</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <signal name="clicked" handler="connect_button_clicked"/>
- </object>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- </child>
- </object>
- <object class="GtkWindow" id="conversion_win">
- <child>
- <object class="GtkVBox" id="vbox4">
- <property name="visible">True</property>
- <property name="orientation">vertical</property>
- <child>
- <object class="GtkHBox" id="convert_editable">
- <property name="visible">True</property>
- <child>
- <object class="GtkFrame" id="frame2">
- <property name="visible">True</property>
- <property name="label_xalign">0</property>
- <property name="shadow_type">out</property>
- <child>
- <object class="GtkAlignment" id="alignment6">
- <property name="visible">True</property>
- <property name="xalign">0</property>
- <property name="yalign">0</property>
- <property name="xscale">0</property>
- <property name="yscale">0</property>
- <property name="left_padding">12</property>
- <child>
- <object class="GtkTable" id="table2">
- <property name="visible">True</property>
- <property name="n_rows">4</property>
- <property name="n_columns">2</property>
- <property name="column_spacing">2</property>
- <child>
- <object class="GtkLabel" id="label14">
- <property name="visible">True</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">Destination Profile:</property>
- </object>
- </child>
- <child>
- <object class="GtkComboBox" id="convert_profile">
- <property name="visible">True</property>
- <property name="model">convert_profile_list</property>
- <signal name="changed" handler="convert_profile_changed"/>
- <child>
- <object class="GtkCellRendererText" id="cellrenderertext8"/>
- <attributes>
- <attribute name="text">0</attribute>
- </attributes>
- </child>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="label16">
- <property name="visible">True</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">Memory (MB):</property>
- </object>
- <packing>
- <property name="top_attach">3</property>
- <property name="bottom_attach">4</property>
- </packing>
- </child>
- <child>
- <object class="GtkEntry" id="convert_memory">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="invisible_char">&#x2022;</property>
- <property name="truncate_multiline">True</property>
- <signal name="changed" handler="convert_memory_changed"/>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">3</property>
- <property name="bottom_attach">4</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="label15">
- <property name="visible">True</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">Number of CPUs:</property>
- </object>
- <packing>
- <property name="top_attach">2</property>
- <property name="bottom_attach">3</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="label18">
- <property name="visible">True</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">Name</property>
- </object>
- <packing>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- </packing>
- </child>
- <child>
- <object class="GtkEntry" id="convert_name">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="invisible_char">&#x2022;</property>
- <property name="truncate_multiline">True</property>
- <signal name="changed" handler="convert_name_changed"/>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- </packing>
- </child>
- <child>
- <object class="GtkEntry" id="convert_cpus">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="invisible_char">&#x2022;</property>
- <property name="truncate_multiline">True</property>
- <signal name="changed" handler="convert_cpus_changed"/>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">2</property>
- <property name="bottom_attach">3</property>
- </packing>
- </child>
- </object>
- </child>
- </object>
- </child>
- <child type="label">
- <object class="GtkLabel" id="label13">
- <property name="visible">True</property>
- <property name="label" translatable="yes">&lt;b&gt;Target properties&lt;/b&gt;</property>
- <property name="use_markup">True</property>
- </object>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkVBox" id="vbox6">
- <property name="visible">True</property>
- <property name="orientation">vertical</property>
- <child>
- <object class="GtkFrame" id="frame3">
- <property name="visible">True</property>
- <property name="label_xalign">0</property>
- <property name="shadow_type">out</property>
- <child>
- <object class="GtkAlignment" id="alignment8">
- <property name="visible">True</property>
- <child>
- <object class="GtkScrolledWindow" id="scrolledwindow2">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="hscrollbar_policy">automatic</property>
- <property name="vscrollbar_policy">automatic</property>
- <child>
- <object class="GtkTreeView" id="treeview1">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="model">convert_fixed_list</property>
- <property name="headers_clickable">False</property>
- <property name="search_column">0</property>
- <child>
- <object class="GtkTreeViewColumn" id="treeviewcolumn4">
- <property name="title">Convert</property>
- <property name="clickable">True</property>
- <child>
- <object class="GtkCellRendererToggle" id="convert_fixed_select">
- <signal name="toggled" handler="convert_fixed_select_toggled"/>
- </object>
- <attributes>
- <attribute name="active">0</attribute>
- </attributes>
- </child>
- </object>
- </child>
- <child>
- <object class="GtkTreeViewColumn" id="treeviewcolumn5">
- <property name="title">Device</property>
- <child>
- <object class="GtkCellRendererText" id="cellrenderertext4"/>
- <attributes>
- <attribute name="text">1</attribute>
- </attributes>
- </child>
- </object>
- </child>
- <child>
- <object class="GtkTreeViewColumn" id="treeviewcolumn8">
- <property name="title">Transfer Progress</property>
- <property name="expand">True</property>
- <child>
- <object class="GtkCellRendererProgress" id="cellrendererprogress1"/>
- <attributes>
- <attribute name="value">2</attribute>
- </attributes>
- </child>
- </object>
- </child>
- </object>
- </child>
- </object>
- </child>
- </object>
- </child>
- <child type="label">
- <object class="GtkLabel" id="label17">
- <property name="visible">True</property>
- <property name="label" translatable="yes">&lt;b&gt;Fixed Storage&lt;/b&gt;</property>
- <property name="use_markup">True</property>
- </object>
- </child>
- </object>
- <packing>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkFrame" id="frame4">
- <property name="visible">True</property>
- <property name="label_xalign">0</property>
- <property name="shadow_type">out</property>
- <child>
- <object class="GtkAlignment" id="alignment11">
- <property name="visible">True</property>
- <child>
- <object class="GtkScrolledWindow" id="scrolledwindow4">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="hscrollbar_policy">automatic</property>
- <property name="vscrollbar_policy">automatic</property>
- <child>
- <object class="GtkTreeView" id="treeview3">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="model">convert_removable_list</property>
- <child>
- <object class="GtkTreeViewColumn" id="treeviewcolumn9">
- <property name="title">Convert</property>
- <child>
- <object class="GtkCellRendererToggle" id="convert_removable_select">
- <signal name="toggled" handler="convert_removable_select_toggled"/>
- </object>
- <attributes>
- <attribute name="active">0</attribute>
- </attributes>
- </child>
- </object>
- </child>
- <child>
- <object class="GtkTreeViewColumn" id="treeviewcolumn10">
- <property name="title">Device</property>
- <child>
- <object class="GtkCellRendererText" id="cellrenderertext6"/>
- <attributes>
- <attribute name="text">1</attribute>
- </attributes>
- </child>
- </object>
- </child>
- <child>
- <object class="GtkTreeViewColumn" id="treeviewcolumn11">
- <property name="title">Type</property>
- <child>
- <object class="GtkCellRendererText" id="cellrenderertext7"/>
- <attributes>
- <attribute name="text">2</attribute>
- </attributes>
- </child>
- </object>
- </child>
- </object>
- </child>
- </object>
- </child>
- </object>
- </child>
- <child type="label">
- <object class="GtkLabel" id="label19">
- <property name="visible">True</property>
- <property name="label" translatable="yes">&lt;b&gt;Removable Media&lt;/b&gt;</property>
- <property name="use_markup">True</property>
- </object>
- </child>
- </object>
- <packing>
- <property name="position">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkFrame" id="frame1">
- <property name="visible">True</property>
- <property name="label_xalign">0</property>
- <property name="shadow_type">out</property>
- <child>
- <object class="GtkAlignment" id="alignment10">
- <property name="visible">True</property>
- <property name="xalign">1</property>
- <property name="yalign">1</property>
- <child>
- <object class="GtkScrolledWindow" id="scrolledwindow3">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="hscrollbar_policy">automatic</property>
- <property name="vscrollbar_policy">automatic</property>
- <child>
- <object class="GtkTreeView" id="treeview2">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="model">convert_network_list</property>
- <property name="headers_clickable">False</property>
- <property name="search_column">0</property>
- <child>
- <object class="GtkTreeViewColumn" id="treeviewcolumn6">
- <property name="title">Convert</property>
- <child>
- <object class="GtkCellRendererToggle" id="convert_network_select">
- <signal name="toggled" handler="convert_network_select_toggled"/>
- </object>
- <attributes>
- <attribute name="active">0</attribute>
- </attributes>
- </child>
- </object>
- </child>
- <child>
- <object class="GtkTreeViewColumn" id="treeviewcolumn7">
- <property name="title">Device</property>
- <child>
- <object class="GtkCellRendererText" id="cellrenderertext5"/>
- <attributes>
- <attribute name="text">1</attribute>
- </attributes>
- </child>
- </object>
- </child>
- </object>
- </child>
- </object>
- </child>
- </object>
- </child>
- <child type="label">
- <object class="GtkLabel" id="label12">
- <property name="visible">True</property>
- <property name="label" translatable="yes">&lt;b&gt;Network Interfaces&lt;/b&gt;</property>
- <property name="use_markup">True</property>
- </object>
- </child>
- </object>
- <packing>
- <property name="position">2</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkHBox" id="hbox1">
- <property name="visible">True</property>
- <child>
- <object class="GtkLabel" id="convert_status">
- <property name="visible">True</property>
- <property name="xalign">0</property>
- <property name="xpad">12</property>
- <attributes>
- <attribute name="foreground" value="#ffff00000000"/>
- </attributes>
- </object>
- <packing>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkButton" id="convert_button">
- <property name="label" translatable="yes">Convert</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <signal name="clicked" handler="convert_button_clicked"/>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- </child>
- </object>
- <object class="GtkWindow" id="success_win">
- <child>
- <object class="GtkVBox" id="vbox7">
- <property name="visible">True</property>
- <property name="orientation">vertical</property>
- <child>
- <object class="GtkLabel" id="label20">
- <property name="visible">True</property>
- <property name="label" translatable="yes">A guest has been successfully created on the target server.
-
-Remove the temporary boot device from this machine and press 'Reboot' to continue.</property>
- <property name="justify">center</property>
- </object>
- <packing>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkAlignment" id="alignment7">
- <property name="visible">True</property>
- <property name="xscale">0.25</property>
- <property name="yscale">0.25</property>
- <child>
- <object class="GtkButton" id="reboot_button">
- <property name="label" translatable="yes">Reboot</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <signal name="clicked" handler="reboot_button_clicked"/>
- </object>
- </child>
- </object>
- <packing>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- </child>
- </object>
-</interface>
diff -ruN virt-v2v-v0.8.1/p2v-client/lib/virt-p2v/ui/success.rb virt-v2v-v0.8.1.new/p2v-client/lib/virt-p2v/ui/success.rb
--- virt-v2v-v0.8.1/p2v-client/lib/virt-p2v/ui/success.rb 2011-04-26 20:58:33.000000000 +0100
+++ virt-v2v-v0.8.1.new/p2v-client/lib/virt-p2v/ui/success.rb 1970-01-01 01:00:00.000000000 +0100
@@ -1,33 +0,0 @@
-# Copyright (C) 2011 Red Hat Inc.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-require 'gettext'
-
-module VirtP2V::UI::Success
- include GetText
-
- def self.init(ui)
- ui.register_handler('reboot_button_clicked',
- method(:reboot_button_clicked))
-
- @ui = ui
- end
-
- def self.reboot_button_clicked
- @ui.quit
- end
-
-end # module
diff -ruN virt-v2v-v0.8.1/p2v-client/Manifest virt-v2v-v0.8.1.new/p2v-client/Manifest
--- virt-v2v-v0.8.1/p2v-client/Manifest 2011-04-26 20:58:33.000000000 +0100
+++ virt-v2v-v0.8.1.new/p2v-client/Manifest 1970-01-01 01:00:00.000000000 +0100
@@ -1,15 +0,0 @@
-Rakefile
-bin/virt-p2v
-lib/virt-p2v/blockdevice.rb
-lib/virt-p2v/connection.rb
-lib/virt-p2v/converter.rb
-lib/virt-p2v/gtk-queue.rb
-lib/virt-p2v/netdevice.rb
-lib/virt-p2v/ui/connect.rb
-lib/virt-p2v/ui/convert.rb
-lib/virt-p2v/ui/main.rb
-lib/virt-p2v/ui/network.rb
-lib/virt-p2v/ui/p2v.ui
-lib/virt-p2v/ui/success.rb
-virt-p2v.gemspec
-Manifest
diff -ruN virt-v2v-v0.8.1/p2v-client/Rakefile virt-v2v-v0.8.1.new/p2v-client/Rakefile
--- virt-v2v-v0.8.1/p2v-client/Rakefile 2011-04-26 20:58:33.000000000 +0100
+++ virt-v2v-v0.8.1.new/p2v-client/Rakefile 1970-01-01 01:00:00.000000000 +0100
@@ -1,37 +0,0 @@
-# Copyright (C) 2011 Red Hat Inc.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-require 'rubygems'
-require 'echoe'
-
-Echoe.new("virt-p2v") do |p|
- p.project = "Virt P2V"
- p.version = `../Build version`
- p.author = "Matthew Booth"
- p.summary = "Send a machine's storage and metadata to virt-p2v-server"
- p.description = <<EOF
-virt-p2v is a client which connects to a virt-p2v-server and transfer's the host
-machine's storage and metadata. virt-p2v is intended to be run from a live
-image, so it is unlikely you want to install it.
-EOF
- p.url = "http://libguestfs.org"
- p.email = "libguestfs@redhat.com"
- p.runtime_dependencies = [
- 'gtk2',
- 'gettext',
- 'net-ssh'
- ]
-end
diff -ruN virt-v2v-v0.8.1/p2v-client/virt-p2v.gemspec virt-v2v-v0.8.1.new/p2v-client/virt-p2v.gemspec
--- virt-v2v-v0.8.1/p2v-client/virt-p2v.gemspec 2011-04-26 20:58:33.000000000 +0100
+++ virt-v2v-v0.8.1.new/p2v-client/virt-p2v.gemspec 1970-01-01 01:00:00.000000000 +0100
@@ -1,44 +0,0 @@
-# -*- encoding: utf-8 -*-
-
-Gem::Specification.new do |s|
- s.name = %q{virt-p2v}
- s.version = "0.7.1"
-
- s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
- s.authors = ["Matthew Booth"]
- s.date = %q{2011-04-15}
- s.default_executable = %q{virt-p2v}
- s.description = %q{virt-p2v is a client which connects to a virt-p2v-server and transfer's the host
-machine's storage and metadata. virt-p2v is intended to be run from a live
-image, so it is unlikely you want to install it.
-}
- s.email = %q{libguestfs@redhat.com}
- s.executables = ["virt-p2v"]
- s.extra_rdoc_files = ["COPYING", "bin/virt-p2v", "lib/virt-p2v/blockdevice.rb", "lib/virt-p2v/connection.rb", "lib/virt-p2v/converter.rb", "lib/virt-p2v/gtk-queue.rb", "lib/virt-p2v/netdevice.rb", "lib/virt-p2v/ui/connect.rb", "lib/virt-p2v/ui/convert.rb", "lib/virt-p2v/ui/main.rb", "lib/virt-p2v/ui/network.rb", "lib/virt-p2v/ui/p2v.ui", "lib/virt-p2v/ui/success.rb"]
- s.files = ["COPYING", "Rakefile", "bin/virt-p2v", "lib/virt-p2v/blockdevice.rb", "lib/virt-p2v/connection.rb", "lib/virt-p2v/converter.rb", "lib/virt-p2v/gtk-queue.rb", "lib/virt-p2v/netdevice.rb", "lib/virt-p2v/ui/connect.rb", "lib/virt-p2v/ui/convert.rb", "lib/virt-p2v/ui/main.rb", "lib/virt-p2v/ui/network.rb", "lib/virt-p2v/ui/p2v.ui", "lib/virt-p2v/ui/success.rb", "virt-p2v.gemspec", "Manifest"]
- s.homepage = %q{http://libguestfs.org}
- s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Virt-p2v"]
- s.require_paths = ["lib"]
- s.rubyforge_project = %q{Virt P2V}
- s.rubygems_version = %q{1.3.7}
- s.summary = %q{Send a machine's storage and metadata to virt-p2v-server}
-
- if s.respond_to? :specification_version then
- current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
- s.specification_version = 3
-
- if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
- s.add_runtime_dependency(%q<gtk2>, [">= 0"])
- s.add_runtime_dependency(%q<gettext>, [">= 0"])
- s.add_runtime_dependency(%q<net-ssh>, [">= 0"])
- else
- s.add_dependency(%q<gtk2>, [">= 0"])
- s.add_dependency(%q<gettext>, [">= 0"])
- s.add_dependency(%q<net-ssh>, [">= 0"])
- end
- else
- s.add_dependency(%q<gtk2>, [">= 0"])
- s.add_dependency(%q<gettext>, [">= 0"])
- s.add_dependency(%q<net-ssh>, [">= 0"])
- end
-end
diff -ruN virt-v2v-v0.8.1/p2v-image-builder/common-install.ks virt-v2v-v0.8.1.new/p2v-image-builder/common-install.ks
--- virt-v2v-v0.8.1/p2v-image-builder/common-install.ks 2011-04-26 20:58:33.000000000 +0100
+++ virt-v2v-v0.8.1.new/p2v-image-builder/common-install.ks 1970-01-01 01:00:00.000000000 +0100
@@ -1,54 +0,0 @@
-lang C
-keyboard us
-timezone --utc UTC
-auth --useshadow --enablemd5
-selinux --disabled
-firewall --disabled
-# TODO: the sizing of the image needs to be more dynamic
-part / --size 1024 --fstype ext2
-services --enabled=NetworkManager --disabled=auditd
-bootloader --timeout=30
-rootpw --iscrypted $1$tQiZwocX$ghhurQEm56p/HqgN.XEtk1
-
-# add missing scsi modules to initramfs
-device 3w-9xxx
-device 3w-sas
-device 3w-xxxx
-device a100u2w
-device aacraid
-device aic79xx
-device aic94xx
-device arcmsr
-device atp870u
-device be2iscsi
-device bfa
-device BusLogic
-device cxgb3i
-device dc395x
-device fnic
-device gdth
-device hpsa
-device hptiop
-device imm
-device initio
-device ips
-device libosd
-device libsas
-device libsrp
-device lpfc
-device megaraid
-device megaraid_mbox
-device megaraid_mm
-device megaraid_sas
-device mpt2sas
-device mvsas
-device osd
-device osst
-device pm8001
-device pmcraid
-device qla1280
-device qla2xxx
-device qla4xxx
-device qlogicfas408
-device stex
-device tmscsim
diff -ruN virt-v2v-v0.8.1/p2v-image-builder/common-manifest-post.ks virt-v2v-v0.8.1.new/p2v-image-builder/common-manifest-post.ks
--- virt-v2v-v0.8.1/p2v-image-builder/common-manifest-post.ks 2011-04-26 20:58:33.000000000 +0100
+++ virt-v2v-v0.8.1.new/p2v-image-builder/common-manifest-post.ks 1970-01-01 01:00:00.000000000 +0100
@@ -1,36 +0,0 @@
-%post
-echo -n "Creating manifest"
-# Create post-image processing manifests
-rpm -qa --qf '%{name}-%{version}-%{release}.%{arch} (%{SIGGPG:pgpsig})\n' | \
- sort > /manifest-rpm.txt
-rpm -qa --qf '%{sourcerpm}\n' | sort -u > /manifest-srpm.txt
-# collect all included licenses rhbz#601927
-rpm -qa --qf '%{license}\n' | sort -u > /manifest-license.txt
-# dependencies
-rpm -qa | xargs -n1 rpm -e --test 2> /manifest-deps.txt
-echo -n "."
-find / -xdev -print -exec rpm -qf {} \; > /manifest-owns.txt
-rpm -qa --qf '%{NAME}\t%{VERSION}\t%{RELEASE}\t%{BUILDTIME}\n' | \
- sort > /rpm-qa.txt
-echo -n "."
-
-du -akx --exclude=/var/cache/yum / > /manifest-file.txt
-du -x --exclude=/var/cache/yum / > /manifest-dir.txt
-echo -n "."
-bzip2 /manifest-deps.txt /manifest-owns.txt /manifest-file.txt /manifest-dir.txt
-echo -n "."
-
-%end
-
-%post --nochroot
-# Move manifests to ISO
-mv $INSTALL_ROOT/manifest-* $LIVE_ROOT/isolinux
-echo "done"
-
-# only works on x86, x86_64
-if [ "$(uname -i)" = "i386" -o "$(uname -i)" = "x86_64" ]; then
- if [ ! -d $LIVE_ROOT/LiveOS ]; then mkdir -p $LIVE_ROOT/LiveOS ; fi
- cp /usr/bin/livecd-iso-to-disk $LIVE_ROOT/LiveOS
- cp /usr/bin/livecd-iso-to-pxeboot $LIVE_ROOT/LiveOS
-fi
-%end
diff -ruN virt-v2v-v0.8.1/p2v-image-builder/common-minimizer.ks virt-v2v-v0.8.1.new/p2v-image-builder/common-minimizer.ks
--- virt-v2v-v0.8.1/p2v-image-builder/common-minimizer.ks 2011-04-26 20:58:33.000000000 +0100
+++ virt-v2v-v0.8.1.new/p2v-image-builder/common-minimizer.ks 1970-01-01 01:00:00.000000000 +0100
@@ -1,239 +0,0 @@
-# This file is only relatively lightly modified from the version copied from
-# oVirt, and certainly contains much which is irrelevant to this image. I have,
-# however, removed some obviously extraneous entries and added a few additional
-# entries.
-#
-# Matthew Booth <mbooth@redhat.com> - 18/4/2011
-
-%post --nochroot --interpreter image-minimizer
-# lokkit is just an install-time dependency; we can remove
-# it afterwards, which we do here
-droprpm system-config-*
-droprpm libsemanage-python
-droprpm python-libs
-droprpm python
-
-droprpm mkinitrd
-droprpm isomd5sum
-droprpm dmraid
-droprpm checkpolicy
-droprpm make
-droprpm policycoreutils-python
-droprpm setools-libs-python
-droprpm setools-libs
-
-droprpm gamin
-droprpm pm-utils
-droprpm kbd
-droprpm usermode
-droprpm vbetool
-droprpm ConsoleKit
-droprpm hdparm
-droprpm efibootmgr
-droprpm linux-atm-libs
-droprpm mtools
-droprpm syslinux
-droprpm wireless-tools
-droprpm radeontool
-droprpm libicu
-droprpm gnupg2
-droprpm fedora-release-notes
-droprpm fedora-logos
-
-# cronie pulls in exim (sendmail) which pulls in all kinds of perl deps
-droprpm exim
-droprpm perl*
-droprpm postfix
-droprpm mysql*
-
-droprpm sysklogd
-
-# unneeded rhn deps
-droprpm yum*
-
-# pam complains when this is missing
-keeprpm ConsoleKit-libs
-
-# kernel modules minimization
-
-# filesystems
-drop /lib/modules/*/kernel/fs
-keep /lib/modules/*/kernel/fs/ext*
-keep /lib/modules/*/kernel/fs/jbd*
-keep /lib/modules/*/kernel/fs/btrfs
-keep /lib/modules/*/kernel/fs/fat
-keep /lib/modules/*/kernel/fs/nfs
-keep /lib/modules/*/kernel/fs/nfs_common
-keep /lib/modules/*/kernel/fs/fscache
-keep /lib/modules/*/kernel/fs/lockd
-keep /lib/modules/*/kernel/fs/nls/nls_utf8.ko
-# autofs4 configfs exportfs *fat *jbd mbcache.ko nls xfs
-#*btrfs cramfs *ext2 *fscache *jbd2 *nfs squashfs
-# cachefiles dlm *ext3 fuse jffs2 *nfs_common ubifs
-# cifs ecryptfs *ext4 gfs2 *lockd nfsd udf
-
-# network
-drop /lib/modules/*/kernel/net
-keep /lib/modules/*/kernel/net/802*
-keep /lib/modules/*/kernel/net/bridge
-keep /lib/modules/*/kernel/net/core
-keep /lib/modules/*/kernel/net/ipv*
-keep /lib/modules/*/kernel/net/key
-keep /lib/modules/*/kernel/net/llc
-keep /lib/modules/*/kernel/net/netfilter
-keep /lib/modules/*/kernel/net/rds
-keep /lib/modules/*/kernel/net/sctp
-keep /lib/modules/*/kernel/net/sunrpc
-#*802 atm can ieee802154 *key *netfilter rfkill *sunrpc xfrm
-#*8021q bluetooth *core *ipv4 *llc phonet sched wimax
-# 9p *bridge dccp *ipv6 mac80211 *rds *sctp wireless
-
-drop /lib/modules/*/kernel/sound
-
-# drivers
-drop /lib/modules/*/kernel/drivers
-keep /lib/modules/*/kernel/drivers/ata
-keep /lib/modules/*/kernel/drivers/block
-keep /lib/modules/*/kernel/drivers/cdrom
-keep /lib/modules/*/kernel/drivers/char
-keep /lib/modules/*/kernel/drivers/cpufreq
-keep /lib/modules/*/kernel/drivers/dca
-keep /lib/modules/*/kernel/drivers/dma
-keep /lib/modules/*/kernel/drivers/edac
-keep /lib/modules/*/kernel/drivers/firmware
-keep /lib/modules/*/kernel/drivers/idle
-keep /lib/modules/*/kernel/drivers/infiniband
-keep /lib/modules/*/kernel/drivers/md
-keep /lib/modules/*/kernel/drivers/message
-keep /lib/modules/*/kernel/drivers/net
-drop /lib/modules/*/kernel/drivers/net/pcmcia
-drop /lib/modules/*/kernel/drivers/net/wireless
-drop /lib/modules/*/kernel/drivers/net/ppp*
-keep /lib/modules/*/kernel/drivers/pci
-keep /lib/modules/*/kernel/drivers/scsi
-keep /lib/modules/*/kernel/drivers/staging/ramzswap
-keep /lib/modules/*/kernel/drivers/uio
-keep /lib/modules/*/kernel/drivers/usb
-drop /lib/modules/*/kernel/drivers/usb/atm
-drop /lib/modules/*/kernel/drivers/usb/class
-drop /lib/modules/*/kernel/drivers/usb/image
-drop /lib/modules/*/kernel/drivers/usb/misc
-drop /lib/modules/*/kernel/drivers/usb/serial
-keep /lib/modules/*/kernel/drivers/vhost
-keep /lib/modules/*/kernel/drivers/virtio
-
-# acpi *cpufreq hid leds mtd ?regulator uwb
-#*ata crypto ?hwmon *md *net* rtc *vhost
-# atm *dca ?i2c media ?parport *scsi* video
-# auxdisplay *dma *idle memstick *pci ?serial *virtio
-#*block *edac ieee802154 *message pcmcia ?ssb watchdog
-# bluetooth firewire *infiniband ?mfd platform *staging xen
-#*cdrom *firmware input misc ?power ?uio
-#*char* ?gpu isdn mmc ?pps *usb
-
-drop /usr/share/zoneinfo
-keep /usr/share/zoneinfo/UTC
-
-drop /etc/alsa
-drop /usr/share/alsa
-drop /usr/share/awk
-drop /usr/share/vim
-drop /usr/share/anaconda
-drop /usr/share/backgrounds
-drop /usr/share/wallpapers
-drop /usr/share/kde-settings
-drop /usr/share/gnome-background-properties
-drop /usr/share/dracut
-drop /usr/share/plymouth
-drop /usr/share/setuptool
-drop /usr/share/hwdata/MonitorsDB
-drop /usr/share/hwdata/oui.txt
-drop /usr/share/hwdata/videoaliases
-drop /usr/share/hwdata/videodrivers
-drop /usr/share/firstboot
-drop /usr/share/lua
-drop /usr/share/kde4
-drop /usr/share/pixmaps
-drop /usr/share/icons
-drop /usr/share/fedora-release
-drop /usr/share/tabset
-
-drop /usr/share/tc
-drop /usr/share/emacs
-drop /usr/share/info
-drop /usr/src
-drop /usr/etc
-drop /usr/games
-drop /usr/include
-drop /usr/local
-drop /usr/sbin/dell*
-keep /usr/sbin/build-locale-archive
-drop /usr/sbin/glibc_post_upgrade.*
-drop /usr/lib*/tc
-drop /usr/lib*/tls
-drop /usr/lib*/sse2
-drop /usr/lib*/pkgconfig
-drop /usr/lib*/nss
-drop /usr/lib*/games
-drop /usr/lib*/alsa-lib
-drop /usr/lib*/krb5
-drop /usr/lib*/hal
-drop /usr/lib*/gio
-
-# syslinux
-drop /usr/share/syslinux
-# glibc-common locales
-drop /usr/lib/locale
-keep /usr/lib/locale/usr/share/locale/en_US
-# openssh
-drop /usr/bin/sftp
-drop /usr/bin/slogin
-drop /usr/bin/ssh-add
-drop /usr/bin/ssh-agent
-drop /usr/bin/ssh-keyscan
-# docs
-drop /usr/share/omf
-drop /usr/share/gnome
-drop /usr/share/doc
-keep /usr/share/doc/*-firmware-*
-drop /usr/share/locale/
-keep /usr/share/locale/en_US
-drop /usr/share/man
-drop /usr/share/i18n
-drop /boot/*
-drop /var/lib/builder
-
-drop /usr/lib*/libboost*
-keep /usr/lib*/libboost_program_options.so*
-keep /usr/lib*/libboost_filesystem.so*
-keep /usr/lib*/libboost_thread-mt.so*
-keep /usr/lib*/libboost_system.so*
-drop /usr/kerberos
-keep /usr/kerberos/bin/kinit
-keep /usr/kerberos/bin/klist
-drop /lib/firmware
-keep /lib/firmware/3com
-keep /lib/firmware/acenic
-keep /lib/firmware/adaptec
-keep /lib/firmware/advansys
-keep /lib/firmware/bnx2
-keep /lib/firmware/cxgb3
-keep /lib/firmware/e100
-keep /lib/firmware/myricom
-keep /lib/firmware/ql*
-keep /lib/firmware/sun
-keep /lib/firmware/tehuti
-keep /lib/firmware/tigon
-drop /lib/kbd/consolefonts
-drop /etc/pki/tls
-drop /etc/pki/java
-drop /etc/pki/nssdb
-drop /etc/pki/rpm-gpg
-%end
-
-%post
-echo "Removing python source files"
-find / -name '*.py' -exec rm -f {} \;
-find / -name '*.pyo' -exec rm -f {} \;
-
-%end
diff -ruN virt-v2v-v0.8.1/p2v-image-builder/common-pkgs.ks virt-v2v-v0.8.1.new/p2v-image-builder/common-pkgs.ks
--- virt-v2v-v0.8.1/p2v-image-builder/common-pkgs.ks 2011-04-26 20:58:33.000000000 +0100
+++ virt-v2v-v0.8.1.new/p2v-image-builder/common-pkgs.ks 1970-01-01 01:00:00.000000000 +0100
@@ -1,48 +0,0 @@
-# Direct requirements
-rubygem-virt-p2v
-bitstream-vera-sans-fonts
-xorg-x11-xinit
-xorg-x11-drivers
-xorg-x11-server-Xorg
-
-# Boot requirements
-device-mapper
-
-# Required for livecd creation
-passwd
-rpm
-/usr/sbin/lokkit
-
-# Remove unnecessary packages
--audit-libs-python
--ustr
--authconfig
--wireless-tools
--setserial
--prelink
--newt-python
--newt
--libselinux-python
--kbd
--usermode
--fedora-release
--fedora-release-notes
--dmraid
--gzip
--less
--which
--parted
--tar
--libuser
--mtools
--cpio
--yum
--numactl # Pulls in perl dependency
--perl
-
-# qlogic firmware
-ql2100-firmware
-ql2200-firmware
-ql23xx-firmware
-ql2400-firmware
-ql2500-firmware
diff -ruN virt-v2v-v0.8.1/p2v-image-builder/common-post.ks virt-v2v-v0.8.1.new/p2v-image-builder/common-post.ks
--- virt-v2v-v0.8.1/p2v-image-builder/common-post.ks 2011-04-26 20:58:33.000000000 +0100
+++ virt-v2v-v0.8.1.new/p2v-image-builder/common-post.ks 1970-01-01 01:00:00.000000000 +0100
@@ -1,43 +0,0 @@
-# -*-Shell-script-*-
-echo "Starting Kickstart Post"
-PATH=/sbin:/usr/sbin:/bin:/usr/bin
-export PATH
-
-# cleanup rpmdb to allow non-matching host and chroot RPM versions
-rm -f /var/lib/rpm/__db*
-
-echo "Creating shadow files"
-# because we aren't installing authconfig, we aren't setting up shadow
-# and gshadow properly. Do it by hand here
-pwconv
-grpconv
-
-echo "Forcing C locale"
-# force logins (via ssh, etc) to use C locale, since we remove locales
-cat >> /etc/profile << \EOF
-# force our locale to C since we don't have locale stuff'
-export LC_ALL=C LANG=C
-EOF
-
-# remove errors from /sbin/dhclient-script
-DHSCRIPT=/sbin/dhclient-script
-sed -i 's/mv /cp -p /g' $DHSCRIPT
-sed -i '/rm -f.*${interface}/d' $DHSCRIPT
-sed -i '/rm -f \/etc\/localtime/d' $DHSCRIPT
-sed -i '/rm -f \/etc\/ntp.conf/d' $DHSCRIPT
-sed -i '/rm -f \/etc\/yp.conf/d' $DHSCRIPT
-
-# Lock root account
-#passwd -l root
-
-#strip out all unncesssary locales
-localedef --list-archive | grep -v -i -E 'en_US.utf8' |xargs localedef --delete-from-archive
-mv /usr/lib/locale/locale-archive /usr/lib/locale/locale-archive.tmpl
-/usr/sbin/build-locale-archive
-
-# Run virt-p2v
-cat >> /etc/rc.local <<EOF
-export HOME=/root # rubygem Net::SSH needs this
-/usr/bin/xinit /usr/bin/virt-p2v > /root/virt-p2v.log 2>&1
-poweroff
-EOF
diff -ruN virt-v2v-v0.8.1/p2v-image-builder/common-post-nochroot.ks virt-v2v-v0.8.1.new/p2v-image-builder/common-post-nochroot.ks
--- virt-v2v-v0.8.1/p2v-image-builder/common-post-nochroot.ks 2011-04-26 20:58:33.000000000 +0100
+++ virt-v2v-v0.8.1.new/p2v-image-builder/common-post-nochroot.ks 1970-01-01 01:00:00.000000000 +0100
@@ -1,60 +0,0 @@
-%include version.ks
-
-PRODUCT='Virt P2V'
-PRODUCT_SHORT='virt-p2v'
-PACKAGE='virt-p2v'
-RELEASE=${RELEASE:-devel.`date +%Y%m%d%H%M%S`}
-
-echo "Customizing boot menu"
-sed -i -e '
-# Put product information at the top of the file
-1 {
- i '"say $PRODUCT $VERSION ($RELEASE)"'
- i '"menu title $PRODUCT_SHORT $VERSION ($RELEASE)"'
-}
-
-# Remove any existing menu title
-/^menu title .*/d
-
-# Remove quiet bootparam
-#s/ quiet//
-
-# Disable selinux entirely. Required, as we dont install an SELinux policy.
-/^\s*append\s/ s/\s*$/ selinux=0/
-
-# Remove Verify and Boot option
-/label check0/{N;N;N;d;}
-
-# Set the default timeout to 15 seconds
-s/^timeout .*/timeout 15/
-' $LIVE_ROOT/isolinux/isolinux.cfg
-
-# TODO: Replace the splash screen with something P2V appropriate
-#cp $INSTALL_ROOT//syslinux-vesa-splash.jpg $LIVE_ROOT/isolinux/splash.jpg
-
-# store image version info in the ISO
-cat > $LIVE_ROOT/isolinux/version <<EOF
-PRODUCT='$PRODUCT'
-PRODUCT_SHORT='${PRODUCT_SHORT}'
-PRODUCT_CODE=$PRODUCT_CODE
-RECIPE_SHA256=$RECIPE_SHA256
-RECIPE_RPM=$RECIPE_RPM
-PACKAGE=$PACKAGE
-VERSION=$VERSION
-RELEASE=$RELEASE
-EOF
-
-# overwrite user visible banners with the image versioning info
-cat > $INSTALL_ROOT/etc/$PACKAGE-release <<EOF
-$PRODUCT release $VERSION ($RELEASE)
-EOF
-ln -snf $PACKAGE-release $INSTALL_ROOT/etc/redhat-release
-ln -snf $PACKAGE-release $INSTALL_ROOT/etc/system-release
-cp $INSTALL_ROOT/etc/$PACKAGE-release $INSTALL_ROOT/etc/issue
-echo "Kernel \r on an \m (\l)" >> $INSTALL_ROOT/etc/issue
-cp $INSTALL_ROOT/etc/issue $INSTALL_ROOT/etc/issue.net
-
-# replace initramfs if regenerated
-if [ -f "$INSTALL_ROOT/initrd0.img" ]; then
- mv -v "$INSTALL_ROOT/initrd0.img" "$LIVE_ROOT/isolinux/initrd0.img"
-fi
diff -ruN virt-v2v-v0.8.1/p2v-image-builder/Makefile virt-v2v-v0.8.1.new/p2v-image-builder/Makefile
--- virt-v2v-v0.8.1/p2v-image-builder/Makefile 2011-04-26 20:58:33.000000000 +0100
+++ virt-v2v-v0.8.1.new/p2v-image-builder/Makefile 1970-01-01 01:00:00.000000000 +0100
@@ -1,2 +0,0 @@
-version.ks: ../Build
- echo VERSION=`../Build version` > version.ks
diff -ruN virt-v2v-v0.8.1/p2v-image-builder/version.ks virt-v2v-v0.8.1.new/p2v-image-builder/version.ks
--- virt-v2v-v0.8.1/p2v-image-builder/version.ks 2011-04-26 20:58:33.000000000 +0100
+++ virt-v2v-v0.8.1.new/p2v-image-builder/version.ks 1970-01-01 01:00:00.000000000 +0100
@@ -1 +0,0 @@
-VERSION=0.8.1
diff -ruN virt-v2v-v0.8.1/p2v-image-builder/virt-p2v-image-builder virt-v2v-v0.8.1.new/p2v-image-builder/virt-p2v-image-builder
--- virt-v2v-v0.8.1/p2v-image-builder/virt-p2v-image-builder 2011-04-26 20:58:33.000000000 +0100
+++ virt-v2v-v0.8.1.new/p2v-image-builder/virt-p2v-image-builder 1970-01-01 01:00:00.000000000 +0100
@@ -1,188 +0,0 @@
-#!/bin/bash
-
-# Copyright (C) 2010-2011, Red Hat, Inc.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; version 2 of the License.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
-# MA 02110-1301, USA. A copy of the GNU General Public License is
-# also available at http://www.gnu.org/copyleft/gpl.html.
-
-# Requires: sudo livecd-creator, sudo setenforce, ksflatten
-
-# Based on oVirt's node-creator
-
-# Current fedora data
-cur_rawhide=16
-cur_devel=15
-
-me=$(basename "$0")
-warn() { printf '%s: %s\n' "$me" "$*" >&2; }
-die() { warn "$*"; exit 1; }
-usage() {
-cat <<EOF
-usage: $me <options>
-
-Build a virt-p2v bootable image.
-
-OPTIONS:
- -a Additional yum repository. Can be specified multiple times.
- -c Yum cache directory.
- -d Directory containing virt-p2v-image.ks.
- -f Specific Fedora mirror to use if building a Fedora image.
- -l Boot image label.
- -r Primary yum repository.
- -u Updates yum repository.
- -h Show this message.
-EOF
-}
-
-onlyonce() {
- warn "-$1 may only be specified once"
- usage
- exit 1
-}
-
-while getopts "a:d:f:hl:r:u:w:" OPTION
-do
- case $OPTION in
- a)
- n_elems=${#extra_repos[*]}
- extra_repos[$n_elems]="$OPTARG"
- ;;
- c)
- [ -n "$cachedir" ] && onlyonce $OPTION
- cachedir="$OPTARG"
- ;;
- d)
- [ -n "$datadir" ] && onlyonce $OPTION
- datadir="$OPTARG"
- ;;
- f)
- [ -n "$fedora_url" ] && onlyonce $OPTION
- fedora_url="$OPTARG"
- ;;
- l)
- [ -n "$label" ] && onlyonce $OPTION
- label="$OPTARG"
- ;;
- r)
- [ -n "$repo" ] && onlyonce $OPTION
- repo="$OPTARG"
- ;;
- u)
- [ -n "$updates" ] && onlyonce $OPTION
- updates="$OPTARG"
- ;;
- h)
- usage
- exit 0
- ;;
- ?)
- usage
- exit 1
- ;;
- esac
-done
-
-# Split out here for simple editing with sed during installation
-DEFAULT_DATADIR=.
-
-# Option defaults
-datadir="${datadir:-$DEFAULT_DATADIR}"
-cachedir="${cachedir:-/var/tmp/p2v-image-builder.$USER}"
-label="${label:-Virt-P2V}"
-
-arch=$(rpm --eval '%{_arch}')
-kstmp=$(mktemp --tmpdir p2v-image-builder.XXXXXXXX)
-
-if pgrep -xl nscd; then
- die "Please stop nscd first"
-fi
-
-rm -f "$kstmp"
-# combine recipe includes
-ksflatten --config "$datadir/virt-p2v-image.ks" --output "$kstmp"
-# XXX broken ksflatten leaves %include
-sed -i 's/^%include /#&/' "$kstmp"
-
-if [ -z "$repo" ]; then
- # Set defaults for Fedora if this is a fedora system
- fedora=$(rpm --eval '%{fedora}' |grep [0-9])
-
- mirrorlist="http://mirrors.fedoraproject.org/mirrorlist"
-
- case "$fedora" in
- $curr_rawhide)
- if [ -z "$fedora_url" ]; then
- repo="--mirrorlist=$mirrorlist?repo=rawhide&arch=$arch"
- else
- repo="--baseurl=$fedora_url/development/rawhide/$arch/os"
- fi
- ;;
- $cur_devel)
- if [ -z "$fedora_url" ]; then
- repo="--mirrorlist=$mirrorlist?repo=fedora-$fedora&arch=$arch"
- else
- repo="--baseurl=$fedora_url/development/$fedora/$arch/os"
- fi
- ;;
- ?*)
- if [ -z "$fedora_url" ]; then
- repo="--mirrorlist=$mirrorlist?repo=fedora-$fedora&arch=$arch"
- updates="--mirrorlist=$mirrorlist?repo=updates-released-f${fedora}&arch=$arch"
- else
- repo="--baseurl=$fedora_url/releases/$fedora/Everything/$arch/os"
- updates="--baseurl=$fedora_url/updates/$fedora/$arch"
- fi
- esac
-else
- repo="--baseurl=$repo"
- [ -n "$updates" ] && updates="--baseurl=$updates"
-fi
-
-if [ -n "$repo" ]; then
- echo "repo --name=base $repo" >> "$kstmp"
-else
- die "No repository specified, and no default available."
-fi
-if [ -n "$updates" ]; then
- echo "repo --name=updates $updates" >> "$kstmp"
-fi
-i=0
-for extra in "${extra_repos[@]}"; do
- ((i++))
- [ -d "$extra" ] && extra="file://$extra"
- echo "repo --name=extra$i --baseurl=$extra" >> "$kstmp"
-done
-
-selinux_enforcing=$(/usr/sbin/getenforce)
-case "$selinux_enforcing" in
- Enforcing) sudo /usr/sbin/setenforce Permissive ;;
- Permissive) ;;
- *) if grep -q '^selinux --disabled' "$kstmp";
- then
- warn "WARNING: SELinux disabled in kickstart"
- else
- die "ERROR: SELinux enabled in kickstart, \
- but disabled on the build machine"
- fi ;;
-esac
-
-mkdir -p $cachedir
-sudo livecd-creator -c "$kstmp" -f "$label" --cache="$cachedir"
-
-# Clean up
-rm -f $kstmp
-if [ "$selinux_enforcing" = Enforcing ]; then
- sudo /usr/sbin/setenforce Enforcing
-fi
diff -ruN virt-v2v-v0.8.1/p2v-image-builder/virt-p2v-image.ks virt-v2v-v0.8.1.new/p2v-image-builder/virt-p2v-image.ks
--- virt-v2v-v0.8.1/p2v-image-builder/virt-p2v-image.ks 2011-04-26 20:58:33.000000000 +0100
+++ virt-v2v-v0.8.1.new/p2v-image-builder/virt-p2v-image.ks 1970-01-01 01:00:00.000000000 +0100
@@ -1,19 +0,0 @@
-# virt-p2v Node image recipe
-
-%include common-install.ks
-
-%packages --excludedocs --nobase
-%include common-pkgs.ks
-%end
-
-%post
-%include common-post.ks
-%end
-
-%include common-minimizer.ks
-
-%post --nochroot
-%include common-post-nochroot.ks
-%end
-
-%include common-manifest-post.ks
diff -ruN virt-v2v-v0.8.1/p2v-server/run-p2v-locally virt-v2v-v0.8.1.new/p2v-server/run-p2v-locally
--- virt-v2v-v0.8.1/p2v-server/run-p2v-locally 2011-04-26 20:58:33.000000000 +0100
+++ virt-v2v-v0.8.1.new/p2v-server/run-p2v-locally 1970-01-01 01:00:00.000000000 +0100
@@ -1,52 +0,0 @@
-#!/bin/sh
-# virt-p2v
-# Copyright (C) 2010 Red Hat Inc.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-# This script sets up the environment so you can run virt-v2v in place
-# without needing to do 'make install' first.
-#
-# Use it like this:
-# ./run-p2v-locally
-#
-# It requires the environment variable VIRTV2V_ROOT to be set. If using
-# libguestfs from source, LIBGUESTFS_ROOT must also be set.
-
-if [ -z "$VIRTV2V_ROOT" ]; then
- echo "VIRTV2V_ROOT must be set"
- exit 1
-fi
-
-if [ -z "$PERL5LIB" ]; then
- PERL5LIB="$VIRTV2V_ROOT/blib/lib"
-else
- PERL5LIB="$VIRTV2V_ROOT/blib/lib:$PERL5LIB"
-fi
-
-if [ ! -z "$LIBGUESTFS_ROOT" ]; then
- if [ -z "$LD_LIBRARY_PATH" ]; then
- LD_LIBRARY_PATH="$LIBGUESTFS_ROOT/src/.libs"
- else
- LD_LIBRARY_PATH="$LIBGUESTFS_ROOT/src/.libs:$LD_LIBRARY_PATH"
- fi
-
- LIBGUESTFS_PATH="$LIBGUESTFS_ROOT/appliance"
- PERL5LIB="$LIBGUESTFS_ROOT/perl/blib/lib:$LIBGUESTFS_ROOT/perl/blib/arch:$PERL5LIB"
-fi
-
-export PERL5LIB LD_LIBRARY_PATH LIBGUESTFS_PATH
-
-exec perl "$VIRTV2V_ROOT/p2v-server/virt-p2v-server.pl" "$@"
diff -ruN virt-v2v-v0.8.1/p2v-server/virt-p2v-server.pl virt-v2v-v0.8.1.new/p2v-server/virt-p2v-server.pl
--- virt-v2v-v0.8.1/p2v-server/virt-p2v-server.pl 2011-04-26 20:58:33.000000000 +0100
+++ virt-v2v-v0.8.1.new/p2v-server/virt-p2v-server.pl 1970-01-01 01:00:00.000000000 +0100
@@ -1,505 +0,0 @@
-#!/usr/bin/perl
-# virt-p2v-server
-# Copyright (C) 2011 Red Hat Inc.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-use warnings;
-use strict;
-
-use IO::Handle;
-use YAML::Any;
-
-use Locale::TextDomain 'virt-v2v';
-
-use Sys::Guestfs;
-
-use Sys::VirtConvert;
-use Sys::VirtConvert::Config;
-use Sys::VirtConvert::Converter;
-use Sys::VirtConvert::Connection::LibVirtTarget;
-use Sys::VirtConvert::Connection::RHEVTarget;
-use Sys::VirtConvert::GuestfsHandle;
-use Sys::VirtConvert::Util qw(:DEFAULT logmsg_init logmsg_level);
-
-=encoding utf8
-
-=head1 NAME
-
-virt-p2v-server - Receive data from virt-p2v
-
-=head1 DESCRIPTION
-
-virt-p2v-server is invoked over SSH by virt-p2v. It is not intended to be run
-manually.
-
-=cut
-
-# SIGPIPE will cause an untidy exit of the perl process, without calling
-# destructors. We don't rely on it anywhere, as we check for errors when reading
-# from or writing to a pipe.
-$SIG{'PIPE'} = 'IGNORE';
-
-# The protocol version we support
-use constant VERSION => 0;
-
-# Message types
-use constant MSG_VERSION => 'VERSION';
-use constant MSG_LANG => 'LANG';
-use constant MSG_METADATA => 'METADATA';
-use constant MSG_PATH => 'PATH';
-use constant MSG_CONVERT => 'CONVERT';
-use constant MSG_LIST_PROFILES => 'LIST_PROFILES';
-use constant MSG_SET_PROFILE => 'SET_PROFILE';
-use constant MSG_CONTAINER => 'CONTAINER';
-use constant MSG_DATA => 'DATA';
-
-# Container types
-use constant CONT_RAW => 'RAW';
-
-# Global state
-my $config;
-my $meta;
-my $target;
-
-# Initialize logging
-logmsg_init('syslog');
-#logmsg_level(DEBUG);
-
-logmsg NOTICE, __x("{program} started.", program => 'p2v-server');
-
-# Wrap everything in a big eval to catch any die(). N.B. $SIG{__DIE__} is no
-# good for this, as it catches every die(), even those inside an eval
-eval {
- # Set the umask to a reasonable default
- umask(0022);
-
- # Don't buffer output
- # While perl will use line buffering when STDOUT is connected to a tty, when
- # not connected to a tty, for example when invoked directly over ssh, it
- # will use a regular, large output buffer. This results in messages being
- # held in the buffer indefinitely.
- STDOUT->autoflush(1);
-
- # Read the config file
- eval {
- $config = Sys::VirtConvert::Config->new('/etc/virt-v2v.conf');
- };
- v2vdie $@ if $@;
-
- my $msg;
- while ($msg = p2v_receive()) {
- my $type = $msg->{type};
-
- # VERSION n
- if ($type eq MSG_VERSION) {
- my $version = $msg->{args}[0];
- if ($version <= VERSION) {
- p2v_return_ok();
- }
-
- else {
- err_and_die(__x('This version of virt-p2v-server does not '.
- 'support protocol version {version}.',
- version => $version));
- }
- }
-
- # LANG lang
- elsif ($type eq MSG_LANG) {
- $ENV{LANG} = $msg->{args}[0];
- p2v_return_ok();
- }
-
- # METADATA length
- # length bytes of YAML
- elsif ($type eq MSG_METADATA) {
- my $yaml = p2v_read($msg->{args}[0]);
- eval { $meta = Load($yaml); };
- err_and_die('Error parsing metadata: '.$@) if $@;
-
- p2v_return_ok();
- }
-
- # PATH length path
- # N.B. path could theoretically include spaces
- elsif ($type eq MSG_PATH) {
- my $length = $msg->{args}[0];
-
- my $path = join(' ', @{$msg->{args}}[1..$#{$msg->{args}}]);
- receive_path($path, $length);
- }
-
- # CONVERT
- elsif ($type eq MSG_CONVERT) {
- convert();
- }
-
- # LIST_PROFILES
- elsif ($type eq MSG_LIST_PROFILES) {
- p2v_return_list($config->list_profiles());
- }
-
- # SET_PROFILE profile
- elsif ($type eq MSG_SET_PROFILE) {
- set_profile($msg->{args}[0]);
- }
-
- else {
- unexpected_msg($type);
- }
- }
-};
-logmsg FATAL, $@ if $@;
-
-exit(0);
-
-# Receive an image file
-sub receive_path
-{
- my ($path, $length) = @_;
-
- err_and_die('PATH without prior SET_PROFILE command')
- unless defined($target);
- err_and_die('PATH without prior METADATA command')
- unless defined($meta);
-
- my ($disk) = grep { $_->{path} eq $path } @{$meta->{disks}};
- err_and_die("$path not found in metadata") unless defined($disk);
-
- # Construct a volume name based on the path and hostname
- my $name = $meta->{name}.'-'.$disk->{device};
- $name =~ s,/,_,g; # e.g. cciss devices have a directory structure
-
- my $sopts = $config->get_storage_opts();
-
- my $convert = 0;
- my $format;
- my $sparse;
-
- # Default to raw. Conversion required for anything else.
- if (!exists($sopts->{format}) || $sopts->{format} eq 'raw') {
- $format = 'raw';
- } else {
- $format = $sopts->{format};
- $convert = 1;
- }
-
- # Default to non-sparse
- my $allocation = $sopts->{allocation};
- if (!defined($allocation) || $allocation eq 'preallocated') {
- $sparse = 0;
- } elsif ($allocation eq 'sparse') {
- $sparse = 1;
- } else {
- err_and_die(__x('Invalid allocation policy {policy} in profile.',
- policy => $allocation));
- }
-
- # Create the target volume
- my $vol;
- eval {
- $vol = $target->create_volume(
- $name,
- $format,
- $length,
- $sparse
- );
- };
- err_and_die($@) if $@;
- p2v_return_ok();
-
- # Receive an initial container
- my $msg = p2v_receive();
- unexpected_msg($msg->{type}) unless $msg->{type} eq MSG_CONTAINER;
-
- # We only support RAW container
- my $ctype = $msg->{args}[0];
- err_and_die("Received unknown container type: $ctype")
- unless $ctype eq CONT_RAW;
- p2v_return_ok();
-
- # Update the disk entry with the new volume details
- $disk->{local_path} = $vol->get_local_path();
- $disk->{path} = $vol->get_path();
- $disk->{is_block} = $vol->is_block();
-
- my $writer = $vol->get_write_stream($convert);
-
- # Receive volume data in chunks
- my $received = 0;
- while ($received < $length) {
- my $data = p2v_receive();
-
- unexpected_msg($data->command) unless $data->{type} eq MSG_DATA;
-
- # Read the data message in chunks of up to 4M
- my $remaining = $data->{args}[0];
- while ($remaining > 0) {
- my $chunk = $remaining > 4*1024*1024 ? 4*1024*1024 : $remaining;
- my $buf = p2v_read($chunk);
-
- $received += $chunk;
- $remaining -= $chunk;
-
- eval { $writer->write($buf); };
- err_and_die($@) if $@;
- }
-
- p2v_return_ok();
- }
-}
-
-# Use the specified profile
-sub set_profile
-{
- my ($profile) = @_;
-
- # Check the profile is in our list
- my $found = 0;
- for my $i ($config->list_profiles()) {
- if ($i eq $profile) {
- $found = 1;
- last;
- }
- }
- err_and_die(__x('Invalid profile: {profile}', profile => $profile))
- unless ($found);
-
- $config->use_profile($profile);
-
- my $storage = $config->get_storage();
- my $method = $config->get_method();
- if ($method eq 'libvirt') {
- $target = new Sys::VirtConvert::Connection::LibVirtTarget
- ('qemu:///system', $storage);
- } elsif ($method eq 'rhev') {
- $target = new Sys::VirtConvert::Connection::RHEVTarget($storage);
- } else {
- err_and_die(__x('Profile {profile} specifies invalid method {method}.',
- profile => $profile, method => $method));
- }
-
- p2v_return_ok();
-}
-
-sub convert
-{
- err_and_die('CONVERT without prior SET_PROFILE command')
- unless (defined($target));
-
- err_and_die('CONVERT without prior METADATA command')
- unless defined($meta);
-
- my @localpaths = map { $_->{local_path} } @{$meta->{disks}};
-
- my $g;
- eval {
- my $transferiso = $config->get_transfer_iso();
-
- $g = new Sys::VirtConvert::GuestfsHandle(
- \@localpaths,
- $transferiso,
- $target->isa('Sys::VirtConvert::Connection::RHEVTarget')
- );
-
- my $transferdev;
- if (defined($transferiso)) {
- my @devices = $g->list_devices();
- $transferdev = pop(@devices);
- }
-
- my $root = inspect_guest($g, $transferdev);
- my $guestcaps =
- Sys::VirtConvert::Converter->convert($g, $config, $root, $meta);
- $target->create_guest($g, $root, $meta, $config, $guestcaps,
- $meta->{name});
-
- if($guestcaps->{block} eq 'virtio' && $guestcaps->{net} eq 'virtio') {
- logmsg NOTICE, __x('{name} configured with virtio drivers.',
- name => $meta->{name});
- } elsif ($guestcaps->{block} eq 'virtio') {
- logmsg NOTICE, __x('{name} configured with virtio storage only.',
- name => $meta->{name});
- } elsif ($guestcaps->{net} eq 'virtio') {
- logmsg NOTICE, __x('{name} configured with virtio networking only.',
- name => $meta->{name});
- } else {
- logmsg NOTICE, __x('{name} configured without virtio drivers.',
- name => $meta->{name});
- }
- };
-
- # If any of the above commands result in failure, we need to ensure that
- # the guestfs qemu process is cleaned up before further cleanup. Failure to
- # do this can result in failure to umount RHEV export's temporary mount
- # point.
- if ($@) {
- my $err = $@;
- $g->close();
-
- # We trust the error was already logged
- p2v_return_err($err);
- die($@);
- }
-
- p2v_return_ok();
-}
-
-sub unexpected_msg
-{
- err_and_die('Received unexpected command: '.shift);
-}
-
-sub err_and_die
-{
- my $err = shift;
- p2v_return_err($err);
- v2vdie $err;
-}
-
-END {
- my $err = $?;
-
- logmsg NOTICE, __x("{program} exited.", program => 'p2v-server');
-
- # die() sets $? to 255, which is untidy.
- $? = $err == 255 ? 1 : $err;
-}
-
-# Perform guest inspection using the libguestfs core inspection API.
-# Returns the root device of the os to be converted.
-sub inspect_guest
-{
- my $g = shift;
- my $transferdev = shift;
-
- # Get list of roots, sorted
- my @roots = $g->inspect_os();
-
- # Filter out the transfer device from the results of inspect_os
- # There's a libguestfs bug (fixed upstream) which meant the transfer ISO
- # could be erroneously detected as an unknown Windows OS. As we know what it
- # is, we can filter out the transfer device here. Even when the fix is
- # released this is reasonable belt & braces.
- @roots = grep(!/^\Q$transferdev\E$/, @roots);
-
- @roots = sort @roots;
-
- # Only work on single-root operating systems.
- v2vdie __('No root device found in this operating system image.')
- if @roots == 0;
-
- v2vdie __('Multiboot operating systems are not supported.')
- if @roots > 1;
-
- return $roots[0];
-}
-
-sub p2v_receive
-{
- my $in = <>;
- v2vdie __('Client closed connection unexpectedly') unless defined($in);
-
- # Messages consist of the message type followed by 0 or more arguments,
- # terminated by a newline
- chomp($in);
- $in =~ /^([A-Z_]+)( .+)?$/ or err_and_die("Received invalid message: $in");
-
- my %msg;
- $msg{type} = $1;
- if (defined($2)) {
- my @args = split(' ', $2);
- $msg{args} = \@args;
- } else {
- $msg{args} = [];
- }
-
- logmsg DEBUG, __x('Received: {command} {args}',
- command => $msg{type},
- args => join(' ', @{$msg{args}}));
-
- return \%msg;
-}
-
-sub p2v_read
-{
- my ($length) = @_;
-
- my $buf;
- my $total = 0;
-
- while($total < $length) {
- my $in = read(STDIN, $buf, $length, $total)
- or err_and_die(__x('Error receiving data: {error}', error => $@));
- logmsg DEBUG, "Read $in bytes";
- $total += $in;
- }
-
- return $buf;
-}
-
-sub p2v_return_ok
-{
- my $msg = "OK";
- logmsg DEBUG, __x('Sent: {msg}', msg => $msg);
- print $msg,"\n";
-}
-
-sub p2v_return_list
-{
- my @values = @_;
-
- my $msg = 'LIST '.scalar(@values);
- foreach my $value (@values) {
- $msg .= "\n$value";
- }
- logmsg DEBUG, __x('Sent: {msg}', msg => $msg);
- print $msg,"\n";
-}
-
-sub p2v_return_err
-{
- my $msg = 'ERROR '.shift;
- logmsg DEBUG, __x('Sent: {msg}', msg => $msg);
- print $msg,"\n";
-}
-
-=head1 SEE ALSO
-
-L<virt-v2v(1)>,
-L<http://libguestfs.org/>.
-
-=head1 AUTHOR
-
-Matthew Booth <mbooth@redhat.com>
-
-=head1 COPYRIGHT
-
-Copyright (C) 2011 Red Hat Inc.
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
diff -ruN virt-v2v-v0.8.1/virt-v2v.spec virt-v2v-v0.8.1.new/virt-v2v.spec
--- virt-v2v-v0.8.1/virt-v2v.spec 2011-04-26 20:58:33.000000000 +0100
+++ virt-v2v-v0.8.1.new/virt-v2v.spec 2011-05-11 17:20:21.000000000 +0100
@@ -55,7 +55,6 @@
# virt-p2v build requirements
BuildRequires: rubygem(rake)
-BuildRequires: rubygem(echoe)
Requires: perl(:MODULE_COMPAT_%(eval "`%{__perl} -V:version`"; echo $version))
@@ -141,7 +140,7 @@
%{__perl} Build.PL
./Build
-pushd p2v-client
+pushd p2v/client
rake gem
popd
@@ -174,7 +173,7 @@
mkdir -p %{buildroot}/%{gemdir}
gem install --local --install-dir %{buildroot}%{gemdir} \
- --force --rdoc p2v-client/pkg/%{gemname}-%{version}.gem
+ --force --rdoc p2v/client/pkg/%{gemname}-%{version}.gem
mv %{buildroot}%{gemdir}/bin/* %{buildroot}/%{_bindir}
find %{buildroot}%{geminstdir}/bin -type f | xargs chmod a+x
cp COPYING %{buildroot}/%{geminstdir}
@@ -183,8 +182,8 @@
%global builderdir %{_datadir}/virt-p2v-image-builder
builder=%{buildroot}/%{_bindir}/virt-p2v-image-builder
mkdir -p %{buildroot}%{builderdir}
-cp p2v-image-builder/*.ks %{buildroot}%{builderdir}
-cp p2v-image-builder/virt-p2v-image-builder $builder
+cp p2v/image-builder/*.ks %{buildroot}%{builderdir}
+cp p2v/image-builder/virt-p2v-image-builder $builder
# Set the default data directory
sed -i -e 's,^DEFAULT_DATADIR=.*,DEFAULT_DATADIR=%{builderdir},' $builder
@@ -193,7 +192,7 @@
%check
./Build test
-pushd p2v-client
+pushd p2v/client
# No tests yet
#rake test
popd
diff -ruN virt-v2v-v0.8.1/virt-v2v.spec.PL virt-v2v-v0.8.1.new/virt-v2v.spec.PL
--- virt-v2v-v0.8.1/virt-v2v.spec.PL 2011-04-26 20:58:33.000000000 +0100
+++ virt-v2v-v0.8.1.new/virt-v2v.spec.PL 2011-05-11 17:20:21.000000000 +0100
@@ -165,7 +165,7 @@
%{__perl} Build.PL
./Build
-pushd p2v-client
+pushd p2v/client
rake gem
popd
@@ -198,7 +198,7 @@
mkdir -p %{buildroot}/%{gemdir}
gem install --local --install-dir %{buildroot}%{gemdir} \
- --force --rdoc p2v-client/pkg/%{gemname}-%{version}.gem
+ --force --rdoc p2v/client/pkg/%{gemname}-%{version}.gem
mv %{buildroot}%{gemdir}/bin/* %{buildroot}/%{_bindir}
find %{buildroot}%{geminstdir}/bin -type f | xargs chmod a+x
cp COPYING %{buildroot}/%{geminstdir}
@@ -207,8 +207,8 @@
%global builderdir %{_datadir}/virt-p2v-image-builder
builder=%{buildroot}/%{_bindir}/virt-p2v-image-builder
mkdir -p %{buildroot}%{builderdir}
-cp p2v-image-builder/*.ks %{buildroot}%{builderdir}
-cp p2v-image-builder/virt-p2v-image-builder $builder
+cp p2v/image-builder/*.ks %{buildroot}%{builderdir}
+cp p2v/image-builder/virt-p2v-image-builder $builder
# Set the default data directory
sed -i -e 's,^DEFAULT_DATADIR=.*,DEFAULT_DATADIR=%{builderdir},' $builder
@@ -217,7 +217,7 @@
%check
./Build test
-pushd p2v-client
+pushd p2v/client
# No tests yet
#rake test
popd