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;
     }