File handle_ova_files.patch of Package virt-v2v
In order to support current OVF and VMDK standards, the following changes
were required:
- Support subdirectories in ova archives (OVF v2.0 standard)
- Open VMDK files in read-only mode (required for version 3)
- Repace rasd:ResourceSubType with rasd:ResourceType, and map
types 10/11 to 'network', and types 30/33 to 'bridge' networks
- Improve 'No mappings found' messages when network translation fails
Index: virt-v2v-0.9.1/lib/Sys/VirtConvert/Connection/VMwareOVASource.pm
===================================================================
--- virt-v2v-0.9.1.orig/lib/Sys/VirtConvert/Connection/VMwareOVASource.pm
+++ virt-v2v-0.9.1/lib/Sys/VirtConvert/Connection/VMwareOVASource.pm
@@ -116,13 +116,16 @@ sub _uncompress_archive
my $ae = Archive::Extract->new(archive => $ova, type => 'tar');
$ae->extract(to => $self->{extractdir});
+ # If the first extracted file ends in /, it's a subdirectory (which is
+ # valid in OVF 2.0). Set 'subdir' to this directory, or ''.
+ $self->{subdir} = ($ae->files->[0] =~/\/$/) ? $ae->files->[0] : '';
}
sub _get_meta
{
my $self = shift;
- my ($ovf) = glob($self->{extractdir}.'/*.ovf');
+ my ($ovf) = glob($self->{extractdir}.'/'.$self->{subdir}.'*.ovf');
my $dom = new XML::DOM::Parser->parsefile($ovf)
or v2vdie __x('Failed to open {ovf} for reading', ovf => $ovf);
my $root = $dom->getDocumentElement();
@@ -202,7 +205,28 @@ sub _get_meta
$info{mac} = undef; # it's assigned automatically by the hypervisor
$info{vnet} = _node_val($nic, 'rasd:Connection/text()'); # not clear how to get it from the ovf
- $info{vnet_type} = _node_val($nic, 'rasd:ResourceSubType/text()');
+ # According to Resource Allocation Profile docs (www.dmtf.org)
+ # and cim-schema (CIM_ResourceAllocationSettingData.mof):
+ #
+ # rasd:ResourceType: uint16 referencing a specific type of resource
+ # 10 = Ethernet Adapter
+ # 11 = Other Network Adapter
+ # 30 = Ethernet Switch Port
+ # 33 = Ethernet Connection
+ # rasd:ResourceSubType: string describing a sub-type or model of resource
+ #
+ # However, it is unclear at this stage if the ResourceType value should
+ # be assigned a network or a bridge. For now, set 10/11 to 'network',
+ # and 30/33 to 'bridge'. If unexpected values are encounted, use the
+ # the nic model (and a mapping error is likely).
+ $info{vnet_type} = _node_val($nic, 'rasd:ResourceType/text()');
+ if ($info{vnet_type} =~ /^(10|11)$/) {
+ $info{vnet_type} = 'network';
+ } elsif ($info{vnet_type} =~ /^(30|33)$/) {
+ $info{vnet_type} = 'bridge';
+ } else {
+ $info{vnet_type} = _node_val($nic, 'rasd:ResourceSubType/text()');
+ }
push(@{$meta{nics}}, \%info);
}
}
@@ -254,7 +278,7 @@ sub _verify_manifest
{
my $self = shift;
- my ($mf_path) = glob($self->{extractdir}.'/*.mf');
+ my ($mf_path) = glob($self->{extractdir}.'/'.$self->{subdir}.'*.mf');
open(my $manifest, '<', $mf_path)
or v2vdie __x('Failed to open {path}: {error}',
path => $mf_path, error => $!);
@@ -267,7 +291,7 @@ sub _verify_manifest
close($manifest);
while (my ($file, $sha1_mf) = each(%files)) {
- open(my $fh, $self->{extractdir}.'/'.$file)
+ open(my $fh, $self->{extractdir}.'/'.$self->{subdir}.$file)
or v2vdie __x('Manifest references non-existant file {name}',
name => $file);
@@ -302,7 +326,7 @@ sub _get_volume
my $name = _node_val($file, '@ovf:href');
die "No href for file $fileRef" unless defined($name);
- my $path = $self->{extractdir}."/$name";
+ my $path = $self->{extractdir}.'/'.$self->{subdir}."$name";
die __x("Guest disk image {path} is not readable.\n", path => $path)
unless (-r $path);
Index: virt-v2v-0.9.1/lib/Sys/VirtConvert/GuestfsHandle.pm
===================================================================
--- virt-v2v-0.9.1.orig/lib/Sys/VirtConvert/GuestfsHandle.pm
+++ virt-v2v-0.9.1/lib/Sys/VirtConvert/GuestfsHandle.pm
@@ -77,9 +77,13 @@ sub new
foreach my $disk (@{$disks}) {
my ($name, $path, $format) = @$disk;
+ # VMDK version 3 disks must be read only
+ my $readonly = ($format eq 'vmdk') ? 1 : 0;
+
$g->add_drive_opts($path,
format => $format,
- name => $name);
+ name => $name,
+ readonly => $readonly);
}
# Add the transfer iso if there is one
Index: virt-v2v-0.9.1/lib/Sys/VirtConvert/Config.pm
===================================================================
--- virt-v2v-0.9.1.orig/lib/Sys/VirtConvert/Config.pm
+++ virt-v2v-0.9.1/lib/Sys/VirtConvert/Config.pm
@@ -497,10 +497,10 @@ sub map_network
return @{$self->{default_net_mapping}}
if (defined($self->{default_net_mapping}));
- logmsg WARN, __x('No mapping found for {type} interface '.
- '{name} in config file. The converted guest may '.
- 'not start until its network interface is updated.',
- type => $oldtype, name => $oldname);
+ logmsg WARN, __x('No mapping found for "network type=\'{type}\' '.
+ 'name=\'{name}\'" in config file. The converted '.
+ 'guest may not start until its network interface '.
+ 'is updated.', type => $oldtype, name => $oldname);
return;
}