From 55697cb1ebd419b29bed0c47b4e4141040fce8e8 Mon Sep 17 00:00:00 2001 From: Matthew Booth Date: Wed, 11 May 2011 17:36:18 +0100 Subject: [PATCH] Pull in upstream patches to remove echoe dependence --- virt-v2v-0.8.1-00-44eb9021-modified.patch | 9296 +++++++++++++++++++++ virt-v2v-0.8.1-01-e34a8c09.patch | 57 + virt-v2v-0.8.1-02-fadb1929.patch | 111 + virt-v2v.spec | 20 +- 4 files changed, 9478 insertions(+), 6 deletions(-) create mode 100644 virt-v2v-0.8.1-00-44eb9021-modified.patch create mode 100644 virt-v2v-0.8.1-01-e34a8c09.patch create mode 100644 virt-v2v-0.8.1-02-fadb1929.patch diff --git a/virt-v2v-0.8.1-00-44eb9021-modified.patch b/virt-v2v-0.8.1-00-44eb9021-modified.patch new file mode 100644 index 0000000..5f0b250 --- /dev/null +++ b/virt-v2v-0.8.1-00-44eb9021-modified.patch @@ -0,0 +1,9296 @@ +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 ++ ++ * 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 + + * 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 @@ ++ ++ ++ ++ ++ ++ False ++ center-always ++ False ++ ++ ++ ++ True ++ 0 ++ 0 ++ ++ ++ 800 ++ 600 ++ True ++ 0 ++ 0 ++ in ++ ++ ++ True ++ vertical ++ 2 ++ ++ ++ True ++ ++ ++ True ++ 0 ++ 0 ++ 5 ++ 5 ++ <span weight='bold' foreground='white' size='xx-large'>virt-p2v</span> ++ True ++ ++ ++ ++ ++ False ++ 0 ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ 800 ++ 550 ++ ++ ++ True ++ vertical ++ ++ ++ True ++ 0 ++ 1 ++ 11 ++ Welcome to virt-p2v. ++ ++ ++ False ++ 0 ++ ++ ++ ++ ++ True ++ 0 ++ out ++ ++ ++ True ++ True ++ automatic ++ automatic ++ ++ ++ True ++ True ++ network_device_list ++ False ++ 0 ++ ++ ++ Device ++ ++ ++ ++ 3 ++ 0 ++ ++ ++ ++ ++ ++ ++ 18 ++ MAC Address ++ ++ ++ ++ 3 ++ 1 ++ ++ ++ ++ ++ ++ ++ Status ++ ++ ++ ++ 3 ++ 2 ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ True ++ <b>Select a network device</b> ++ True ++ ++ ++ ++ ++ 1 ++ ++ ++ ++ ++ True ++ 0 ++ in ++ ++ ++ True ++ 12 ++ ++ ++ True ++ vertical ++ ++ ++ Automatic configuration ++ True ++ True ++ False ++ True ++ True ++ ++ ++ ++ 0 ++ ++ ++ ++ ++ True ++ False ++ 3 ++ 2 ++ 2 ++ ++ ++ True ++ 0 ++ IP Address: ++ ++ ++ GTK_FILL ++ GTK_FILL ++ ++ ++ ++ ++ True ++ 0 ++ Gateway: ++ ++ ++ 1 ++ 2 ++ GTK_FILL ++ GTK_FILL ++ ++ ++ ++ ++ True ++ 0 ++ DNS Servers: ++ ++ ++ 2 ++ 3 ++ GTK_FILL ++ GTK_FILL ++ ++ ++ ++ ++ True ++ True ++ 39 ++ 39 ++ True ++ ++ ++ ++ 1 ++ 2 ++ 1 ++ 2 ++ GTK_FILL ++ ++ ++ ++ ++ True ++ True ++ 35 ++ ++ ++ ++ 1 ++ 2 ++ 2 ++ 3 ++ GTK_FILL ++ ++ ++ ++ ++ True ++ 2 ++ ++ ++ True ++ True ++ 39 ++ 39 ++ True ++ ++ ++ ++ 0 ++ ++ ++ ++ ++ True ++ 0 ++ Prefix: ++ ++ ++ False ++ 1 ++ ++ ++ ++ ++ True ++ True ++ 2 ++ 2 ++ True ++ ++ ++ ++ False ++ 2 ++ ++ ++ ++ ++ 1 ++ 2 ++ GTK_FILL ++ ++ ++ ++ ++ 1 ++ ++ ++ ++ ++ ++ ++ ++ ++ True ++ <b>IP Configuration</b> ++ True ++ ++ ++ ++ ++ False ++ 2 ++ ++ ++ ++ ++ True ++ 1 ++ 0 ++ ++ ++ Use these network settings ++ True ++ False ++ True ++ True ++ ++ ++ ++ ++ ++ False ++ 3 ++ ++ ++ ++ ++ ++ ++ ++ ++ True ++ vertical ++ ++ ++ True ++ 0 ++ 0 ++ ++ ++ True ++ 0 ++ in ++ ++ ++ True ++ 12 ++ ++ ++ True ++ vertical ++ ++ ++ True ++ 3 ++ 2 ++ 2 ++ ++ ++ True ++ 0 ++ Hostname: ++ ++ ++ ++ ++ ++ ++ ++ ++ True ++ 0 ++ Username: ++ ++ ++ 1 ++ 2 ++ ++ ++ ++ ++ ++ ++ True ++ 0 ++ Password: ++ ++ ++ 2 ++ 3 ++ ++ ++ ++ ++ ++ ++ True ++ True ++ ++ 40 ++ ++ ++ ++ 1 ++ 2 ++ ++ ++ ++ ++ ++ True ++ True ++ False ++ ++ 40 ++ ++ ++ ++ 1 ++ 2 ++ 2 ++ 3 ++ ++ ++ ++ ++ ++ True ++ True ++ ++ 40 ++ root ++ ++ ++ ++ 1 ++ 2 ++ 1 ++ 2 ++ ++ ++ ++ ++ ++ False ++ 0 ++ ++ ++ ++ ++ True ++ 0 ++ 0 ++ 8 ++ 8 ++ ++ ++ ++ ++ ++ 1 ++ ++ ++ ++ ++ ++ ++ ++ ++ True ++ <b>Connect to conversion server</b> ++ True ++ ++ ++ ++ ++ ++ ++ 0 ++ ++ ++ ++ ++ True ++ 1 ++ 0 ++ 0 ++ 0 ++ ++ ++ Connect ++ True ++ False ++ True ++ True ++ ++ ++ ++ ++ ++ False ++ 1 ++ ++ ++ ++ ++ ++ ++ ++ ++ True ++ vertical ++ ++ ++ True ++ ++ ++ True ++ 0 ++ out ++ ++ ++ True ++ 0 ++ 0 ++ 0 ++ 0 ++ 12 ++ ++ ++ True ++ 4 ++ 2 ++ 2 ++ ++ ++ True ++ 0 ++ Destination Profile: ++ ++ ++ ++ ++ True ++ convert_profile_list ++ ++ ++ ++ ++ 0 ++ ++ ++ ++ ++ 1 ++ 2 ++ ++ ++ ++ ++ True ++ 0 ++ Memory (MB): ++ ++ ++ 3 ++ 4 ++ ++ ++ ++ ++ True ++ True ++ ++ True ++ ++ ++ ++ 1 ++ 2 ++ 3 ++ 4 ++ ++ ++ ++ ++ True ++ 0 ++ Number of CPUs: ++ ++ ++ 2 ++ 3 ++ ++ ++ ++ ++ True ++ 0 ++ Name ++ ++ ++ 1 ++ 2 ++ ++ ++ ++ ++ True ++ True ++ ++ True ++ ++ ++ ++ 1 ++ 2 ++ 1 ++ 2 ++ ++ ++ ++ ++ True ++ True ++ ++ True ++ ++ ++ ++ 1 ++ 2 ++ 2 ++ 3 ++ ++ ++ ++ ++ ++ ++ ++ ++ True ++ <b>Target properties</b> ++ True ++ ++ ++ ++ ++ False ++ False ++ 0 ++ ++ ++ ++ ++ True ++ vertical ++ ++ ++ True ++ 0 ++ out ++ ++ ++ True ++ ++ ++ True ++ True ++ automatic ++ automatic ++ ++ ++ True ++ True ++ convert_fixed_list ++ False ++ 0 ++ ++ ++ Convert ++ True ++ ++ ++ ++ ++ ++ 0 ++ ++ ++ ++ ++ ++ ++ Device ++ ++ ++ ++ 1 ++ ++ ++ ++ ++ ++ ++ Transfer Progress ++ True ++ ++ ++ ++ 2 ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ True ++ <b>Fixed Storage</b> ++ True ++ ++ ++ ++ ++ 0 ++ ++ ++ ++ ++ True ++ 0 ++ out ++ ++ ++ True ++ ++ ++ True ++ True ++ automatic ++ automatic ++ ++ ++ True ++ True ++ convert_removable_list ++ ++ ++ Convert ++ ++ ++ ++ ++ ++ 0 ++ ++ ++ ++ ++ ++ ++ Device ++ ++ ++ ++ 1 ++ ++ ++ ++ ++ ++ ++ Type ++ ++ ++ ++ 2 ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ True ++ <b>Removable Media</b> ++ True ++ ++ ++ ++ ++ 1 ++ ++ ++ ++ ++ True ++ 0 ++ out ++ ++ ++ True ++ 1 ++ 1 ++ ++ ++ True ++ True ++ automatic ++ automatic ++ ++ ++ True ++ True ++ convert_network_list ++ False ++ 0 ++ ++ ++ Convert ++ ++ ++ ++ ++ ++ 0 ++ ++ ++ ++ ++ ++ ++ Device ++ ++ ++ ++ 1 ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ True ++ <b>Network Interfaces</b> ++ True ++ ++ ++ ++ ++ 2 ++ ++ ++ ++ ++ 1 ++ ++ ++ ++ ++ 0 ++ ++ ++ ++ ++ True ++ ++ ++ True ++ 0 ++ 12 ++ ++ ++ ++ ++ ++ 0 ++ ++ ++ ++ ++ Convert ++ True ++ True ++ True ++ ++ ++ ++ False ++ False ++ 1 ++ ++ ++ ++ ++ False ++ False ++ 1 ++ ++ ++ ++ ++ ++ ++ ++ ++ True ++ vertical ++ ++ ++ True ++ A guest has been successfully created on the target server. ++ ++Remove the temporary boot device from this machine and press 'Reboot' to continue. ++ center ++ ++ ++ 0 ++ ++ ++ ++ ++ True ++ 0.25 ++ 0.25 ++ ++ ++ Reboot ++ True ++ True ++ True ++ ++ ++ ++ ++ ++ 1 ++ ++ ++ ++ ++ ++ +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 = < /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 - 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 < /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 < $INSTALL_ROOT/etc/$PACKAGE-release <> $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 < ++ ++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, ++L. ++ ++=head1 AUTHOR ++ ++Matthew Booth ++ ++=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 @@ +- +- +- +- +- +- False +- center-always +- False +- +- +- +- True +- 0 +- 0 +- +- +- 800 +- 600 +- True +- 0 +- 0 +- in +- +- +- True +- vertical +- 2 +- +- +- True +- +- +- True +- 0 +- 0 +- 5 +- 5 +- <span weight='bold' foreground='white' size='xx-large'>virt-p2v</span> +- True +- +- +- +- +- False +- 0 +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- 800 +- 550 +- +- +- True +- vertical +- +- +- True +- 0 +- 1 +- 11 +- Welcome to virt-p2v. +- +- +- False +- 0 +- +- +- +- +- True +- 0 +- out +- +- +- True +- True +- automatic +- automatic +- +- +- True +- True +- network_device_list +- False +- 0 +- +- +- Device +- +- +- +- 3 +- 0 +- +- +- +- +- +- +- 18 +- MAC Address +- +- +- +- 3 +- 1 +- +- +- +- +- +- +- Status +- +- +- +- 3 +- 2 +- +- +- +- +- +- +- +- +- +- +- True +- <b>Select a network device</b> +- True +- +- +- +- +- 1 +- +- +- +- +- True +- 0 +- in +- +- +- True +- 12 +- +- +- True +- vertical +- +- +- Automatic configuration +- True +- True +- False +- True +- True +- +- +- +- 0 +- +- +- +- +- True +- False +- 3 +- 2 +- 2 +- +- +- True +- 0 +- IP Address: +- +- +- GTK_FILL +- GTK_FILL +- +- +- +- +- True +- 0 +- Gateway: +- +- +- 1 +- 2 +- GTK_FILL +- GTK_FILL +- +- +- +- +- True +- 0 +- DNS Servers: +- +- +- 2 +- 3 +- GTK_FILL +- GTK_FILL +- +- +- +- +- True +- True +- 39 +- 39 +- True +- +- +- +- 1 +- 2 +- 1 +- 2 +- GTK_FILL +- +- +- +- +- True +- True +- 35 +- +- +- +- 1 +- 2 +- 2 +- 3 +- GTK_FILL +- +- +- +- +- True +- 2 +- +- +- True +- True +- 39 +- 39 +- True +- +- +- +- 0 +- +- +- +- +- True +- 0 +- Prefix: +- +- +- False +- 1 +- +- +- +- +- True +- True +- 2 +- 2 +- True +- +- +- +- False +- 2 +- +- +- +- +- 1 +- 2 +- GTK_FILL +- +- +- +- +- 1 +- +- +- +- +- +- +- +- +- True +- <b>IP Configuration</b> +- True +- +- +- +- +- False +- 2 +- +- +- +- +- True +- 1 +- 0 +- +- +- Use these network settings +- True +- False +- True +- True +- +- +- +- +- +- False +- 3 +- +- +- +- +- +- +- +- +- True +- vertical +- +- +- True +- 0 +- 0 +- +- +- True +- 0 +- in +- +- +- True +- 12 +- +- +- True +- vertical +- +- +- True +- 3 +- 2 +- 2 +- +- +- True +- 0 +- Hostname: +- +- +- +- +- +- +- +- +- True +- 0 +- Username: +- +- +- 1 +- 2 +- +- +- +- +- +- +- True +- 0 +- Password: +- +- +- 2 +- 3 +- +- +- +- +- +- +- True +- True +- +- 40 +- +- +- +- 1 +- 2 +- +- +- +- +- +- True +- True +- False +- +- 40 +- +- +- +- 1 +- 2 +- 2 +- 3 +- +- +- +- +- +- True +- True +- +- 40 +- root +- +- +- +- 1 +- 2 +- 1 +- 2 +- +- +- +- +- +- False +- 0 +- +- +- +- +- True +- 0 +- 0 +- 8 +- 8 +- +- +- +- +- +- 1 +- +- +- +- +- +- +- +- +- True +- <b>Connect to conversion server</b> +- True +- +- +- +- +- +- +- 0 +- +- +- +- +- True +- 1 +- 0 +- 0 +- 0 +- +- +- Connect +- True +- False +- True +- True +- +- +- +- +- +- False +- 1 +- +- +- +- +- +- +- +- +- True +- vertical +- +- +- True +- +- +- True +- 0 +- out +- +- +- True +- 0 +- 0 +- 0 +- 0 +- 12 +- +- +- True +- 4 +- 2 +- 2 +- +- +- True +- 0 +- Destination Profile: +- +- +- +- +- True +- convert_profile_list +- +- +- +- +- 0 +- +- +- +- +- 1 +- 2 +- +- +- +- +- True +- 0 +- Memory (MB): +- +- +- 3 +- 4 +- +- +- +- +- True +- True +- +- True +- +- +- +- 1 +- 2 +- 3 +- 4 +- +- +- +- +- True +- 0 +- Number of CPUs: +- +- +- 2 +- 3 +- +- +- +- +- True +- 0 +- Name +- +- +- 1 +- 2 +- +- +- +- +- True +- True +- +- True +- +- +- +- 1 +- 2 +- 1 +- 2 +- +- +- +- +- True +- True +- +- True +- +- +- +- 1 +- 2 +- 2 +- 3 +- +- +- +- +- +- +- +- +- True +- <b>Target properties</b> +- True +- +- +- +- +- False +- False +- 0 +- +- +- +- +- True +- vertical +- +- +- True +- 0 +- out +- +- +- True +- +- +- True +- True +- automatic +- automatic +- +- +- True +- True +- convert_fixed_list +- False +- 0 +- +- +- Convert +- True +- +- +- +- +- +- 0 +- +- +- +- +- +- +- Device +- +- +- +- 1 +- +- +- +- +- +- +- Transfer Progress +- True +- +- +- +- 2 +- +- +- +- +- +- +- +- +- +- +- +- +- True +- <b>Fixed Storage</b> +- True +- +- +- +- +- 0 +- +- +- +- +- True +- 0 +- out +- +- +- True +- +- +- True +- True +- automatic +- automatic +- +- +- True +- True +- convert_removable_list +- +- +- Convert +- +- +- +- +- +- 0 +- +- +- +- +- +- +- Device +- +- +- +- 1 +- +- +- +- +- +- +- Type +- +- +- +- 2 +- +- +- +- +- +- +- +- +- +- +- +- +- True +- <b>Removable Media</b> +- True +- +- +- +- +- 1 +- +- +- +- +- True +- 0 +- out +- +- +- True +- 1 +- 1 +- +- +- True +- True +- automatic +- automatic +- +- +- True +- True +- convert_network_list +- False +- 0 +- +- +- Convert +- +- +- +- +- +- 0 +- +- +- +- +- +- +- Device +- +- +- +- 1 +- +- +- +- +- +- +- +- +- +- +- +- +- True +- <b>Network Interfaces</b> +- True +- +- +- +- +- 2 +- +- +- +- +- 1 +- +- +- +- +- 0 +- +- +- +- +- True +- +- +- True +- 0 +- 12 +- +- +- +- +- +- 0 +- +- +- +- +- Convert +- True +- True +- True +- +- +- +- False +- False +- 1 +- +- +- +- +- False +- False +- 1 +- +- +- +- +- +- +- +- +- True +- vertical +- +- +- True +- A guest has been successfully created on the target server. +- +-Remove the temporary boot device from this machine and press 'Reboot' to continue. +- center +- +- +- 0 +- +- +- +- +- True +- 0.25 +- 0.25 +- +- +- Reboot +- True +- True +- True +- +- +- +- +- +- 1 +- +- +- +- +- +- +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 = <= 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, [">= 0"]) +- s.add_runtime_dependency(%q, [">= 0"]) +- s.add_runtime_dependency(%q, [">= 0"]) +- else +- s.add_dependency(%q, [">= 0"]) +- s.add_dependency(%q, [">= 0"]) +- s.add_dependency(%q, [">= 0"]) +- end +- else +- s.add_dependency(%q, [">= 0"]) +- s.add_dependency(%q, [">= 0"]) +- s.add_dependency(%q, [">= 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 - 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 < /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 < $INSTALL_ROOT/etc/$PACKAGE-release <> $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 < +- +-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, +-L. +- +-=head1 AUTHOR +- +-Matthew Booth +- +-=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 diff --git a/virt-v2v-0.8.1-01-e34a8c09.patch b/virt-v2v-0.8.1-01-e34a8c09.patch new file mode 100644 index 0000000..58b03a3 --- /dev/null +++ b/virt-v2v-0.8.1-01-e34a8c09.patch @@ -0,0 +1,57 @@ +commit e34a8c0911f53cff64f9a33d3802ac7361f3fe19 +Author: Matthew Booth +Date: Wed May 11 16:05:18 2011 +0100 + + p2v-client: Drop echoe for build + + echoe changes incompatibly from F14->F15. We're not using the vast majority of + its features, and it remains completely undocumented as far as I can tell. This + patch drops it in favour of a simple, explicit gem build task. + +diff --git a/p2v/client/Rakefile b/p2v/client/Rakefile +index d190f08..23c26f5 100644 +--- a/p2v/client/Rakefile ++++ b/p2v/client/Rakefile +@@ -14,24 +14,10 @@ + # along with this program; if not, write to the Free Software + # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +-require 'rubygems' +-require 'echoe' ++require 'rake' ++require 'rake/gempackagetask' + +-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 = < :gem ++ ++load 'virt-p2v.gemspec' ++Rake::GemPackageTask.new(GEMSPEC) {} +diff --git a/virt-v2v.spec.PL b/virt-v2v.spec.PL +index 2249b01..6a155e2 100644 +--- a/virt-v2v.spec.PL ++++ b/virt-v2v.spec.PL +@@ -79,7 +79,6 @@ BuildRequires: perl-hivex >= 1.2.2 + + # virt-p2v build requirements + BuildRequires: rubygem(rake) +-BuildRequires: rubygem(echoe) + + Requires: perl(:MODULE_COMPAT_%(eval "`%{__perl} -V:version`"; echo $version)) + diff --git a/virt-v2v-0.8.1-02-fadb1929.patch b/virt-v2v-0.8.1-02-fadb1929.patch new file mode 100644 index 0000000..8fc6c4a --- /dev/null +++ b/virt-v2v-0.8.1-02-fadb1929.patch @@ -0,0 +1,111 @@ +commit fadb1929b4a8447a719a34f07e5934badf694f45 +Author: Matthew Booth +Date: Wed May 11 16:46:37 2011 +0100 + + p2v-client: Add missing gemspec + + gemspec used to be auto-generated, so was explicitly ignored. It's no longer + auto-generated, so we need it. + +diff --git a/p2v/client/virt-p2v.gemspec b/p2v/client/virt-p2v.gemspec +new file mode 100644 +index 0000000..d8edde8 +--- /dev/null ++++ b/p2v/client/virt-p2v.gemspec +@@ -0,0 +1,96 @@ ++# 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. ++ ++V2V_VERSION = `../../Build version` ++abort "Failed to get version" unless $? == 0 ++ ++GEMSPEC = Gem::Specification.new do |s| ++ s.name = %q{virt-p2v} ++ s.version = V2V_VERSION ++ ++ s.authors = ["Matthew Booth"] ++ s.date = %q{2011-05-10} ++ s.summary = %q{Send a machine's storage and metadata to virt-p2v-server} ++ 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.homepage = %q{http://libguestfs.org} ++ ++ s.default_executable = %q{virt-p2v} ++ s.executables = ["virt-p2v"] ++ s.files = [ ++ "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.require_paths = ["lib"] ++ ++ 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, [">= 0"]) ++ s.add_runtime_dependency(%q, [">= 0"]) ++ s.add_runtime_dependency(%q, [">= 0"]) ++ else ++ s.add_dependency(%q, [">= 0"]) ++ s.add_dependency(%q, [">= 0"]) ++ s.add_dependency(%q, [">= 0"]) ++ end ++ else ++ s.add_dependency(%q, [">= 0"]) ++ s.add_dependency(%q, [">= 0"]) ++ s.add_dependency(%q, [">= 0"]) ++ end ++ ++# Source doesn't contain any rdoc ++# s.extra_rdoc_files = [ ++# "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.rdoc_options = [ ++# "--line-numbers", ++# "--inline-source", ++# "--title", ++# "Virt-p2v" ++# ] ++end diff --git a/virt-v2v.spec b/virt-v2v.spec index 645e393..20f99e2 100644 --- a/virt-v2v.spec +++ b/virt-v2v.spec @@ -16,6 +16,10 @@ BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) # local seq no: the order the patches should be applied in # git commit: the first 8 characters of the git commit hash +Patch0: virt-v2v-0.8.1-00-44eb9021-modified.patch +Patch1: virt-v2v-0.8.1-01-e34a8c09.patch +Patch2: virt-v2v-0.8.1-02-fadb1929.patch + # Unfortunately, despite really being noarch, we have to make virt-v2v arch # dependent to avoid build failures on architectures where libguestfs isn't # available. @@ -53,7 +57,6 @@ BuildRequires: perl-hivex >= 1.2.2 # virt-p2v build requirements BuildRequires: rubygem(rake) -BuildRequires: rubygem(echoe) Requires: perl(:MODULE_COMPAT_%(eval "`%{__perl} -V:version`"; echo $version)) @@ -135,11 +138,16 @@ virt-p2v-image-builder is a tool to create a bootable virt-p2v live image. %prep %setup -q -n %{name}-v%{version} +%patch0 -p1 +%patch1 -p1 +%patch2 -p1 + + %build %{__perl} Build.PL ./Build -pushd p2v-client +pushd p2v/client rake gem popd @@ -172,7 +180,7 @@ mkdir -p %{buildroot}/%{_bindir} 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} @@ -181,8 +189,8 @@ cp COPYING %{buildroot}/%{geminstdir} %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 @@ -191,7 +199,7 @@ sed -i -e 's,^DEFAULT_DATADIR=.*,DEFAULT_DATADIR=%{builderdir},' $builder %check ./Build test -pushd p2v-client +pushd p2v/client # No tests yet #rake test popd